Flutter Engine
The Flutter Engine
paragraph_builder_skia.cc
Go to the documentation of this file.
1/*
2 * Copyright 2019 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
18#include "paragraph_skia.h"
19
23#include "txt/paragraph_style.h"
24
25namespace skt = skia::textlayout;
26
27namespace txt {
28
29namespace {
30
31// Convert txt::FontWeight values (ranging from 0-8) to SkFontStyle::Weight
32// values (ranging from 100-900).
33SkFontStyle::Weight GetSkFontStyleWeight(txt::FontWeight font_weight) {
34 return static_cast<SkFontStyle::Weight>(static_cast<int>(font_weight) * 100 +
35 100);
36}
37
38SkFontStyle MakeSkFontStyle(txt::FontWeight font_weight,
39 txt::FontStyle font_style) {
40 return SkFontStyle(
41 GetSkFontStyleWeight(font_weight), SkFontStyle::Width::kNormal_Width,
42 font_style == txt::FontStyle::normal ? SkFontStyle::Slant::kUpright_Slant
43 : SkFontStyle::Slant::kItalic_Slant);
44}
45
46} // anonymous namespace
47
49 const ParagraphStyle& style,
50 std::shared_ptr<FontCollection> font_collection,
51 const bool impeller_enabled)
52 : base_style_(style.GetTextStyle()), impeller_enabled_(impeller_enabled) {
54 TxtToSkia(style),
55 font_collection->CreateSktFontCollection(),
57}
58
60
62 builder_->pushStyle(TxtToSkia(style));
63 txt_style_stack_.push(style);
64}
65
67 builder_->pop();
68 txt_style_stack_.pop();
69}
70
72 return txt_style_stack_.empty() ? base_style_ : txt_style_stack_.top();
73}
74
75void ParagraphBuilderSkia::AddText(const std::u16string& text) {
76 builder_->addText(text);
77}
78
80 skt::PlaceholderStyle placeholder_style;
81 placeholder_style.fHeight = span.height;
82 placeholder_style.fWidth = span.width;
83 placeholder_style.fBaseline = static_cast<skt::TextBaseline>(span.baseline);
84 placeholder_style.fBaselineOffset = span.baseline_offset;
85 placeholder_style.fAlignment =
86 static_cast<skt::PlaceholderAlignment>(span.alignment);
87
88 builder_->addPlaceholder(placeholder_style);
89}
90
91std::unique_ptr<Paragraph> ParagraphBuilderSkia::Build() {
92 return std::make_unique<ParagraphSkia>(
93 builder_->Build(), std::move(dl_paints_), impeller_enabled_);
94}
95
96skt::ParagraphPainter::PaintID ParagraphBuilderSkia::CreatePaintID(
97 const flutter::DlPaint& dl_paint) {
98 dl_paints_.push_back(dl_paint);
99 return dl_paints_.size() - 1;
100}
101
102skt::ParagraphStyle ParagraphBuilderSkia::TxtToSkia(const ParagraphStyle& txt) {
104 skt::TextStyle text_style;
105
106 // Convert the default color of an SkParagraph text style into a DlPaint.
107 flutter::DlPaint dl_paint;
108 dl_paint.setColor(flutter::DlColor(text_style.getColor()));
109 text_style.setForegroundPaintID(CreatePaintID(dl_paint));
110
111 text_style.setFontStyle(MakeSkFontStyle(txt.font_weight, txt.font_style));
112 text_style.setFontSize(SkDoubleToScalar(txt.font_size));
113 text_style.setHeight(SkDoubleToScalar(txt.height));
114 text_style.setHeightOverride(txt.has_height_override);
115 text_style.setFontFamilies({SkString(txt.font_family.c_str())});
116 text_style.setLocale(SkString(txt.locale.c_str()));
117 skia.setTextStyle(text_style);
118
119 skt::StrutStyle strut_style;
120 strut_style.setFontStyle(
121 MakeSkFontStyle(txt.strut_font_weight, txt.strut_font_style));
122 strut_style.setFontSize(SkDoubleToScalar(txt.strut_font_size));
123 strut_style.setHeight(SkDoubleToScalar(txt.strut_height));
124 strut_style.setHeightOverride(txt.strut_has_height_override);
125 strut_style.setHalfLeading(txt.strut_half_leading);
126
127 std::vector<SkString> strut_fonts;
128 std::transform(txt.strut_font_families.begin(), txt.strut_font_families.end(),
129 std::back_inserter(strut_fonts),
130 [](const std::string& f) { return SkString(f.c_str()); });
131 strut_style.setFontFamilies(strut_fonts);
132 strut_style.setLeading(txt.strut_leading);
133 strut_style.setForceStrutHeight(txt.force_strut_height);
134 strut_style.setStrutEnabled(txt.strut_enabled);
135 skia.setStrutStyle(strut_style);
136
137 skia.setTextAlign(static_cast<skt::TextAlign>(txt.text_align));
138 skia.setTextDirection(static_cast<skt::TextDirection>(txt.text_direction));
139 skia.setMaxLines(txt.max_lines);
140 skia.setEllipsis(txt.ellipsis);
141 skia.setTextHeightBehavior(
142 static_cast<skt::TextHeightBehavior>(txt.text_height_behavior));
143
144 skia.turnHintingOff();
145 skia.setReplaceTabCharacters(true);
146 skia.setApplyRoundingHack(false);
147
148 return skia;
149}
150
151skt::TextStyle ParagraphBuilderSkia::TxtToSkia(const TextStyle& txt) {
153
154 skia.setColor(txt.color);
155 skia.setDecoration(static_cast<skt::TextDecoration>(txt.decoration));
156 skia.setDecorationColor(txt.decoration_color);
157 skia.setDecorationStyle(
158 static_cast<skt::TextDecorationStyle>(txt.decoration_style));
159 skia.setDecorationThicknessMultiplier(
160 SkDoubleToScalar(txt.decoration_thickness_multiplier));
161 skia.setFontStyle(MakeSkFontStyle(txt.font_weight, txt.font_style));
162 skia.setTextBaseline(static_cast<skt::TextBaseline>(txt.text_baseline));
163
164 std::vector<SkString> skia_fonts;
165 std::transform(txt.font_families.begin(), txt.font_families.end(),
166 std::back_inserter(skia_fonts),
167 [](const std::string& f) { return SkString(f.c_str()); });
168 skia.setFontFamilies(skia_fonts);
169
170 skia.setFontSize(SkDoubleToScalar(txt.font_size));
171 skia.setLetterSpacing(SkDoubleToScalar(txt.letter_spacing));
172 skia.setWordSpacing(SkDoubleToScalar(txt.word_spacing));
173 skia.setHeight(SkDoubleToScalar(txt.height));
174 skia.setHeightOverride(txt.has_height_override);
175 skia.setHalfLeading(txt.half_leading);
176
177 skia.setLocale(SkString(txt.locale.c_str()));
178 if (txt.background.has_value()) {
179 skia.setBackgroundPaintID(CreatePaintID(txt.background.value()));
180 }
181 if (txt.foreground.has_value()) {
182 skia.setForegroundPaintID(CreatePaintID(txt.foreground.value()));
183 } else {
184 flutter::DlPaint dl_paint;
185 dl_paint.setColor(flutter::DlColor(txt.color));
186 skia.setForegroundPaintID(CreatePaintID(dl_paint));
187 }
188
189 skia.resetFontFeatures();
190 for (const auto& ff : txt.font_features.GetFontFeatures()) {
191 skia.addFontFeature(SkString(ff.first.c_str()), ff.second);
192 }
193
194 if (!txt.font_variations.GetAxisValues().empty()) {
195 std::vector<SkFontArguments::VariationPosition::Coordinate> coordinates;
196 for (const auto& it : txt.font_variations.GetAxisValues()) {
197 const std::string& axis = it.first;
198 if (axis.length() != 4) {
199 continue;
200 }
201 coordinates.push_back({
202 SkSetFourByteTag(axis[0], axis[1], axis[2], axis[3]),
203 it.second,
204 });
205 }
207 coordinates.data(), static_cast<int>(coordinates.size())};
208 skia.setFontArguments(
210 }
211
212 skia.resetShadows();
213 for (const txt::TextShadow& txt_shadow : txt.text_shadows) {
214 skt::TextShadow shadow;
215 shadow.fOffset = txt_shadow.offset;
216 shadow.fBlurSigma = txt_shadow.blur_sigma;
217 shadow.fColor = txt_shadow.color;
218 skia.addShadow(shadow);
219 }
220
221 return skia;
222}
223
224} // namespace txt
#define SkDoubleToScalar(x)
Definition: SkScalar.h:64
static constexpr SkFourByteTag SkSetFourByteTag(char a, char b, char c, char d)
Definition: SkTypes.h:167
DlPaint & setColor(DlColor color)
Definition: dl_paint.h:70
static std::unique_ptr< ParagraphBuilder > make(const ParagraphStyle &style, sk_sp< FontCollection > fontCollection, sk_sp< SkUnicode > unicode)
void setFontFamilies(std::vector< SkString > families)
Definition: TextStyle.h:253
void setHeight(SkScalar height)
Definition: TextStyle.h:260
void setHeightOverride(bool heightOverride)
Definition: TextStyle.h:263
void setFontStyle(SkFontStyle fontStyle)
Definition: TextStyle.h:228
void setLocale(const SkString &locale)
Definition: TextStyle.h:280
SkColor getColor() const
Definition: TextStyle.h:165
void setFontSize(SkScalar size)
Definition: TextStyle.h:250
void setForegroundPaintID(ParagraphPainter::PaintID paintID)
Definition: TextStyle.h:185
virtual const TextStyle & PeekStyle() override
ParagraphBuilderSkia(const ParagraphStyle &style, std::shared_ptr< FontCollection > font_collection, const bool impeller_enabled)
virtual void PushStyle(const TextStyle &style) override
virtual std::unique_ptr< Paragraph > Build() override
virtual void AddText(const std::u16string &text) override
virtual void AddPlaceholder(PlaceholderRun &span) override
virtual void Pop() override
TextBaseline baseline
PlaceholderAlignment alignment
SkPoint offset
Definition: text_shadow.h:28
double blur_sigma
Definition: text_shadow.h:29
std::u16string text
SKUNICODE_API sk_sp< SkUnicode > Make()
PlaceholderAlignment
Where to vertically align the placeholder relative to the surrounding text.
Definition: TextStyle.h:87
Definition: DartTypes.h:13
FontWeight
Definition: font_weight.h:22
FontStyle
Definition: font_style.h:22
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Definition: p3.cpp:47
SkFontArguments & setVariationDesignPosition(VariationPosition position)
PlaceholderAlignment fAlignment
Definition: TextStyle.h:138
void setHalfLeading(bool halfLeading)
void setFontFamilies(std::vector< SkString > families)
void setFontStyle(SkFontStyle fontStyle)
void setHeight(SkScalar height)
void setLeading(SkScalar Leading)
void setFontSize(SkScalar size)