File indexing completed on 2024-06-23 04:20:41
0001 /* 0002 * SPDX-FileCopyrightText: 2017 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef KOSVGTEXT_H 0008 #define KOSVGTEXT_H 0009 0010 #include <QFont> 0011 #include <QList> 0012 #include <QPainterPath> 0013 #include <QTextCharFormat> 0014 #include <QVariant> 0015 #include <QVector> 0016 #include <array> 0017 #include <boost/operators.hpp> 0018 #include <boost/optional.hpp> 0019 0020 #include <QSharedPointer> 0021 #include <KoShapeBackground.h> 0022 #include <KoShapeStrokeModel.h> 0023 0024 #include <QDomDocument> 0025 0026 #include <kritaflake_export.h> 0027 0028 class SvgLoadingContext; 0029 class QDebug; 0030 0031 #include <KoShape.h> 0032 class KoSvgTextChunkShape; 0033 0034 namespace KoSvgText 0035 { 0036 enum WritingMode { 0037 HorizontalTB, ///< Left to right, lay out new lines bottom of previous. RTL 0038 ///< scripts use this with BIDI reordering. 0039 VerticalRL, ///< Top to bottom, lay out new lines right of the previous. 0040 ///< used for CJK scripts. 0041 VerticalLR ///< Top to bottom, lay out new lines left of the previous. Used 0042 ///< for Mongolian. 0043 }; 0044 0045 /// Base direction used by Bidi algorithm. 0046 enum Direction { 0047 DirectionLeftToRight, 0048 DirectionRightToLeft 0049 }; 0050 0051 /// These values control the type of bidi-controls we'll inject into the final 0052 /// text. 0053 enum UnicodeBidi { 0054 BidiNormal, ///< No new bidi-level is started. 0055 BidiEmbed, ///< Opens an additional Bidi-reordering level. 0056 BidiOverride, ///< Opens an additional Bidi-reordering level, implicit part 0057 ///< of the algorithm is ignored. 0058 BidiIsolate, ///< Content is ordered as if in a seperate paragraph. 0059 BidiIsolateOverride, ///< Ordered like a directional override inside an 0060 ///< isolated paragraph. 0061 BidiPlainText ///< Behaves like isolate, except using heuristics defined in 0062 ///< P2 and P3 of the unicode bidirectional algorithm. 0063 }; 0064 0065 /// Orientation of the glyphs, used for vertical writing modes. 0066 enum TextOrientation { 0067 OrientationMixed, ///< Use UA50 to determine whether a character should be 0068 ///< sideways. 0069 OrientationUpright, ///< Set all characters upright. 0070 OrientationSideWays ///< Set all characters sideways. 0071 }; 0072 0073 /// Where the text is anchored for SVG 1.1 text and 'inline-size'. 0074 enum TextAnchor { 0075 AnchorStart, ///< Anchor left for LTR, right for RTL. 0076 AnchorMiddle, ///< Anchor to the middle. 0077 AnchorEnd ///< Anchor right for LTR, left for RTL. 0078 }; 0079 0080 /* 0081 * CSS-Text-3 defines the white space property, and SVG 2 adopts this, except, 0082 * CSS-Text-3 doesn't have a concept of 'xml:space="preserve"'. CSS-Text-4 0083 * *does*, however, that works by splitting the white-space property into the 0084 * the following three enums. Officially the SVG2 spec says to use 'white-space' 0085 * of CSS-Text-4 because of this. 0086 */ 0087 0088 /// Part of "white-space", NOTE: white-space:break-spaces; is not really covered 0089 /// by this new method yet. 0090 enum TextSpaceCollapse { 0091 Collapse, ///< Collapse white space sequences into a single character. 0092 Discard, ///< Discard all Spaces 0093 Preserve, ///< Do not collapse any space 0094 PreserveBreaks, ///< Preserve segment breaks like /n, but otherwise collapse 0095 ///< all whitespace. 0096 PreserveSpaces ///< Preserve spaces, convert tabs and linebreaks to spaces, 0097 ///< required for 'xml:space="preserve"' emulation. 0098 }; 0099 0100 /// Part of "white-space", in practice we only support wrap and nowrap. 0101 enum TextWrap { 0102 Wrap, ///< Do any kind of text wrapping at soft wrapping opportunities, 0103 ///< typically greedy. 0104 NoWrap, ///< Do not do any text wrapping. 0105 Balance, ///< Select algorithm that tries to ensure white space is balanced 0106 ///< instead of as much text as possible on each line. 0107 Stable, ///< Select algorithm that doesn't change the text before the cursor 0108 ///< when adjusting text. 0109 Pretty ///< select algorithm that gives the best looking result, may require 0110 ///< looking ahead. 0111 }; 0112 0113 /// Part of "white-space" 0114 enum TextSpaceTrim { 0115 TrimNone = 0x0, ///< No trimming. 0116 TrimInner = 0x1, ///< Discard white space at the beginning and end of element. 0117 DiscardBefore = 0x2, ///< Trim white space before the start of the element. 0118 DiscardAfter = 0x4 ///< Trim white space after the end of the element. 0119 }; 0120 0121 /// Whether to break words. 0122 enum WordBreak { 0123 WordBreakNormal, ///< Set according to script. Also "break-word" 0124 WordBreakKeepAll, ///< Never break inside words. 0125 WordBreakBreakAll, ///< Always break inside words. 0126 }; 0127 0128 /// Line breaking strictness. A number of these values are values to be handed 0129 /// over to the line/word breaking algorithm. 0130 enum LineBreak { 0131 LineBreakAuto, ///< Use preferred method. 0132 LineBreakLoose, ///< Use loose method, language specific. 0133 LineBreakNormal, ///< Use normal method, language specific. 0134 LineBreakStrict, ///< Use strict method, language specific. 0135 LineBreakAnywhere ///< Break between any typographic clusters. 0136 }; 0137 0138 /// What to do with words that cannot be broken, but still overflow. 0139 enum OverflowWrap { 0140 OverflowWrapNormal, ///< Do nothing besides 'relaxing' the strictness of 0141 ///< 'wordbreak'. 0142 OverflowWrapAnywhere, ///< Break anywhere as soon as overflow happens. 0143 OverflowWrapBreakWord ///< Break previous soft-break before breaking the 0144 ///< word. 0145 }; 0146 0147 /// TextAlign values, see 0148 /// https://www.w3.org/TR/css-writing-modes-4/#logical-to-physical for 0149 /// interaction with writing mode and direction. 0150 enum TextAlign { 0151 AlignLastAuto, ///< TextAlignLast: same as text-align-all, unless that's 0152 ///< justify, then this is AlignStart. 0153 AlignStart, ///< Align text to left side of line with LTR, right with RTL, 0154 ///< top with the vertical writing modes. 0155 AlignEnd, ///< Align text to right side of line with LTR, left with RTL, 0156 ///< bottom with the vertical writing modes. 0157 AlignLeft, ///< Align text to left side of line. Top with the vertical 0158 ///< writing modes, bottom in sideways. 0159 AlignRight, ///< Align text to right side of line. Bottom with the vertical 0160 ///< writing modes, top in sideways 0161 AlignCenter, ///< Center text in line. 0162 AlignJustify, ///< Justify text, so that the end and start both touch the 0163 ///< end and start of the line. 0164 AlignMatchParent ///< Inherit, except Start and End are matched against the 0165 ///< parent values... We don't support this. 0166 }; 0167 0168 /// Whether and how to transform text. Not strictly necessary according to SVG2. 0169 /// Fullwidth and FullSizeKana are inside the textTransform Struct. 0170 enum TextTransform { 0171 TextTransformNone = 0x0, ///< No transforms. 0172 TextTransformCapitalize = 0x1, ///< Convert first letter in word of bicarmel 0173 ///< text to upper-case, locale dependant. 0174 TextTransformUppercase = 0x2, ///< Convert all bicarmel text to upper-case, locale dependant. 0175 TextTransformLowercase = 0x4, ///< Convert all bicarmel text to lower-case, locale dependant. 0176 }; 0177 0178 /// How to handle overflow. 0179 enum TextOverflow { 0180 OverFlowVisible, ///< Determined by 'overflow' property, not by 0181 ///< text-overflow. In svg all the non-visible values 0182 ///< compute to 'clip'. 0183 OverFlowClip, ///< Clip the rendered content. 0184 OverFlowEllipse ///< Replace the last characters with "U+2026" 0185 }; 0186 0187 /// Flags. Whether and how to hang punctuation. Not strictly necessary according 0188 /// to SVG2, marked as 'at-risk' in CSS-Text-3, though this feature is useful 0189 /// for East-Asian text layout. 0190 enum HangingPunctuation { 0191 HangNone = 0x0, ///< Hang nothing. 0192 HangFirst = 0x1, ///< Hang opening brackets and quotes. 0193 HangLast = 0x2, ///< Hang closing brackets and quotes. 0194 HangEnd = 0x4, ///< Hang stops and commas. Force/Allow is a seperate boolean. 0195 HangForce = 0x8 ///< Whether to force hanging stops or commas. 0196 }; 0197 0198 /// Baseline values used by dominant-baseline and baseline-align. 0199 enum Baseline { 0200 BaselineAuto, ///< Use the preferred baseline for the writing-mode and 0201 ///< text-orientation. 0202 BaselineUseScript, ///< SVG 1.1 feature, Deprecated in CSS-Inline-3. Use the 0203 ///< preferred baseline for the given script. 0204 BaselineDominant, ///< alignment-baseline has the same value as 0205 ///< dominant-baseline. 0206 BaselineNoChange, ///< Use parent baseline table. 0207 BaselineResetSize, ///< Use parent baseline table, but adjust to current 0208 ///< fontsize. 0209 BaselineIdeographic, ///< Use 'ideo' or 'ideographic under/left' baselines. 0210 ///< Used for CJK. 0211 BaselineAlphabetic, ///< Use 'romn' or the baseline for LCG scripts. 0212 BaselineHanging, ///< Use 'hang', or the baseline for scripts that hang like 0213 ///< Tibetan and Devanagari. 0214 BaselineMathematical, ///< Use 'math' or the mathematical baseline, used for 0215 ///< aligning numbers and mathematical symbols 0216 ///< correctly. 0217 BaselineCentral, ///< Use the center between the ideographic over and under. 0218 BaselineMiddle, ///< Use the center between the alphabetical and x-height, 0219 ///< or central in vertical. 0220 BaselineTextBottom, ///< Bottom side of the inline line-box. 0221 BaselineTextTop ///< Top side of the inline line-box. 0222 }; 0223 0224 /// Mode of the baseline shift. 0225 enum BaselineShiftMode { 0226 ShiftNone, ///< No shift. 0227 ShiftSub, ///< Use parent font metric for 'subscript'. 0228 ShiftSuper, ///< Use parent font metric for 'superscript'. 0229 ShiftPercentage ///< Percentage of the current fontsize. 0230 // note: we convert all the <length> values into the relative font values! 0231 }; 0232 0233 enum LengthAdjust { 0234 LengthAdjustSpacing, ///< Only stretch the spaces. 0235 LengthAdjustSpacingAndGlyphs ///< Stretches the glyphs as well. 0236 }; 0237 0238 /// Flags for text-decoration, for underline, overline and strikethrough. 0239 enum TextDecoration { 0240 DecorationNone = 0x0, 0241 DecorationUnderline = 0x1, 0242 DecorationOverline = 0x2, 0243 DecorationLineThrough = 0x4 0244 }; 0245 0246 /// Style of the text-decoration. 0247 enum TextDecorationStyle { 0248 Solid, ///< Draw a solid line.Ex: ----- 0249 Double, ///< Draw two lines. Ex: ===== 0250 Dotted, ///< Draw a dotted line. Ex: ..... 0251 Dashed, ///< Draw a dashed line. Ex: - - - - - 0252 Wavy ///< Draw a wavy line. We currently make a zigzag, ex: ^^^^^ 0253 }; 0254 0255 /// Which location to choose for the underline. 0256 enum TextDecorationUnderlinePosition { 0257 UnderlineAuto, ///< Use Font metrics. 0258 UnderlineUnder, ///< Use the bottom of the text decoration bounding box. 0259 UnderlineLeft, ///< Put the underline on the left of the text decoration 0260 ///< bounding box, overline right. 0261 UnderlineRight ///< Put the underline on the right of the text decoration 0262 ///< bounding box, overline left. 0263 }; 0264 0265 /// Whether to stretch the glyphs along a path. 0266 enum TextPathMethod { 0267 TextPathAlign, ///< Only align position and rotation of glyphs to the path. 0268 TextPathStretch ///< Align position and rotation and stretch glyphs' path 0269 ///< points along the path as well. 0270 }; 0271 0272 /// Currently not used, this value suggest using either the default values or 0273 /// 'better' ones. Currently not used. 0274 enum TextPathSpacing { 0275 TextPathAuto, 0276 TextPathExact 0277 }; 0278 0279 /// Whether to reverse the path before laying out text. 0280 enum TextPathSide { 0281 TextPathSideRight, 0282 TextPathSideLeft 0283 }; 0284 0285 /// CSS defines a number of font features as CSS properties. Not all Opentype 0286 /// features are part of this. 0287 enum FontVariantFeature { 0288 FontVariantNormal, ///< Use default features. 0289 FontVariantNone, ///< All features are disabled. 0290 /// font-variant-ligatures, common and contextual are on by default. 0291 CommonLigatures, 0292 NoCommonLigatures, 0293 DiscretionaryLigatures, 0294 NoDiscretionaryLigatures, 0295 HistoricalLigatures, 0296 NoHistoricalLigatures, 0297 ContextualAlternates, 0298 NoContextualAlternates, 0299 /// font-variant-position, neither values are on by default. 0300 PositionSub, 0301 PositionSuper, 0302 /// font-variant-caps, none of the values applicable are on by default. 0303 SmallCaps, 0304 AllSmallCaps, 0305 PetiteCaps, 0306 AllPetiteCaps, 0307 Unicase, 0308 TitlingCaps, 0309 /// font-variant-numeric, none of the values applicable are on by default. 0310 LiningNums, 0311 OldStyleNums, 0312 ProportionalNums, 0313 TabularNums, 0314 DiagonalFractions, 0315 StackedFractions, 0316 Ordinal, 0317 SlashedZero, 0318 /// font-variant-alternates 0319 HistoricalForms, 0320 StylisticAlt, 0321 StyleSet, 0322 CharacterVariant, 0323 Swash, 0324 Ornaments, 0325 Annotation, 0326 /// font-variant-east-asian, none of the values applicable are on by 0327 /// default. 0328 EastAsianJis78, 0329 EastAsianJis83, 0330 EastAsianJis90, 0331 EastAsianJis04, 0332 EastAsianSimplified, 0333 EastAsianTraditional, 0334 EastAsianFullWidth, 0335 EastAsianProportionalWidth, 0336 EastAsianRuby 0337 }; 0338 0339 Q_DECLARE_FLAGS(TextDecorations, TextDecoration) 0340 Q_DECLARE_OPERATORS_FOR_FLAGS(TextDecorations) 0341 0342 Q_DECLARE_FLAGS(TextSpaceTrims, TextSpaceTrim) 0343 Q_DECLARE_OPERATORS_FOR_FLAGS(TextSpaceTrims) 0344 0345 Q_DECLARE_FLAGS(HangingPunctuations, HangingPunctuation) 0346 Q_DECLARE_OPERATORS_FOR_FLAGS(HangingPunctuations) 0347 0348 /** 0349 * AutoValue represents the "auto-or-real" values used in SVG 0350 * 0351 * Some SVG attributes can be set to either "auto" or some floating point 0352 * value. E.g. 'kerning' attribute. If its value is "auto", the kerning is 0353 * defined by the kerning tables of the font. And if its value is a real 0354 * number, e.g. 0 or 5.5, the font kerning is set to this particular number. 0355 */ 0356 struct AutoValue : public boost::equality_comparable<AutoValue> 0357 { 0358 AutoValue() {} 0359 AutoValue(qreal _customValue) : isAuto(false), customValue(_customValue) {} 0360 0361 bool isAuto = true; 0362 qreal customValue = 0.0; 0363 0364 bool operator==(const AutoValue & other) const { 0365 return isAuto == other.isAuto && (isAuto || customValue == other.customValue); 0366 } 0367 }; 0368 0369 QDebug KRITAFLAKE_EXPORT operator<<(QDebug dbg, const KoSvgText::AutoValue &value); 0370 0371 inline QVariant fromAutoValue(const KoSvgText::AutoValue &value) { 0372 return QVariant::fromValue(value); 0373 } 0374 0375 AutoValue parseAutoValueX(const QString &value, const SvgLoadingContext &context, const QString &autoKeyword = "auto"); 0376 AutoValue parseAutoValueY(const QString &value, const SvgLoadingContext &context, const QString &autoKeyword = "auto"); 0377 AutoValue parseAutoValueXY(const QString &value, const SvgLoadingContext &context, const QString &autoKeyword = "auto"); 0378 AutoValue parseAutoValueAngular(const QString &value, const SvgLoadingContext &context, const QString &autoKeyword = "auto"); 0379 0380 WritingMode parseWritingMode(const QString &value); 0381 Direction parseDirection(const QString &value); 0382 UnicodeBidi parseUnicodeBidi(const QString &value); 0383 TextOrientation parseTextOrientation(const QString &value); 0384 TextOrientation parseTextOrientationFromGlyphOrientation(AutoValue value); 0385 TextAnchor parseTextAnchor(const QString &value); 0386 0387 /** 0388 * @brief whiteSpaceValueToLongHands 0389 * CSS-Text-4 takes CSS-Text-3 whitespace values and treats them as a shorthand 0390 * for three more specific properties. This method sets the three properties 0391 * according to the white space value given. 0392 * 0393 * @return whether the value could be parsed. 0394 * Some CSS-Text-3 whitespace values ("break-spaces") have no CSS-Text-4 0395 * variants yet, and thus will be interpreted as "Normal" while this boolean 0396 * returns false. 0397 */ 0398 bool whiteSpaceValueToLongHands(const QString &value, TextSpaceCollapse &collapseMethod, TextWrap &wrapMethod, TextSpaceTrims &trimMethod); 0399 /** 0400 * @brief xmlSpaceToLongHands 0401 * This takes xml:space values and converts them to CSS-Text-4 properties. 0402 * @see whiteSpaceValueToLongHands 0403 */ 0404 bool xmlSpaceToLongHands(const QString &value, TextSpaceCollapse &collapseMethod); 0405 0406 WordBreak parseWordBreak(const QString &value); 0407 LineBreak parseLineBreak(const QString &value); 0408 TextAlign parseTextAlign(const QString &value); 0409 0410 Baseline parseBaseline(const QString &value); 0411 BaselineShiftMode parseBaselineShiftMode(const QString &value); 0412 0413 LengthAdjust parseLengthAdjust(const QString &value); 0414 0415 static const std::array<const char *, 9> fontStretchNames = {"ultra-condensed", 0416 "extra-condensed", 0417 "condensed", 0418 "semi-condensed", 0419 "normal", 0420 "semi-expanded", 0421 "expanded", 0422 "extra-expanded", 0423 "ultra-expanded"}; 0424 static const std::array<const char *, 7> fontSizeNames = 0425 {"xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large"}; 0426 /** 0427 * @brief parseCSSFontStretch 0428 * For CSS3, the font-stretches were only given as keywords. In Css 4 and above, 0429 * they also allow values, except in the "font"-shorthand. The css3 bool will 0430 * restrict parsing to this value for this reason. 0431 */ 0432 int parseCSSFontStretch(const QString &value, int currentStretch); 0433 0434 int parseCSSFontWeight(const QString &value, int currentWeight); 0435 0436 QMap<QString, FontVariantFeature> fontVariantStrings(); 0437 QStringList fontVariantOpentypeTags(FontVariantFeature feature); 0438 0439 TextPathMethod parseTextPathMethod(const QString &value); 0440 TextPathSpacing parseTextPathSpacing(const QString &value); 0441 TextPathSide parseTextPathSide(const QString &value); 0442 0443 QString writeAutoValue(const AutoValue &value, const QString &autoKeyword = "auto"); 0444 0445 QString writeWritingMode(WritingMode value, bool svg1_1 = false); 0446 QString writeDirection(Direction value); 0447 QString writeUnicodeBidi(UnicodeBidi value); 0448 QString writeTextOrientation(TextOrientation orientation); 0449 QString writeTextAnchor(TextAnchor value); 0450 QString writeDominantBaseline(Baseline value); 0451 QString writeAlignmentBaseline(Baseline value); 0452 QString writeBaselineShiftMode(BaselineShiftMode value, qreal portion); 0453 QString writeLengthAdjust(LengthAdjust value); 0454 0455 QString writeTextPathMethod(TextPathMethod value); 0456 QString writeTextPathSpacing(TextPathSpacing value); 0457 QString writeTextPathSide(TextPathSide value); 0458 0459 QString writeWordBreak(WordBreak value); 0460 QString writeLineBreak(LineBreak value); 0461 QString writeTextAlign(TextAlign value); 0462 0463 /** 0464 * @brief writeWhiteSpaceValue 0465 * determine the CSS-3-Whitespace shorthand value. 0466 * @see whiteSpaceValueToLongHands 0467 */ 0468 QString writeWhiteSpaceValue(TextSpaceCollapse collapseMethod, TextWrap wrapMethod, KoSvgText::TextSpaceTrims trimMethod); 0469 QString writeXmlSpace(TextSpaceCollapse collapseMethod); 0470 0471 struct CharTransformation : public boost::equality_comparable<CharTransformation> 0472 { 0473 boost::optional<qreal> xPos; 0474 boost::optional<qreal> yPos; 0475 boost::optional<qreal> dxPos; 0476 boost::optional<qreal> dyPos; 0477 boost::optional<qreal> rotate; 0478 0479 void mergeInParentTransformation(const CharTransformation &t); 0480 bool isNull() const; 0481 bool startsNewChunk() const; 0482 bool hasRelativeOffset() const; 0483 0484 QPointF absolutePos() const; 0485 QPointF relativeOffset() const; 0486 0487 bool operator==(const CharTransformation & other) const; 0488 }; 0489 QDebug KRITAFLAKE_EXPORT operator<<(QDebug dbg, const KoSvgText::CharTransformation &t); 0490 0491 struct TextOnPathInfo { 0492 qreal startOffset = 0.0; 0493 bool startOffsetIsPercentage = false; 0494 TextPathMethod method = TextPathAlign; 0495 TextPathSpacing spacing = TextPathAuto; 0496 TextPathSide side = TextPathSideLeft; 0497 }; 0498 0499 /// "This property transforms text for styling purposes. 0500 /// It has no effect on the underlying content, and must not affect the content 0501 /// of a plain text copy & paste operation." 0502 /// -- CSS-Text-3 0503 struct TextTransformInfo : public boost::equality_comparable<TextTransformInfo> { 0504 TextTransformInfo() = default; 0505 TextTransform capitals = TextTransformNone; ///< Text transform upper/lower/capitalize. 0506 bool fullWidth = false; ///< Convert proportional or half-width text to 0507 ///< full-width text. 'at-risk' 0508 bool fullSizeKana = false; ///< Convert Japanese Katakana and Hiragana to 0509 ///< their 'fullsize' equivelants. 'at-risk' 0510 bool operator==(const TextTransformInfo &rhs) const 0511 { 0512 return (capitals == rhs.capitals) && (fullWidth == rhs.fullWidth) && (fullSizeKana == rhs.fullSizeKana); 0513 } 0514 }; 0515 QDebug KRITAFLAKE_EXPORT operator<<(QDebug dbg, const KoSvgText::TextTransformInfo &t); 0516 TextTransformInfo parseTextTransform(const QString &value); 0517 QString writeTextTransform(TextTransformInfo textTransform); 0518 0519 /// "This property specifies the indentation applied to lines of inline content 0520 /// in a block. 0521 /// The indent is treated as a margin applied to the start edge of the line 0522 /// box." -- CSS-Text-3 0523 struct TextIndentInfo : public boost::equality_comparable<TextIndentInfo> { 0524 TextIndentInfo() = default; 0525 0526 qreal value = 0.0; ///< The indentation length or percentage. 0527 bool isPercentage = false; ///< Interpret the value as a percentage of the 0528 ///< total run length of a box. 0529 bool hanging = false; ///< Flip the lines to which text-indent is applied. 0530 bool eachLine = false; ///< Apply the text-indent to each line following a hardbreak. 0531 bool operator==(const TextIndentInfo &rhs) const 0532 { 0533 return (value == rhs.value) && (isPercentage == rhs.isPercentage) && (hanging == rhs.hanging) && (eachLine == rhs.eachLine); 0534 } 0535 }; 0536 0537 TextIndentInfo parseTextIndent(const QString &value, const SvgLoadingContext &context); 0538 QString writeTextIndent(TextIndentInfo textIndent); 0539 0540 QDebug KRITAFLAKE_EXPORT operator<<(QDebug dbg, const KoSvgText::TextIndentInfo &value); 0541 0542 /// "This property determines the tab size used to render preserved tab 0543 /// characters (U+0009)." -- CSS-Text-3 0544 struct TabSizeInfo : public boost::equality_comparable<TabSizeInfo> { 0545 qreal value = 8; ///< A length or a number. Length is currently marked 'at-risk'. 0546 bool isNumber = true; ///< Multiply by width of 'space' character, including 0547 ///< word- and letter-spacing. 0548 qreal extraSpacing = 0.0; ///< Extra spacing due word or letter-spacing. Not 0549 ///< written to css and only used during layout. 0550 bool operator==(const TabSizeInfo &rhs) const 0551 { 0552 return (value == rhs.value) && (isNumber == rhs.isNumber); 0553 } 0554 }; 0555 TabSizeInfo parseTabSize(const QString &value, const SvgLoadingContext &context); 0556 QString writeTabSize(TabSizeInfo tabSize); 0557 QDebug KRITAFLAKE_EXPORT operator<<(QDebug dbg, const KoSvgText::TabSizeInfo &value); 0558 0559 0560 struct LineHeightInfo : public boost::equality_comparable<LineHeightInfo> { 0561 qreal value = 1.0; /// Length or number. 0562 bool isNumber = false; /// It's a number indicating the lineHeight; 0563 bool isNormal = true; /// The 'auto' value. 0564 0565 bool operator==(const LineHeightInfo &rhs) const 0566 { 0567 return (value == rhs.value) && (isNumber == rhs.isNumber) && (isNormal == rhs.isNormal); 0568 } 0569 }; 0570 0571 LineHeightInfo parseLineHeight(const QString &value, const SvgLoadingContext &context); 0572 QString writeLineHeight(LineHeightInfo lineHeight); 0573 QDebug KRITAFLAKE_EXPORT operator<<(QDebug dbg, const KoSvgText::LineHeightInfo &value); 0574 0575 /** 0576 * @brief BackgroundProperty is a special wrapper around KoShapeBackground for managing it in KoSvgTextProperties 0577 */ 0578 struct BackgroundProperty : public boost::equality_comparable<BackgroundProperty> 0579 { 0580 BackgroundProperty() {} 0581 BackgroundProperty(QSharedPointer<KoShapeBackground> p) : property(p) {} 0582 0583 bool operator==(const BackgroundProperty &rhs) const { 0584 return (!property && !rhs.property) || 0585 (property && rhs.property && 0586 property->compareTo(rhs.property.data())); 0587 } 0588 0589 QSharedPointer<KoShapeBackground> property; 0590 }; 0591 0592 QDebug KRITAFLAKE_EXPORT operator<<(QDebug dbg, const KoSvgText::BackgroundProperty &prop); 0593 0594 /** 0595 * @brief StrokeProperty is a special wrapper around KoShapeStrokeModel for managing it in KoSvgTextProperties 0596 */ 0597 struct StrokeProperty : public boost::equality_comparable<StrokeProperty> 0598 { 0599 StrokeProperty() {} 0600 StrokeProperty(QSharedPointer<KoShapeStrokeModel> p) : property(p) {} 0601 0602 bool operator==(const StrokeProperty &rhs) const { 0603 return (!property && !rhs.property) || 0604 (property && rhs.property && 0605 property->compareFillTo(rhs.property.data()) && property->compareStyleTo(rhs.property.data())); 0606 } 0607 0608 QSharedPointer<KoShapeStrokeModel> property; 0609 }; 0610 0611 QDebug KRITAFLAKE_EXPORT operator<<(QDebug dbg, const KoSvgText::StrokeProperty &prop); 0612 0613 } // namespace KoSvgText 0614 0615 Q_DECLARE_METATYPE(KoSvgText::AutoValue) 0616 Q_DECLARE_METATYPE(KoSvgText::TextDecorations) 0617 Q_DECLARE_METATYPE(KoSvgText::HangingPunctuations) 0618 Q_DECLARE_METATYPE(KoSvgText::TextSpaceTrims) 0619 Q_DECLARE_METATYPE(KoSvgText::BackgroundProperty) 0620 Q_DECLARE_METATYPE(KoSvgText::StrokeProperty) 0621 Q_DECLARE_METATYPE(KoSvgText::TextTransformInfo) 0622 Q_DECLARE_METATYPE(KoSvgText::TextIndentInfo) 0623 Q_DECLARE_METATYPE(KoSvgText::TabSizeInfo) 0624 Q_DECLARE_METATYPE(KoSvgText::LineHeightInfo) 0625 0626 #endif // KOSVGTEXT_H