1 /*
2  *  Copyright (c) 2017 Dmitry Kazakov <dimula73@gmail.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #ifndef KOSVGTEXTPROPERTIES_H
20 #define KOSVGTEXTPROPERTIES_H
21 
22 #include "kritaflake_export.h"
23 
24 #include <QScopedPointer>
25 #include <QVariant>
26 #include <QList>
27 
28 class SvgLoadingContext;
29 
30 
31 
32 /**
33  * KoSvgTextProperties represents the text attributes defined in SVG DOM tree
34  *
35  * There is a limitation in flake: it doesn't support the inheritance of shape
36  * properties: every shape stores all the properties that were defined at the
37  * loading/creation stage. KoSvgTextProperties allows the user to compare
38  * the properties of the two shapes and distinguish, which properties were
39  * inherited by text shape, and which are its own. It is needed to generate a
40  * correct and clean SVG/markup code that can be edited by the user easily.
41  * Otherwise, every \<tspan\> block will contain the full list of 20+ attributes,
42  * which are not interesting for the user, since they are inherited or default.
43  *
44  * To achieve the goal, KoSvgTextProperties wraps all the SVG attributes into a
45  * map of QVariants. When the user need to find a set of unique properties
46  * of the shape, it iterates through the map and compares values with standard
47  * QVariant-based comparison operator. If the property value in a child and a
48  * parent is not the same, then it is not inherited.
49  */
50 class KRITAFLAKE_EXPORT KoSvgTextProperties
51 {
52 public:
53     /**
54      * Defines a set of supported properties. See SVG 1.1 for details.
55      */
56     enum PropertyId {
57         WritingModeId,
58         DirectionId,
59         UnicodeBidiId,
60         TextAnchorId,
61         DominantBaselineId,
62         AlignmentBaselineId,
63         BaselineShiftModeId,
64         BaselineShiftValueId,
65         KerningId,
66         GlyphOrientationVerticalId,
67         GlyphOrientationHorizontalId,
68         LetterSpacingId,
69         WordSpacingId,
70 
71         FontFamiliesId,
72         FontStyleId,
73         FontIsSmallCapsId,
74         FontStretchId,
75         FontWeightId,
76         FontSizeId,
77         FontSizeAdjustId,
78         TextDecorationId,
79 
80         FillId,
81         StrokeId
82     };
83 
84 public:
85 
86     KoSvgTextProperties();
87     ~KoSvgTextProperties();
88 
89     KoSvgTextProperties(const KoSvgTextProperties &rhs);
90     KoSvgTextProperties& operator=(const KoSvgTextProperties &rhs);
91 
92     /**
93      * Set the property \p id to \p value
94      */
95     void setProperty(PropertyId id, const QVariant &value);
96 
97     /**
98      * Check if property \p id is present in this properties set
99      */
100     bool hasProperty(PropertyId id) const;
101 
102     /**
103      * Return the value of property \p id. If the property doesn't exist in
104      * the shape, return \p defaultValue instead.
105      */
106     QVariant property(PropertyId id, const QVariant &defaultValue = QVariant()) const;
107 
108     /**
109      * Remove property \p id from the set
110      */
111     void removeProperty(PropertyId id);
112 
113     /**
114      * Return the value of property \p id. If the property doesn't exist in the
115      * shape, return the default value define in SVG 1.1.
116      */
117     QVariant propertyOrDefault(PropertyId id) const;
118 
119     /**
120      * Return a list of properties contained in this set
121      */
122     QList<PropertyId> properties() const;
123 
124     /**
125      * Return true if the set contains no properties
126      */
127     bool isEmpty() const;
128 
129     /**
130      * Reset all non-inheritable properties to default values. The set of
131      * non-inheritable properties is define by SVG 1.1. Used by the loading
132      * code for resetting state automata's properties on entering a \<tspan\>.
133      */
134     void resetNonInheritableToDefault();
135 
136 
137     /**
138      * Apply properties from the parent shape. The property is set **iff** the
139      * property is inheritable according to SVG and this set does not define
140      * it.
141      */
142     void inheritFrom(const KoSvgTextProperties &parentProperties);
143 
144     /**
145      * Return true if the property \p id is inherited from \p parentProperties.
146      * The property is considered "inherited" **iff* it is inheritable
147      * according to SVG and the parent defined the same property with the same
148      * value.
149      */
150     bool inheritsProperty(PropertyId id, const KoSvgTextProperties &parentProperties) const;
151 
152     /**
153      * Return a set of properties that ar **not** inherited from \p
154      * parentProperties. The property is considered "inherited" **iff* it is
155      * inheritable according to SVG and the parent defined the same property
156      * with the same value.
157      */
158     KoSvgTextProperties ownProperties(const KoSvgTextProperties &parentProperties) const;
159 
160     /**
161      * @brief parseSvgTextAttribute add a property according to an XML attribute value.
162      * @param context shared loading context
163      * @param command XML attribute name
164      * @param value attribute value
165      *
166      * @see supportedXmlAttributes for a list of supported attributes
167      */
168     void parseSvgTextAttribute(const SvgLoadingContext &context, const QString &command, const QString &value);
169 
170     /**
171      * Convert all the properties of the set into a map of XML attribute/value
172      * pairs.
173      */
174     QMap<QString,QString> convertToSvgTextAttributes() const;
175 
176     /**
177      * Return a list of supported XML attribute names (defined in SVG)
178      */
179     static QStringList supportedXmlAttributes();
180 
181     /**
182      * Return a static object that defines default values for all the supported
183      * properties according to SVG
184      */
185     static const KoSvgTextProperties& defaultProperties();
186 
187 private:
188     struct Private;
189     const QScopedPointer<Private> m_d;
190 };
191 
192 #endif // KOSVGTEXTPROPERTIES_H
193