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 
6 #include "flutter/display_list/geometry/dl_path.h" // nogncheck
7 #include "fml/status.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 
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 
40  return has_color_ ? GlyphAtlas::Type::kColorBitmap
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
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 
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 
76  value += 0.125;
77  value = (value - floorf(value));
78  if (value < 0.25) {
80  }
81  if (value < 0.5) {
83  }
84  if (value < 0.75) {
86  }
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
95  const TextRun::GlyphPosition& glyph_position,
96  AxisAlignment alignment,
97  const Matrix& transform) {
98  Point pos = transform * glyph_position.position;
99  switch (alignment) {
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>(
110  (ComputeFractionalPosition(pos.y) << 2));
111  }
112 }
113 
115  return transform_ * Matrix::MakeTranslation(offset_);
116 }
117 
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 
130  return scale_;
131 }
132 
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 
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
Describes a typeface along with any modifications to its intrinsic properties.
Definition: font.h:35
Type
Describes how the glyphs are represented in the texture.
Definition: glyph_atlas.h:74
int32_t GetNumerator() const
Definition: rational.h:19
uint32_t GetDenominator() const
Definition: rational.h:21
static Rational RoundScaledFontSize(Scalar scale)
Definition: text_frame.cc:55
Rect GetBounds() const
The conservative bounding box for this text frame.
Definition: text_frame.cc:27
bool IsFrameComplete() const
Verifies that all glyphs in this text frame have computed bounds information.
Definition: text_frame.cc:156
GlyphAtlas::Type GetAtlasType() const
The type of atlas this run should be place in.
Definition: text_frame.cc:39
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
bool HasColor() const
Returns the paint color this text frame was recorded with.
Definition: text_frame.cc:44
Rational GetScale() const
Definition: text_frame.cc:129
const FrameBounds & GetFrameBounds(size_t index) const
Retrieve the frame bounds for the glyph at [index].
Definition: text_frame.cc:175
const Font & GetFont() const
Return the font of the first glyph run.
Definition: text_frame.cc:164
std::pair< size_t, intptr_t > GetAtlasGenerationAndID() const
Definition: text_frame.cc:180
size_t GetRunCount() const
The number of runs in this text frame.
Definition: text_frame.cc:31
Point GetOffset() const
Definition: text_frame.cc:133
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
Matrix GetOffsetTransform() const
Definition: text_frame.cc:114
fml::StatusOr< flutter::DlPath > GetPath() const
Definition: text_frame.cc:149
static SubpixelPosition ComputeSubpixelPosition(const TextRun::GlyphPosition &glyph_position, AxisAlignment alignment, const Matrix &transform)
Definition: text_frame.cc:94
const std::vector< TextRun > & GetRuns() const
Returns a reference to all the text runs in this frame.
Definition: text_frame.cc:35
int32_t value
int32_t x
float Scalar
Definition: scalar.h:19
AxisAlignment
Determines the axis along which there is subpixel positioning.
Definition: font.h:20
std::function< fml::StatusOr< flutter::DlPath >()> PathCreator
Definition: text_frame.h:19
static constexpr SubpixelPosition ComputeFractionalPosition(Scalar value)
Definition: text_frame.cc:75
Definition: comparable.h:95
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition: matrix.h:95