Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
TextStyle.cpp
Go to the documentation of this file.
1// Copyright 2019 Google LLC.
5
6namespace skia {
7namespace textlayout {
8
9const std::vector<SkString>* TextStyle::kDefaultFontFamilies =
10 new std::vector<SkString>{SkString(DEFAULT_FONT_FAMILY)};
11
14 result.fColor = fColor;
15 result.fFontSize = fFontSize;
16 result.fFontFamilies = fFontFamilies;
17 result.fDecoration = fDecoration;
18 result.fHasBackground = fHasBackground;
19 result.fHasForeground = fHasForeground;
20 result.fBackground = fBackground;
21 result.fForeground = fForeground;
22 result.fHeightOverride = fHeightOverride;
23 result.fIsPlaceholder = true;
24 result.fFontFeatures = fFontFeatures;
25 result.fHalfLeading = fHalfLeading;
26 result.fBaselineShift = fBaselineShift;
27 result.fFontArguments = fFontArguments;
28 return result;
29}
30
31bool TextStyle::equals(const TextStyle& other) const {
32
33 if (fIsPlaceholder || other.fIsPlaceholder) {
34 return false;
35 }
36
37 if (fColor != other.fColor) {
38 return false;
39 }
40 if (!(fDecoration == other.fDecoration)) {
41 return false;
42 }
43 if (!(fFontStyle == other.fFontStyle)) {
44 return false;
45 }
46 if (fFontFamilies != other.fFontFamilies) {
47 return false;
48 }
49 if (fLetterSpacing != other.fLetterSpacing) {
50 return false;
51 }
52 if (fWordSpacing != other.fWordSpacing) {
53 return false;
54 }
55 if (fHeight != other.fHeight) {
56 return false;
57 }
58 if (fHeightOverride != other.fHeightOverride) {
59 return false;
60 }
61 if (fHalfLeading != other.fHalfLeading) {
62 return false;
63 }
64 if (fBaselineShift != other.fBaselineShift) {
65 return false;
66 }
67 if (fFontSize != other.fFontSize) {
68 return false;
69 }
70 if (fLocale != other.fLocale) {
71 return false;
72 }
73 if (fHasForeground != other.fHasForeground || fForeground != other.fForeground) {
74 return false;
75 }
76 if (fHasBackground != other.fHasBackground || fBackground != other.fBackground) {
77 return false;
78 }
79 if (fTextShadows.size() != other.fTextShadows.size()) {
80 return false;
81 }
82 for (size_t i = 0; i < fTextShadows.size(); ++i) {
83 if (fTextShadows[i] != other.fTextShadows[i]) {
84 return false;
85 }
86 }
87 if (fFontFeatures.size() != other.fFontFeatures.size()) {
88 return false;
89 }
90 for (size_t i = 0; i < fFontFeatures.size(); ++i) {
91 if (!(fFontFeatures[i] == other.fFontFeatures[i])) {
92 return false;
93 }
94 }
95 if (fFontArguments != other.fFontArguments) {
96 return false;
97 }
98
99 return true;
100}
101
102bool TextStyle::equalsByFonts(const TextStyle& that) const {
103
104 return !fIsPlaceholder && !that.fIsPlaceholder &&
105 fFontStyle == that.fFontStyle &&
106 fFontFamilies == that.fFontFamilies &&
107 fFontFeatures == that.fFontFeatures &&
108 fFontArguments == that.getFontArguments() &&
109 nearlyEqual(fLetterSpacing, that.fLetterSpacing) &&
110 nearlyEqual(fWordSpacing, that.fWordSpacing) &&
111 nearlyEqual(fHeight, that.fHeight) &&
112 nearlyEqual(fBaselineShift, that.fBaselineShift) &&
113 nearlyEqual(fFontSize, that.fFontSize) &&
114 fLocale == that.fLocale;
115}
116
117bool TextStyle::matchOneAttribute(StyleType styleType, const TextStyle& other) const {
118 switch (styleType) {
119 case kForeground:
120 return (!fHasForeground && !other.fHasForeground && fColor == other.fColor) ||
121 ( fHasForeground && other.fHasForeground && fForeground == other.fForeground);
122
123 case kBackground:
124 return (!fHasBackground && !other.fHasBackground) ||
125 ( fHasBackground && other.fHasBackground && fBackground == other.fBackground);
126
127 case kShadow:
128 if (fTextShadows.size() != other.fTextShadows.size()) {
129 return false;
130 }
131
132 for (int32_t i = 0; i < SkToInt(fTextShadows.size()); ++i) {
133 if (fTextShadows[i] != other.fTextShadows[i]) {
134 return false;
135 }
136 }
137 return true;
138
139 case kDecorations:
140 return this->fDecoration == other.fDecoration;
141
142 case kLetterSpacing:
143 return fLetterSpacing == other.fLetterSpacing;
144
145 case kWordSpacing:
146 return fWordSpacing == other.fWordSpacing;
147
148 case kAllAttributes:
149 return this->equals(other);
150
151 case kFont:
152 // TODO: should not we take typefaces in account?
153 return fFontStyle == other.fFontStyle &&
154 fLocale == other.fLocale &&
155 fFontFamilies == other.fFontFamilies &&
156 fFontSize == other.fFontSize &&
157 fHeight == other.fHeight &&
158 fHalfLeading == other.fHalfLeading &&
159 fBaselineShift == other.fBaselineShift &&
160 fFontArguments == other.fFontArguments;
161 default:
162 SkASSERT(false);
163 return false;
164 }
165}
166
168 SkFont font(fTypeface, fFontSize);
169 font.setEdging(SkFont::Edging::kAntiAlias);
170 font.setSubpixel(true);
171 font.setHinting(SkFontHinting::kSlight);
172 font.getMetrics(metrics);
173 if (fHeightOverride) {
174 auto multiplier = fHeight * fFontSize;
175 auto height = metrics->fDescent - metrics->fAscent + metrics->fLeading;
176 metrics->fAscent = (metrics->fAscent - metrics->fLeading / 2) * multiplier / height;
177 metrics->fDescent = (metrics->fDescent + metrics->fLeading / 2) * multiplier / height;
178
179 } else {
180 metrics->fAscent = (metrics->fAscent - metrics->fLeading / 2);
181 metrics->fDescent = (metrics->fDescent + metrics->fLeading / 2);
182 }
183 // If we shift the baseline we need to make sure the shifted text fits the line
184 metrics->fAscent += fBaselineShift;
185 metrics->fDescent += fBaselineShift;
186}
187
188void TextStyle::setFontArguments(const std::optional<SkFontArguments>& args) {
189 if (!args) {
190 fFontArguments.reset();
191 return;
192 }
193
194 fFontArguments.emplace(*args);
195}
196
198 return nearlyEqual(fWidth, other.fWidth) &&
199 nearlyEqual(fHeight, other.fHeight) &&
200 fAlignment == other.fAlignment &&
201 fBaseline == other.fBaseline &&
204}
205
206} // namespace textlayout
207} // namespace skia
#define SkASSERT(cond)
Definition SkAssert.h:116
@ kSlight
minimal modification to improve constrast
constexpr int SkToInt(S x)
Definition SkTo.h:29
#define DEFAULT_FONT_FAMILY
Definition TextStyle.h:19
@ kAntiAlias
may have transparent pixels on glyph edges
bool matchOneAttribute(StyleType styleType, const TextStyle &other) const
bool equals(const TextStyle &other) const
Definition TextStyle.cpp:31
void getFontMetrics(SkFontMetrics *metrics) const
bool equalsByFonts(const TextStyle &that) const
void setFontArguments(const std::optional< SkFontArguments > &args)
const std::optional< FontArguments > & getFontArguments() const
Definition TextStyle.h:244
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
GAsyncResult * result
@ kBaseline
Match the baseline of the placeholder with the baseline.
static bool nearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition TextStyle.h:31
int32_t height
SkScalar fLeading
distance to add between lines, typically positive or zero
SkScalar fAscent
distance to reserve above baseline, typically negative
SkScalar fDescent
distance to reserve below baseline, typically positive
PlaceholderAlignment fAlignment
Definition TextStyle.h:138
bool equals(const PlaceholderStyle &) const