File indexing completed on 2024-06-16 04:11:24
0001 /* 0002 * SPDX-FileCopyrightText: 2017 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef KOSVGTEXTPROPERTIES_H 0008 #define KOSVGTEXTPROPERTIES_H 0009 0010 #include "kritaflake_export.h" 0011 #include "KoFlakeTypes.h" 0012 0013 #include <QScopedPointer> 0014 #include <QVariant> 0015 #include <QList> 0016 0017 class SvgLoadingContext; 0018 class KoShapeBackground; 0019 0020 /** 0021 * KoSvgTextProperties represents the text attributes defined in SVG DOM tree 0022 * 0023 * There is a limitation in flake: it doesn't support the inheritance of shape 0024 * properties: every shape stores all the properties that were defined at the 0025 * loading/creation stage. KoSvgTextProperties allows the user to compare 0026 * the properties of the two shapes and distinguish, which properties were 0027 * inherited by text shape, and which are its own. It is needed to generate a 0028 * correct and clean SVG/markup code that can be edited by the user easily. 0029 * Otherwise, every \<tspan\> block will contain the full list of 20+ attributes, 0030 * which are not interesting for the user, since they are inherited or default. 0031 * 0032 * To achieve the goal, KoSvgTextProperties wraps all the SVG attributes into a 0033 * map of QVariants. When the user need to find a set of unique properties 0034 * of the shape, it iterates through the map and compares values with standard 0035 * QVariant-based comparison operator. If the property value in a child and a 0036 * parent is not the same, then it is not inherited. 0037 */ 0038 class KRITAFLAKE_EXPORT KoSvgTextProperties 0039 { 0040 public: 0041 /** 0042 * Defines a set of supported properties. See SVG 1.1 for details. 0043 */ 0044 enum PropertyId { 0045 WritingModeId, ///< KoSvgText::WritingMode 0046 DirectionId, ///< KoSvgText::Direction 0047 UnicodeBidiId, ///< KoSvgText::UnicodeBidi 0048 TextAnchorId, ///< KoSvgText::TextAnchor 0049 DominantBaselineId, ///< KoSvgText::Baseline 0050 AlignmentBaselineId, ///< KoSvgText::Baseline 0051 BaselineShiftModeId, ///< KoSvgText::BaselineShiftMode 0052 BaselineShiftValueId, ///< Double 0053 KerningId, ///< KoSvgText::AutoValue 0054 TextOrientationId, ///< KoSvgText::TextOrientation 0055 LetterSpacingId, ///< KoSvgText::AutoValue 0056 WordSpacingId, ///< KoSvgText::AutoValue 0057 0058 FontFamiliesId, ///< QStringList 0059 FontStyleId, ///< QFont::Style 0060 FontStretchId, ///< Int 0061 FontWeightId, ///< Int 0062 FontSizeId, ///< Double 0063 FontSizeAdjustId, ///< KoSvgText::AutoValue 0064 0065 /// KoSvgText::FontVariantFeature 0066 FontVariantCommonLigId, 0067 FontVariantDiscretionaryLigId, 0068 FontVariantHistoricalLigId, 0069 FontVariantContextualAltId, 0070 FontVariantPositionId, 0071 FontVariantCapsId, 0072 FontVariantNumFigureId, 0073 FontVariantNumSpacingId, 0074 FontVariantNumFractId, 0075 FontVariantNumOrdinalId, 0076 FontVariantNumSlashedZeroId, 0077 FontVariantHistoricalFormsId, 0078 FontVariantEastAsianVarId, 0079 FontVariantEastAsianWidthId, 0080 FontVariantRubyId, 0081 0082 FontFeatureSettingsId, ///< QStringList 0083 FontOpticalSizingId, ///< Bool 0084 FontVariationSettingsId, ///< QStringList 0085 0086 TextDecorationLineId, ///< Flags, KoSvgText::TextDecorations 0087 TextDecorationStyleId, ///< KoSvgText::TextDecorationStyle 0088 TextDecorationColorId, ///< QColor 0089 TextDecorationPositionHorizontalId, ///< KoSvgText::TextDecorationUnderlinePosition 0090 TextDecorationPositionVerticalId, ///< KoSvgText::TextDecorationUnderlinePosition 0091 FillId, ///< KoSvgText::BackgroundProperty 0092 StrokeId, ///< KoSvgText::StrokeProperty 0093 Opacity, ///< Double, SVG shape opacity. 0094 PaintOrder, ///< QVector<KoShape::PaintOrder> 0095 Visiblity, ///< Bool, CSS visibility 0096 0097 TextLanguage, ///< a language string. 0098 0099 TextCollapseId, ///< KoSvgText::TextSpaceCollapse 0100 TextWrapId, ///< KoSvgText::TextWrap 0101 TextTrimId, ///< Flags, KoSvgText::TextSpaceTrims 0102 LineBreakId, ///< KoSvgText::LineBreak 0103 WordBreakId, ///< KoSvgText::WordBreak 0104 TextAlignAllId, ///< KoSvgText::TextAlign 0105 TextAlignLastId, ///< KoSvgText::TextAlign 0106 TextTransformId, ///< KoSvgText::TextTransformInfo Struct 0107 TextOverFlowId, ///< KoSvgText::WordBreak 0108 OverflowWrapId, ///< 0109 InlineSizeId, ///< KoSvgText::AutoValue 0110 LineHeightId, ///< KoSvgText::AutoValue 0111 TextIndentId, ///< KoSvgText::TextIndentInfo Struct. 0112 HangingPunctuationId, ///< Flags, KoSvgText::HangingPunctuations 0113 TabSizeId, ///< Int 0114 0115 ShapePaddingId, ///< Double 0116 ShapeMarginId, ///< Double 0117 0118 KraTextVersionId ///< Int, used for handling incorrectly saved files. 0119 }; 0120 0121 KoSvgTextProperties(); 0122 ~KoSvgTextProperties(); 0123 0124 KoSvgTextProperties(const KoSvgTextProperties &rhs); 0125 KoSvgTextProperties& operator=(const KoSvgTextProperties &rhs); 0126 0127 /** 0128 * Set the property \p id to \p value 0129 */ 0130 void setProperty(PropertyId id, const QVariant &value); 0131 0132 /** 0133 * Check if property \p id is present in this properties set 0134 */ 0135 bool hasProperty(PropertyId id) const; 0136 0137 /** 0138 * Return the value of property \p id. If the property doesn't exist in 0139 * the shape, return \p defaultValue instead. 0140 */ 0141 QVariant property(PropertyId id, const QVariant &defaultValue = QVariant()) const; 0142 0143 /** 0144 * Remove property \p id from the set 0145 */ 0146 void removeProperty(PropertyId id); 0147 0148 /** 0149 * Return the value of property \p id. If the property doesn't exist in the 0150 * shape, return the default value define in SVG 1.1. 0151 */ 0152 QVariant propertyOrDefault(PropertyId id) const; 0153 0154 /** 0155 * Return a list of properties contained in this set 0156 */ 0157 QList<PropertyId> properties() const; 0158 0159 /** 0160 * Return true if the set contains no properties 0161 */ 0162 bool isEmpty() const; 0163 0164 /** 0165 * Reset all non-inheritable properties to default values. The set of 0166 * non-inheritable properties is define by SVG 1.1. Used by the loading 0167 * code for resetting state automata's properties on entering a \<tspan\>. 0168 */ 0169 void resetNonInheritableToDefault(); 0170 0171 0172 /** 0173 * Apply properties from the parent shape. The property is set **iff** the 0174 * property is inheritable according to SVG and this set does not define 0175 * it. 0176 */ 0177 void inheritFrom(const KoSvgTextProperties &parentProperties); 0178 0179 /** 0180 * Return true if the property \p id is inherited from \p parentProperties. 0181 * The property is considered "inherited" **iff* it is inheritable 0182 * according to SVG and the parent defined the same property with the same 0183 * value. 0184 */ 0185 bool inheritsProperty(PropertyId id, const KoSvgTextProperties &parentProperties) const; 0186 0187 /** 0188 * Return a set of properties that ar **not** inherited from \p 0189 * parentProperties. The property is considered "inherited" **iff* it is 0190 * inheritable according to SVG and the parent defined the same property 0191 * with the same value. 0192 * @param keepFontSize whether to keep the font size, use for root nodes 0193 * so that it won't be omitted and inheriting from the "default", which may 0194 * not be deterministic. 0195 */ 0196 KoSvgTextProperties ownProperties(const KoSvgTextProperties &parentProperties, bool keepFontSize = false) const; 0197 0198 /** 0199 * @brief parseSvgTextAttribute add a property according to an XML attribute value. 0200 * @param context shared loading context 0201 * @param command XML attribute name 0202 * @param value attribute value 0203 * 0204 * @see supportedXmlAttributes for a list of supported attributes 0205 */ 0206 void parseSvgTextAttribute(const SvgLoadingContext &context, const QString &command, const QString &value); 0207 0208 /** 0209 * Convert all the properties of the set into a map of XML attribute/value 0210 * pairs. 0211 */ 0212 QMap<QString, QString> convertToSvgTextAttributes() const; 0213 0214 /** 0215 * @brief convertParagraphProperties 0216 * some properties only apply to the root shape, so we write those separately. 0217 * @return 0218 */ 0219 QMap<QString, QString> convertParagraphProperties() const; 0220 0221 QFont generateFont() const; 0222 0223 /** 0224 * @brief fontFeaturesForText 0225 * Returns a harfbuzz friendly list of opentype font-feature settings using 0226 * the various font-variant and font-feature-settings values. 0227 * @param start the start pos of the text. 0228 * @param length the length of the text. 0229 * @return a list of strings for font-features and their ranges that can be 0230 * understood by harfbuzz. 0231 */ 0232 QStringList fontFeaturesForText(int start, int length) const; 0233 0234 /** 0235 * @brief fontAxisSettings 0236 * This is used to configure variable fonts. It gets the appropriate values 0237 * from font width, stretch, style, size, if font-optical-sizing is not set 0238 * to 'none, and finally the font-variation-settings property. 0239 * @return a map of axis-tags and their values. 0240 */ 0241 QMap<QString, qreal> fontAxisSettings() const; 0242 0243 QSharedPointer<KoShapeBackground> background() const; 0244 KoShapeStrokeModelSP stroke() const; 0245 0246 /** 0247 * Return a list of supported XML attribute names (defined in SVG) 0248 */ 0249 static QStringList supportedXmlAttributes(); 0250 0251 /** 0252 * Return a static object that defines default values for all the supported 0253 * properties according to SVG 0254 */ 0255 static const KoSvgTextProperties& defaultProperties(); 0256 0257 private: 0258 struct Private; 0259 const QScopedPointer<Private> m_d; 0260 }; 0261 0262 #endif // KOSVGTEXTPROPERTIES_H