blob: 449626d96314de70e673cb62417ba592e5731a7e [file] [log] [blame]
Julia Lavrovaa3552c52019-05-30 16:12:56 -04001// Copyright 2019 Google LLC.
2#ifndef TextStyle_DEFINED
3#define TextStyle_DEFINED
4
5#include <vector>
Julia Lavrovaa3552c52019-05-30 16:12:56 -04006#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"
Greg Danielf91aeb22019-06-18 09:58:02 -040011#include "modules/skparagraph/include/DartTypes.h"
12#include "modules/skparagraph/include/TextShadow.h"
Julia Lavrovaa3552c52019-05-30 16:12:56 -040013
14// TODO: Make it external so the other platforms (Android) could use it
15#define DEFAULT_FONT_FAMILY "sans-serif"
16
17namespace skia {
18namespace textlayout {
19
20// Multiple decorations can be applied at once. Ex: Underline and overline is
21// (0x1 | 0x2)
22enum TextDecoration {
23 kNoDecoration = 0x0,
24 kUnderline = 0x1,
25 kOverline = 0x2,
26 kLineThrough = 0x4,
27};
Julia Lavrovab5c69a42019-07-11 09:34:39 -040028constexpr TextDecoration AllTextDecorations[] = {
Julia Lavrovaa3552c52019-05-30 16:12:56 -040029 kNoDecoration,
30 kUnderline,
31 kOverline,
32 kLineThrough,
33};
34
35enum TextDecorationStyle { kSolid, kDouble, kDotted, kDashed, kWavy };
36
37enum StyleType {
38 kAllAttributes,
Julia Lavrovaa3552c52019-05-30 16:12:56 -040039 kFont,
40 kForeground,
41 kBackground,
42 kShadow,
43 kDecorations,
44 kLetterSpacing,
45 kWordSpacing
46};
47
Julia Lavrova5207f352019-06-21 12:22:32 -040048struct 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
Julia Lavrovaa3552c52019-05-30 16:12:56 -040062class TextStyle {
63public:
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
72 SkColor getColor() const { return fColor; }
73 void setColor(SkColor color) { fColor = color; }
74
75 bool hasForeground() const { return fHasForeground; }
76 SkPaint getForeground() const { return fForeground; }
77 void setForegroundColor(SkPaint paint) {
78 fHasForeground = true;
79 fForeground = std::move(paint);
80 }
81 void clearForegroundColor() { fHasForeground = false; }
82
83 bool hasBackground() const { return fHasBackground; }
84 SkPaint getBackground() const { return fBackground; }
85 void setBackgroundColor(SkPaint paint) {
86 fHasBackground = true;
87 fBackground = std::move(paint);
88 }
89 void clearBackgroundColor() { fHasBackground = false; }
90
91 // Decorations
Julia Lavrova5207f352019-06-21 12:22:32 -040092 Decoration getDecoration() const { return fDecoration; }
93 TextDecoration getDecorationType() const { return fDecoration.fType; }
94 SkColor getDecorationColor() const { return fDecoration.fColor; }
95 TextDecorationStyle getDecorationStyle() const { return fDecoration.fStyle; }
Julia Lavrovaa3552c52019-05-30 16:12:56 -040096 SkScalar getDecorationThicknessMultiplier() const {
Julia Lavrova5207f352019-06-21 12:22:32 -040097 return fDecoration.fThicknessMultiplier;
Julia Lavrovaa3552c52019-05-30 16:12:56 -040098 }
Julia Lavrova5207f352019-06-21 12:22:32 -040099 void setDecoration(TextDecoration decoration) { fDecoration.fType = decoration; }
100 void setDecorationStyle(TextDecorationStyle style) { fDecoration.fStyle = style; }
101 void setDecorationColor(SkColor color) { fDecoration.fColor = color; }
102 void setDecorationThicknessMultiplier(SkScalar m) { fDecoration.fThicknessMultiplier = m; }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400103
104 // Weight/Width/Slant
105 SkFontStyle getFontStyle() const { return fFontStyle; }
106 void setFontStyle(SkFontStyle fontStyle) { fFontStyle = fontStyle; }
107
108 // Shadows
109 size_t getShadowNumber() const { return fTextShadows.size(); }
110 std::vector<TextShadow> getShadows() const { return fTextShadows; }
111 void addShadow(TextShadow shadow) { fTextShadows.emplace_back(shadow); }
112 void resetShadows() { fTextShadows.clear(); }
113
114 SkScalar getFontSize() const { return fFontSize; }
115 void setFontSize(SkScalar size) { fFontSize = size; }
116
117 const std::vector<SkString>& getFontFamilies() const { return fFontFamilies; }
118 void setFontFamilies(std::vector<SkString> families) {
119 fFontFamilies = std::move(families);
120 }
121
122 void setHeight(SkScalar height) { fHeight = height; }
Julia Lavrovadb9f6692019-08-01 16:02:17 -0400123 SkScalar getHeight() const { return fHeightOverride ? fHeight : 0; }
124
125 void setHeightOverride(bool heightOverride) { fHeightOverride = heightOverride; }
126 bool getHeightOverride() const { return fHeightOverride; }
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400127
128 void setLetterSpacing(SkScalar letterSpacing) { fLetterSpacing = letterSpacing; }
129 SkScalar getLetterSpacing() const { return fLetterSpacing; }
130
131 void setWordSpacing(SkScalar wordSpacing) { fWordSpacing = wordSpacing; }
132 SkScalar getWordSpacing() const { return fWordSpacing; }
133
134 SkTypeface* getTypeface() const { return fTypeface.get(); }
135 sk_sp<SkTypeface> refTypeface() const { return fTypeface; }
136 void setTypeface(sk_sp<SkTypeface> typeface) { fTypeface = std::move(typeface); }
137
138 SkString getLocale() const { return fLocale; }
139 void setLocale(const SkString& locale) { fLocale = locale; }
140
141 TextBaseline getTextBaseline() const { return fTextBaseline; }
142 void setTextBaseline(TextBaseline baseline) { fTextBaseline = baseline; }
143
Julia Lavrovadb9f6692019-08-01 16:02:17 -0400144 void getFontMetrics(SkFontMetrics* metrics) const;
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400145
146private:
Julia Lavrova5207f352019-06-21 12:22:32 -0400147 Decoration fDecoration;
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400148
149 SkFontStyle fFontStyle;
150
151 std::vector<SkString> fFontFamilies;
152 SkScalar fFontSize;
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400153 SkScalar fHeight;
Julia Lavrovadb9f6692019-08-01 16:02:17 -0400154 bool fHeightOverride;
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400155 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};
Julia Lavrova5207f352019-06-21 12:22:32 -0400171
172typedef size_t TextIndex;
173typedef SkRange<size_t> TextRange;
174const SkRange<size_t> EMPTY_TEXT = EMPTY_RANGE;
175
176
177struct Block {
178 Block() : fRange(EMPTY_RANGE), fStyle() { }
179 Block(size_t start, size_t end, const TextStyle& style)
180 : fRange(start, end), fStyle(style) {}
181 Block(TextRange textRange, const TextStyle& style)
182 : fRange(textRange), fStyle(style) {}
183
184 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
Julia Lavrovaa3552c52019-05-30 16:12:56 -0400192} // namespace textlayout
193} // namespace skia
194
195#endif // TextStyle_DEFINED