| 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 "impeller/geometry/scalar.h"
7 #include "impeller/typographer/font.h"
8 #include "impeller/typographer/font_glyph_pair.h"
9
10 namespace impeller {
11
12 TextFrame::TextFrame() = default;
13
14 TextFrame::TextFrame(std::vector<TextRun>& runs, Rect bounds, bool has_color)
15 : runs_(std::move(runs)), bounds_(bounds), has_color_(has_color) {}
16
17 TextFrame::~TextFrame() = default;
18
19 Rect TextFrame::GetBounds() const {
20 return bounds_;
21 }
22
23 size_t TextFrame::GetRunCount() const {
24 return runs_.size();
25 }
26
27 const std::vector<TextRun>& TextFrame::GetRuns() const {
28 return runs_;
29 }
30
31 GlyphAtlas::Type TextFrame::GetAtlasType() const {
32 return has_color_ ? GlyphAtlas::Type::kColorBitmap
33 : GlyphAtlas::Type::kAlphaBitmap;
34 }
35
36 bool TextFrame::HasColor() const {
37 return has_color_;
38 }
39
40 // static
41 Scalar TextFrame::RoundScaledFontSize(Scalar scale) {
42 // An arbitrarily chosen maximum text scale to ensure that regardless of the
43 // CTM, a glyph will fit in the atlas. If we clamp significantly, this may
44 // reduce fidelity but is preferable to the alternative of failing to render.
45 constexpr Scalar kMaximumTextScale = 48;
46 Scalar result = std::round(scale * 200) / 200;
47 return std::clamp(result, 0.0f, kMaximumTextScale);
48 }
49
50 static constexpr Scalar ComputeFractionalPosition(Scalar value) {
51 value += 0.125;
52 value = (value - floorf(value));
53 if (value < 0.25) {
54 return 0;
55 }
56 if (value < 0.5) {
57 return 0.25;
58 }
59 if (value < 0.75) {
60 return 0.5;
61 }
62 return 0.75;
63 }
64
65 // Compute subpixel position for glyphs based on X position and provided
66 // max basis length (scale).
67 // This logic is based on the SkPackedGlyphID logic in SkGlyph.h
68 // static
69 Point TextFrame::ComputeSubpixelPosition(
70 const TextRun::GlyphPosition& glyph_position,
71 AxisAlignment alignment,
72 const Matrix& transform) {
73 Point pos = transform * glyph_position.position;
74 switch (alignment) {
75 case AxisAlignment::kNone:
76 return Point(0, 0);
77 case AxisAlignment::kX:
78 return Point(ComputeFractionalPosition(pos.x), 0);
79 case AxisAlignment::kY:
80 return Point(0, ComputeFractionalPosition(pos.y));
81 case AxisAlignment::kAll:
82 return Point(ComputeFractionalPosition(pos.x),
83 ComputeFractionalPosition(pos.y));
84 }
85 }
86
87 Matrix TextFrame::GetOffsetTransform() const {
88 return transform_ * Matrix::MakeTranslation(offset_);
89 }
90
91 void TextFrame::SetPerFrameData(Scalar scale,
92 Point offset,
93 const Matrix& transform,
94 std::optional<GlyphProperties> properties) {
95 bound_values_.clear();
96 scale_ = scale;
97 offset_ = offset;
98 properties_ = properties;
99 transform_ = transform;
100 }
101
102 Scalar TextFrame::GetScale() const {
103 return scale_;
104 }
105
106 Point TextFrame::GetOffset() const {
107 return offset_;
108 }
109
110 std::optional<GlyphProperties> TextFrame::GetProperties() const {
111 return properties_;
112 }
113
114 void TextFrame::AppendFrameBounds(const FrameBounds& frame_bounds) {
115 bound_values_.push_back(frame_bounds);
116 }
117
118 void TextFrame::ClearFrameBounds() {
119 bound_values_.clear();
120 }
121
122 bool TextFrame::IsFrameComplete() const {
123 size_t run_size = 0;
124 for (const auto& x : runs_) {
125 run_size += x.GetGlyphCount();
126 }
127 return bound_values_.size() == run_size;
128 }
129
130 const FrameBounds& TextFrame::GetFrameBounds(size_t index) const {
131 FML_DCHECK(index < bound_values_.size());
132 return bound_values_[index];
133 }
134
135 std::pair<size_t, intptr_t> TextFrame::GetAtlasGenerationAndID() const {
136 return std::make_pair(generation_, atlas_id_);
137 }
138
139 void TextFrame::SetAtlasGeneration(size_t value, intptr_t atlas_id) {
140 generation_ = value;
141 atlas_id_ = atlas_id;
142 }
143
144 } // namespace impeller
impeller::GlyphAtlas::Type
Type
Describes how the glyphs are represented in the texture.
Definition: glyph_atlas.h:74
impeller::GlyphAtlas::Type::kAlphaBitmap
@ kAlphaBitmap
impeller::GlyphAtlas::Type::kColorBitmap
@ kColorBitmap
impeller::TextFrame::SetPerFrameData
void SetPerFrameData(Scalar 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:91
impeller::TextFrame::GetBounds
Rect GetBounds() const
The conservative bounding box for this text frame.
Definition: text_frame.cc:19
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:122
impeller::TextFrame::GetScale
Scalar GetScale() const
Definition: text_frame.cc:102
impeller::TextFrame::GetAtlasType
GlyphAtlas::Type GetAtlasType() const
The type of atlas this run should be place in.
Definition: text_frame.cc:31
impeller::TextFrame::HasColor
bool HasColor() const
Returns the paint color this text frame was recorded with.
Definition: text_frame.cc:36
impeller::TextFrame::GetFrameBounds
const FrameBounds & GetFrameBounds(size_t index) const
Retrieve the frame bounds for the glyph at [index].
Definition: text_frame.cc:130
impeller::TextFrame::GetAtlasGenerationAndID
std::pair< size_t, intptr_t > GetAtlasGenerationAndID() const
Definition: text_frame.cc:135
impeller::TextFrame::ComputeSubpixelPosition
static Point ComputeSubpixelPosition(const TextRun::GlyphPosition &glyph_position, AxisAlignment alignment, const Matrix &transform)
Definition: text_frame.cc:69
impeller::TextFrame::GetRunCount
size_t GetRunCount() const
The number of runs in this text frame.
Definition: text_frame.cc:23
impeller::TextFrame::GetOffset
Point GetOffset() const
Definition: text_frame.cc:106
impeller::TextFrame::GetOffsetTransform
Matrix GetOffsetTransform() const
Definition: text_frame.cc:87
impeller::TextFrame::RoundScaledFontSize
static Scalar RoundScaledFontSize(Scalar scale)
Definition: text_frame.cc:41
impeller::TextFrame::GetRuns
const std::vector< TextRun > & GetRuns() const
Returns a reference to all the text runs in this frame.
Definition: text_frame.cc:27
impeller::TextFrame::~TextFrame
~TextFrame()
value
int32_t value
Definition: dl_golden_unittests.cc:444
x
int32_t x
Definition: dl_golden_unittests.cc:443
font.h
font_glyph_pair.h
transform
Matrix transform
Definition: gaussian_blur_filter_contents.cc:214
impeller
Definition: allocation.cc:12
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::Point
TPoint< Scalar > Point
Definition: point.h:327
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::ComputeFractionalPosition
static constexpr Scalar ComputeFractionalPosition(Scalar value)
Definition: text_frame.cc:50
std
Definition: comparable.h:95
scalar.h
scale
const Scalar scale
Definition: stroke_path_geometry.cc:316
offset
SeparatedVector2 offset
Definition: stroke_path_geometry.cc:319
impeller::FrameBounds
Definition: glyph_atlas.h:55
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