• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 Google LLC.
2 #ifndef TextStyle_DEFINED
3 #define TextStyle_DEFINED
4 
5 #include <vector>
6 #include "include/core/SkColor.h"
7 #include "include/core/SkFont.h"
8 #include "include/core/SkFontMetrics.h"
9 #include "include/core/SkFontStyle.h"
10 #include "include/core/SkPaint.h"
11 #include "modules/skparagraph/include/DartTypes.h"
12 #include "modules/skparagraph/include/TextShadow.h"
13 
14 // TODO: Make it external so the other platforms (Android) could use it
15 #define DEFAULT_FONT_FAMILY "sans-serif"
16 
17 namespace skia {
18 namespace textlayout {
19 
20 // Multiple decorations can be applied at once. Ex: Underline and overline is
21 // (0x1 | 0x2)
22 enum TextDecoration {
23     kNoDecoration = 0x0,
24     kUnderline = 0x1,
25     kOverline = 0x2,
26     kLineThrough = 0x4,
27 };
28 constexpr TextDecoration AllTextDecorations[] = {
29         kNoDecoration,
30         kUnderline,
31         kOverline,
32         kLineThrough,
33 };
34 
35 enum TextDecorationStyle { kSolid, kDouble, kDotted, kDashed, kWavy };
36 
37 enum StyleType {
38     kAllAttributes,
39     kFont,
40     kForeground,
41     kBackground,
42     kShadow,
43     kDecorations,
44     kLetterSpacing,
45     kWordSpacing
46 };
47 
48 struct Decoration {
49     TextDecoration fType;
50     SkColor fColor;
51     TextDecorationStyle fStyle;
52     SkScalar fThicknessMultiplier;
53 
54     bool operator==(const Decoration& other) const {
55         return this->fType == other.fType &&
56                this->fColor == other.fColor &&
57                this->fStyle == other.fStyle &&
58                this->fThicknessMultiplier == other.fThicknessMultiplier;
59     }
60 };
61 
62 class TextStyle {
63 public:
64     TextStyle();
65     ~TextStyle() = default;
66 
67     bool equals(const TextStyle& other) const;
68     bool matchOneAttribute(StyleType styleType, const TextStyle& other) const;
69     bool operator==(const TextStyle& rhs) const { return this->equals(rhs); }
70 
71     // Colors
getColor()72     SkColor getColor() const { return fColor; }
setColor(SkColor color)73     void setColor(SkColor color) { fColor = color; }
74 
hasForeground()75     bool hasForeground() const { return fHasForeground; }
getForeground()76     SkPaint getForeground() const { return fForeground; }
setForegroundColor(SkPaint paint)77     void setForegroundColor(SkPaint paint) {
78         fHasForeground = true;
79         fForeground = std::move(paint);
80     }
clearForegroundColor()81     void clearForegroundColor() { fHasForeground = false; }
82 
hasBackground()83     bool hasBackground() const { return fHasBackground; }
getBackground()84     SkPaint getBackground() const { return fBackground; }
setBackgroundColor(SkPaint paint)85     void setBackgroundColor(SkPaint paint) {
86         fHasBackground = true;
87         fBackground = std::move(paint);
88     }
clearBackgroundColor()89     void clearBackgroundColor() { fHasBackground = false; }
90 
91     // Decorations
getDecoration()92     Decoration getDecoration() const { return fDecoration; }
getDecorationType()93     TextDecoration getDecorationType() const { return fDecoration.fType; }
getDecorationColor()94     SkColor getDecorationColor() const { return fDecoration.fColor; }
getDecorationStyle()95     TextDecorationStyle getDecorationStyle() const { return fDecoration.fStyle; }
getDecorationThicknessMultiplier()96     SkScalar getDecorationThicknessMultiplier() const {
97         return fDecoration.fThicknessMultiplier;
98     }
setDecoration(TextDecoration decoration)99     void setDecoration(TextDecoration decoration) { fDecoration.fType = decoration; }
setDecorationStyle(TextDecorationStyle style)100     void setDecorationStyle(TextDecorationStyle style) { fDecoration.fStyle = style; }
setDecorationColor(SkColor color)101     void setDecorationColor(SkColor color) { fDecoration.fColor = color; }
setDecorationThicknessMultiplier(SkScalar m)102     void setDecorationThicknessMultiplier(SkScalar m) { fDecoration.fThicknessMultiplier = m; }
103 
104     // Weight/Width/Slant
getFontStyle()105     SkFontStyle getFontStyle() const { return fFontStyle; }
setFontStyle(SkFontStyle fontStyle)106     void setFontStyle(SkFontStyle fontStyle) { fFontStyle = fontStyle; }
107 
108     // Shadows
getShadowNumber()109     size_t getShadowNumber() const { return fTextShadows.size(); }
getShadows()110     std::vector<TextShadow> getShadows() const { return fTextShadows; }
addShadow(TextShadow shadow)111     void addShadow(TextShadow shadow) { fTextShadows.emplace_back(shadow); }
resetShadows()112     void resetShadows() { fTextShadows.clear(); }
113 
getFontSize()114     SkScalar getFontSize() const { return fFontSize; }
setFontSize(SkScalar size)115     void setFontSize(SkScalar size) { fFontSize = size; }
116 
getFontFamilies()117     const std::vector<SkString>& getFontFamilies() const { return fFontFamilies; }
setFontFamilies(std::vector<SkString> families)118     void setFontFamilies(std::vector<SkString> families) {
119         fFontFamilies = std::move(families);
120     }
121 
setHeight(SkScalar height)122     void setHeight(SkScalar height) { fHeight = height; }
getHeight()123     SkScalar getHeight() const { return fHeightOverride ? fHeight : 0; }
124 
setHeightOverride(bool heightOverride)125     void setHeightOverride(bool heightOverride) { fHeightOverride = heightOverride; }
getHeightOverride()126     bool getHeightOverride() const { return fHeightOverride; }
127 
setLetterSpacing(SkScalar letterSpacing)128     void setLetterSpacing(SkScalar letterSpacing) { fLetterSpacing = letterSpacing; }
getLetterSpacing()129     SkScalar getLetterSpacing() const { return fLetterSpacing; }
130 
setWordSpacing(SkScalar wordSpacing)131     void setWordSpacing(SkScalar wordSpacing) { fWordSpacing = wordSpacing; }
getWordSpacing()132     SkScalar getWordSpacing() const { return fWordSpacing; }
133 
getTypeface()134     SkTypeface* getTypeface() const { return fTypeface.get(); }
refTypeface()135     sk_sp<SkTypeface> refTypeface() const { return fTypeface; }
setTypeface(sk_sp<SkTypeface> typeface)136     void setTypeface(sk_sp<SkTypeface> typeface) { fTypeface = std::move(typeface); }
137 
getLocale()138     SkString getLocale() const { return fLocale; }
setLocale(const SkString & locale)139     void setLocale(const SkString& locale) { fLocale = locale; }
140 
getTextBaseline()141     TextBaseline getTextBaseline() const { return fTextBaseline; }
setTextBaseline(TextBaseline baseline)142     void setTextBaseline(TextBaseline baseline) { fTextBaseline = baseline; }
143 
144     void getFontMetrics(SkFontMetrics* metrics) const;
145 
146 private:
147     Decoration fDecoration;
148 
149     SkFontStyle fFontStyle;
150 
151     std::vector<SkString> fFontFamilies;
152     SkScalar fFontSize;
153     SkScalar fHeight;
154     bool fHeightOverride;
155     SkString fLocale;
156     SkScalar fLetterSpacing;
157     SkScalar fWordSpacing;
158 
159     TextBaseline fTextBaseline;
160 
161     SkColor fColor;
162     bool fHasBackground;
163     SkPaint fBackground;
164     bool fHasForeground;
165     SkPaint fForeground;
166 
167     std::vector<TextShadow> fTextShadows;
168 
169     sk_sp<SkTypeface> fTypeface;
170 };
171 
172 typedef size_t TextIndex;
173 typedef SkRange<size_t> TextRange;
174 const SkRange<size_t> EMPTY_TEXT = EMPTY_RANGE;
175 
176 
177 struct Block {
BlockBlock178     Block() : fRange(EMPTY_RANGE), fStyle() { }
BlockBlock179     Block(size_t start, size_t end, const TextStyle& style)
180         : fRange(start, end), fStyle(style) {}
BlockBlock181     Block(TextRange textRange, const TextStyle& style)
182         : fRange(textRange), fStyle(style) {}
183 
addBlock184     void add(TextRange tail) {
185         SkASSERT(fRange.end == tail.start);
186         fRange = TextRange(fRange.start, fRange.start + fRange.width() + tail.width());
187     }
188     TextRange fRange;
189     TextStyle fStyle;
190 };
191 
192 }  // namespace textlayout
193 }  // namespace skia
194 
195 #endif  // TextStyle_DEFINED
196