Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
22#include "txt/paragraph_style.h"
23
24namespace skt = skia::textlayout;
25
26namespace txt {
27
28namespace {
29
30// Convert txt::FontWeight values (ranging from 0-8) to SkFontStyle::Weight
31// values (ranging from 100-900).
32SkFontStyle::Weight GetSkFontStyleWeight(txt::FontWeight font_weight) {
33 return static_cast<SkFontStyle::Weight>(static_cast<int>(font_weight) * 100 +
34 100);
35}
36
37SkFontStyle MakeSkFontStyle(txt::FontWeight font_weight,
38 txt::FontStyle font_style) {
39 return SkFontStyle(
40 GetSkFontStyleWeight(font_weight), SkFontStyle::Width::kNormal_Width,
43}
44
45} // anonymous namespace
46
48 const ParagraphStyle& style,
49 std::shared_ptr<FontCollection> font_collection,
50 const bool impeller_enabled)
51 : base_style_(style.GetTextStyle()), impeller_enabled_(impeller_enabled) {
52 builder_ = skt::ParagraphBuilder::make(
53 TxtToSkia(style), font_collection->CreateSktFontCollection());
54}
55
57
59 builder_->pushStyle(TxtToSkia(style));
60 txt_style_stack_.push(style);
61}
62
64 builder_->pop();
65 txt_style_stack_.pop();
66}
67
69 return txt_style_stack_.empty() ? base_style_ : txt_style_stack_.top();
70}
71
72void ParagraphBuilderSkia::AddText(const std::u16string& text) {
73 builder_->addText(text);
74}
75
77 skt::PlaceholderStyle placeholder_style;
78 placeholder_style.fHeight = span.height;
79 placeholder_style.fWidth = span.width;
80 placeholder_style.fBaseline = static_cast<skt::TextBaseline>(span.baseline);
81 placeholder_style.fBaselineOffset = span.baseline_offset;
82 placeholder_style.fAlignment =
83 static_cast<skt::PlaceholderAlignment>(span.alignment);
84
85 builder_->addPlaceholder(placeholder_style);
86}
87
88std::unique_ptr<Paragraph> ParagraphBuilderSkia::Build() {
89 return std::make_unique<ParagraphSkia>(
90 builder_->Build(), std::move(dl_paints_), impeller_enabled_);
91}
92
93skt::ParagraphPainter::PaintID ParagraphBuilderSkia::CreatePaintID(
94 const flutter::DlPaint& dl_paint) {
95 dl_paints_.push_back(dl_paint);
96 return dl_paints_.size() - 1;
97}
98
99skt::ParagraphStyle ParagraphBuilderSkia::TxtToSkia(const ParagraphStyle& txt) {
101 skt::TextStyle text_style;
102
103 // Convert the default color of an SkParagraph text style into a DlPaint.
104 flutter::DlPaint dl_paint;
105 dl_paint.setColor(flutter::DlColor(text_style.getColor()));
106 text_style.setForegroundPaintID(CreatePaintID(dl_paint));
107
108 text_style.setFontStyle(MakeSkFontStyle(txt.font_weight, txt.font_style));
109 text_style.setFontSize(SkDoubleToScalar(txt.font_size));
110 text_style.setHeight(SkDoubleToScalar(txt.height));
111 text_style.setHeightOverride(txt.has_height_override);
112 text_style.setFontFamilies({SkString(txt.font_family.c_str())});
113 text_style.setLocale(SkString(txt.locale.c_str()));
114 skia.setTextStyle(text_style);
115
116 skt::StrutStyle strut_style;
117 strut_style.setFontStyle(
118 MakeSkFontStyle(txt.strut_font_weight, txt.strut_font_style));
119 strut_style.setFontSize(SkDoubleToScalar(txt.strut_font_size));
120 strut_style.setHeight(SkDoubleToScalar(txt.strut_height));
121 strut_style.setHeightOverride(txt.strut_has_height_override);
122 strut_style.setHalfLeading(txt.strut_half_leading);
123
124 std::vector<SkString> strut_fonts;
125 std::transform(txt.strut_font_families.begin(), txt.strut_font_families.end(),
126 std::back_inserter(strut_fonts),
127 [](const std::string& f) { return SkString(f.c_str()); });
128 strut_style.setFontFamilies(strut_fonts);
129 strut_style.setLeading(txt.strut_leading);
130 strut_style.setForceStrutHeight(txt.force_strut_height);
131 strut_style.setStrutEnabled(txt.strut_enabled);
132 skia.setStrutStyle(strut_style);
133
134 skia.setTextAlign(static_cast<skt::TextAlign>(txt.text_align));
135 skia.setTextDirection(static_cast<skt::TextDirection>(txt.text_direction));
136 skia.setMaxLines(txt.max_lines);
137 skia.setEllipsis(txt.ellipsis);
138 skia.setTextHeightBehavior(
139 static_cast<skt::TextHeightBehavior>(txt.text_height_behavior));
140
141 skia.turnHintingOff();
142 skia.setReplaceTabCharacters(true);
143 skia.setApplyRoundingHack(false);
144
145 return skia;
146}
147
148skt::TextStyle ParagraphBuilderSkia::TxtToSkia(const TextStyle& txt) {
150
151 skia.setColor(txt.color);
152 skia.setDecoration(static_cast<skt::TextDecoration>(txt.decoration));
153 skia.setDecorationColor(txt.decoration_color);
154 skia.setDecorationStyle(
155 static_cast<skt::TextDecorationStyle>(txt.decoration_style));
156 skia.setDecorationThicknessMultiplier(
157 SkDoubleToScalar(txt.decoration_thickness_multiplier));
158 skia.setFontStyle(MakeSkFontStyle(txt.font_weight, txt.font_style));
159 skia.setTextBaseline(static_cast<skt::TextBaseline>(txt.text_baseline));
160
161 std::vector<SkString> skia_fonts;
162 std::transform(txt.font_families.begin(), txt.font_families.end(),
163 std::back_inserter(skia_fonts),
164 [](const std::string& f) { return SkString(f.c_str()); });
165 skia.setFontFamilies(skia_fonts);
166
167 skia.setFontSize(SkDoubleToScalar(txt.font_size));
168 skia.setLetterSpacing(SkDoubleToScalar(txt.letter_spacing));
169 skia.setWordSpacing(SkDoubleToScalar(txt.word_spacing));
170 skia.setHeight(SkDoubleToScalar(txt.height));
171 skia.setHeightOverride(txt.has_height_override);
172 skia.setHalfLeading(txt.half_leading);
173
174 skia.setLocale(SkString(txt.locale.c_str()));
175 if (txt.background.has_value()) {
176 skia.setBackgroundPaintID(CreatePaintID(txt.background.value()));
177 }
178 if (txt.foreground.has_value()) {
179 skia.setForegroundPaintID(CreatePaintID(txt.foreground.value()));
180 } else {
181 flutter::DlPaint dl_paint;
182 dl_paint.setColor(flutter::DlColor(txt.color));
183 skia.setForegroundPaintID(CreatePaintID(dl_paint));
184 }
185
186 skia.resetFontFeatures();
187 for (const auto& ff : txt.font_features.GetFontFeatures()) {
188 skia.addFontFeature(SkString(ff.first.c_str()), ff.second);
189 }
190
191 if (!txt.font_variations.GetAxisValues().empty()) {
192 std::vector<SkFontArguments::VariationPosition::Coordinate> coordinates;
193 for (const auto& it : txt.font_variations.GetAxisValues()) {
194 const std::string& axis = it.first;
195 if (axis.length() != 4) {
196 continue;
197 }
198 coordinates.push_back({
199 SkSetFourByteTag(axis[0], axis[1], axis[2], axis[3]),
200 it.second,
201 });
202 }
204 coordinates.data(), static_cast<int>(coordinates.size())};
205 skia.setFontArguments(
207 }
208
209 skia.resetShadows();
210 for (const txt::TextShadow& txt_shadow : txt.text_shadows) {
211 skt::TextShadow shadow;
212 shadow.fOffset = txt_shadow.offset;
213 shadow.fBlurSigma = txt_shadow.blur_sigma;
214 shadow.fColor = txt_shadow.color;
215 skia.addShadow(shadow);
216 }
217
218 return skia;
219}
220
221} // 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:71
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
PlaceholderAlignment alignment
std::u16string text
PlaceholderAlignment
Where to vertically align the placeholder relative to the surrounding text.
Definition TextStyle.h:87
FontWeight
Definition font_weight.h:22
FontStyle
Definition font_style.h:22
SkFontArguments & setVariationDesignPosition(VariationPosition position)
void offset(float dx, float dy)
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)