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 "flutter/third_party/abseil-cpp/absl/container/flat_hash_map.h"
13 #include "impeller/core/texture.h"
14 #include "impeller/geometry/rect.h"
17 
18 namespace impeller {
19 
20 class FontGlyphAtlas;
21 
22 struct FrameBounds {
23  /// The bounds of the glyph within the glyph atlas.
25  /// The local 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.
49 
50  //--------------------------------------------------------------------------
51  /// The glyphs are reprsented at their requested size using N32 premul
52  /// colors.
53  ///
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 
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  ///
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  ///
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,
165  absl::Hash<ScaledFont>,
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 ///
179  public:
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 ///
230  public:
231  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>,
258 
259  PositionsMap positions_;
260  FontGlyphAtlas(const FontGlyphAtlas&) = delete;
261 };
262 
263 } // namespace impeller
264 
265 #endif // FLUTTER_IMPELLER_TYPOGRAPHER_GLYPH_ATLAS_H_
GLenum type
An object that can look up glyph locations within the GlyphAtlas for a particular typeface.
Definition: glyph_atlas.h:229
void AppendGlyph(const SubpixelGlyph &glyph, const FrameBounds &frame_bounds)
Append the frame bounds of a glyph to this atlas.
Definition: glyph_atlas.cc:140
std::optional< FrameBounds > FindGlyphBounds(const SubpixelGlyph &glyph) const
Find the location of a glyph in the atlas.
Definition: glyph_atlas.cc:131
FontGlyphAtlas(FontGlyphAtlas &&)=default
A container for caching a glyph atlas across frames.
Definition: glyph_atlas.h:178
GlyphAtlasContext(GlyphAtlas::Type type)
Definition: glyph_atlas.cc:14
std::shared_ptr< RectanglePacker > GetRectPacker() const
Retrieve the previous (if any) rect packer.
Definition: glyph_atlas.cc:32
void UpdateRectPacker(std::shared_ptr< RectanglePacker > rect_packer)
Definition: glyph_atlas.cc:44
std::shared_ptr< GlyphAtlas > GetGlyphAtlas() const
Retrieve the current glyph atlas.
Definition: glyph_atlas.cc:20
const ISize & GetAtlasSize() const
Retrieve the size of the current glyph atlas.
Definition: glyph_atlas.cc:24
int64_t GetHeightAdjustment() const
A y-coordinate shift that must be applied to glyphs appended to the atlas.
Definition: glyph_atlas.cc:28
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
A texture containing the bitmap representation of glyphs in different fonts along with the ability to...
Definition: glyph_atlas.h:37
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
bool IsValid() const
Definition: glyph_atlas.cc:54
void SetTexture(std::shared_ptr< Texture > texture)
Set the texture for the glyph atlas.
Definition: glyph_atlas.cc:66
void SetAtlasGeneration(size_t value)
Update the atlas generation.
Definition: glyph_atlas.cc:74
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
Type
Describes how the glyphs are represented in the texture.
Definition: glyph_atlas.h:41
size_t GetAtlasGeneration() const
Retrieve the generation id for this glyph atlas.
Definition: glyph_atlas.cc:70
Type GetType() const
Describes how the glyphs are represented in the texture.
Definition: glyph_atlas.cc:58
const std::shared_ptr< Texture > & GetTexture() const
Get the texture for the glyph atlas.
Definition: glyph_atlas.cc:62
GlyphAtlas(Type type, size_t initial_generation)
Create an empty glyph atlas.
Definition: glyph_atlas.cc:49
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
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
size_t GetGlyphCount() const
Get the number of unique font-glyph pairs in this atlas.
Definition: glyph_atlas.cc:103
int32_t value
A font along with a glyph in that font rendered at a particular scale and subpixel position.
Rect atlas_bounds
The bounds of the glyph within the glyph atlas.
Definition: glyph_atlas.h:24
Rect glyph_bounds
The local glyph bounds.
Definition: glyph_atlas.h:26
A font and a scale. Used as a key that represents a typeface within a glyph atlas.
A glyph and its subpixel position.