1 // Copyright 2019 Google LLC. 2 #ifndef ParagraphStyle_DEFINED 3 #define ParagraphStyle_DEFINED 4 5 #include "include/core/SkFontStyle.h" 6 #include "include/core/SkScalar.h" 7 #include "include/core/SkString.h" 8 #include "modules/skparagraph/include/DartTypes.h" 9 #include "modules/skparagraph/include/TextStyle.h" 10 #ifdef ENABLE_TEXT_ENHANCE 11 #include "drawing.h" 12 #endif 13 14 #include <stddef.h> 15 #include <algorithm> 16 #include <limits> 17 #include <string> 18 #include <utility> 19 #include <vector> 20 21 namespace skia { 22 namespace textlayout { 23 24 #ifdef ENABLE_TEXT_ENHANCE 25 struct TextTabs { 26 TextAlign alignment; 27 SkScalar location; 28 bool operator==(const TextTabs& other) const { 29 return (alignment == other.alignment) && nearlyEqual(location, other.location); 30 } 31 }; 32 33 struct TextBlobRecordInfo { 34 std::shared_ptr<RSTextBlob> fBlob{nullptr}; 35 SkPoint fOffset{0.0f, 0.0f}; 36 ParagraphPainter::SkPaintOrID fPaint; 37 }; 38 39 enum class TextVerticalAlign { 40 BASELINE, 41 BOTTOM, 42 CENTER, 43 TOP, 44 }; 45 46 enum class WordBreakType { 47 NORMAL, // to be done. 48 BREAK_ALL, // break occur after any characters. 49 BREAK_WORD, // break only occur after word. 50 BREAK_HYPHEN, 51 }; 52 53 enum class LineBreakStrategy { 54 GREEDY, // faster and linear. 55 HIGH_QUALITY, // breaking tries to split the lines as efficiently as possible 56 BALANCED, // breaking tries to make the line lengths even 57 }; 58 #endif 59 struct StrutStyle { 60 StrutStyle(); 61 getFontFamiliesStrutStyle62 const std::vector<SkString>& getFontFamilies() const { return fFontFamilies; } setFontFamiliesStrutStyle63 void setFontFamilies(std::vector<SkString> families) { fFontFamilies = std::move(families); } 64 65 #ifdef ENABLE_TEXT_ENHANCE getFontStyleStrutStyle66 RSFontStyle getFontStyle() const { return fFontStyle; } setFontStyleStrutStyle67 void setFontStyle(RSFontStyle fontStyle) { fFontStyle = fontStyle; } 68 #else getFontStyleStrutStyle69 SkFontStyle getFontStyle() const { return fFontStyle; } setFontStyleStrutStyle70 void setFontStyle(SkFontStyle fontStyle) { fFontStyle = fontStyle; } 71 #endif 72 getFontSizeStrutStyle73 SkScalar getFontSize() const { return fFontSize; } setFontSizeStrutStyle74 void setFontSize(SkScalar size) { fFontSize = size; } 75 setHeightStrutStyle76 void setHeight(SkScalar height) { fHeight = height; } getHeightStrutStyle77 SkScalar getHeight() const { return fHeight; } 78 setLeadingStrutStyle79 void setLeading(SkScalar Leading) { fLeading = Leading; } getLeadingStrutStyle80 SkScalar getLeading() const { return fLeading; } 81 getStrutEnabledStrutStyle82 bool getStrutEnabled() const { return fEnabled; } setStrutEnabledStrutStyle83 void setStrutEnabled(bool v) { fEnabled = v; } 84 getForceStrutHeightStrutStyle85 bool getForceStrutHeight() const { return fForceHeight; } setForceStrutHeightStrutStyle86 void setForceStrutHeight(bool v) { fForceHeight = v; } 87 getHeightOverrideStrutStyle88 bool getHeightOverride() const { return fHeightOverride; } setHeightOverrideStrutStyle89 void setHeightOverride(bool v) { fHeightOverride = v; } 90 setHalfLeadingStrutStyle91 void setHalfLeading(bool halfLeading) { fHalfLeading = halfLeading; } getHalfLeadingStrutStyle92 bool getHalfLeading() const { return fHalfLeading; } 93 94 #ifdef ENABLE_TEXT_ENHANCE setWordBreakTypeStrutStyle95 void setWordBreakType(const WordBreakType& wordBreakType) { fWordBreakType = wordBreakType; } getWordBreakTypeStrutStyle96 WordBreakType getWordBreakType() const { return fWordBreakType; } 97 setLineBreakStrategyStrutStyle98 void setLineBreakStrategy(const LineBreakStrategy& lineBreakStrategy) { fLineBreakStrategy = lineBreakStrategy; } getLineBreakStrategyStrutStyle99 LineBreakStrategy getLineBreakStrategy() const { return fLineBreakStrategy; } 100 #endif 101 102 bool operator==(const StrutStyle& rhs) const { 103 #ifdef ENABLE_TEXT_ENHANCE 104 return this->fEnabled == rhs.fEnabled && 105 this->fHeightOverride == rhs.fHeightOverride && 106 this->fForceHeight == rhs.fForceHeight && 107 this->fHalfLeading == rhs.fHalfLeading && 108 nearlyEqual(this->fLeading, rhs.fLeading) && 109 nearlyEqual(this->fHeight, rhs.fHeight) && 110 nearlyEqual(this->fFontSize, rhs.fFontSize) && 111 this->fFontStyle == rhs.fFontStyle && 112 this->fFontFamilies == rhs.fFontFamilies && 113 this->fWordBreakType == rhs.fWordBreakType && 114 this->fLineBreakStrategy == rhs.fLineBreakStrategy; 115 #else 116 return this->fEnabled == rhs.fEnabled && 117 this->fHeightOverride == rhs.fHeightOverride && 118 this->fForceHeight == rhs.fForceHeight && 119 this->fHalfLeading == rhs.fHalfLeading && 120 nearlyEqual(this->fLeading, rhs.fLeading) && 121 nearlyEqual(this->fHeight, rhs.fHeight) && 122 nearlyEqual(this->fFontSize, rhs.fFontSize) && 123 this->fFontStyle == rhs.fFontStyle && 124 this->fFontFamilies == rhs.fFontFamilies; 125 #endif 126 } 127 128 private: 129 130 std::vector<SkString> fFontFamilies; 131 #ifdef ENABLE_TEXT_ENHANCE 132 RSFontStyle fFontStyle; 133 #else 134 SkFontStyle fFontStyle; 135 #endif 136 SkScalar fFontSize; 137 SkScalar fHeight; 138 SkScalar fLeading; 139 bool fForceHeight; 140 bool fEnabled; 141 bool fHeightOverride; 142 // true: half leading. 143 // false: scale ascent/descent with fHeight. 144 bool fHalfLeading; 145 #ifdef ENABLE_TEXT_ENHANCE 146 WordBreakType fWordBreakType; 147 LineBreakStrategy fLineBreakStrategy { LineBreakStrategy::GREEDY }; 148 #endif 149 }; 150 151 struct ParagraphStyle { 152 ParagraphStyle(); 153 154 bool operator==(const ParagraphStyle& rhs) const { 155 #ifdef ENABLE_TEXT_ENHANCE 156 return this->fHeight == rhs.fHeight && this->fEllipsis == rhs.fEllipsis && 157 this->fEllipsisUtf16 == rhs.fEllipsisUtf16 && 158 this->fTextDirection == rhs.fTextDirection && this->fTextAlign == rhs.fTextAlign && 159 this->fDefaultTextStyle == rhs.fDefaultTextStyle && 160 this->fEllipsisModal == rhs.fEllipsisModal && 161 this->fTextOverflower == rhs.fTextOverflower && 162 this->fReplaceTabCharacters == rhs.fReplaceTabCharacters && 163 this->fTextTab == rhs.fTextTab && this->fParagraphSpacing == rhs.fParagraphSpacing && 164 this->fIsEndAddParagraphSpacing == rhs.fIsEndAddParagraphSpacing && 165 this->fIsTrailingSpaceOptimized == rhs.fIsTrailingSpaceOptimized && 166 this->fEnableAutoSpace == rhs.fEnableAutoSpace && 167 this->fVerticalAlignment == rhs.fVerticalAlignment && 168 nearlyEqual(this->fTextSplitRatio, rhs.fTextSplitRatio); 169 #else 170 return this->fHeight == rhs.fHeight && 171 this->fEllipsis == rhs.fEllipsis && 172 this->fEllipsisUtf16 == rhs.fEllipsisUtf16 && 173 this->fTextDirection == rhs.fTextDirection && this->fTextAlign == rhs.fTextAlign && 174 this->fDefaultTextStyle == rhs.fDefaultTextStyle && 175 this->fReplaceTabCharacters == rhs.fReplaceTabCharacters; 176 #endif 177 } 178 getStrutStyleParagraphStyle179 const StrutStyle& getStrutStyle() const { return fStrutStyle; } setStrutStyleParagraphStyle180 void setStrutStyle(StrutStyle strutStyle) { fStrutStyle = std::move(strutStyle); } 181 getTextStyleParagraphStyle182 const TextStyle& getTextStyle() const { return fDefaultTextStyle; } setTextStyleParagraphStyle183 void setTextStyle(const TextStyle& textStyle) { fDefaultTextStyle = textStyle; } 184 getTextDirectionParagraphStyle185 TextDirection getTextDirection() const { return fTextDirection; } setTextDirectionParagraphStyle186 void setTextDirection(TextDirection direction) { fTextDirection = direction; } 187 getTextAlignParagraphStyle188 TextAlign getTextAlign() const { return fTextAlign; } setTextAlignParagraphStyle189 void setTextAlign(TextAlign align) { fTextAlign = align; } 190 getMaxLinesParagraphStyle191 size_t getMaxLines() const { return fLinesLimit; } setMaxLinesParagraphStyle192 void setMaxLines(size_t maxLines) { fLinesLimit = maxLines; } 193 getEllipsisParagraphStyle194 SkString getEllipsis() const { return fEllipsis; } getEllipsisUtf16ParagraphStyle195 std::u16string getEllipsisUtf16() const { return fEllipsisUtf16; } setEllipsisParagraphStyle196 void setEllipsis(const std::u16string& ellipsis) { fEllipsisUtf16 = ellipsis; } setEllipsisParagraphStyle197 void setEllipsis(const SkString& ellipsis) { fEllipsis = ellipsis; } 198 getHeightParagraphStyle199 SkScalar getHeight() const { return fHeight; } setHeightParagraphStyle200 void setHeight(SkScalar height) { fHeight = height; } 201 getTextHeightBehaviorParagraphStyle202 TextHeightBehavior getTextHeightBehavior() const { return fTextHeightBehavior; } setTextHeightBehaviorParagraphStyle203 void setTextHeightBehavior(TextHeightBehavior v) { fTextHeightBehavior = v; } 204 unlimited_linesParagraphStyle205 bool unlimited_lines() const { 206 return fLinesLimit == std::numeric_limits<size_t>::max(); 207 } ellipsizedParagraphStyle208 bool ellipsized() const { return !fEllipsis.isEmpty() || !fEllipsisUtf16.empty(); } 209 TextAlign effective_align() const; hintingIsOnParagraphStyle210 bool hintingIsOn() const { return fHintingIsOn; } turnHintingOffParagraphStyle211 void turnHintingOff() { fHintingIsOn = false; } 212 getReplaceTabCharactersParagraphStyle213 bool getReplaceTabCharacters() const { return fReplaceTabCharacters; } setReplaceTabCharactersParagraphStyle214 void setReplaceTabCharacters(bool value) { fReplaceTabCharacters = value; } 215 216 #ifdef ENABLE_TEXT_ENHANCE setVerticalAlignmentParagraphStyle217 void setVerticalAlignment(TextVerticalAlign verticalAlignment) { fVerticalAlignment = verticalAlignment; } getVerticalAlignmentParagraphStyle218 TextVerticalAlign getVerticalAlignment() const { return fVerticalAlignment; } exportStrutStyleParagraphStyle219 StrutStyle& exportStrutStyle() { return fStrutStyle; } exportTextStyleParagraphStyle220 TextStyle& exportTextStyle() { return fDefaultTextStyle; } 221 getEllipsisModParagraphStyle222 skia::textlayout::EllipsisModal getEllipsisMod() const { return fEllipsisModal; } setEllipsisModParagraphStyle223 void setEllipsisMod(skia::textlayout::EllipsisModal ellipsisModel) { fEllipsisModal = ellipsisModel; } getTextSplitRatioParagraphStyle224 SkScalar getTextSplitRatio() const { return fTextSplitRatio; } setTextSplitRatioParagraphStyle225 void setTextSplitRatio(SkScalar textSplitRatio) { fTextSplitRatio = textSplitRatio; } 226 getTextOverflowerParagraphStyle227 bool getTextOverflower() const { return fTextOverflower; } setTextOverflowerParagraphStyle228 void setTextOverflower(bool textOverflowerFlag) { fTextOverflower = textOverflowerFlag; } getTextTabParagraphStyle229 const TextTabs& getTextTab() const { return fTextTab; } setTextTabParagraphStyle230 void setTextTab(const TextTabs& textTab) { fTextTab = textTab; } getParagraphSpacingParagraphStyle231 SkScalar getParagraphSpacing() const { return fParagraphSpacing; } setParagraphSpacingParagraphStyle232 void setParagraphSpacing(SkScalar paragraphSpacing) 233 { 234 fParagraphSpacing = paragraphSpacing; 235 } getIsEndAddParagraphSpacingParagraphStyle236 bool getIsEndAddParagraphSpacing() const { return fIsEndAddParagraphSpacing; } setIsEndAddParagraphSpacingParagraphStyle237 void setIsEndAddParagraphSpacing(bool isEndAddParagraphSpacing) 238 { 239 fIsEndAddParagraphSpacing = isEndAddParagraphSpacing; 240 } getTrailingSpaceOptimizedParagraphStyle241 bool getTrailingSpaceOptimized() const { return fIsTrailingSpaceOptimized; } setTrailingSpaceOptimizedParagraphStyle242 void setTrailingSpaceOptimized(bool isTrailingSpaceOptimized) 243 { 244 fIsTrailingSpaceOptimized = isTrailingSpaceOptimized; 245 } 246 getEnableAutoSpaceParagraphStyle247 bool getEnableAutoSpace() const { return fEnableAutoSpace; } setEnableAutoSpaceParagraphStyle248 void setEnableAutoSpace(bool enableAutoSpace) 249 { 250 fEnableAutoSpace = enableAutoSpace; 251 } 252 #endif getApplyRoundingHackParagraphStyle253 bool getApplyRoundingHack() const { return fApplyRoundingHack; } setApplyRoundingHackParagraphStyle254 void setApplyRoundingHack(bool value) { fApplyRoundingHack = value; } 255 256 private: 257 StrutStyle fStrutStyle; 258 TextStyle fDefaultTextStyle; 259 TextAlign fTextAlign; 260 TextDirection fTextDirection; 261 size_t fLinesLimit; 262 std::u16string fEllipsisUtf16; 263 SkString fEllipsis; 264 SkScalar fHeight; 265 TextHeightBehavior fTextHeightBehavior; 266 bool fHintingIsOn; 267 bool fReplaceTabCharacters; 268 bool fApplyRoundingHack = true; 269 #ifdef ENABLE_TEXT_ENHANCE 270 bool fTextOverflower; 271 skia::textlayout::EllipsisModal fEllipsisModal; 272 SkScalar fTextSplitRatio{0.5f}; 273 TextTabs fTextTab; 274 SkScalar fParagraphSpacing{0.0f}; 275 bool fIsEndAddParagraphSpacing{false}; 276 bool fIsTrailingSpaceOptimized{false}; 277 bool fEnableAutoSpace{false}; 278 TextVerticalAlign fVerticalAlignment{TextVerticalAlign::BASELINE}; 279 #endif 280 }; 281 } // namespace textlayout 282 } // namespace skia 283 284 #endif // ParagraphStyle_DEFINED 285