Swiftray  1.0
stylable-context.h
Go to the documentation of this file.
1 #include <QDebug>
2 #include <parser/svgpp-common.h>
3 
4 #pragma once
5 
6 namespace Parser {
7 
8 using namespace svgpp;
9 
10 inline color_t BlackColor() { return color_t(0, 0, 0); }
11 
12 inline color_t TransparentBlackColor() { return color_t(0, 0, 0); }
13 
14 inline color_t TransparentWhiteColor() { return color_t(255, 255, 255); }
15 
16 #define BUTTER_CAP 1
17 #define MITER_JOIN 1
18 
21  : color_(BlackColor()), fill_paint_(BlackColor()),
22  stroke_paint_(tag::value::none()), nonzero_fill_rule_(true),
23  stroke_opacity_(1.0), fill_opacity_(1.0), stroke_width_(1.0),
24  line_cap_(BUTTER_CAP), line_join_(MITER_JOIN), miterlimit_(4.0),
25  stroke_dashoffset_(0) {}
26 
28  SVGPPPaint fill_paint_, stroke_paint_;
29  double stroke_opacity_, fill_opacity_;
31  double stroke_width_;
32  int line_cap_;
34  double miterlimit_;
35  std::vector<double> stroke_dasharray_;
37  boost::optional<std::string> marker_start_, marker_mid_, marker_end_;
38 };
39 
40 struct NoninheritedStyle {
41  NoninheritedStyle() : opacity_(1.0), display_(true), overflow_clip_(true) {}
42 
43  double opacity_;
44  bool display_;
45  boost::optional<std::string> mask_fragment_, clip_path_fragment_;
46  boost::optional<std::string> filter_;
47  bool overflow_clip_;
48 };
49 
50 struct Style : InheritedStyle, NoninheritedStyle {
51  struct inherit_tag {
52  };
53 
54  Style() {}
55 
56  Style(Style const &src, inherit_tag) : InheritedStyle(src) {}
57 };
58 
59 template<class AttributeTag>
60 class PaintContext {
61 public:
62  PaintContext(SVGPPPaint &paint) : paint_(paint) {}
63 
64  void set(AttributeTag, svgpp::tag::value::none) {
65  paint_ = svgpp::tag::value::none();
66  }
67 
68  void set(AttributeTag, svgpp::tag::value::currentColor) {
69  paint_ = svgpp::tag::value::currentColor();
70  }
71 
72  void set(AttributeTag, color_t color,
73  svgpp::tag::skip_icc_color = svgpp::tag::skip_icc_color()) {
74  paint_ = color;
75  }
76 
77  template<class IRI>
78  void set(AttributeTag tag, IRI const &iri) {
79  throw std::runtime_error("Non-local references aren't supported");
80  }
81 
82  template<class IRI>
83  void set(AttributeTag tag, svgpp::tag::iri_fragment, IRI const &fragment) {
84  paint_ =
85  IRIPaint(std::string(boost::begin(fragment), boost::end(fragment)));
86  }
87 
88  template<class IRI>
89  void set(AttributeTag tag, IRI const &, svgpp::tag::value::none val) {
90  set(tag, val);
91  }
92 
93  template<class IRI>
94  void set(AttributeTag tag, svgpp::tag::iri_fragment, IRI const &fragment,
95  svgpp::tag::value::none val) {
96  paint_ =
97  IRIPaint(std::string(boost::begin(fragment), boost::end(fragment)),
98  boost::optional<SolidPaint>(val));
99  }
100 
101  template<class IRI>
102  void set(AttributeTag tag, IRI const &,
103  svgpp::tag::value::currentColor val) {
104  set(tag, val);
105  }
106 
107  template<class IRI>
108  void set(AttributeTag tag, svgpp::tag::iri_fragment, IRI const &fragment,
109  svgpp::tag::value::currentColor val) {
110  paint_ =
111  IRIPaint(std::string(boost::begin(fragment), boost::end(fragment)),
112  boost::optional<SolidPaint>(val));
113  }
114 
115  template<class IRI>
116  void set(AttributeTag tag, IRI const &, color_t val,
117  svgpp::tag::skip_icc_color = svgpp::tag::skip_icc_color()) {
118  set(tag, val);
119  }
120 
121  template<class IRI>
122  void set(AttributeTag tag, svgpp::tag::iri_fragment, IRI const &fragment,
123  color_t val,
124  svgpp::tag::skip_icc_color = svgpp::tag::skip_icc_color()) {
125  paint_ =
126  IRIPaint(std::string(boost::begin(fragment), boost::end(fragment)),
127  boost::optional<SolidPaint>(val));
128  }
129 
130 protected:
132 };
133 
134 class StylableContext : public PaintContext<svgpp::tag::attribute::stroke>,
135  public PaintContext<svgpp::tag::attribute::fill> {
136 public:
139 
141  : stroke_paint(style_.stroke_paint_), fill_paint(style_.fill_paint_) {}
142 
144  : stroke_paint(style_.stroke_paint_), fill_paint(style_.fill_paint_),
145  style_(src.style_, Style::inherit_tag()) {}
146 
147  using fill_paint::set;
148  using stroke_paint::set;
149 
150  void set(svgpp::tag::attribute::display, svgpp::tag::value::none) {
151  style().display_ = false;
152  }
153 
154  void set(svgpp::tag::attribute::display, svgpp::tag::value::inherit) {
155  style().display_ = parentStyle_.display_;
156  }
157 
158  template<class ValueTag>
159  void set(svgpp::tag::attribute::display, ValueTag) {
160  style().display_ = true;
161  }
162 
163  void set(svgpp::tag::attribute::color, color_t val) {
164  style().color_ = val;
165  }
166 
167  void set(svgpp::tag::attribute::stroke_width, double val) {
168  style().stroke_width_ = val;
169  }
170 
171  void set(svgpp::tag::attribute::stroke_opacity, double val) {
172  style().stroke_opacity_ = std::min(double(1), std::max(double(0), val));
173  }
174 
175  void set(svgpp::tag::attribute::fill_opacity, double val) {
176  style().fill_opacity_ = std::min(double(1), std::max(double(0), val));
177  }
178 
179  void set(svgpp::tag::attribute::opacity, double val) {
180  style().opacity_ = std::min(double(1), std::max(double(0), val));
181  }
182 
183  void set(svgpp::tag::attribute::opacity, svgpp::tag::value::inherit) {
184  style().opacity_ = parentStyle_.opacity_;
185  }
186 
187  void set(svgpp::tag::attribute::fill_rule, svgpp::tag::value::nonzero) {
188  style().nonzero_fill_rule_ = true;
189  }
190 
191  void set(svgpp::tag::attribute::fill_rule, svgpp::tag::value::evenodd) {
192  style().nonzero_fill_rule_ = false;
193  }
194 
195  void set(svgpp::tag::attribute::stroke_linecap, svgpp::tag::value::butt) {}
196 
197  void set(svgpp::tag::attribute::stroke_linecap, svgpp::tag::value::round) {}
198 
199  void set(svgpp::tag::attribute::stroke_linecap, svgpp::tag::value::square) {
200  }
201 
202  void set(svgpp::tag::attribute::stroke_linejoin, svgpp::tag::value::miter) {
203  }
204 
205  void set(svgpp::tag::attribute::stroke_linejoin, svgpp::tag::value::round) {
206  }
207 
208  void set(svgpp::tag::attribute::stroke_linejoin, svgpp::tag::value::bevel) {
209  }
210 
211  void set(svgpp::tag::attribute::stroke_miterlimit, double val) {
212  style().miterlimit_ = val;
213  }
214 
215  void set(svgpp::tag::attribute::stroke_dasharray, svgpp::tag::value::none) {
216  style().stroke_dasharray_.clear();
217  }
218 
219  template<class Range>
220  void set(svgpp::tag::attribute::stroke_dasharray, Range const &range) {
221  style().stroke_dasharray_.assign(boost::begin(range),
222  boost::end(range));
223  }
224 
225  void set(svgpp::tag::attribute::stroke_dashoffset, double val) {
226  style().stroke_dashoffset_ = val;
227  }
228 
229  template<class IRI>
230  void set(svgpp::tag::attribute::mask, IRI const &) {
231  throw std::runtime_error("Non-local references aren't supported");
232  }
233 
234  template<class IRI>
235  void set(svgpp::tag::attribute::mask, svgpp::tag::iri_fragment,
236  IRI const &fragment) {
237  style().mask_fragment_ =
238  std::string(boost::begin(fragment), boost::end(fragment));
239  }
240 
241  void set(svgpp::tag::attribute::mask, svgpp::tag::value::none val) {
242  style().mask_fragment_.reset();
243  }
244 
245  void set(svgpp::tag::attribute::mask, svgpp::tag::value::inherit val) {
246  style().mask_fragment_ = parentStyle_.mask_fragment_;
247  }
248 
249  template<class IRI>
250  void set(svgpp::tag::attribute::clip_path, IRI const &) {
251  throw std::runtime_error("Non-local references aren't supported");
252  }
253 
254  template<class IRI>
255  void set(svgpp::tag::attribute::clip_path, svgpp::tag::iri_fragment,
256  IRI const &fragment) {
257  style().clip_path_fragment_ =
258  std::string(boost::begin(fragment), boost::end(fragment));
259  }
260 
261  void set(svgpp::tag::attribute::clip_path, svgpp::tag::value::none val) {
262  style().clip_path_fragment_.reset();
263  }
264 
265  void set(svgpp::tag::attribute::clip_path, svgpp::tag::value::inherit val) {
266  style().clip_path_fragment_ = parentStyle_.clip_path_fragment_;
267  }
268 
269  Style &style() { return style_; }
270 
271  Style const &style() const { return style_; }
272 
273  template<class IRI>
274  void set(svgpp::tag::attribute::marker_start, IRI const &) {
275  std::cout << "Non-local references aren't supported\n"; // Not error
276  style().marker_start_.reset();
277  }
278 
279  template<class IRI>
280  void set(svgpp::tag::attribute::marker_start, svgpp::tag::iri_fragment,
281  IRI const &fragment) {
282  style().marker_start_ =
283  std::string(boost::begin(fragment), boost::end(fragment));
284  }
285 
286  void set(svgpp::tag::attribute::marker_start, svgpp::tag::value::none) {
287  style().marker_start_.reset();
288  }
289 
290  template<class IRI>
291  void set(svgpp::tag::attribute::marker_mid, IRI const &) {
292  std::cout << "Non-local references aren't supported\n"; // Not error
293  style().marker_mid_.reset();
294  }
295 
296  template<class IRI>
297  void set(svgpp::tag::attribute::marker_mid, svgpp::tag::iri_fragment,
298  IRI const &fragment) {
299  style().marker_mid_ =
300  std::string(boost::begin(fragment), boost::end(fragment));
301  }
302 
303  void set(svgpp::tag::attribute::marker_mid, svgpp::tag::value::none) {
304  style().marker_mid_.reset();
305  }
306 
307  template<class IRI>
308  void set(svgpp::tag::attribute::marker_end, IRI const &) {
309  std::cout << "Non-local references aren't supported\n"; // Not error
310  style().marker_end_.reset();
311  }
312 
313  template<class IRI>
314  void set(svgpp::tag::attribute::marker_end, svgpp::tag::iri_fragment,
315  IRI const &fragment) {
316  style().marker_end_ =
317  std::string(boost::begin(fragment), boost::end(fragment));
318  }
319 
320  void set(svgpp::tag::attribute::marker_end, svgpp::tag::value::none) {
321  style().marker_end_.reset();
322  }
323 
324  template<class IRI>
325  void set(svgpp::tag::attribute::marker, IRI const &) {
326  std::cout << "Non-local references aren't supported\n"; // Not error
327  style().marker_start_.reset();
328  style().marker_mid_.reset();
329  style().marker_end_.reset();
330  }
331 
332  template<class IRI>
333  void set(svgpp::tag::attribute::marker, svgpp::tag::iri_fragment,
334  IRI const &fragment) {
335  std::string iri(boost::begin(fragment), boost::end(fragment));
336  style().marker_start_ = iri;
337  style().marker_mid_ = iri;
338  style().marker_end_ = iri;
339  }
340 
341  void set(svgpp::tag::attribute::marker, svgpp::tag::value::none) {
342  style().marker_start_.reset();
343  style().marker_mid_.reset();
344  style().marker_end_.reset();
345  }
346 
347  template<class IRI>
348  void set(svgpp::tag::attribute::filter, IRI const &) {
349  throw std::runtime_error("Non-local references aren't supported");
350  }
351 
352  template<class IRI>
353  void set(svgpp::tag::attribute::filter, svgpp::tag::iri_fragment,
354  IRI const &fragment) {
355  style().filter_ =
356  std::string(boost::begin(fragment), boost::end(fragment));
357  }
358 
359  void set(svgpp::tag::attribute::filter, svgpp::tag::value::none val) {
360  style().filter_.reset();
361  }
362 
363  void set(svgpp::tag::attribute::filter, svgpp::tag::value::inherit) {
364  style().filter_ = parentStyle_.filter_;
365  }
366 
367  void set(svgpp::tag::attribute::overflow, svgpp::tag::value::inherit) {
368  style().overflow_clip_ = parentStyle_.overflow_clip_;
369  }
370 
371  void set(svgpp::tag::attribute::overflow, svgpp::tag::value::visible) {
372  style().overflow_clip_ = false;
373  }
374 
375  void set(svgpp::tag::attribute::overflow, svgpp::tag::value::auto_) {
376  style().overflow_clip_ = false;
377  }
378 
379  void set(svgpp::tag::attribute::overflow, svgpp::tag::value::hidden) {
380  style().overflow_clip_ = true;
381  }
382 
383  void set(svgpp::tag::attribute::overflow, svgpp::tag::value::scroll) {
384  style().overflow_clip_ = true;
385  }
386 
387  QString strokeColor() {
388  if (auto *color_solid = boost::get<SolidPaint>(&style_.stroke_paint_)) {
389  if (auto *ease_color = boost::get<color_t>(color_solid)) {
390  QString label = "#" +
391  QString::number(ease_color->get<0>(), 16).rightJustified(2, '0') +
392  QString::number((int) ease_color->get<1>(), 16).rightJustified(2, '0') +
393  QString::number((int) ease_color->get<2>(), 16).rightJustified(2, '0');
394  return label;
395  }
396  }
397  return "N/A";
398  }
399 
400  QString fillColor() {
401  if (auto *color_solid = boost::get<SolidPaint>(&style_.fill_paint_)) {
402  if (auto *ease_color = boost::get<color_t>(color_solid)) {
403  QString label = "#" +
404  QString::number(ease_color->get<0>(), 16).rightJustified(2, '0') +
405  QString::number((int) ease_color->get<1>(), 16).rightJustified(2, '0') +
406  QString::number((int) ease_color->get<2>(), 16).rightJustified(2, '0');
407  return label;
408  }
409  }
410  return "N/A";
411  }
412 
413 
414 private:
415  Style style_;
416  NoninheritedStyle parentStyle_;
417 };
418 
419 }
Definition: stylable-context.h:60
void set(AttributeTag, color_t color, svgpp::tag::skip_icc_color=svgpp::tag::skip_icc_color())
Definition: stylable-context.h:72
void set(AttributeTag tag, svgpp::tag::iri_fragment, IRI const &fragment)
Definition: stylable-context.h:83
void set(AttributeTag tag, svgpp::tag::iri_fragment, IRI const &fragment, color_t val, svgpp::tag::skip_icc_color=svgpp::tag::skip_icc_color())
Definition: stylable-context.h:122
SVGPPPaint & paint_
Definition: stylable-context.h:131
void set(AttributeTag tag, IRI const &, color_t val, svgpp::tag::skip_icc_color=svgpp::tag::skip_icc_color())
Definition: stylable-context.h:116
void set(AttributeTag, svgpp::tag::value::currentColor)
Definition: stylable-context.h:68
void set(AttributeTag tag, IRI const &iri)
Definition: stylable-context.h:78
void set(AttributeTag tag, IRI const &, svgpp::tag::value::none val)
Definition: stylable-context.h:89
void set(AttributeTag tag, svgpp::tag::iri_fragment, IRI const &fragment, svgpp::tag::value::none val)
Definition: stylable-context.h:94
void set(AttributeTag, svgpp::tag::value::none)
Definition: stylable-context.h:64
void set(AttributeTag tag, IRI const &, svgpp::tag::value::currentColor val)
Definition: stylable-context.h:102
void set(AttributeTag tag, svgpp::tag::iri_fragment, IRI const &fragment, svgpp::tag::value::currentColor val)
Definition: stylable-context.h:108
PaintContext(SVGPPPaint &paint)
Definition: stylable-context.h:62
Definition: stylable-context.h:135
void set(svgpp::tag::attribute::stroke_linejoin, svgpp::tag::value::miter)
Definition: stylable-context.h:202
void set(svgpp::tag::attribute::marker, svgpp::tag::iri_fragment, IRI const &fragment)
Definition: stylable-context.h:333
void set(svgpp::tag::attribute::marker_mid, IRI const &)
Definition: stylable-context.h:291
void set(svgpp::tag::attribute::stroke_miterlimit, double val)
Definition: stylable-context.h:211
void set(svgpp::tag::attribute::stroke_dashoffset, double val)
Definition: stylable-context.h:225
void set(svgpp::tag::attribute::display, svgpp::tag::value::none)
Definition: stylable-context.h:150
StylableContext(StylableContext const &src)
Definition: stylable-context.h:143
void set(svgpp::tag::attribute::marker, IRI const &)
Definition: stylable-context.h:325
void set(svgpp::tag::attribute::stroke_linejoin, svgpp::tag::value::bevel)
Definition: stylable-context.h:208
void set(svgpp::tag::attribute::fill_rule, svgpp::tag::value::nonzero)
Definition: stylable-context.h:187
void set(svgpp::tag::attribute::filter, svgpp::tag::value::inherit)
Definition: stylable-context.h:363
void set(svgpp::tag::attribute::stroke_dasharray, svgpp::tag::value::none)
Definition: stylable-context.h:215
void set(svgpp::tag::attribute::marker_start, svgpp::tag::iri_fragment, IRI const &fragment)
Definition: stylable-context.h:280
void set(svgpp::tag::attribute::mask, svgpp::tag::value::inherit val)
Definition: stylable-context.h:245
PaintContext< svgpp::tag::attribute::fill > fill_paint
Definition: stylable-context.h:138
void set(svgpp::tag::attribute::marker_start, svgpp::tag::value::none)
Definition: stylable-context.h:286
void set(svgpp::tag::attribute::stroke_width, double val)
Definition: stylable-context.h:167
void set(svgpp::tag::attribute::fill_rule, svgpp::tag::value::evenodd)
Definition: stylable-context.h:191
void set(svgpp::tag::attribute::stroke_linecap, svgpp::tag::value::square)
Definition: stylable-context.h:199
void set(svgpp::tag::attribute::filter, svgpp::tag::value::none val)
Definition: stylable-context.h:359
void set(svgpp::tag::attribute::opacity, svgpp::tag::value::inherit)
Definition: stylable-context.h:183
void set(svgpp::tag::attribute::mask, svgpp::tag::value::none val)
Definition: stylable-context.h:241
void set(svgpp::tag::attribute::filter, svgpp::tag::iri_fragment, IRI const &fragment)
Definition: stylable-context.h:353
void set(svgpp::tag::attribute::clip_path, IRI const &)
Definition: stylable-context.h:250
void set(svgpp::tag::attribute::fill_opacity, double val)
Definition: stylable-context.h:175
void set(svgpp::tag::attribute::marker_mid, svgpp::tag::value::none)
Definition: stylable-context.h:303
Style const & style() const
Definition: stylable-context.h:271
void set(svgpp::tag::attribute::overflow, svgpp::tag::value::hidden)
Definition: stylable-context.h:379
void set(svgpp::tag::attribute::overflow, svgpp::tag::value::auto_)
Definition: stylable-context.h:375
PaintContext< svgpp::tag::attribute::stroke > stroke_paint
Definition: stylable-context.h:137
void set(svgpp::tag::attribute::stroke_opacity, double val)
Definition: stylable-context.h:171
void set(svgpp::tag::attribute::marker_end, svgpp::tag::iri_fragment, IRI const &fragment)
Definition: stylable-context.h:314
void set(svgpp::tag::attribute::stroke_linejoin, svgpp::tag::value::round)
Definition: stylable-context.h:205
void set(svgpp::tag::attribute::marker_end, svgpp::tag::value::none)
Definition: stylable-context.h:320
void set(svgpp::tag::attribute::marker_mid, svgpp::tag::iri_fragment, IRI const &fragment)
Definition: stylable-context.h:297
void set(svgpp::tag::attribute::display, svgpp::tag::value::inherit)
Definition: stylable-context.h:154
void set(svgpp::tag::attribute::clip_path, svgpp::tag::iri_fragment, IRI const &fragment)
Definition: stylable-context.h:255
void set(svgpp::tag::attribute::opacity, double val)
Definition: stylable-context.h:179
StylableContext()
Definition: stylable-context.h:140
void set(svgpp::tag::attribute::stroke_linecap, svgpp::tag::value::butt)
Definition: stylable-context.h:195
void set(svgpp::tag::attribute::marker_start, IRI const &)
Definition: stylable-context.h:274
void set(svgpp::tag::attribute::overflow, svgpp::tag::value::visible)
Definition: stylable-context.h:371
void set(svgpp::tag::attribute::marker_end, IRI const &)
Definition: stylable-context.h:308
QString fillColor()
Definition: stylable-context.h:400
void set(svgpp::tag::attribute::clip_path, svgpp::tag::value::inherit val)
Definition: stylable-context.h:265
void set(svgpp::tag::attribute::overflow, svgpp::tag::value::inherit)
Definition: stylable-context.h:367
QString strokeColor()
Definition: stylable-context.h:387
void set(svgpp::tag::attribute::overflow, svgpp::tag::value::scroll)
Definition: stylable-context.h:383
Style & style()
Definition: stylable-context.h:269
void set(svgpp::tag::attribute::mask, IRI const &)
Definition: stylable-context.h:230
void set(svgpp::tag::attribute::clip_path, svgpp::tag::value::none val)
Definition: stylable-context.h:261
void set(svgpp::tag::attribute::stroke_linecap, svgpp::tag::value::round)
Definition: stylable-context.h:197
void set(svgpp::tag::attribute::stroke_dasharray, Range const &range)
Definition: stylable-context.h:220
void set(svgpp::tag::attribute::mask, svgpp::tag::iri_fragment, IRI const &fragment)
Definition: stylable-context.h:235
void set(svgpp::tag::attribute::color, color_t val)
Definition: stylable-context.h:163
void set(svgpp::tag::attribute::filter, IRI const &)
Definition: stylable-context.h:348
void set(svgpp::tag::attribute::display, ValueTag)
Definition: stylable-context.h:159
void set(svgpp::tag::attribute::marker, svgpp::tag::value::none)
Definition: stylable-context.h:341
Definition: base-context.h:8
boost::variant< SolidPaint, IRIPaint > SVGPPPaint
Definition: svgpp-defs.h:27
color_t TransparentBlackColor()
Definition: stylable-context.h:12
color_t TransparentWhiteColor()
Definition: stylable-context.h:14
color_t BlackColor()
Definition: stylable-context.h:10
boost::tuple< unsigned char, unsigned char, unsigned char > color_t
Definition: svgpp-color-factory.h:7
Definition: stylable-context.h:19
int line_cap_
Definition: stylable-context.h:32
InheritedStyle()
Definition: stylable-context.h:20
std::vector< double > stroke_dasharray_
Definition: stylable-context.h:35
int line_join_
Definition: stylable-context.h:33
double fill_opacity_
Definition: stylable-context.h:29
SVGPPPaint fill_paint_
Definition: stylable-context.h:28
double miterlimit_
Definition: stylable-context.h:34
bool nonzero_fill_rule_
Definition: stylable-context.h:30
double stroke_width_
Definition: stylable-context.h:31
double stroke_dashoffset_
Definition: stylable-context.h:36
boost::optional< std::string > marker_end_
Definition: stylable-context.h:37
color_t color_
Definition: stylable-context.h:27
Definition: stylable-context.h:51
Definition: stylable-context.h:50
Style(Style const &src, inherit_tag)
Definition: stylable-context.h:56
Style()
Definition: stylable-context.h:54
#define MITER_JOIN
Definition: stylable-context.h:17
#define BUTTER_CAP
Definition: stylable-context.h:16