1*c8dee2aaSAndroid Build Coastguard Worker // Copyright 2019 Google LLC. 2*c8dee2aaSAndroid Build Coastguard Worker #ifndef TextStyle_DEFINED 3*c8dee2aaSAndroid Build Coastguard Worker #define TextStyle_DEFINED 4*c8dee2aaSAndroid Build Coastguard Worker 5*c8dee2aaSAndroid Build Coastguard Worker #include <optional> 6*c8dee2aaSAndroid Build Coastguard Worker #include <vector> 7*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h" 8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFont.h" 9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontMetrics.h" 10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontStyle.h" 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/DartTypes.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/FontArguments.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/ParagraphPainter.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skparagraph/include/TextShadow.h" 17*c8dee2aaSAndroid Build Coastguard Worker 18*c8dee2aaSAndroid Build Coastguard Worker // TODO: Make it external so the other platforms (Android) could use it 19*c8dee2aaSAndroid Build Coastguard Worker #define DEFAULT_FONT_FAMILY "sans-serif" 20*c8dee2aaSAndroid Build Coastguard Worker 21*c8dee2aaSAndroid Build Coastguard Worker namespace skia { 22*c8dee2aaSAndroid Build Coastguard Worker namespace textlayout { 23*c8dee2aaSAndroid Build Coastguard Worker 24*c8dee2aaSAndroid Build Coastguard Worker static inline bool nearlyZero(SkScalar x, SkScalar tolerance = SK_ScalarNearlyZero) { 25*c8dee2aaSAndroid Build Coastguard Worker if (SkIsFinite(x)) { 26*c8dee2aaSAndroid Build Coastguard Worker return SkScalarNearlyZero(x, tolerance); 27*c8dee2aaSAndroid Build Coastguard Worker } 28*c8dee2aaSAndroid Build Coastguard Worker return false; 29*c8dee2aaSAndroid Build Coastguard Worker } 30*c8dee2aaSAndroid Build Coastguard Worker 31*c8dee2aaSAndroid Build Coastguard Worker static inline bool nearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance = SK_ScalarNearlyZero) { 32*c8dee2aaSAndroid Build Coastguard Worker if (SkIsFinite(x, y)) { 33*c8dee2aaSAndroid Build Coastguard Worker return SkScalarNearlyEqual(x, y, tolerance); 34*c8dee2aaSAndroid Build Coastguard Worker } 35*c8dee2aaSAndroid Build Coastguard Worker // Inf == Inf, anything else is false 36*c8dee2aaSAndroid Build Coastguard Worker return x == y; 37*c8dee2aaSAndroid Build Coastguard Worker } 38*c8dee2aaSAndroid Build Coastguard Worker 39*c8dee2aaSAndroid Build Coastguard Worker // Multiple decorations can be applied at once. Ex: Underline and overline is 40*c8dee2aaSAndroid Build Coastguard Worker // (0x1 | 0x2) 41*c8dee2aaSAndroid Build Coastguard Worker enum TextDecoration { 42*c8dee2aaSAndroid Build Coastguard Worker kNoDecoration = 0x0, 43*c8dee2aaSAndroid Build Coastguard Worker kUnderline = 0x1, 44*c8dee2aaSAndroid Build Coastguard Worker kOverline = 0x2, 45*c8dee2aaSAndroid Build Coastguard Worker kLineThrough = 0x4, 46*c8dee2aaSAndroid Build Coastguard Worker }; 47*c8dee2aaSAndroid Build Coastguard Worker constexpr TextDecoration AllTextDecorations[] = { 48*c8dee2aaSAndroid Build Coastguard Worker kNoDecoration, 49*c8dee2aaSAndroid Build Coastguard Worker kUnderline, 50*c8dee2aaSAndroid Build Coastguard Worker kOverline, 51*c8dee2aaSAndroid Build Coastguard Worker kLineThrough, 52*c8dee2aaSAndroid Build Coastguard Worker }; 53*c8dee2aaSAndroid Build Coastguard Worker 54*c8dee2aaSAndroid Build Coastguard Worker enum TextDecorationStyle { kSolid, kDouble, kDotted, kDashed, kWavy }; 55*c8dee2aaSAndroid Build Coastguard Worker 56*c8dee2aaSAndroid Build Coastguard Worker enum TextDecorationMode { kGaps, kThrough }; 57*c8dee2aaSAndroid Build Coastguard Worker 58*c8dee2aaSAndroid Build Coastguard Worker enum StyleType { 59*c8dee2aaSAndroid Build Coastguard Worker kNone, 60*c8dee2aaSAndroid Build Coastguard Worker kAllAttributes, 61*c8dee2aaSAndroid Build Coastguard Worker kFont, 62*c8dee2aaSAndroid Build Coastguard Worker kForeground, 63*c8dee2aaSAndroid Build Coastguard Worker kBackground, 64*c8dee2aaSAndroid Build Coastguard Worker kShadow, 65*c8dee2aaSAndroid Build Coastguard Worker kDecorations, 66*c8dee2aaSAndroid Build Coastguard Worker kLetterSpacing, 67*c8dee2aaSAndroid Build Coastguard Worker kWordSpacing 68*c8dee2aaSAndroid Build Coastguard Worker }; 69*c8dee2aaSAndroid Build Coastguard Worker 70*c8dee2aaSAndroid Build Coastguard Worker struct Decoration { 71*c8dee2aaSAndroid Build Coastguard Worker TextDecoration fType; 72*c8dee2aaSAndroid Build Coastguard Worker TextDecorationMode fMode; 73*c8dee2aaSAndroid Build Coastguard Worker SkColor fColor; 74*c8dee2aaSAndroid Build Coastguard Worker TextDecorationStyle fStyle; 75*c8dee2aaSAndroid Build Coastguard Worker SkScalar fThicknessMultiplier; 76*c8dee2aaSAndroid Build Coastguard Worker 77*c8dee2aaSAndroid Build Coastguard Worker bool operator==(const Decoration& other) const { 78*c8dee2aaSAndroid Build Coastguard Worker return this->fType == other.fType && 79*c8dee2aaSAndroid Build Coastguard Worker this->fMode == other.fMode && 80*c8dee2aaSAndroid Build Coastguard Worker this->fColor == other.fColor && 81*c8dee2aaSAndroid Build Coastguard Worker this->fStyle == other.fStyle && 82*c8dee2aaSAndroid Build Coastguard Worker this->fThicknessMultiplier == other.fThicknessMultiplier; 83*c8dee2aaSAndroid Build Coastguard Worker } 84*c8dee2aaSAndroid Build Coastguard Worker }; 85*c8dee2aaSAndroid Build Coastguard Worker 86*c8dee2aaSAndroid Build Coastguard Worker /// Where to vertically align the placeholder relative to the surrounding text. 87*c8dee2aaSAndroid Build Coastguard Worker enum class PlaceholderAlignment { 88*c8dee2aaSAndroid Build Coastguard Worker /// Match the baseline of the placeholder with the baseline. 89*c8dee2aaSAndroid Build Coastguard Worker kBaseline, 90*c8dee2aaSAndroid Build Coastguard Worker 91*c8dee2aaSAndroid Build Coastguard Worker /// Align the bottom edge of the placeholder with the baseline such that the 92*c8dee2aaSAndroid Build Coastguard Worker /// placeholder sits on top of the baseline. 93*c8dee2aaSAndroid Build Coastguard Worker kAboveBaseline, 94*c8dee2aaSAndroid Build Coastguard Worker 95*c8dee2aaSAndroid Build Coastguard Worker /// Align the top edge of the placeholder with the baseline specified in 96*c8dee2aaSAndroid Build Coastguard Worker /// such that the placeholder hangs below the baseline. 97*c8dee2aaSAndroid Build Coastguard Worker kBelowBaseline, 98*c8dee2aaSAndroid Build Coastguard Worker 99*c8dee2aaSAndroid Build Coastguard Worker /// Align the top edge of the placeholder with the top edge of the font. 100*c8dee2aaSAndroid Build Coastguard Worker /// When the placeholder is very tall, the extra space will hang from 101*c8dee2aaSAndroid Build Coastguard Worker /// the top and extend through the bottom of the line. 102*c8dee2aaSAndroid Build Coastguard Worker kTop, 103*c8dee2aaSAndroid Build Coastguard Worker 104*c8dee2aaSAndroid Build Coastguard Worker /// Align the bottom edge of the placeholder with the top edge of the font. 105*c8dee2aaSAndroid Build Coastguard Worker /// When the placeholder is very tall, the extra space will rise from 106*c8dee2aaSAndroid Build Coastguard Worker /// the bottom and extend through the top of the line. 107*c8dee2aaSAndroid Build Coastguard Worker kBottom, 108*c8dee2aaSAndroid Build Coastguard Worker 109*c8dee2aaSAndroid Build Coastguard Worker /// Align the middle of the placeholder with the middle of the text. When the 110*c8dee2aaSAndroid Build Coastguard Worker /// placeholder is very tall, the extra space will grow equally from 111*c8dee2aaSAndroid Build Coastguard Worker /// the top and bottom of the line. 112*c8dee2aaSAndroid Build Coastguard Worker kMiddle, 113*c8dee2aaSAndroid Build Coastguard Worker }; 114*c8dee2aaSAndroid Build Coastguard Worker 115*c8dee2aaSAndroid Build Coastguard Worker struct FontFeature { FontFeatureFontFeature116*c8dee2aaSAndroid Build Coastguard Worker FontFeature(SkString name, int value) : fName(std::move(name)), fValue(value) {} 117*c8dee2aaSAndroid Build Coastguard Worker bool operator==(const FontFeature& that) const { 118*c8dee2aaSAndroid Build Coastguard Worker return fName == that.fName && fValue == that.fValue; 119*c8dee2aaSAndroid Build Coastguard Worker } 120*c8dee2aaSAndroid Build Coastguard Worker SkString fName; 121*c8dee2aaSAndroid Build Coastguard Worker int fValue; 122*c8dee2aaSAndroid Build Coastguard Worker }; 123*c8dee2aaSAndroid Build Coastguard Worker 124*c8dee2aaSAndroid Build Coastguard Worker struct PlaceholderStyle { 125*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle() = default; PlaceholderStylePlaceholderStyle126*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle(SkScalar width, SkScalar height, PlaceholderAlignment alignment, 127*c8dee2aaSAndroid Build Coastguard Worker TextBaseline baseline, SkScalar offset) 128*c8dee2aaSAndroid Build Coastguard Worker : fWidth(width) 129*c8dee2aaSAndroid Build Coastguard Worker , fHeight(height) 130*c8dee2aaSAndroid Build Coastguard Worker , fAlignment(alignment) 131*c8dee2aaSAndroid Build Coastguard Worker , fBaseline(baseline) 132*c8dee2aaSAndroid Build Coastguard Worker , fBaselineOffset(offset) {} 133*c8dee2aaSAndroid Build Coastguard Worker 134*c8dee2aaSAndroid Build Coastguard Worker bool equals(const PlaceholderStyle&) const; 135*c8dee2aaSAndroid Build Coastguard Worker 136*c8dee2aaSAndroid Build Coastguard Worker SkScalar fWidth = 0; 137*c8dee2aaSAndroid Build Coastguard Worker SkScalar fHeight = 0; 138*c8dee2aaSAndroid Build Coastguard Worker PlaceholderAlignment fAlignment = PlaceholderAlignment::kBaseline; 139*c8dee2aaSAndroid Build Coastguard Worker TextBaseline fBaseline = TextBaseline::kAlphabetic; 140*c8dee2aaSAndroid Build Coastguard Worker // Distance from the top edge of the rect to the baseline position. This 141*c8dee2aaSAndroid Build Coastguard Worker // baseline will be aligned against the alphabetic baseline of the surrounding 142*c8dee2aaSAndroid Build Coastguard Worker // text. 143*c8dee2aaSAndroid Build Coastguard Worker // 144*c8dee2aaSAndroid Build Coastguard Worker // Positive values drop the baseline lower (positions the rect higher) and 145*c8dee2aaSAndroid Build Coastguard Worker // small or negative values will cause the rect to be positioned underneath 146*c8dee2aaSAndroid Build Coastguard Worker // the line. When baseline == height, the bottom edge of the rect will rest on 147*c8dee2aaSAndroid Build Coastguard Worker // the alphabetic baseline. 148*c8dee2aaSAndroid Build Coastguard Worker SkScalar fBaselineOffset = 0; 149*c8dee2aaSAndroid Build Coastguard Worker }; 150*c8dee2aaSAndroid Build Coastguard Worker 151*c8dee2aaSAndroid Build Coastguard Worker class TextStyle { 152*c8dee2aaSAndroid Build Coastguard Worker public: 153*c8dee2aaSAndroid Build Coastguard Worker TextStyle() = default; 154*c8dee2aaSAndroid Build Coastguard Worker TextStyle(const TextStyle& other) = default; 155*c8dee2aaSAndroid Build Coastguard Worker TextStyle& operator=(const TextStyle& other) = default; 156*c8dee2aaSAndroid Build Coastguard Worker 157*c8dee2aaSAndroid Build Coastguard Worker TextStyle cloneForPlaceholder(); 158*c8dee2aaSAndroid Build Coastguard Worker 159*c8dee2aaSAndroid Build Coastguard Worker bool equals(const TextStyle& other) const; 160*c8dee2aaSAndroid Build Coastguard Worker bool equalsByFonts(const TextStyle& that) const; 161*c8dee2aaSAndroid Build Coastguard Worker bool matchOneAttribute(StyleType styleType, const TextStyle& other) const; 162*c8dee2aaSAndroid Build Coastguard Worker bool operator==(const TextStyle& rhs) const { return this->equals(rhs); } 163*c8dee2aaSAndroid Build Coastguard Worker 164*c8dee2aaSAndroid Build Coastguard Worker // Colors getColor()165*c8dee2aaSAndroid Build Coastguard Worker SkColor getColor() const { return fColor; } setColor(SkColor color)166*c8dee2aaSAndroid Build Coastguard Worker void setColor(SkColor color) { fColor = color; } 167*c8dee2aaSAndroid Build Coastguard Worker hasForeground()168*c8dee2aaSAndroid Build Coastguard Worker bool hasForeground() const { return fHasForeground; } getForeground()169*c8dee2aaSAndroid Build Coastguard Worker SkPaint getForeground() const { 170*c8dee2aaSAndroid Build Coastguard Worker const SkPaint* paint = std::get_if<SkPaint>(&fForeground); 171*c8dee2aaSAndroid Build Coastguard Worker return paint ? *paint : SkPaint(); 172*c8dee2aaSAndroid Build Coastguard Worker } getForegroundPaintOrID()173*c8dee2aaSAndroid Build Coastguard Worker ParagraphPainter::SkPaintOrID getForegroundPaintOrID() const { 174*c8dee2aaSAndroid Build Coastguard Worker return fForeground; 175*c8dee2aaSAndroid Build Coastguard Worker } setForegroundPaint(SkPaint paint)176*c8dee2aaSAndroid Build Coastguard Worker void setForegroundPaint(SkPaint paint) { 177*c8dee2aaSAndroid Build Coastguard Worker fHasForeground = true; 178*c8dee2aaSAndroid Build Coastguard Worker fForeground = std::move(paint); 179*c8dee2aaSAndroid Build Coastguard Worker } 180*c8dee2aaSAndroid Build Coastguard Worker // DEPRECATED: prefer `setForegroundPaint`. setForegroundColor(SkPaint paint)181*c8dee2aaSAndroid Build Coastguard Worker void setForegroundColor(SkPaint paint) { setForegroundPaint(std::move(paint)); } 182*c8dee2aaSAndroid Build Coastguard Worker 183*c8dee2aaSAndroid Build Coastguard Worker // Set the foreground to a paint ID. This is intended for use by clients 184*c8dee2aaSAndroid Build Coastguard Worker // that implement a custom ParagraphPainter that can not accept an SkPaint. setForegroundPaintID(ParagraphPainter::PaintID paintID)185*c8dee2aaSAndroid Build Coastguard Worker void setForegroundPaintID(ParagraphPainter::PaintID paintID) { 186*c8dee2aaSAndroid Build Coastguard Worker fHasForeground = true; 187*c8dee2aaSAndroid Build Coastguard Worker fForeground = paintID; 188*c8dee2aaSAndroid Build Coastguard Worker } clearForegroundColor()189*c8dee2aaSAndroid Build Coastguard Worker void clearForegroundColor() { fHasForeground = false; } 190*c8dee2aaSAndroid Build Coastguard Worker hasBackground()191*c8dee2aaSAndroid Build Coastguard Worker bool hasBackground() const { return fHasBackground; } getBackground()192*c8dee2aaSAndroid Build Coastguard Worker SkPaint getBackground() const { 193*c8dee2aaSAndroid Build Coastguard Worker const SkPaint* paint = std::get_if<SkPaint>(&fBackground); 194*c8dee2aaSAndroid Build Coastguard Worker return paint ? *paint : SkPaint(); 195*c8dee2aaSAndroid Build Coastguard Worker } getBackgroundPaintOrID()196*c8dee2aaSAndroid Build Coastguard Worker ParagraphPainter::SkPaintOrID getBackgroundPaintOrID() const { 197*c8dee2aaSAndroid Build Coastguard Worker return fBackground; 198*c8dee2aaSAndroid Build Coastguard Worker } setBackgroundPaint(SkPaint paint)199*c8dee2aaSAndroid Build Coastguard Worker void setBackgroundPaint(SkPaint paint) { 200*c8dee2aaSAndroid Build Coastguard Worker fHasBackground = true; 201*c8dee2aaSAndroid Build Coastguard Worker fBackground = std::move(paint); 202*c8dee2aaSAndroid Build Coastguard Worker } 203*c8dee2aaSAndroid Build Coastguard Worker // DEPRECATED: prefer `setBackgroundPaint`. setBackgroundColor(SkPaint paint)204*c8dee2aaSAndroid Build Coastguard Worker void setBackgroundColor(SkPaint paint) { setBackgroundPaint(std::move(paint)); } setBackgroundPaintID(ParagraphPainter::PaintID paintID)205*c8dee2aaSAndroid Build Coastguard Worker void setBackgroundPaintID(ParagraphPainter::PaintID paintID) { 206*c8dee2aaSAndroid Build Coastguard Worker fHasBackground = true; 207*c8dee2aaSAndroid Build Coastguard Worker fBackground = paintID; 208*c8dee2aaSAndroid Build Coastguard Worker } clearBackgroundColor()209*c8dee2aaSAndroid Build Coastguard Worker void clearBackgroundColor() { fHasBackground = false; } 210*c8dee2aaSAndroid Build Coastguard Worker 211*c8dee2aaSAndroid Build Coastguard Worker // Decorations getDecoration()212*c8dee2aaSAndroid Build Coastguard Worker Decoration getDecoration() const { return fDecoration; } getDecorationType()213*c8dee2aaSAndroid Build Coastguard Worker TextDecoration getDecorationType() const { return fDecoration.fType; } getDecorationMode()214*c8dee2aaSAndroid Build Coastguard Worker TextDecorationMode getDecorationMode() const { return fDecoration.fMode; } getDecorationColor()215*c8dee2aaSAndroid Build Coastguard Worker SkColor getDecorationColor() const { return fDecoration.fColor; } getDecorationStyle()216*c8dee2aaSAndroid Build Coastguard Worker TextDecorationStyle getDecorationStyle() const { return fDecoration.fStyle; } getDecorationThicknessMultiplier()217*c8dee2aaSAndroid Build Coastguard Worker SkScalar getDecorationThicknessMultiplier() const { 218*c8dee2aaSAndroid Build Coastguard Worker return fDecoration.fThicknessMultiplier; 219*c8dee2aaSAndroid Build Coastguard Worker } setDecoration(TextDecoration decoration)220*c8dee2aaSAndroid Build Coastguard Worker void setDecoration(TextDecoration decoration) { fDecoration.fType = decoration; } setDecorationMode(TextDecorationMode mode)221*c8dee2aaSAndroid Build Coastguard Worker void setDecorationMode(TextDecorationMode mode) { fDecoration.fMode = mode; } setDecorationStyle(TextDecorationStyle style)222*c8dee2aaSAndroid Build Coastguard Worker void setDecorationStyle(TextDecorationStyle style) { fDecoration.fStyle = style; } setDecorationColor(SkColor color)223*c8dee2aaSAndroid Build Coastguard Worker void setDecorationColor(SkColor color) { fDecoration.fColor = color; } setDecorationThicknessMultiplier(SkScalar m)224*c8dee2aaSAndroid Build Coastguard Worker void setDecorationThicknessMultiplier(SkScalar m) { fDecoration.fThicknessMultiplier = m; } 225*c8dee2aaSAndroid Build Coastguard Worker 226*c8dee2aaSAndroid Build Coastguard Worker // Weight/Width/Slant getFontStyle()227*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle getFontStyle() const { return fFontStyle; } setFontStyle(SkFontStyle fontStyle)228*c8dee2aaSAndroid Build Coastguard Worker void setFontStyle(SkFontStyle fontStyle) { fFontStyle = fontStyle; } 229*c8dee2aaSAndroid Build Coastguard Worker 230*c8dee2aaSAndroid Build Coastguard Worker // Shadows getShadowNumber()231*c8dee2aaSAndroid Build Coastguard Worker size_t getShadowNumber() const { return fTextShadows.size(); } getShadows()232*c8dee2aaSAndroid Build Coastguard Worker std::vector<TextShadow> getShadows() const { return fTextShadows; } addShadow(TextShadow shadow)233*c8dee2aaSAndroid Build Coastguard Worker void addShadow(TextShadow shadow) { fTextShadows.emplace_back(shadow); } resetShadows()234*c8dee2aaSAndroid Build Coastguard Worker void resetShadows() { fTextShadows.clear(); } 235*c8dee2aaSAndroid Build Coastguard Worker 236*c8dee2aaSAndroid Build Coastguard Worker // Font features getFontFeatureNumber()237*c8dee2aaSAndroid Build Coastguard Worker size_t getFontFeatureNumber() const { return fFontFeatures.size(); } getFontFeatures()238*c8dee2aaSAndroid Build Coastguard Worker std::vector<FontFeature> getFontFeatures() const { return fFontFeatures; } addFontFeature(const SkString & fontFeature,int value)239*c8dee2aaSAndroid Build Coastguard Worker void addFontFeature(const SkString& fontFeature, int value) 240*c8dee2aaSAndroid Build Coastguard Worker { fFontFeatures.emplace_back(fontFeature, value); } resetFontFeatures()241*c8dee2aaSAndroid Build Coastguard Worker void resetFontFeatures() { fFontFeatures.clear(); } 242*c8dee2aaSAndroid Build Coastguard Worker 243*c8dee2aaSAndroid Build Coastguard Worker // Font arguments getFontArguments()244*c8dee2aaSAndroid Build Coastguard Worker const std::optional<FontArguments>& getFontArguments() const { return fFontArguments; } 245*c8dee2aaSAndroid Build Coastguard Worker // The contents of the SkFontArguments will be copied into the TextStyle, 246*c8dee2aaSAndroid Build Coastguard Worker // and the SkFontArguments can be safely deleted after setFontArguments returns. 247*c8dee2aaSAndroid Build Coastguard Worker void setFontArguments(const std::optional<SkFontArguments>& args); 248*c8dee2aaSAndroid Build Coastguard Worker getFontSize()249*c8dee2aaSAndroid Build Coastguard Worker SkScalar getFontSize() const { return fFontSize; } setFontSize(SkScalar size)250*c8dee2aaSAndroid Build Coastguard Worker void setFontSize(SkScalar size) { fFontSize = size; } 251*c8dee2aaSAndroid Build Coastguard Worker getFontFamilies()252*c8dee2aaSAndroid Build Coastguard Worker const std::vector<SkString>& getFontFamilies() const { return fFontFamilies; } setFontFamilies(std::vector<SkString> families)253*c8dee2aaSAndroid Build Coastguard Worker void setFontFamilies(std::vector<SkString> families) { 254*c8dee2aaSAndroid Build Coastguard Worker fFontFamilies = std::move(families); 255*c8dee2aaSAndroid Build Coastguard Worker } 256*c8dee2aaSAndroid Build Coastguard Worker getBaselineShift()257*c8dee2aaSAndroid Build Coastguard Worker SkScalar getBaselineShift() const { return fBaselineShift; } setBaselineShift(SkScalar baselineShift)258*c8dee2aaSAndroid Build Coastguard Worker void setBaselineShift(SkScalar baselineShift) { fBaselineShift = baselineShift; } 259*c8dee2aaSAndroid Build Coastguard Worker setHeight(SkScalar height)260*c8dee2aaSAndroid Build Coastguard Worker void setHeight(SkScalar height) { fHeight = height; } getHeight()261*c8dee2aaSAndroid Build Coastguard Worker SkScalar getHeight() const { return fHeightOverride ? fHeight : 0; } 262*c8dee2aaSAndroid Build Coastguard Worker setHeightOverride(bool heightOverride)263*c8dee2aaSAndroid Build Coastguard Worker void setHeightOverride(bool heightOverride) { fHeightOverride = heightOverride; } getHeightOverride()264*c8dee2aaSAndroid Build Coastguard Worker bool getHeightOverride() const { return fHeightOverride; } 265*c8dee2aaSAndroid Build Coastguard Worker setHalfLeading(bool halfLeading)266*c8dee2aaSAndroid Build Coastguard Worker void setHalfLeading(bool halfLeading) { fHalfLeading = halfLeading; } getHalfLeading()267*c8dee2aaSAndroid Build Coastguard Worker bool getHalfLeading() const { return fHalfLeading; } 268*c8dee2aaSAndroid Build Coastguard Worker setLetterSpacing(SkScalar letterSpacing)269*c8dee2aaSAndroid Build Coastguard Worker void setLetterSpacing(SkScalar letterSpacing) { fLetterSpacing = letterSpacing; } getLetterSpacing()270*c8dee2aaSAndroid Build Coastguard Worker SkScalar getLetterSpacing() const { return fLetterSpacing; } 271*c8dee2aaSAndroid Build Coastguard Worker setWordSpacing(SkScalar wordSpacing)272*c8dee2aaSAndroid Build Coastguard Worker void setWordSpacing(SkScalar wordSpacing) { fWordSpacing = wordSpacing; } getWordSpacing()273*c8dee2aaSAndroid Build Coastguard Worker SkScalar getWordSpacing() const { return fWordSpacing; } 274*c8dee2aaSAndroid Build Coastguard Worker getTypeface()275*c8dee2aaSAndroid Build Coastguard Worker SkTypeface* getTypeface() const { return fTypeface.get(); } refTypeface()276*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> refTypeface() const { return fTypeface; } setTypeface(sk_sp<SkTypeface> typeface)277*c8dee2aaSAndroid Build Coastguard Worker void setTypeface(sk_sp<SkTypeface> typeface) { fTypeface = std::move(typeface); } 278*c8dee2aaSAndroid Build Coastguard Worker getLocale()279*c8dee2aaSAndroid Build Coastguard Worker SkString getLocale() const { return fLocale; } setLocale(const SkString & locale)280*c8dee2aaSAndroid Build Coastguard Worker void setLocale(const SkString& locale) { fLocale = locale; } 281*c8dee2aaSAndroid Build Coastguard Worker getTextBaseline()282*c8dee2aaSAndroid Build Coastguard Worker TextBaseline getTextBaseline() const { return fTextBaseline; } setTextBaseline(TextBaseline baseline)283*c8dee2aaSAndroid Build Coastguard Worker void setTextBaseline(TextBaseline baseline) { fTextBaseline = baseline; } 284*c8dee2aaSAndroid Build Coastguard Worker 285*c8dee2aaSAndroid Build Coastguard Worker void getFontMetrics(SkFontMetrics* metrics) const; 286*c8dee2aaSAndroid Build Coastguard Worker isPlaceholder()287*c8dee2aaSAndroid Build Coastguard Worker bool isPlaceholder() const { return fIsPlaceholder; } setPlaceholder()288*c8dee2aaSAndroid Build Coastguard Worker void setPlaceholder() { fIsPlaceholder = true; } 289*c8dee2aaSAndroid Build Coastguard Worker 290*c8dee2aaSAndroid Build Coastguard Worker private: 291*c8dee2aaSAndroid Build Coastguard Worker static const std::vector<SkString>* kDefaultFontFamilies; 292*c8dee2aaSAndroid Build Coastguard Worker 293*c8dee2aaSAndroid Build Coastguard Worker Decoration fDecoration = { 294*c8dee2aaSAndroid Build Coastguard Worker TextDecoration::kNoDecoration, 295*c8dee2aaSAndroid Build Coastguard Worker // TODO: switch back to kGaps when (if) switching flutter to skparagraph 296*c8dee2aaSAndroid Build Coastguard Worker TextDecorationMode::kThrough, 297*c8dee2aaSAndroid Build Coastguard Worker // It does not make sense to draw a transparent object, so we use this as a default 298*c8dee2aaSAndroid Build Coastguard Worker // value to indicate no decoration color was set. 299*c8dee2aaSAndroid Build Coastguard Worker SK_ColorTRANSPARENT, TextDecorationStyle::kSolid, 300*c8dee2aaSAndroid Build Coastguard Worker // Thickness is applied as a multiplier to the default thickness of the font. 301*c8dee2aaSAndroid Build Coastguard Worker 1.0f}; 302*c8dee2aaSAndroid Build Coastguard Worker 303*c8dee2aaSAndroid Build Coastguard Worker SkFontStyle fFontStyle; 304*c8dee2aaSAndroid Build Coastguard Worker 305*c8dee2aaSAndroid Build Coastguard Worker std::vector<SkString> fFontFamilies = *kDefaultFontFamilies; 306*c8dee2aaSAndroid Build Coastguard Worker 307*c8dee2aaSAndroid Build Coastguard Worker SkScalar fFontSize = 14.0; 308*c8dee2aaSAndroid Build Coastguard Worker SkScalar fHeight = 1.0; 309*c8dee2aaSAndroid Build Coastguard Worker bool fHeightOverride = false; 310*c8dee2aaSAndroid Build Coastguard Worker SkScalar fBaselineShift = 0.0f; 311*c8dee2aaSAndroid Build Coastguard Worker // true: half leading. 312*c8dee2aaSAndroid Build Coastguard Worker // false: scale ascent/descent with fHeight. 313*c8dee2aaSAndroid Build Coastguard Worker bool fHalfLeading = false; 314*c8dee2aaSAndroid Build Coastguard Worker SkString fLocale = {}; 315*c8dee2aaSAndroid Build Coastguard Worker SkScalar fLetterSpacing = 0.0; 316*c8dee2aaSAndroid Build Coastguard Worker SkScalar fWordSpacing = 0.0; 317*c8dee2aaSAndroid Build Coastguard Worker 318*c8dee2aaSAndroid Build Coastguard Worker TextBaseline fTextBaseline = TextBaseline::kAlphabetic; 319*c8dee2aaSAndroid Build Coastguard Worker 320*c8dee2aaSAndroid Build Coastguard Worker SkColor fColor = SK_ColorWHITE; 321*c8dee2aaSAndroid Build Coastguard Worker bool fHasBackground = false; 322*c8dee2aaSAndroid Build Coastguard Worker ParagraphPainter::SkPaintOrID fBackground; 323*c8dee2aaSAndroid Build Coastguard Worker bool fHasForeground = false; 324*c8dee2aaSAndroid Build Coastguard Worker ParagraphPainter::SkPaintOrID fForeground; 325*c8dee2aaSAndroid Build Coastguard Worker 326*c8dee2aaSAndroid Build Coastguard Worker std::vector<TextShadow> fTextShadows; 327*c8dee2aaSAndroid Build Coastguard Worker 328*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkTypeface> fTypeface; 329*c8dee2aaSAndroid Build Coastguard Worker bool fIsPlaceholder = false; 330*c8dee2aaSAndroid Build Coastguard Worker 331*c8dee2aaSAndroid Build Coastguard Worker std::vector<FontFeature> fFontFeatures; 332*c8dee2aaSAndroid Build Coastguard Worker 333*c8dee2aaSAndroid Build Coastguard Worker std::optional<FontArguments> fFontArguments; 334*c8dee2aaSAndroid Build Coastguard Worker }; 335*c8dee2aaSAndroid Build Coastguard Worker 336*c8dee2aaSAndroid Build Coastguard Worker typedef size_t TextIndex; 337*c8dee2aaSAndroid Build Coastguard Worker typedef SkRange<size_t> TextRange; 338*c8dee2aaSAndroid Build Coastguard Worker const SkRange<size_t> EMPTY_TEXT = EMPTY_RANGE; 339*c8dee2aaSAndroid Build Coastguard Worker 340*c8dee2aaSAndroid Build Coastguard Worker struct Block { 341*c8dee2aaSAndroid Build Coastguard Worker Block() = default; BlockBlock342*c8dee2aaSAndroid Build Coastguard Worker Block(size_t start, size_t end, const TextStyle& style) : fRange(start, end), fStyle(style) {} BlockBlock343*c8dee2aaSAndroid Build Coastguard Worker Block(TextRange textRange, const TextStyle& style) : fRange(textRange), fStyle(style) {} 344*c8dee2aaSAndroid Build Coastguard Worker addBlock345*c8dee2aaSAndroid Build Coastguard Worker void add(TextRange tail) { 346*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fRange.end == tail.start); 347*c8dee2aaSAndroid Build Coastguard Worker fRange = TextRange(fRange.start, fRange.start + fRange.width() + tail.width()); 348*c8dee2aaSAndroid Build Coastguard Worker } 349*c8dee2aaSAndroid Build Coastguard Worker 350*c8dee2aaSAndroid Build Coastguard Worker TextRange fRange = EMPTY_RANGE; 351*c8dee2aaSAndroid Build Coastguard Worker TextStyle fStyle; 352*c8dee2aaSAndroid Build Coastguard Worker }; 353*c8dee2aaSAndroid Build Coastguard Worker 354*c8dee2aaSAndroid Build Coastguard Worker 355*c8dee2aaSAndroid Build Coastguard Worker typedef size_t BlockIndex; 356*c8dee2aaSAndroid Build Coastguard Worker typedef SkRange<size_t> BlockRange; 357*c8dee2aaSAndroid Build Coastguard Worker const size_t EMPTY_BLOCK = EMPTY_INDEX; 358*c8dee2aaSAndroid Build Coastguard Worker const SkRange<size_t> EMPTY_BLOCKS = EMPTY_RANGE; 359*c8dee2aaSAndroid Build Coastguard Worker 360*c8dee2aaSAndroid Build Coastguard Worker struct Placeholder { 361*c8dee2aaSAndroid Build Coastguard Worker Placeholder() = default; PlaceholderPlaceholder362*c8dee2aaSAndroid Build Coastguard Worker Placeholder(size_t start, size_t end, const PlaceholderStyle& style, const TextStyle& textStyle, 363*c8dee2aaSAndroid Build Coastguard Worker BlockRange blocksBefore, TextRange textBefore) 364*c8dee2aaSAndroid Build Coastguard Worker : fRange(start, end) 365*c8dee2aaSAndroid Build Coastguard Worker , fStyle(style) 366*c8dee2aaSAndroid Build Coastguard Worker , fTextStyle(textStyle) 367*c8dee2aaSAndroid Build Coastguard Worker , fBlocksBefore(blocksBefore) 368*c8dee2aaSAndroid Build Coastguard Worker , fTextBefore(textBefore) {} 369*c8dee2aaSAndroid Build Coastguard Worker 370*c8dee2aaSAndroid Build Coastguard Worker TextRange fRange = EMPTY_RANGE; 371*c8dee2aaSAndroid Build Coastguard Worker PlaceholderStyle fStyle; 372*c8dee2aaSAndroid Build Coastguard Worker TextStyle fTextStyle; 373*c8dee2aaSAndroid Build Coastguard Worker BlockRange fBlocksBefore; 374*c8dee2aaSAndroid Build Coastguard Worker TextRange fTextBefore; 375*c8dee2aaSAndroid Build Coastguard Worker }; 376*c8dee2aaSAndroid Build Coastguard Worker 377*c8dee2aaSAndroid Build Coastguard Worker } // namespace textlayout 378*c8dee2aaSAndroid Build Coastguard Worker } // namespace skia 379*c8dee2aaSAndroid Build Coastguard Worker 380*c8dee2aaSAndroid Build Coastguard Worker #endif // TextStyle_DEFINED 381