Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
style-internal.h
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2#ifndef SEEN_SP_STYLE_INTERNAL_H
3#define SEEN_SP_STYLE_INTERNAL_H
4
8/* Authors:
9 * Lauris Kaplinski <lauris@kaplinski.com>
10 * Jon A. Cruz <jon@joncruz.org>
11 * Tavmjong Bah <tavmjong@free.fr>
12 *
13 * Copyright (C) 2014, 2018 Tavmjong Bah
14 * Copyright (C) 2010 Jon A. Cruz
15 * Copyright (C) 2001-2002 Lauris Kaplinski
16 * Copyright (C) 2001 Ximian, Inc.
17 *
18 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
19 */
20
21#include <utility>
22#include <vector>
23#include <map>
24
25#include "attributes.h"
26#include "style-enums.h"
27
29#include "object/sp-filter.h"
33
34#include "object/uri.h"
35
36// TODO: Remove include when we figure out how to store Color without the full class
37#include "colors/color.h"
38
39#include "xml/repr.h"
40
41namespace Inkscape {
42class ObjectSet;
43namespace Colors {
44class Color;
45class DocumentCMS;
46}
47};
48
49using namespace Inkscape;
50
51static const unsigned SP_STYLE_FLAG_ALWAYS (1 << 2);
52static const unsigned SP_STYLE_FLAG_IFSET (1 << 0);
53static const unsigned SP_STYLE_FLAG_IFDIFF (1 << 1);
54static const unsigned SP_STYLE_FLAG_IFSRC (1 << 3); // If source matches
55
56enum class SPStyleSrc : unsigned char
57{
58 UNSET,
59 ATTRIBUTE, // fill="red"
60 STYLE_PROP, // style="fill:red"
61 STYLE_SHEET, // .red { fill:red; }
62};
63
64/* General comments:
65 *
66 * This code is derived from the original C style code in style.cpp.
67 *
68 * Overview:
69 * Style can be obtained (in order of precedence) [CHECK]
70 * 1. "style" property in an element (style="fill:red").
71 * 2. Style sheet, internal or external (<style> rect {fill:red;}</style>).
72 * 3. Attributes in an element (fill="red").
73 * 4. Parent's style.
74 * A later property overrides an earlier property. This is implemented by
75 * reading in the properties backwards. If a property is already set, it
76 * prevents an earlier property from being read.
77 *
78 * A declaration with an "!important" rule overrides any other declarations (except those that
79 * also have an "!important" rule). Attributes can not use the "!important" rule and the rule
80 * is not inherited.
81 *
82 * In order for cascading to work, each element in the tree must be read in from top to bottom
83 * (parent before child). At each step, if a style property is not explicitly set, the property
84 * value is taken from the parent. Some properties have "computed" values that depend on:
85 * the parent's value (e.g. "font-size:larger"),
86 * another property value ("stroke-width":1em"), or
87 * an external value ("stroke-width:5%").
88 *
89 * To summarize:
90 *
91 * An explicitly set value (including 'inherit') has a 'true' "set" flag.
92 * The "value" is either explicitly set or inherited.
93 * The "computed" value (if present) is calculated from "value" and some other input.
94 *
95 * Functions:
96 * write(): Write a property and its value to a string.
97 * Flags:
98 * ALWAYS: Always write out property.
99 * IFSET: Write a property if 'set' flag is true, otherwise return empty string.
100 * IFDIFF: Write a property if computed values are different, otherwise return empty string,
101 * This is only used for text!!
102 * IFSRC Write a property if the source matches the requested source (style sheet, etc.).
103 *
104 * read(): Set a property value from a string.
105 * clear(): Set a property to its default value and set the 'set' flag to false.
106 * cascade(): Cascade the parent's property values to the child if the child's property
107 * is unset (and it allows inheriting) or the value is 'inherit'.
108 * Calculate computed values that depend on parent.
109 * This requires that the parent already be updated.
110 * merge(): Merge the property values of a child and a parent that is being deleted,
111 * attempting to preserve the style of the child.
112 * operator=: Assignment operator required due to use of templates (in original C code).
113 * operator==: True if computed values are equal. TO DO: DEFINE EXACTLY WHAT THIS MEANS
114 * operator!=: Inverse of operator==.
115 *
116 *
117 * Outside dependencies:
118 *
119 * The C structures that these classes are evolved from were designed to be embedded in to the
120 * style structure (i.e they are "internal" and thus have an "I" in the SPI prefix). However,
121 * they should be reasonably stand-alone and can provide some functionality outside of the style
122 * structure (i.e. reading and writing style strings). Some properties do need access to other
123 * properties from the same object (e.g. SPILength sometimes needs to know font size) to
124 * calculate 'computed' values. Inheritance, of course, requires access to the parent object's
125 * style class.
126 *
127 * The only real outside dependency is SPObject... which is needed in the cases of SPIPaint and
128 * SPIFilter for setting up the "href". (Currently, SPDocument is needed but this dependency
129 * should be removed as an "href" only needs the SPDocument for attaching an external document to
130 * the XML tree [see uri-references.cpp]. If SPDocument is really needed, it can be obtained from
131 * SPObject.)
132 *
133 */
134
137{
138
139public:
140 SPIBase(bool inherits_ = true)
141 : inherits(inherits_),
142 set(false),
143 inherit(false),
144 important(false),
145 style_src(SPStyleSrc::STYLE_PROP), // Default to property, see bug 1662285.
146 style(nullptr)
147 {}
148
149 virtual ~SPIBase()
150 = default;
151
152 virtual void read( gchar const *str ) = 0;
153 void readIfUnset(gchar const *str, SPStyleSrc source = SPStyleSrc::STYLE_PROP);
154
155protected:
156 char const *important_str() const { return important ? " !important" : ""; }
157
158public:
160 {
162 }
163
164 virtual const Glib::ustring get_value() const = 0;
165 bool shall_write( guint const flags = SP_STYLE_FLAG_IFSET,
166 SPStyleSrc const &style_src_req = SPStyleSrc::STYLE_PROP,
167 SPIBase const *const base = nullptr ) const;
168 virtual const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET,
169 SPStyleSrc const &style_src_req = SPStyleSrc::STYLE_PROP,
170 SPIBase const *const base = nullptr ) const;
171 virtual void clear() {
172 set = false, inherit = false, important = false;
173 // Attr::D is a special case where the best default for it is actually ATTRIBUTE
174 // and not STYLE_PROP, this exception allows us to not have to refactor more.
175 if (id() != SPAttr::D) {
177 }
178 }
179 void overwrite(const SPIBase* const other) {
180 clear();
181 merge(other);
182 }
183
184 virtual void cascade( const SPIBase* const parent ) = 0;
185 virtual void merge( const SPIBase* const parent ) = 0;
186
187 void setStylePointer(SPStyle *style_in) { style = style_in; }
188
189 // Explicit assignment operator required due to templates.
190 SPIBase& operator=(const SPIBase& rhs) = default;
191
192 // Check apples being compared to apples
193 virtual bool equals(const SPIBase& rhs) const {
194 return id() == rhs.id();
195 }
196
197 bool operator==(const SPIBase& rhs) const { return equals(rhs); }
198
199 virtual SPAttr id() const { return SPAttr::INVALID; }
200 Glib::ustring const &name() const;
201
202 // To do: make private
203public:
204 bool inherits : 1; // Property inherits by default from parent.
205 bool set : 1; // Property has been explicitly set (vs. inherited).
206 bool inherit : 1; // Property value set to 'inherit'.
207 bool important : 1; // Property rule 'important' has been explicitly set.
208 SPStyleSrc style_src; // Source (attribute, style attribute, style-sheet).
209
210protected:
211 SPStyle* style; // Used by SPIPaint, SPIFilter... to find values of other properties
212};
213
214
218template <SPAttr Id, class Base>
219class TypedSPI : public Base {
220 public:
221 using Base::Base;
222
226 SPAttr id() const override { return Id; }
227 static SPAttr static_id() { return Id; }
228
232 Base *upcast() { return static_cast<Base *>(this); }
233 Base const *upcast() const { return static_cast<Base const *>(this); }
234};
235
236
238class SPIFloat : public SPIBase
239{
240
241public:
246
247 ~SPIFloat() override = default;
248 void read( gchar const *str ) override;
249 const Glib::ustring get_value() const override;
250 void clear() override {
253 }
254
255 void cascade( const SPIBase* const parent ) override;
256 void merge( const SPIBase* const parent ) override;
257
258 SPIFloat& operator=(const SPIFloat& rhs) = default;
259
260 bool equals(const SPIBase& rhs) const override;
261
262 // To do: make private
263public:
264 float value = 0.0;
265
266private:
267 float value_default = 0.0;
268};
269
270/*
271 * One might think that the best value for SP_SCALE24_MAX would be ((1<<24)-1), which allows the
272 * greatest possible precision for fitting [0, 1] fractions into 24 bits.
273 *
274 * However, in practice, that gives a problem with 0.5, which falls half way between two fractions
275 * of ((1<<24)-1). What's worse is that casting double(1<<23) / ((1<<24)-1) to float on x86
276 * produces wrong rounding behaviour, resulting in a fraction of ((1<<23)+2.0f) / (1<<24) rather
277 * than ((1<<23)+1.0f) / (1<<24) as one would expect, let alone ((1<<23)+0.0f) / (1<<24) as one
278 * would ideally like for this example.
279 *
280 * The value (1<<23) is thus best if one considers float conversions alone.
281 *
282 * The value 0xff0000 can exactly represent all 8-bit alpha channel values,
283 * and can exactly represent all multiples of 0.1. I haven't yet tested whether
284 * rounding bugs still get in the way of conversions to & from float, but my instinct is that
285 * it's fairly safe because 0xff fits three times inside float's significand.
286 *
287 * We should probably use the value 0xffff00 once we support 16 bits per channel and/or LittleCMS,
288 * though that might need to be accompanied by greater use of double instead of float for
289 * colours and opacities, to be safe from rounding bugs.
290 */
291static const unsigned SP_SCALE24_MAX = 0xff0000;
292#define SP_SCALE24_TO_FLOAT(v) ((double) (v) / SP_SCALE24_MAX)
293#define SP_SCALE24_FROM_FLOAT(v) unsigned(((v) * SP_SCALE24_MAX) + .5)
294
296#define SP_SCALE24_MUL(_v1, _v2) unsigned((double)(_v1) * (_v2) / SP_SCALE24_MAX + .5)
297
298
300// Used only for opacity, fill-opacity, stroke-opacity.
301// Opacity does not inherit but stroke-opacity and fill-opacity do.
302class SPIScale24 : public SPIBase
303{
304 static unsigned get_default() { return SP_SCALE24_MAX; }
305
306public:
307 SPIScale24(bool inherits = true )
308 : SPIBase(inherits),
310 {}
311
312 ~SPIScale24() override
313 = default;
314
315 operator double() const { return SP_SCALE24_TO_FLOAT(value); }
316
317 void read( gchar const *str ) override;
318 const Glib::ustring get_value() const override;
319 void clear() override {
321 value = get_default();
322 }
323 void set_double(const double& other) {
324 value = SP_SCALE24_FROM_FLOAT(other);
325 set = true;
326 }
327
328 void cascade( const SPIBase* const parent ) override;
329 void merge( const SPIBase* const parent ) override;
330
331 SPIScale24& operator=(const SPIScale24& rhs) = default;
332
333 bool equals(const SPIBase& rhs) const override;
334
335 // To do: make private
336public:
337 unsigned value : 24;
338};
339
340
353
354
356// Needs access to 'font-size' and 'font-family' for computed values.
357// Used for 'stroke-width' 'stroke-dash-offset' ('none' not handled), text-indent
358class SPILength : public SPIBase
359{
360
361public:
362 SPILength(float value = 0)
364 value(value),
367 {}
368
369 ~SPILength() override
370 = default;
371
372 void read( gchar const *str ) override;
373 const Glib::ustring get_value() const override;
374 void clear() override {
378 }
379
380 void cascade( const SPIBase* const parent ) override;
381 void merge( const SPIBase* const parent ) override;
382
383 SPILength& operator=(const SPILength& rhs) = default;
384
385 bool equals(const SPIBase& rhs) const override;
386 void setDouble(double v);
387 virtual const Glib::ustring toString(bool wname = false) const;
388
389 // To do: make private
390 public:
391 unsigned unit : 4;
392 float value = 0.f;
393 float computed = 0.f;
394
395private:
396 float value_default = 0.f;
397};
398
399
401// Used for: line-height, letter-spacing, word-spacing
403{
404
405public:
407 : SPILength(value),
408 normal(true)
409 {}
410
412 = default;
413
414 void read( gchar const *str ) override;
415 const Glib::ustring get_value() const override;
416 void clear() override {
418 normal = true;
419 }
420
421 void cascade( const SPIBase* const parent ) override;
422 void merge( const SPIBase* const parent ) override;
423
425
426 bool equals(const SPIBase& rhs) const override;
427
428 // To do: make private
429public:
430 bool normal : 1;
431};
432
433
435// Used for: font-variation-settings
437{
438
439public:
441 : normal(true)
442 {}
443
445 = default;
446
447 void read( gchar const *str ) override;
448 const Glib::ustring get_value() const override;
449 void clear() override {
451 axes.clear();
452 normal = true;
453 }
454
455 void cascade( const SPIBase* const parent ) override;
456 void merge( const SPIBase* const parent ) override;
457
460 axes = rhs.axes;
461 normal = rhs.normal;
462 return *this;
463 }
464
465 bool equals(const SPIBase& rhs) const override;
466
467 virtual const Glib::ustring toString() const;
468
469 // To do: make private
470public:
471 bool normal : 1;
472 std::map<Glib::ustring, float> axes;
473};
474
475
477// Used for many properties. 'font-stretch' and 'font-weight' must be special cased.
478template <typename T>
479class SPIEnum : public SPIBase
480{
481
482public:
483 SPIEnum(T value = T(), bool inherits = true) :
485 value(value),
487 {
489 }
490
491 ~SPIEnum() override
492 = default;
493
494 void read( gchar const *str ) override;
495 const Glib::ustring get_value() const override;
496 void clear() override {
500 }
501
502 void cascade( const SPIBase* const parent ) override;
503 void merge( const SPIBase* const parent ) override;
504
505 SPIEnum& operator=(const SPIEnum& rhs) {
507 value = rhs.value;
508 computed = rhs.computed;
510 return *this;
511 }
512
513 bool equals(const SPIBase& rhs) const override;
514
515 // To do: make private
516public:
517 T value{};
519
520private:
522
524 void update_computed();
526 void update_computed_cascade(T const &parent_computed) {}
530 void update_value_merge(SPIEnum<T> const &, T, T);
531};
532
533
534#if 0
536class SPIEnumBits : public SPIEnum
537{
538
539public:
540 SPIEnumBits( Glib::ustring const &name, SPStyleEnum const *enums, unsigned value = 0, bool inherits = true ) :
541 SPIEnum( name, enums, value, inherits )
542 {}
543
544 ~SPIEnumBits() override
545 = default;
546
547 void read( gchar const *str ) override;
548 const Glib::ustring get_value() const override;
549};
550#endif
551
552
557using _SPCSSFontVariantLigatures_int = typename std::underlying_type<SPCSSFontVariantLigatures>::type;
558class SPILigatures : public SPIEnum<_SPCSSFontVariantLigatures_int>
559{
560
561public:
565
566 ~SPILigatures() override
567 = default;
568
569 void read( gchar const *str ) override;
570 const Glib::ustring get_value() const override;
571};
572
573
576using _SPCSSFontVariantNumeric_int = typename std::underlying_type<SPCSSFontVariantNumeric>::type;
577class SPINumeric : public SPIEnum<_SPCSSFontVariantNumeric_int>
578{
579
580public:
584
585 ~SPINumeric() override
586 = default;
587
588 void read( gchar const *str ) override;
589 const Glib::ustring get_value() const override;
590};
591
592
595using _SPCSSFontVariantEastAsian_int = typename std::underlying_type<SPCSSFontVariantEastAsian>::type;
596class SPIEastAsian : public SPIEnum<_SPCSSFontVariantEastAsian_int>
597{
598
599public:
603
604 ~SPIEastAsian() override
605 = default;
606
607 void read( gchar const *str ) override;
608 const Glib::ustring get_value() const override;
609};
610
611
613// Used for 'marker', ..., 'font', 'font-family', 'inkscape-font-specification'
614class SPIString : public SPIBase
615{
616
617public:
618 SPIString(bool inherits = true)
620 {}
621
622 SPIString(const SPIString &rhs) { *this = rhs; }
623
624 ~SPIString() override {
625 g_free(_value);
626 }
627
628 void read( gchar const *str ) override;
629 const Glib::ustring get_value() const override;
630 void clear() override; // TODO check about value and value_default
631 void cascade( const SPIBase* const parent ) override;
632 void merge( const SPIBase* const parent ) override;
633
635 if (this == &rhs) {
636 return *this;
637 }
639 g_free(_value);
640 _value = g_strdup(rhs._value);
641 return *this;
642 }
643
644 bool equals(const SPIBase& rhs) const override;
645
647 char const *value() const;
648
649 private:
650 char const *get_default_value() const;
651
652 gchar *_value = nullptr;
653};
654
656// Used for 'shape-inside', shape-subtract'
657// Differs from SPIString by creating/deleting listeners on referenced shapes.
658class SPIShapes : public SPIString
659{
660 void hrefs_clear();
661
662public:
663 ~SPIShapes() override;
664 SPIShapes();
665 SPIShapes(const SPIShapes &) = delete; // Copying causes problems with hrefs.
666 void read( gchar const *str ) override;
667 void clear() override;
668
669public:
670 std::vector<SPShapeReference *> hrefs;
672};
673
674class SPIColor : public SPIBase
675{
676
677public:
678 SPIColor(bool inherits = true);
679 ~SPIColor() override = default;
680
681 void read(gchar const *str) override;
682 void read(gchar const *str, SPStyle &style);
683
684 const Glib::ustring get_value() const override;
685 void clear() override {
687 _color.reset();
688 }
689
690 void cascade( const SPIBase* const parent ) override;
691 void merge( const SPIBase* const parent ) override;
692
693 SPIColor& operator=(const SPIColor& rhs);
694 SPIColor& operator=(const Colors::Color &rhs);
695
696 bool equals(const SPIBase& rhs) const override;
697
698 void setColor(Colors::Color const &other);
699 Colors::Color const &getColor() const;
700
701 bool canHaveCMS() const;
702 Colors::DocumentCMS const &getCMS() const;
703public:
704 bool currentcolor = false;
705private:
706 std::optional<Colors::Color> _color;
707};
708
709
710
711#define SP_STYLE_FILL_SERVER(s) ((const_cast<SPStyle *> (s))->getFillPaintServer())
712#define SP_STYLE_STROKE_SERVER(s) ((const_cast<SPStyle *> (s))->getStrokePaintServer())
713
714// SVG 2
721
722
724class SPIPaint : public SPIBase
725{
726
727public:
728 SPIPaint();
729 ~SPIPaint() override = default;
730 void read(gchar const *str) override;
731 const Glib::ustring get_value() const override;
732 void clear() override;
733 virtual void reset( bool init ); // Used internally when reading or cascading
734 void cascade( const SPIBase* const parent ) override;
735 void merge( const SPIBase* const parent ) override;
736
741 noneSet = rhs.noneSet;
742 _color = rhs._color;
743 href = rhs.href;
744 return *this;
745 }
746
747 bool equals(const SPIBase& rhs) const override;
748
749 bool isSameType( SPIPaint const & other ) const {
750 return
751 (isPaintserver() == other.isPaintserver()) &&
752 (isColor() == other.isColor()) &&
753 (paintOrigin == other.paintOrigin) &&
754 (paintSource == other.paintSource);
755 }
756
757 bool isNoneSet() const {
758 return noneSet;
759 }
760
761 bool isNone() const {
763 }
764
765 bool isColor() const {
766 return _color && !isPaintserver();
767 }
768
769 bool isPaintserver() const {
770 return href && href->getObject() != nullptr;
771 }
772
778
779 void setNone() {
780 noneSet = true;
781 _color.reset();
782 }
783
784 void setTag(SPObject* tag) { this->tag = tag; }
785 SPObject* getTag() { return tag; }
786
787 void setColor(Colors::Color const &other);
788 Colors::Color const &getColor() const;
789
790 bool canHaveCMS() const;
791 Colors::DocumentCMS const &getCMS() const;
792 // To do: make private
793public:
794 SPPaintOrigin paintOrigin : 2; // Inherited value (from cascade)
795 SPPaintOrigin paintSource: 2; // Set value (from XML)
796 bool noneSet : 1;
797 std::shared_ptr<SPPaintServerReference> href;
798 SPObject *tag = nullptr;
799private:
800 std::optional<Colors::Color> _color;
801};
802
803
804// SVG 2
811
812// Normal maybe should be moved out as is done in other classes.
813// This could be replaced by a generic enum class where multiple keywords are allowed and
814// where order matters (in contrast to 'text-decoration-line' where order does not matter).
815
816// Each layer represents a layer of paint which can be a fill, a stroke, or markers.
817inline constexpr size_t PAINT_ORDER_LAYERS = 3;
818
820class SPIPaintOrder : public SPIBase
821{
822
823public:
825 this->clear();
826 }
827
828 SPIPaintOrder(const SPIPaintOrder &rhs) { *this = rhs; }
829
830 ~SPIPaintOrder() override {
831 g_free( value );
832 }
833
834 void read( gchar const *str ) override;
835 const Glib::ustring get_value() const override;
836 unsigned get_order(SPPaintOrderLayer paint_order) const;
837
838 void clear() override {
840 for( unsigned i = 0; i < PAINT_ORDER_LAYERS; ++i ) {
842 layer_set[i] = false;
843 }
844 g_free(value);
845 value = nullptr;
846 }
847 void cascade( const SPIBase* const parent ) override;
848 void merge( const SPIBase* const parent ) override;
849
851 if (this == &rhs) {
852 return *this;
853 }
855 for( unsigned i = 0; i < PAINT_ORDER_LAYERS; ++i ) {
856 layer[i] = rhs.layer[i];
857 layer_set[i] = rhs.layer_set[i];
858 }
859 g_free(value);
860 value = g_strdup(rhs.value);
861 return *this;
862 }
863
864 bool equals(const SPIBase& rhs) const override;
865
866 std::array<SPPaintOrderLayer, PAINT_ORDER_LAYERS> get_layers() const;
867
868 // To do: make private
869public:
872 gchar *value = nullptr; // Raw string
873};
874
875
877class SPIDashArray : public SPIBase
878{
879
880public:
881 SPIDashArray() = default;
882
883 ~SPIDashArray() override
884 = default;
885
886 void read( gchar const *str ) override;
887 const Glib::ustring get_value() const override;
888 void clear() override {
890 values.clear();
891 }
892
893 void cascade( const SPIBase* const parent ) override;
894 void merge( const SPIBase* const parent ) override;
895
896 SPIDashArray& operator=(const SPIDashArray& rhs) = default;
897
898 bool equals(const SPIBase& rhs) const override;
899
900 bool is_valid() const;
901
902 std::vector<double> get_computed() const {
903 std::vector<double> output;
904 for (auto val : values) {
905 output.push_back(val.computed);
906 }
907 return output;
908 }
909
910 // To do: make private, change double to SVGLength
911public:
912 std::vector<SPILength> values;
913};
914
916class SPIFilter : public SPIBase
917{
918
919public:
921 : SPIBase(false)
922 {}
923
924 ~SPIFilter() override;
925 void read( gchar const *str ) override;
926 const Glib::ustring get_value() const override;
927 void clear() override;
928 void cascade( const SPIBase* const parent ) override;
929 void merge( const SPIBase* const parent ) override;
930
931 SPIFilter& operator=(const SPIFilter& rhs) = default;
932
933 bool equals(const SPIBase& rhs) const override;
934
935 // To do: make private
936public:
938};
939
940
941
942enum {
947
949class SPIFontSize : public SPIBase
950{
951
952public:
954 this->clear();
955 }
956
957 ~SPIFontSize() override
958 = default;
959
960 void read( gchar const *str ) override;
961 const Glib::ustring get_value() const override;
962 void clear() override {
966 }
967
968 void cascade( const SPIBase* const parent ) override;
969 void merge( const SPIBase* const parent ) override;
970
971 SPIFontSize& operator=(const SPIFontSize& rhs) = default;
972
973 bool equals(const SPIBase& rhs) const override;
974
975public:
976 static float const font_size_default;
977
978 // To do: make private
979public:
980 unsigned type : 2;
981 unsigned unit : 4;
982 unsigned literal : 4;
983 float value;
984 float computed;
985
986private:
987 double relative_fraction() const;
988 static float const font_size_table[];
989};
990
991
993class SPIFont : public SPIBase
994{
995
996public:
997 SPIFont() = default;
998
999 ~SPIFont() override
1000 = default;
1001
1002 void read( gchar const *str ) override;
1003 const Glib::ustring get_value() const override;
1004 void clear() override {
1006 }
1007
1008 void cascade( const SPIBase* const /*parent*/ ) override
1009 {} // Done in dependent properties
1010
1011 void merge( const SPIBase* const /*parent*/ ) override
1012 {}
1013
1014 SPIFont& operator=(const SPIFont& rhs) = default;
1015
1016 bool equals(const SPIBase& rhs) const override;
1017};
1018
1019
1020enum {
1025
1028{
1029
1030public:
1032 : SPIBase(false) {
1033 this->clear();
1034 }
1035
1037 = default;
1038
1039 void read( gchar const *str ) override;
1040 const Glib::ustring get_value() const override;
1046
1047 void cascade( const SPIBase* const parent ) override;
1048 void merge( const SPIBase* const parent ) override;
1049
1051
1052 // This is not used but we have it for completeness, it has not been tested.
1053 bool equals(const SPIBase& rhs) const override;
1054
1055 bool isZero() const;
1056
1057 // To do: make private
1058public:
1059 unsigned type : 2;
1060 unsigned unit : 4;
1061 unsigned literal: 2;
1062 float value; // Can be negative
1064};
1065
1066// CSS 2. Changes in CSS 3, where description is for TextDecorationLine, NOT TextDecoration
1067// See http://www.w3.org/TR/css-text-decor-3/
1068
1069// CSS3 2.2
1072{
1073
1074public:
1076 this->clear();
1077 }
1078
1080 = default;
1081
1082 void read( gchar const *str ) override;
1083 const Glib::ustring get_value() const override;
1084 void clear() override {
1086 underline = false, overline = false, line_through = false, blink = false;
1087 }
1088
1089 void cascade( const SPIBase* const parent ) override;
1090 void merge( const SPIBase* const parent ) override;
1091
1093
1094 bool equals(const SPIBase& rhs) const override;
1095
1096 // To do: make private
1097public:
1098 bool underline : 1;
1099 bool overline : 1;
1101 bool blink : 1; // "Conforming user agents are not required to support this value." yay!
1102};
1103
1104// CSS3 2.2
1107{
1108
1109public:
1111 this->clear();
1112 }
1113
1115 = default;
1116
1117 void read( gchar const *str ) override;
1118 const Glib::ustring get_value() const override;
1119 void clear() override {
1121 solid = true, isdouble = false, dotted = false, dashed = false, wavy = false;
1122 }
1123
1124 void cascade( const SPIBase* const parent ) override;
1125 void merge( const SPIBase* const parent ) override;
1126
1128
1129 bool equals(const SPIBase& rhs) const override;
1130
1131 // To do: make private
1132public:
1133 bool solid : 1;
1134 bool isdouble : 1; // cannot use "double" as it is a reserved keyword
1135 bool dotted : 1;
1136 bool dashed : 1;
1137 bool wavy : 1;
1138};
1139
1140
1141
1142// This class reads in both CSS2 and CSS3 'text-decoration' property. It passes the line, style,
1143// and color parts to the appropriate CSS3 long-hand classes for reading and storing values. When
1144// writing out data, we write all four properties, with 'text-decoration' being written out with
1145// the CSS2 format. This allows CSS1/CSS2 renderers to at least render lines, even if they are not
1146// the right style. (See http://www.w3.org/TR/css-text-decor-3/#text-decoration-property )
1147
1150{
1151
1152public:
1154
1156 = default;
1157
1158 void read( gchar const *str ) override;
1159 const Glib::ustring get_value() const override;
1160 const Glib::ustring write( guint const flags = SP_STYLE_FLAG_IFSET,
1161 SPStyleSrc const &style_src_req = SPStyleSrc::STYLE_PROP,
1162 SPIBase const *const base = nullptr ) const override;
1163 void clear() override {
1165 style_td = nullptr;
1166 }
1167
1168 void cascade( const SPIBase* const parent ) override;
1169 void merge( const SPIBase* const parent ) override;
1170
1172 SPIBase::operator=(rhs);
1173 return *this;
1174 }
1175
1176 // Use CSS2 value
1177 bool equals(const SPIBase& rhs) const override;
1178
1179public:
1180 SPStyle* style_td = nullptr; // Style to be used for drawing CSS2 text decorations
1181};
1182
1183
1184// These are used to implement text_decoration. The values are not saved to or read from SVG file
1186 float phase_length; // length along text line,used for phase for dot/dash/wavy
1187 bool tspan_line_start; // is first span on a line
1188 bool tspan_line_end; // is last span on a line
1189 float tspan_width; // from libnrtype, when it calculates spans
1190 float ascender; // the rest from tspan's font
1196};
1197
1200{
1201
1202public:
1204 : SPIBase(false)
1205 {
1206 this->clear();
1207 }
1208
1210 = default;
1211
1212 void read( gchar const *str ) override;
1213 const Glib::ustring get_value() const override;
1214 void clear() override {
1216 stroke = false;
1217 size = false;
1218 rotate = false;
1219 fixed = false;
1220 }
1221
1222 // Does not inherit
1223 void cascade( const SPIBase* const parent ) override {};
1224 void merge( const SPIBase* const parent ) override {};
1225
1227
1228 bool equals(const SPIBase& rhs) const override;
1229
1230 // To do: make private
1231public:
1232 bool stroke : 1;
1233 bool size : 1;
1234 bool rotate : 1;
1235 bool fixed : 1;
1236};
1237
1240{
1241
1242public:
1244 : hairline(false)
1245 {}
1246
1247 ~SPIStrokeExtensions() override = default;
1248 void read( gchar const *str ) override;
1249 const Glib::ustring get_value() const override;
1250 void clear() override {
1252 hairline = false;
1253 }
1254
1255 // Does not inherit
1256 void cascade( const SPIBase* const parent ) override {};
1257 void merge( const SPIBase* const parent ) override {};
1258
1260
1261 bool equals(const SPIBase& rhs) const override;
1262
1263 // To do: make private
1264public:
1265 bool hairline : 1;
1266};
1267
1268#endif // SEEN_SP_STYLE_INTERNAL_H
1269
1270
1271/*
1272 Local Variables:
1273 mode:c++
1274 c-file-style:"stroustrup"
1275 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1276 indent-tabs-mode:nil
1277 fill-column:99
1278 End:
1279*/
1280// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Lookup dictionary for attributes/properties.
SPAttr
Definition attributes.h:27
@ INVALID
Must have value 0.
Interface for refcounted XML nodes.
Definition node.h:80
virtual char const * attribute(char const *key) const =0
Get the string representation of a node's attribute.
Virtual base class for all SPStyle internal classes.
bool operator==(const SPIBase &rhs) const
virtual void merge(const SPIBase *const parent)=0
virtual void cascade(const SPIBase *const parent)=0
virtual const Glib::ustring write(guint const flags=SP_STYLE_FLAG_IFSET, SPStyleSrc const &style_src_req=SPStyleSrc::STYLE_PROP, SPIBase const *const base=nullptr) const
Compile this style conditionally into a 'name: value' string suitable for css attrs.
Glib::ustring const & name() const
SPIBase & operator=(const SPIBase &rhs)=default
SPIBase(bool inherits_=true)
char const * important_str() const
virtual bool equals(const SPIBase &rhs) const
void setStylePointer(SPStyle *style_in)
void overwrite(const SPIBase *const other)
SPStyleSrc style_src
void readAttribute(Inkscape::XML::Node *repr)
SPStyle * style
virtual void read(gchar const *str)=0
virtual ~SPIBase()=default
void readIfUnset(gchar const *str, SPStyleSrc source=SPStyleSrc::STYLE_PROP)
bool shall_write(guint const flags=SP_STYLE_FLAG_IFSET, SPStyleSrc const &style_src_req=SPStyleSrc::STYLE_PROP, SPIBase const *const base=nullptr) const
Check if this property should be written.
virtual const Glib::ustring get_value() const =0
virtual SPAttr id() const
virtual void clear()
Baseline shift type internal to SPStyle. (This is actually just like SPIFontSize)
void cascade(const SPIBase *const parent) override
~SPIBaselineShift() override=default
void clear() override
const Glib::ustring get_value() const override
bool equals(const SPIBase &rhs) const override
void merge(const SPIBase *const parent) override
void read(gchar const *str) override
SPIBaselineShift & operator=(const SPIBaselineShift &rhs)=default
void clear() override
std::optional< Colors::Color > _color
Colors::DocumentCMS const & getCMS() const
void read(gchar const *str, SPStyle &style)
void setColor(Colors::Color const &other)
void read(gchar const *str) override
Colors::Color const & getColor() const
void cascade(const SPIBase *const parent) override
SPIColor & operator=(const SPIColor &rhs)
void merge(const SPIBase *const parent) override
~SPIColor() override=default
bool canHaveCMS() const
const Glib::ustring get_value() const override
bool currentcolor
bool equals(const SPIBase &rhs) const override
Filter type internal to SPStyle.
const Glib::ustring get_value() const override
void clear() override
bool equals(const SPIBase &rhs) const override
SPIDashArray & operator=(const SPIDashArray &rhs)=default
bool is_valid() const
SPIDashArray()=default
std::vector< SPILength > values
void cascade(const SPIBase *const parent) override
void merge(const SPIBase *const parent) override
std::vector< double > get_computed() const
~SPIDashArray() override=default
void read(gchar const *str) override
void read(gchar const *str) override
~SPIEastAsian() override=default
const Glib::ustring get_value() const override
SPIEnum w/ bits, allows values with multiple key words.
void read(gchar const *str) override
~SPIEnumBits() override=default
const Glib::ustring get_value() const override
SPIEnumBits(Glib::ustring const &name, SPStyleEnum const *enums, unsigned value=0, bool inherits=true)
Enum type internal to SPStyle.
~SPIEnum() override=default
void update_computed()
Update computed from value.
SPIEnum & operator=(const SPIEnum &rhs)
void merge(const SPIBase *const parent) override
void cascade(const SPIBase *const parent) override
const Glib::ustring get_value() const override
bool equals(const SPIBase &rhs) const override
void update_computed_cascade(T const &parent_computed)
Update computed from parent computed.
void clear() override
SPIEnum(T value=T(), bool inherits=true)
void read(gchar const *str) override
void update_value_merge(SPIEnum< T > const &)
Update value from parent.
Filter type internal to SPStyle.
void cascade(const SPIBase *const parent) override
void merge(const SPIBase *const parent) override
const Glib::ustring get_value() const override
void read(gchar const *str) override
SPFilterReference * href
~SPIFilter() override
void clear() override
bool equals(const SPIBase &rhs) const override
SPIFilter & operator=(const SPIFilter &rhs)=default
Float type internal to SPStyle. (Only 'stroke-miterlimit')
~SPIFloat() override=default
SPIFloat(float value_default=0.0)
void read(gchar const *str) override
const Glib::ustring get_value() const override
float value_default
void merge(const SPIBase *const parent) override
SPIFloat & operator=(const SPIFloat &rhs)=default
bool equals(const SPIBase &rhs) const override
void clear() override
void cascade(const SPIBase *const parent) override
Fontsize type internal to SPStyle (also used by libnrtype/Layout-TNG-Input.cpp).
unsigned literal
~SPIFontSize() override=default
SPIFontSize & operator=(const SPIFontSize &rhs)=default
void cascade(const SPIBase *const parent) override
void read(gchar const *str) override
double relative_fraction() const
static float const font_size_default
bool equals(const SPIBase &rhs) const override
const Glib::ustring get_value() const override
void clear() override
static float const font_size_table[]
Indexed by SP_CSS_FONT_SIZE_blah.
void merge(const SPIBase *const parent) override
Extended length type internal to SPStyle.
~SPIFontVariationSettings() override=default
void read(gchar const *str) override
bool equals(const SPIBase &rhs) const override
virtual const Glib::ustring toString() const
SPIFontVariationSettings & operator=(const SPIFontVariationSettings &rhs)
void merge(const SPIBase *const parent) override
const Glib::ustring get_value() const override
void cascade(const SPIBase *const parent) override
std::map< Glib::ustring, float > axes
Font type internal to SPStyle ('font' shorthand)
SPIFont()=default
~SPIFont() override=default
void read(gchar const *str) override
const Glib::ustring get_value() const override
void clear() override
SPIFont & operator=(const SPIFont &rhs)=default
void merge(const SPIBase *const) override
bool equals(const SPIBase &rhs) const override
void cascade(const SPIBase *const) override
Extended length type internal to SPStyle.
void cascade(const SPIBase *const parent) override
bool equals(const SPIBase &rhs) const override
void read(gchar const *str) override
~SPILengthOrNormal() override=default
const Glib::ustring get_value() const override
SPILengthOrNormal & operator=(const SPILengthOrNormal &rhs)=default
void clear() override
SPILengthOrNormal(float value=0)
void merge(const SPIBase *const parent) override
Length type internal to SPStyle.
void cascade(const SPIBase *const parent) override
SPILength(float value=0)
float value_default
SPILength & operator=(const SPILength &rhs)=default
const Glib::ustring get_value() const override
void setDouble(double v)
void read(gchar const *str) override
unsigned unit
void clear() override
~SPILength() override=default
virtual const Glib::ustring toString(bool wname=false) const
void merge(const SPIBase *const parent) override
bool equals(const SPIBase &rhs) const override
~SPILigatures() override=default
void read(gchar const *str) override
const Glib::ustring get_value() const override
void read(gchar const *str) override
~SPINumeric() override=default
const Glib::ustring get_value() const override
Paint order type internal to SPStyle.
SPIPaintOrder & operator=(const SPIPaintOrder &rhs)
~SPIPaintOrder() override
unsigned get_order(SPPaintOrderLayer paint_order) const
Return the index of the given paint order.
void clear() override
void read(gchar const *str) override
void cascade(const SPIBase *const parent) override
std::array< SPPaintOrderLayer, PAINT_ORDER_LAYERS > get_layers() const
Get the actual layer order, converting "normal" to layers.
bool layer_set[PAINT_ORDER_LAYERS]
bool equals(const SPIBase &rhs) const override
const Glib::ustring get_value() const override
SPPaintOrderLayer layer[PAINT_ORDER_LAYERS]
SPIPaintOrder(const SPIPaintOrder &rhs)
void merge(const SPIBase *const parent) override
Paint type internal to SPStyle.
bool equals(const SPIBase &rhs) const override
void merge(const SPIBase *const parent) override
SPObject * tag
bool isPaintserver() const
const Glib::ustring get_value() const override
void clear() override
bool isContext() const
std::optional< Colors::Color > _color
bool isColor() const
SPObject * getTag()
void setNone()
void cascade(const SPIBase *const parent) override
bool isSameType(SPIPaint const &other) const
bool isNone() const
bool canHaveCMS() const
virtual void reset(bool init)
std::shared_ptr< SPPaintServerReference > href
Colors::DocumentCMS const & getCMS() const
void setTag(SPObject *tag)
SPPaintOrigin paintSource
bool isNoneSet() const
SPPaintOrigin paintOrigin
void read(gchar const *str) override
Set SPIPaint object from string.
~SPIPaint() override=default
SPIPaint & operator=(const SPIPaint &rhs)
void setColor(Colors::Color const &other)
Colors::Color const & getColor() const
24 bit data type internal to SPStyle.
const Glib::ustring get_value() const override
static unsigned get_default()
SPIScale24 & operator=(const SPIScale24 &rhs)=default
void read(gchar const *str) override
unsigned value
~SPIScale24() override=default
void set_double(const double &other)
bool equals(const SPIBase &rhs) const override
void merge(const SPIBase *const parent) override
SPIScale24(bool inherits=true)
void cascade(const SPIBase *const parent) override
void clear() override
Shapes type internal to SPStyle.
SPIShapes(const SPIShapes &)=delete
bool containsAnyShape(Inkscape::ObjectSet *set)
Check if a Shape object exists in the selection Needed for when user selects multiple objects and.
std::vector< SPShapeReference * > hrefs
~SPIShapes() override
void clear() override
void read(gchar const *str) override
String type internal to SPStyle.
~SPIString() override
char const * get_default_value() const
const Glib::ustring get_value() const override
Value as it should be written to CSS representation, including quotes if needed.
gchar * _value
SPIString & operator=(const SPIString &rhs)
SPIString(const SPIString &rhs)
void clear() override
void merge(const SPIBase *const parent) override
void read(gchar const *str) override
SPIString(bool inherits=true)
bool equals(const SPIBase &rhs) const override
void cascade(const SPIBase *const parent) override
char const * value() const
Get value if set, or inherited value, or default value (may be NULL)
Custom stroke properties. Only used for -inkscape-stroke: hairline.
const Glib::ustring get_value() const override
void clear() override
void cascade(const SPIBase *const parent) override
SPIStrokeExtensions & operator=(const SPIStrokeExtensions &rhs)=default
~SPIStrokeExtensions() override=default
void read(gchar const *str) override
void merge(const SPIBase *const parent) override
bool equals(const SPIBase &rhs) const override
Text decoration line type internal to SPStyle. THIS SHOULD BE A GENERIC CLASS.
SPITextDecorationLine & operator=(const SPITextDecorationLine &rhs)=default
void read(gchar const *str) override
void cascade(const SPIBase *const parent) override
const Glib::ustring get_value() const override
void merge(const SPIBase *const parent) override
bool equals(const SPIBase &rhs) const override
~SPITextDecorationLine() override=default
Text decoration style type internal to SPStyle. THIS SHOULD JUST BE SPIEnum!
SPITextDecorationStyle & operator=(const SPITextDecorationStyle &rhs)=default
~SPITextDecorationStyle() override=default
void cascade(const SPIBase *const parent) override
const Glib::ustring get_value() const override
bool equals(const SPIBase &rhs) const override
void merge(const SPIBase *const parent) override
void read(gchar const *str) override
Text decoration type internal to SPStyle.
void cascade(const SPIBase *const parent) override
SPITextDecoration & operator=(const SPITextDecoration &rhs)
SPITextDecoration()=default
~SPITextDecoration() override=default
const Glib::ustring write(guint const flags=SP_STYLE_FLAG_IFSET, SPStyleSrc const &style_src_req=SPStyleSrc::STYLE_PROP, SPIBase const *const base=nullptr) const override
Compile this style conditionally into a 'name: value' string suitable for css attrs.
void clear() override
void read(gchar const *str) override
bool equals(const SPIBase &rhs) const override
const Glib::ustring get_value() const override
void merge(const SPIBase *const parent) override
Vector Effects. THIS SHOULD BE A GENERIC CLASS.
const Glib::ustring get_value() const override
void merge(const SPIBase *const parent) override
~SPIVectorEffect() override=default
bool equals(const SPIBase &rhs) const override
void read(gchar const *str) override
void clear() override
SPIVectorEffect & operator=(const SPIVectorEffect &rhs)=default
void cascade(const SPIBase *const parent) override
SPObject is an abstract base class of all of the document nodes at the SVG document level.
Definition sp-object.h:160
An SVG style object.
Definition style.h:45
Decorator which overrides SPIBase::id()
static SPAttr static_id()
Base * upcast()
Upcast to the base class.
SPAttr id() const override
Get the attribute enum.
Base const * upcast() const
static char const *const parent
Definition dir-util.cpp:70
Helper class to stream background task notifications as a series of messages.
C facade to Inkscape::XML::Node.
TODO: insert short description here.
SVG <filter> element.
TODO: insert short description here.
SPStyle enums: named public enums that correspond to SVG property values.
@ SP_CSS_FONT_VARIANT_LIGATURES_NORMAL
@ SP_CSS_BASELINE_SHIFT_BASELINE
@ SP_CSS_FONT_SIZE_MEDIUM
Definition style-enums.h:52
@ SP_CSS_FONT_VARIANT_NUMERIC_NORMAL
@ SP_CSS_FONT_VARIANT_EAST_ASIAN_NORMAL
SPStyleSrc
static const unsigned SP_STYLE_FLAG_IFSET(1<< 0)
@ SP_FONT_SIZE_LITERAL
@ SP_FONT_SIZE_LENGTH
@ SP_FONT_SIZE_PERCENTAGE
constexpr size_t PAINT_ORDER_LAYERS
SPPaintOrigin
@ SP_CSS_PAINT_ORIGIN_CONTEXT_STROKE
@ SP_CSS_PAINT_ORIGIN_CURRENT_COLOR
@ SP_CSS_PAINT_ORIGIN_NORMAL
@ SP_CSS_PAINT_ORIGIN_CONTEXT_FILL
static const unsigned SP_SCALE24_MAX
typename std::underlying_type< SPCSSFontVariantLigatures >::type _SPCSSFontVariantLigatures_int
SPIEnum w/ extra bits.
typename std::underlying_type< SPCSSFontVariantNumeric >::type _SPCSSFontVariantNumeric_int
SPIEnum w/ extra bits.
SPPaintOrderLayer
@ SP_CSS_PAINT_ORDER_STROKE
@ SP_CSS_PAINT_ORDER_MARKER
@ SP_CSS_PAINT_ORDER_FILL
@ SP_CSS_PAINT_ORDER_NORMAL
@ SP_BASELINE_SHIFT_PERCENTAGE
@ SP_BASELINE_SHIFT_LENGTH
@ SP_BASELINE_SHIFT_LITERAL
static const unsigned SP_STYLE_FLAG_ALWAYS(1<< 2)
static const unsigned SP_STYLE_FLAG_IFSRC(1<< 3)
static const unsigned SP_STYLE_FLAG_IFDIFF(1<< 1)
SPCSSUnit
@ SP_CSS_UNIT_IN
@ SP_CSS_UNIT_PT
@ SP_CSS_UNIT_PX
@ SP_CSS_UNIT_PC
@ SP_CSS_UNIT_MM
@ SP_CSS_UNIT_PERCENT
@ SP_CSS_UNIT_NONE
@ SP_CSS_UNIT_EM
@ SP_CSS_UNIT_CM
@ SP_CSS_UNIT_EX
typename std::underlying_type< SPCSSFontVariantEastAsian >::type _SPCSSFontVariantEastAsian_int
SPIEnum w/ extra bits.
void init(int argc, char **argv, Toy *t, int width=600, int height=600)