| Flutter Impeller |

glyph_atlas.h
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 #ifndef FLUTTER_IMPELLER_TYPOGRAPHER_GLYPH_ATLAS_H_
6 #define FLUTTER_IMPELLER_TYPOGRAPHER_GLYPH_ATLAS_H_
7
8 #include <functional>
9 #include <memory>
10 #include <optional>
11
12 #include "impeller/core/texture.h"
13 #include "impeller/geometry/rect.h"
14 #include "impeller/typographer/font_glyph_pair.h"
15 #include "impeller/typographer/rectangle_packer.h"
16 #include "third_party/abseil-cpp/absl/container/flat_hash_map.h"
17
18 namespace impeller {
19
20 class FontGlyphAtlas;
21
22 struct FrameBounds {
23 /// The bounds of the glyph within the glyph atlas.
24 Rect atlas_bounds;
25 /// The local glyph bounds.
26 Rect glyph_bounds;
27 /// Whether [atlas_bounds] are still a placeholder and have
28 /// not yet been computed.
29 bool is_placeholder = true;
30 };
31
32 //------------------------------------------------------------------------------
33 /// @brief A texture containing the bitmap representation of glyphs in
34 /// different fonts along with the ability to query the location of
35 /// specific font glyphs within the texture.
36 ///
37 class GlyphAtlas {
38 public:
39 //----------------------------------------------------------------------------
40 /// @brief Describes how the glyphs are represented in the texture.
41 enum class Type {
42 //--------------------------------------------------------------------------
43 /// The glyphs are reprsented at their requested size using only an 8-bit
44 /// color channel.
45 ///
46 /// This might be backed by a grey or red single channel texture, depending
47 /// on the backend capabilities.
48 kAlphaBitmap,
49
50 //--------------------------------------------------------------------------
51 /// The glyphs are reprsented at their requested size using N32 premul
52 /// colors.
53 ///
54 kColorBitmap,
55 };
56
57 //----------------------------------------------------------------------------
58 /// @brief Create an empty glyph atlas.
59 ///
60 /// @param[in] type How the glyphs are represented in the texture.
61 /// @param[in] initial_generation the atlas generation.
62 ///
63 GlyphAtlas(Type type, size_t initial_generation);
64
65 ~GlyphAtlas();
66
67 bool IsValid() const;
68
69 //----------------------------------------------------------------------------
70 /// @brief Describes how the glyphs are represented in the texture.
71 ///
72 Type GetType() const;
73
74 //----------------------------------------------------------------------------
75 /// @brief Set the texture for the glyph atlas.
76 ///
77 /// @param[in] texture The texture
78 ///
79 void SetTexture(std::shared_ptr<Texture> texture);
80
81 //----------------------------------------------------------------------------
82 /// @brief Get the texture for the glyph atlas.
83 ///
84 /// @return The texture.
85 ///
86 const std::shared_ptr<Texture>& GetTexture() const;
87
88 //----------------------------------------------------------------------------
89 /// @brief Record the location of a specific font-glyph pair within the
90 /// atlas.
91 ///
92 /// @param[in] pair The font-glyph pair
93 /// @param[in] rect The position in the atlas
94 /// @param[in] bounds The bounds of the glyph at scale
95 ///
96 void AddTypefaceGlyphPositionAndBounds(const FontGlyphPair& pair,
97 Rect position,
98 Rect bounds);
99
100 //----------------------------------------------------------------------------
101 /// @brief Get the number of unique font-glyph pairs in this atlas.
102 ///
103 /// @return The glyph count.
104 ///
105 size_t GetGlyphCount() const;
106
107 //----------------------------------------------------------------------------
108 /// @brief Iterate of all the glyphs along with their locations in the
109 /// atlas.
110 ///
111 /// @param[in] iterator The iterator. Return `false` from the iterator to
112 /// stop iterating.
113 ///
114 /// @return The number of glyphs iterated over.
115 ///
116 size_t IterateGlyphs(
117 const std::function<bool(const ScaledFont& scaled_font,
118 const SubpixelGlyph& glyph,
119 const Rect& rect)>& iterator) const;
120
121 //----------------------------------------------------------------------------
122 /// @brief Find the location of a specific font-glyph pair in the atlas.
123 ///
124 /// @param[in] pair The font-glyph pair
125 ///
126 /// @return The location of the font-glyph pair in the atlas.
127 /// `std::nullopt` if the pair is not in the atlas.
128 ///
129 std::optional<FrameBounds> FindFontGlyphBounds(
130 const FontGlyphPair& pair) const;
131
132 //----------------------------------------------------------------------------
133 /// @brief Obtain an interface for querying the location of glyphs in the
134 /// atlas for the given font and scale. This provides a more
135 /// efficient way to look up a run of glyphs in the same font.
136 ///
137 /// @param[in] font The font
138 /// @param[in] scale The scale
139 ///
140 /// @return A pointer to a FontGlyphAtlas, or nullptr if the font and
141 /// scale are not available in the atlas. The pointer is only
142 /// valid for the lifetime of the GlyphAtlas.
143 ///
144 FontGlyphAtlas* GetOrCreateFontGlyphAtlas(const ScaledFont& scaled_font);
145
146 //----------------------------------------------------------------------------
147 /// @brief Retrieve the generation id for this glyph atlas.
148 ///
149 /// The generation id is used to match with a TextFrame to
150 /// determine if the frame is guaranteed to already be populated
151 /// in the atlas.
152 size_t GetAtlasGeneration() const;
153
154 //----------------------------------------------------------------------------
155 /// @brief Update the atlas generation.
156 void SetAtlasGeneration(size_t value);
157
158 private:
159 const Type type_;
160 std::shared_ptr<Texture> texture_;
161 size_t generation_ = 0;
162
163 using FontAtlasMap = absl::flat_hash_map<ScaledFont,
164 FontGlyphAtlas,
165 absl::Hash<ScaledFont>,
166 ScaledFont::Equal>;
167
168 FontAtlasMap font_atlas_map_;
169
170 GlyphAtlas(const GlyphAtlas&) = delete;
171
172 GlyphAtlas& operator=(const GlyphAtlas&) = delete;
173 };
174
175 //------------------------------------------------------------------------------
176 /// @brief A container for caching a glyph atlas across frames.
177 ///
178 class GlyphAtlasContext {
179 public:
180 explicit GlyphAtlasContext(GlyphAtlas::Type type);
181
182 virtual ~GlyphAtlasContext();
183
184 //----------------------------------------------------------------------------
185 /// @brief Retrieve the current glyph atlas.
186 std::shared_ptr<GlyphAtlas> GetGlyphAtlas() const;
187
188 //----------------------------------------------------------------------------
189 /// @brief Retrieve the size of the current glyph atlas.
190 const ISize& GetAtlasSize() const;
191
192 //----------------------------------------------------------------------------
193 /// @brief Retrieve the previous (if any) rect packer.
194 std::shared_ptr<RectanglePacker> GetRectPacker() const;
195
196 //----------------------------------------------------------------------------
197 /// @brief A y-coordinate shift that must be applied to glyphs appended
198 /// to
199 /// the atlas.
200 ///
201 /// The rectangle packer is only initialized for unfilled regions
202 /// of the atlas. The area the rectangle packer covers is offset
203 /// from the origin by this height adjustment.
204 int64_t GetHeightAdjustment() const;
205
206 //----------------------------------------------------------------------------
207 /// @brief Update the context with a newly constructed glyph atlas.
208 void UpdateGlyphAtlas(std::shared_ptr<GlyphAtlas> atlas,
209 ISize size,
210 int64_t height_adjustment_);
211
212 void UpdateRectPacker(std::shared_ptr<RectanglePacker> rect_packer);
213
214 private:
215 std::shared_ptr<GlyphAtlas> atlas_;
216 ISize atlas_size_;
217 std::shared_ptr<RectanglePacker> rect_packer_;
218 int64_t height_adjustment_;
219
220 GlyphAtlasContext(const GlyphAtlasContext&) = delete;
221
222 GlyphAtlasContext& operator=(const GlyphAtlasContext&) = delete;
223 };
224
225 //------------------------------------------------------------------------------
226 /// @brief An object that can look up glyph locations within the GlyphAtlas
227 /// for a particular typeface.
228 ///
229 class FontGlyphAtlas {
230 public:
231 FontGlyphAtlas() = default;
232 FontGlyphAtlas(FontGlyphAtlas&&) = default;
233
234 //----------------------------------------------------------------------------
235 /// @brief Find the location of a glyph in the atlas.
236 ///
237 /// @param[in] glyph The glyph
238 ///
239 /// @return The location of the glyph in the atlas.
240 /// `std::nullopt` if the glyph is not in the atlas.
241 ///
242 std::optional<FrameBounds> FindGlyphBounds(const SubpixelGlyph& glyph) const;
243
244 //----------------------------------------------------------------------------
245 /// @brief Append the frame bounds of a glyph to this atlas.
246 ///
247 /// This may indicate a placeholder glyph location to be replaced
248 /// at a later time, as indicated by FrameBounds.placeholder.
249 void AppendGlyph(const SubpixelGlyph& glyph, const FrameBounds& frame_bounds);
250
251 private:
252 friend class GlyphAtlas;
253
254 using PositionsMap = absl::flat_hash_map<SubpixelGlyph,
255 FrameBounds,
256 absl::Hash<SubpixelGlyph>,
257 SubpixelGlyph::Equal>;
258
259 PositionsMap positions_;
260 FontGlyphAtlas(const FontGlyphAtlas&) = delete;
261 };
262
263 } // namespace impeller
264
265 #endif // FLUTTER_IMPELLER_TYPOGRAPHER_GLYPH_ATLAS_H_
type
GLenum type
Definition: blit_command_gles.cc:153
impeller::FontGlyphAtlas
An object that can look up glyph locations within the GlyphAtlas for a particular typeface.
Definition: glyph_atlas.h:229
impeller::FontGlyphAtlas::AppendGlyph
void AppendGlyph(const SubpixelGlyph &glyph, const FrameBounds &frame_bounds)
Append the frame bounds of a glyph to this atlas.
Definition: glyph_atlas.cc:140
impeller::FontGlyphAtlas::FontGlyphAtlas
FontGlyphAtlas()=default
impeller::FontGlyphAtlas::FindGlyphBounds
std::optional< FrameBounds > FindGlyphBounds(const SubpixelGlyph &glyph) const
Find the location of a glyph in the atlas.
Definition: glyph_atlas.cc:131
impeller::FontGlyphAtlas::FontGlyphAtlas
FontGlyphAtlas(FontGlyphAtlas &&)=default
impeller::GlyphAtlasContext
A container for caching a glyph atlas across frames.
Definition: glyph_atlas.h:178
impeller::GlyphAtlasContext::GlyphAtlasContext
GlyphAtlasContext(GlyphAtlas::Type type)
Definition: glyph_atlas.cc:14
impeller::GlyphAtlasContext::GetRectPacker
std::shared_ptr< RectanglePacker > GetRectPacker() const
Retrieve the previous (if any) rect packer.
Definition: glyph_atlas.cc:32
impeller::GlyphAtlasContext::UpdateRectPacker
void UpdateRectPacker(std::shared_ptr< RectanglePacker > rect_packer)
Definition: glyph_atlas.cc:44
impeller::GlyphAtlasContext::GetGlyphAtlas
std::shared_ptr< GlyphAtlas > GetGlyphAtlas() const
Retrieve the current glyph atlas.
Definition: glyph_atlas.cc:20
impeller::GlyphAtlasContext::GetAtlasSize
const ISize & GetAtlasSize() const
Retrieve the size of the current glyph atlas.
Definition: glyph_atlas.cc:24
impeller::GlyphAtlasContext::GetHeightAdjustment
int64_t GetHeightAdjustment() const
A y-coordinate shift that must be applied to glyphs appended to the atlas.
Definition: glyph_atlas.cc:28
impeller::GlyphAtlasContext::~GlyphAtlasContext
virtual ~GlyphAtlasContext()
Definition: glyph_atlas.cc:18
impeller::GlyphAtlasContext::UpdateGlyphAtlas
void UpdateGlyphAtlas(std::shared_ptr< GlyphAtlas > atlas, ISize size, int64_t height_adjustment_)
Update the context with a newly constructed glyph atlas.
Definition: glyph_atlas.cc:36
impeller::GlyphAtlas
A texture containing the bitmap representation of glyphs in different fonts along with the ability to...
Definition: glyph_atlas.h:37
impeller::GlyphAtlas::FindFontGlyphBounds
std::optional< FrameBounds > FindFontGlyphBounds(const FontGlyphPair &pair) const
Find the location of a specific font-glyph pair in the atlas.
Definition: glyph_atlas.cc:87
impeller::GlyphAtlas::IsValid
bool IsValid() const
Definition: glyph_atlas.cc:54
impeller::GlyphAtlas::SetTexture
void SetTexture(std::shared_ptr< Texture > texture)
Set the texture for the glyph atlas.
Definition: glyph_atlas.cc:66
impeller::GlyphAtlas::SetAtlasGeneration
void SetAtlasGeneration(size_t value)
Update the atlas generation.
Definition: glyph_atlas.cc:74
impeller::GlyphAtlas::GetOrCreateFontGlyphAtlas
FontGlyphAtlas * GetOrCreateFontGlyphAtlas(const ScaledFont &scaled_font)
Obtain an interface for querying the location of glyphs in the atlas for the given font and scale....
Definition: glyph_atlas.cc:96
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::GlyphAtlas::GetAtlasGeneration
size_t GetAtlasGeneration() const
Retrieve the generation id for this glyph atlas.
Definition: glyph_atlas.cc:70
impeller::GlyphAtlas::GetType
Type GetType() const
Describes how the glyphs are represented in the texture.
Definition: glyph_atlas.cc:58
impeller::GlyphAtlas::GetTexture
const std::shared_ptr< Texture > & GetTexture() const
Get the texture for the glyph atlas.
Definition: glyph_atlas.cc:62
impeller::GlyphAtlas::~GlyphAtlas
~GlyphAtlas()
impeller::GlyphAtlas::GlyphAtlas
GlyphAtlas(Type type, size_t initial_generation)
Create an empty glyph atlas.
Definition: glyph_atlas.cc:49
impeller::GlyphAtlas::IterateGlyphs
size_t IterateGlyphs(const std::function< bool(const ScaledFont &scaled_font, const SubpixelGlyph &glyph, const Rect &rect)> &iterator) const
Iterate of all the glyphs along with their locations in the atlas.
Definition: glyph_atlas.cc:110
impeller::GlyphAtlas::AddTypefaceGlyphPositionAndBounds
void AddTypefaceGlyphPositionAndBounds(const FontGlyphPair &pair, Rect position, Rect bounds)
Record the location of a specific font-glyph pair within the atlas.
Definition: glyph_atlas.cc:78
impeller::GlyphAtlas::GetGlyphCount
size_t GetGlyphCount() const
Get the number of unique font-glyph pairs in this atlas.
Definition: glyph_atlas.cc:103
texture.h
value
int32_t value
Definition: dl_golden_unittests.cc:459
font_glyph_pair.h
impeller
Definition: allocation.cc:12
rect.h
rectangle_packer.h
impeller::FontGlyphPair
A font along with a glyph in that font rendered at a particular scale and subpixel position.
Definition: font_glyph_pair.h:137
impeller::FrameBounds
Definition: glyph_atlas.h:22
impeller::FrameBounds::atlas_bounds
Rect atlas_bounds
The bounds of the glyph within the glyph atlas.
Definition: glyph_atlas.h:24
impeller::FrameBounds::glyph_bounds
Rect glyph_bounds
The local glyph bounds.
Definition: glyph_atlas.h:26
impeller::FrameBounds::is_placeholder
bool is_placeholder
Definition: glyph_atlas.h:29
impeller::ScaledFont::Equal
Definition: font_glyph_pair.h:45
impeller::ScaledFont
A font and a scale. Used as a key that represents a typeface within a glyph atlas.
Definition: font_glyph_pair.h:36
impeller::SubpixelGlyph::Equal
Definition: font_glyph_pair.h:112
impeller::SubpixelGlyph
A glyph and its subpixel position.
Definition: font_glyph_pair.h:85
impeller::TRect< Scalar >
impeller::TSize
Definition: size.h:25