| 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/typographer/font.h"
7 #include "impeller/typographer/font_glyph_pair.h"
8
9 namespace impeller {
10
11 TextFrame::TextFrame() = default;
12
13 TextFrame::TextFrame(std::vector<TextRun>& runs, Rect bounds, bool has_color)
14 : runs_(std::move(runs)), bounds_(bounds), has_color_(has_color) {}
15
16 TextFrame::~TextFrame() = default;
17
18 Rect TextFrame::GetBounds() const {
19 return bounds_;
20 }
21
22 size_t TextFrame::GetRunCount() const {
23 return runs_.size();
24 }
25
26 const std::vector<TextRun>& TextFrame::GetRuns() const {
27 return runs_;
28 }
29
30 GlyphAtlas::Type TextFrame::GetAtlasType() const {
31 return has_color_ ? GlyphAtlas::Type::kColorBitmap
32 : GlyphAtlas::Type::kAlphaBitmap;
33 }
34
35 bool TextFrame::HasColor() const {
36 return has_color_;
37 }
38
39 // static
40 Scalar TextFrame::RoundScaledFontSize(Scalar scale, Scalar point_size) {
41 // An arbitrarily chosen maximum text scale to ensure that regardless of the
42 // CTM, a glyph will fit in the atlas. If we clamp significantly, this may
43 // reduce fidelity but is preferable to the alternative of failing to render.
44 constexpr Scalar kMaximumTextScale = 48;
45 Scalar result = std::round(scale * 100) / 100;
46 return std::clamp(result, 0.0f, kMaximumTextScale);
47 }
48
49 static constexpr Scalar ComputeFractionalPosition(Scalar value) {
50 value += 0.125;
51 value = (value - floorf(value));
52 if (value < 0.25) {
53 return 0;
54 }
55 if (value < 0.5) {
56 return 0.25;
57 }
58 if (value < 0.75) {
59 return 0.5;
60 }
61 return 0.75;
62 }
63
64 // Compute subpixel position for glyphs based on X position and provided
65 // max basis length (scale).
66 // This logic is based on the SkPackedGlyphID logic in SkGlyph.h
67 // static
68 Point TextFrame::ComputeSubpixelPosition(
69 const TextRun::GlyphPosition& glyph_position,
70 AxisAlignment alignment,
71 Point offset,
72 Scalar scale) {
73 Point pos = glyph_position.position + offset;
74 switch (alignment) {
75 case AxisAlignment::kNone:
76 return Point(0, 0);
77 case AxisAlignment::kX:
78 return Point(ComputeFractionalPosition(pos.x * scale), 0);
79 case AxisAlignment::kY:
80 return Point(0, ComputeFractionalPosition(pos.y * scale));
81 case AxisAlignment::kAll:
82 return Point(ComputeFractionalPosition(pos.x * scale),
83 ComputeFractionalPosition(pos.y * scale));
84 }
85 }
86
87 void TextFrame::CollectUniqueFontGlyphPairs(
88 FontGlyphMap& glyph_map,
89 Scalar scale,
90 Point offset,
91 const GlyphProperties& properties) const {
92 std::optional<GlyphProperties> lookup =
93 (properties.stroke || HasColor())
94 ? std::optional<GlyphProperties>(properties)
95 : std::nullopt;
96 for (const TextRun& run : GetRuns()) {
97 const Font& font = run.GetFont();
98 auto rounded_scale =
99 RoundScaledFontSize(scale, font.GetMetrics().point_size);
100 auto& set = glyph_map[ScaledFont{font, rounded_scale}];
101 for (const TextRun::GlyphPosition& glyph_position :
102 run.GetGlyphPositions()) {
103 Point subpixel = ComputeSubpixelPosition(
104 glyph_position, font.GetAxisAlignment(), offset, scale);
105 set.emplace(glyph_position.glyph, subpixel, lookup);
106 }
107 }
108 }
109
110 } // namespace impeller
impeller::GlyphAtlas::Type::kColorBitmap
@ kColorBitmap
impeller::TextFrame::HasColor
bool HasColor() const
Returns the paint color this text frame was recorded with.
Definition: text_frame.cc:35
impeller::AxisAlignment::kAll
@ kAll
impeller::TPoint::y
Type y
Definition: point.h:31
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::Font
Describes a typeface along with any modifications to its intrinsic properties.
Definition: font.h:35
impeller::GlyphAtlas::Type::kAlphaBitmap
@ kAlphaBitmap
impeller::FontGlyphMap
std::unordered_map< ScaledFont, std::unordered_set< SubpixelGlyph, SubpixelGlyph::Hash, SubpixelGlyph::Equal >, ScaledFont::Hash, ScaledFont::Equal > FontGlyphMap
Definition: font_glyph_pair.h:108
impeller::GlyphProperties
Definition: font_glyph_pair.h:20
impeller::TextFrame::TextFrame
TextFrame()
impeller::TextFrame::~TextFrame
~TextFrame()
impeller::TextFrame::ComputeSubpixelPosition
static Point ComputeSubpixelPosition(const TextRun::GlyphPosition &glyph_position, AxisAlignment alignment, Point offset, Scalar scale)
Definition: text_frame.cc:68
impeller::TextFrame::GetRuns
const std::vector< TextRun > & GetRuns() const
Returns a reference to all the text runs in this frame.
Definition: text_frame.cc:26
impeller::TextFrame::GetRunCount
size_t GetRunCount() const
The number of runs in this text frame.
Definition: text_frame.cc:22
impeller::TextFrame::RoundScaledFontSize
static Scalar RoundScaledFontSize(Scalar scale, Scalar point_size)
Definition: text_frame.cc:40
impeller::TextRun
Represents a collection of positioned glyphs from a specific font.
Definition: text_run.h:20
offset
SeparatedVector2 offset
Definition: stroke_path_geometry.cc:304
impeller::Point
TPoint< Scalar > Point
Definition: point.h:327
font.h
impeller::GlyphAtlas::Type
Type
Describes how the glyphs are represented in the texture.
Definition: glyph_atlas.h:31
font_glyph_pair.h
impeller::Font::Metrics::point_size
Scalar point_size
Definition: font.h:48
impeller::AxisAlignment
AxisAlignment
Determines the axis along which there is subpixel positioning.
Definition: font.h:20
impeller::GlyphProperties::stroke
bool stroke
Definition: font_glyph_pair.h:26
impeller::AxisAlignment::kX
@ kX
impeller::TextFrame::CollectUniqueFontGlyphPairs
void CollectUniqueFontGlyphPairs(FontGlyphMap &glyph_map, Scalar scale, Point offset, const GlyphProperties &properties) const
Definition: text_frame.cc:87
impeller::Font::GetMetrics
const Metrics & GetMetrics() const
Definition: font.cc:45
impeller::TextFrame::GetBounds
Rect GetBounds() const
The conservative bounding box for this text frame.
Definition: text_frame.cc:18
impeller::TPoint::x
Type x
Definition: point.h:30
std
Definition: comparable.h:95
impeller::TextFrame::GetAtlasType
GlyphAtlas::Type GetAtlasType() const
The type of atlas this run should be emplaced in.
Definition: text_frame.cc:30
impeller::TPoint< Scalar >
impeller::TextRun::GlyphPosition
Definition: text_run.h:22
scale
const Scalar scale
Definition: stroke_path_geometry.cc:301
text_frame.h
impeller::ComputeFractionalPosition
static constexpr Scalar ComputeFractionalPosition(Scalar value)
Definition: text_frame.cc:49
impeller::AxisAlignment::kNone
@ kNone
impeller
Definition: allocation.cc:12
impeller::TRect< Scalar >
impeller::ScaledFont
A font and a scale. Used as a key that represents a typeface within a glyph atlas.
Definition: font_glyph_pair.h:33
impeller::TextRun::GlyphPosition::position
Point position
Definition: text_run.h:24
impeller::Font::GetAxisAlignment
AxisAlignment GetAxisAlignment() const
Definition: font.cc:41
impeller::AxisAlignment::kY
@ kY