| Flutter Impeller |

text_frame.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "impeller/typographer/text_frame.h"
6 #include "flutter/display_list/geometry/dl_path.h" // nogncheck
7 #include "fml/status.h"
8 #include "impeller/geometry/scalar.h"
9 #include "impeller/typographer/font.h"
10 #include "impeller/typographer/font_glyph_pair.h"
11
12 namespace impeller {
13
14 TextFrame::TextFrame() = default;
15
16 TextFrame::TextFrame(std::vector<TextRun>& runs,
17 Rect bounds,
18 bool has_color,
19 const PathCreator& path_creator)
20 : runs_(std::move(runs)),
21 bounds_(bounds),
22 has_color_(has_color),
23 path_creator_(path_creator) {}
24
25 TextFrame::~TextFrame() = default;
26
27 Rect TextFrame::GetBounds() const {
28 return bounds_;
29 }
30
31 size_t TextFrame::GetRunCount() const {
32 return runs_.size();
33 }
34
35 const std::vector<TextRun>& TextFrame::GetRuns() const {
36 return runs_;
37 }
38
39 GlyphAtlas::Type TextFrame::GetAtlasType() const {
40 return has_color_ ? GlyphAtlas::Type::kColorBitmap
41 : GlyphAtlas::Type::kAlphaBitmap;
42 }
43
44 bool TextFrame::HasColor() const {
45 return has_color_;
46 }
47
48 namespace {
49 constexpr uint32_t kDenominator = 200;
50 constexpr int32_t kMaximumTextScale = 48;
51 constexpr Rational kZero(0, kDenominator);
52 } // namespace
53
54 // static
55 Rational TextFrame::RoundScaledFontSize(Scalar scale) {
56 if (scale > kMaximumTextScale) {
57 return Rational(kMaximumTextScale * kDenominator, kDenominator);
58 }
59 // An arbitrarily chosen maximum text scale to ensure that regardless of the
60 // CTM, a glyph will fit in the atlas. If we clamp significantly, this may
61 // reduce fidelity but is preferable to the alternative of failing to render.
62 Rational result = Rational(std::round(scale * kDenominator), kDenominator);
63 return result < kZero ? kZero : result;
64 }
65
66 Rational TextFrame::RoundScaledFontSize(Rational scale) {
67 Rational result = Rational(
68 std::round((scale.GetNumerator() * static_cast<Scalar>(kDenominator))) /
69 scale.GetDenominator(),
70 kDenominator);
71 return std::clamp(result, Rational(0, kDenominator),
72 Rational(kMaximumTextScale * kDenominator, kDenominator));
73 }
74
75 static constexpr SubpixelPosition ComputeFractionalPosition(Scalar value) {
76 value += 0.125;
77 value = (value - floorf(value));
78 if (value < 0.25) {
79 return SubpixelPosition::kSubpixel00;
80 }
81 if (value < 0.5) {
82 return SubpixelPosition::kSubpixel10;
83 }
84 if (value < 0.75) {
85 return SubpixelPosition::kSubpixel20;
86 }
87 return SubpixelPosition::kSubpixel30;
88 }
89
90 // Compute subpixel position for glyphs based on X position and provided
91 // max basis length (scale).
92 // This logic is based on the SkPackedGlyphID logic in SkGlyph.h
93 // static
94 SubpixelPosition TextFrame::ComputeSubpixelPosition(
95 const TextRun::GlyphPosition& glyph_position,
96 AxisAlignment alignment,
97 const Matrix& transform) {
98 Point pos = transform * glyph_position.position;
99 switch (alignment) {
100 case AxisAlignment::kNone:
101 return SubpixelPosition::kSubpixel00;
102 case AxisAlignment::kX:
103 return ComputeFractionalPosition(pos.x);
104 case AxisAlignment::kY:
105 return static_cast<SubpixelPosition>(ComputeFractionalPosition(pos.y)
106 << 2);
107 case AxisAlignment::kAll:
108 return static_cast<SubpixelPosition>(
109 ComputeFractionalPosition(pos.x) |
110 (ComputeFractionalPosition(pos.y) << 2));
111 }
112 }
113
114 Matrix TextFrame::GetOffsetTransform() const {
115 return transform_ * Matrix::MakeTranslation(offset_);
116 }
117
118 void TextFrame::SetPerFrameData(Rational scale,
119 Point offset,
120 const Matrix& transform,
121 std::optional<GlyphProperties> properties) {
122 bound_values_.clear();
123 scale_ = scale;
124 offset_ = offset;
125 properties_ = properties;
126 transform_ = transform;
127 }
128
129 Rational TextFrame::GetScale() const {
130 return scale_;
131 }
132
133 Point TextFrame::GetOffset() const {
134 return offset_;
135 }
136
137 std::optional<GlyphProperties> TextFrame::GetProperties() const {
138 return properties_;
139 }
140
141 void TextFrame::AppendFrameBounds(const FrameBounds& frame_bounds) {
142 bound_values_.push_back(frame_bounds);
143 }
144
145 void TextFrame::ClearFrameBounds() {
146 bound_values_.clear();
147 }
148
149 fml::StatusOr<flutter::DlPath> TextFrame::GetPath() const {
150 if (path_creator_) {
151 return path_creator_();
152 }
153 return fml::Status(fml::StatusCode::kCancelled, "no path creator specified.");
154 }
155
156 bool TextFrame::IsFrameComplete() const {
157 size_t run_size = 0;
158 for (const auto& x : runs_) {
159 run_size += x.GetGlyphCount();
160 }
161 return bound_values_.size() == run_size;
162 }
163
164 const Font& TextFrame::GetFont() const {
165 return runs_[0].GetFont();
166 }
167
168 std::optional<Glyph> TextFrame::AsSingleGlyph() const {
169 if (runs_.size() == 1 && runs_[0].GetGlyphCount() == 1) {
170 return runs_[0].GetGlyphPositions()[0].glyph;
171 }
172 return std::nullopt;
173 }
174
175 const FrameBounds& TextFrame::GetFrameBounds(size_t index) const {
176 FML_DCHECK(index < bound_values_.size());
177 return bound_values_[index];
178 }
179
180 std::pair<size_t, intptr_t> TextFrame::GetAtlasGenerationAndID() const {
181 return std::make_pair(generation_, atlas_id_);
182 }
183
184 void TextFrame::SetAtlasGeneration(size_t value, intptr_t atlas_id) {
185 generation_ = value;
186 atlas_id_ = atlas_id;
187 }
188
189 } // namespace impeller
impeller::Font
Describes a typeface along with any modifications to its intrinsic properties.
Definition: font.h:35
impeller::GlyphAtlas::Type
Type
Describes how the glyphs are represented in the texture.
Definition: glyph_atlas.h:41
impeller::GlyphAtlas::Type::kAlphaBitmap
@ kAlphaBitmap
impeller::GlyphAtlas::Type::kColorBitmap
@ kColorBitmap
impeller::Rational
Definition: rational.h:13
impeller::Rational::GetNumerator
int32_t GetNumerator() const
Definition: rational.h:19
impeller::Rational::GetDenominator
uint32_t GetDenominator() const
Definition: rational.h:21
impeller::TextFrame::RoundScaledFontSize
static Rational RoundScaledFontSize(Scalar scale)
Definition: text_frame.cc:55
impeller::TextFrame::GetBounds
Rect GetBounds() const
The conservative bounding box for this text frame.
Definition: text_frame.cc:27
impeller::TextFrame::TextFrame
TextFrame()
impeller::TextFrame::IsFrameComplete
bool IsFrameComplete() const
Verifies that all glyphs in this text frame have computed bounds information.
Definition: text_frame.cc:156
impeller::TextFrame::GetAtlasType
GlyphAtlas::Type GetAtlasType() const
The type of atlas this run should be place in.
Definition: text_frame.cc:39
impeller::TextFrame::AsSingleGlyph
std::optional< Glyph > AsSingleGlyph() const
If this text frame contains a single glyph (such as for an Icon), then return it, otherwise std::null...
Definition: text_frame.cc:168
impeller::TextFrame::HasColor
bool HasColor() const
Returns the paint color this text frame was recorded with.
Definition: text_frame.cc:44
impeller::TextFrame::GetScale
Rational GetScale() const
Definition: text_frame.cc:129
impeller::TextFrame::GetFrameBounds
const FrameBounds & GetFrameBounds(size_t index) const
Retrieve the frame bounds for the glyph at [index].
Definition: text_frame.cc:175
impeller::TextFrame::GetFont
const Font & GetFont() const
Return the font of the first glyph run.
Definition: text_frame.cc:164
impeller::TextFrame::GetAtlasGenerationAndID
std::pair< size_t, intptr_t > GetAtlasGenerationAndID() const
Definition: text_frame.cc:180
impeller::TextFrame::GetRunCount
size_t GetRunCount() const
The number of runs in this text frame.
Definition: text_frame.cc:31
impeller::TextFrame::GetOffset
Point GetOffset() const
Definition: text_frame.cc:133
impeller::TextFrame::SetPerFrameData
void SetPerFrameData(Rational scale, Point offset, const Matrix &transform, std::optional< GlyphProperties > properties)
Store text frame scale, offset, and properties for hashing in th glyph atlas.
Definition: text_frame.cc:118
impeller::TextFrame::GetOffsetTransform
Matrix GetOffsetTransform() const
Definition: text_frame.cc:114
impeller::TextFrame::GetPath
fml::StatusOr< flutter::DlPath > GetPath() const
Definition: text_frame.cc:149
impeller::TextFrame::ComputeSubpixelPosition
static SubpixelPosition ComputeSubpixelPosition(const TextRun::GlyphPosition &glyph_position, AxisAlignment alignment, const Matrix &transform)
Definition: text_frame.cc:94
impeller::TextFrame::GetRuns
const std::vector< TextRun > & GetRuns() const
Returns a reference to all the text runs in this frame.
Definition: text_frame.cc:35
impeller::TextFrame::~TextFrame
~TextFrame()
value
int32_t value
Definition: dl_golden_unittests.cc:459
x
int32_t x
Definition: dl_golden_unittests.cc:458
font.h
font_glyph_pair.h
transform
Matrix transform
Definition: gaussian_blur_filter_contents.cc:214
impeller
Definition: allocation.cc:12
impeller::BlendFactor::kZero
@ kZero
impeller::Scalar
float Scalar
Definition: scalar.h:19
impeller::AxisAlignment
AxisAlignment
Determines the axis along which there is subpixel positioning.
Definition: font.h:20
impeller::AxisAlignment::kX
@ kX
impeller::AxisAlignment::kAll
@ kAll
impeller::AxisAlignment::kNone
@ kNone
impeller::AxisAlignment::kY
@ kY
impeller::PathCreator
std::function< fml::StatusOr< flutter::DlPath >()> PathCreator
Definition: text_frame.h:19
impeller::SubpixelPosition
SubpixelPosition
Definition: font_glyph_pair.h:56
impeller::kSubpixel20
@ kSubpixel20
Definition: font_glyph_pair.h:62
impeller::kSubpixel00
@ kSubpixel00
Definition: font_glyph_pair.h:58
impeller::kSubpixel10
@ kSubpixel10
Definition: font_glyph_pair.h:60
impeller::kSubpixel30
@ kSubpixel30
Definition: font_glyph_pair.h:64
impeller::ComputeFractionalPosition
static constexpr SubpixelPosition ComputeFractionalPosition(Scalar value)
Definition: text_frame.cc:75
std
Definition: comparable.h:95
scalar.h
impeller::FrameBounds
Definition: glyph_atlas.h:22
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::Matrix::MakeTranslation
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition: matrix.h:95
impeller::TPoint< Scalar >
impeller::TPoint::y
Type y
Definition: point.h:31
impeller::TPoint::x
Type x
Definition: point.h:30
impeller::TRect< Scalar >
impeller::TextRun::GlyphPosition
Definition: text_run.h:22
impeller::TextRun::GlyphPosition::position
Point position
Definition: text_run.h:24
text_frame.h