Flutter Impeller
typographer_context_stb.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 
7 #include <numeric>
8 #include <utility>
9 
10 #include "flutter/fml/logging.h"
11 #include "flutter/fml/trace_event.h"
16 #include "typeface_stb.h"
17 
18 #define DISABLE_COLOR_FONT_SUPPORT 1
19 #ifdef DISABLE_COLOR_FONT_SUPPORT
20 constexpr auto kColorFontBitsPerPixel = 1;
21 #else
22 constexpr auto kColorFontBitsPerPixel = 4;
23 #endif
24 
25 namespace impeller {
26 
27 constexpr size_t kPadding = 1;
28 
29 std::unique_ptr<TypographerContext> TypographerContextSTB::Make() {
30  return std::make_unique<TypographerContextSTB>();
31 }
32 
34 
36 
37 std::shared_ptr<GlyphAtlasContext>
39  return std::make_shared<GlyphAtlasContextSTB>();
40 }
41 
42 // Function returns the count of "remaining pairs" not packed into rect of given
43 // size.
44 static size_t PairsFitInAtlasOfSize(
45  const std::vector<FontGlyphPair>& pairs,
46  const ISize& atlas_size,
47  std::vector<Rect>& glyph_positions,
48  const std::shared_ptr<RectanglePacker>& rect_packer) {
49  if (atlas_size.IsEmpty()) {
50  return false;
51  }
52 
53  glyph_positions.clear();
54  glyph_positions.reserve(pairs.size());
55 
56  size_t i = 0;
57  for (auto it = pairs.begin(); it != pairs.end(); ++i, ++it) {
58  const auto& pair = *it;
59  const Font& font = pair.scaled_font.font;
60 
61  // We downcast to the correct typeface type to access `stb` specific
62  // methods.
63  std::shared_ptr<TypefaceSTB> typeface_stb =
64  std::reinterpret_pointer_cast<TypefaceSTB>(font.GetTypeface());
65  // Conversion factor to scale font size in Points to pixels.
66  // Note this assumes typical DPI.
67  float text_size_pixels =
69 
70  ISize glyph_size;
71  {
72  int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
73  // NOTE: We increase the size of the glyph by one pixel in all dimensions
74  // to allow us to cut out padding later.
75  float scale = stbtt_ScaleForPixelHeight(typeface_stb->GetFontInfo(),
76  text_size_pixels);
77  stbtt_GetGlyphBitmapBox(typeface_stb->GetFontInfo(), pair.glyph.index,
78  scale, scale, &x0, &y0, &x1, &y1);
79 
80  glyph_size = ISize(x1 - x0, y1 - y0);
81  }
82 
83  IPoint16 location_in_atlas;
84  if (!rect_packer->addRect(glyph_size.width + kPadding, //
85  glyph_size.height + kPadding, //
86  &location_in_atlas //
87  )) {
88  return pairs.size() - i;
89  }
90  glyph_positions.emplace_back(Rect::MakeXYWH(location_in_atlas.x(), //
91  location_in_atlas.y(), //
92  glyph_size.width, //
93  glyph_size.height //
94  ));
95  }
96 
97  return 0;
98 }
99 
101  const std::shared_ptr<GlyphAtlas>& atlas,
102  const std::vector<FontGlyphPair>& extra_pairs,
103  std::vector<Rect>& glyph_positions,
104  ISize atlas_size,
105  const std::shared_ptr<RectanglePacker>& rect_packer) {
106  TRACE_EVENT0("impeller", __FUNCTION__);
107  if (!rect_packer || atlas_size.IsEmpty()) {
108  return false;
109  }
110 
111  // We assume that all existing glyphs will fit. After all, they fit before.
112  // The glyph_positions only contains the values for the additional glyphs
113  // from extra_pairs.
114  FML_DCHECK(glyph_positions.size() == 0);
115  glyph_positions.reserve(extra_pairs.size());
116  for (size_t i = 0; i < extra_pairs.size(); i++) {
117  const FontGlyphPair& pair = extra_pairs[i];
118  const Font& font = pair.scaled_font.font;
119 
120  // We downcast to the correct typeface type to access `stb` specific methods
121  std::shared_ptr<TypefaceSTB> typeface_stb =
122  std::reinterpret_pointer_cast<TypefaceSTB>(font.GetTypeface());
123  // Conversion factor to scale font size in Points to pixels.
124  // Note this assumes typical DPI.
125  float text_size_pixels =
127 
128  ISize glyph_size;
129  {
130  int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
131  // NOTE: We increase the size of the glyph by one pixel in all dimensions
132  // to allow us to cut out padding later.
133  float scale_y = stbtt_ScaleForPixelHeight(typeface_stb->GetFontInfo(),
134  text_size_pixels);
135  float scale_x = scale_y;
136  stbtt_GetGlyphBitmapBox(typeface_stb->GetFontInfo(), pair.glyph.index,
137  scale_x, scale_y, &x0, &y0, &x1, &y1);
138 
139  glyph_size = ISize(x1 - x0, y1 - y0);
140  }
141 
142  IPoint16 location_in_atlas;
143  if (!rect_packer->addRect(glyph_size.width + kPadding, //
144  glyph_size.height + kPadding, //
145  &location_in_atlas //
146  )) {
147  return false;
148  }
149  glyph_positions.emplace_back(Rect::MakeXYWH(location_in_atlas.x(), //
150  location_in_atlas.y(), //
151  glyph_size.width, //
152  glyph_size.height //
153  ));
154  }
155 
156  return true;
157 }
158 
160  const std::vector<FontGlyphPair>& pairs,
161  std::vector<Rect>& glyph_positions,
162  const std::shared_ptr<GlyphAtlasContext>& atlas_context,
163  GlyphAtlas::Type type,
164  const ISize& max_texture_size) {
165  static constexpr auto kMinAtlasSize = 8u;
166  static constexpr auto kMinAlphaBitmapSize = 1024u;
167 
168  TRACE_EVENT0("impeller", __FUNCTION__);
169 
170  ISize current_size = type == GlyphAtlas::Type::kAlphaBitmap
171  ? ISize(kMinAlphaBitmapSize, kMinAlphaBitmapSize)
172  : ISize(kMinAtlasSize, kMinAtlasSize);
173  size_t total_pairs = pairs.size() + 1;
174  do {
175  auto rect_packer = std::shared_ptr<RectanglePacker>(
176  RectanglePacker::Factory(current_size.width, current_size.height));
177 
178  auto remaining_pairs = PairsFitInAtlasOfSize(pairs, current_size,
179  glyph_positions, rect_packer);
180  if (remaining_pairs == 0) {
181  atlas_context->UpdateRectPacker(rect_packer);
182  return current_size;
183  } else if (remaining_pairs < std::ceil(total_pairs / 2)) {
184  current_size = ISize::MakeWH(
185  std::max(current_size.width, current_size.height),
187  std::min(current_size.width, current_size.height) + 1));
188  } else {
189  current_size = ISize::MakeWH(
190  Allocation::NextPowerOfTwoSize(current_size.width + 1),
191  Allocation::NextPowerOfTwoSize(current_size.height + 1));
192  }
193  } while (current_size.width <= max_texture_size.width &&
194  current_size.height <= max_texture_size.height);
195  return ISize{0, 0};
196 }
197 
198 static void DrawGlyph(BitmapSTB* bitmap,
199  const ScaledFont& scaled_font,
200  const Glyph& glyph,
201  const Rect& location,
202  bool has_color) {
203  const auto& metrics = scaled_font.font.GetMetrics();
204 
205  const impeller::Font& font = scaled_font.font;
206  auto typeface = font.GetTypeface();
207  // We downcast to the correct typeface type to access `stb` specific methods
208  std::shared_ptr<TypefaceSTB> typeface_stb =
209  std::reinterpret_pointer_cast<TypefaceSTB>(typeface);
210  // Conversion factor to scale font size in Points to pixels.
211  // Note this assumes typical DPI.
212  float text_size_pixels = metrics.point_size * TypefaceSTB::kPointsToPixels;
213  float scale_y =
214  stbtt_ScaleForPixelHeight(typeface_stb->GetFontInfo(), text_size_pixels);
215  float scale_x = scale_y;
216 
217  auto output = bitmap->GetPixelAddress({static_cast<size_t>(location.GetX()),
218  static_cast<size_t>(location.GetY())});
219  // For Alpha and Signed Distance field bitmaps we can use STB to draw the
220  // Glyph in place
221  if (!has_color || DISABLE_COLOR_FONT_SUPPORT) {
222  stbtt_MakeGlyphBitmap(typeface_stb->GetFontInfo(), output,
223  location.GetWidth() - kPadding,
224  location.GetHeight() - kPadding,
225  bitmap->GetRowBytes(), scale_x, scale_y, glyph.index);
226  } else {
227  // But for color bitmaps we need to get the glyph pixels and then carry all
228  // channels into the atlas bitmap. This may not be performant but I'm unsure
229  // of any other approach currently.
230  int glyph_bitmap_width = 0;
231  int glyph_bitmap_height = 0;
232  int glyph_bitmap_xoff = 0;
233  int glyph_bitmap_yoff = 0;
234  auto glyph_pixels = stbtt_GetGlyphBitmap(
235  typeface_stb->GetFontInfo(), scale_x, scale_y, glyph.index,
236  &glyph_bitmap_width, &glyph_bitmap_height, &glyph_bitmap_xoff,
237  &glyph_bitmap_yoff);
238 
239  uint8_t* write_pos = output;
240  for (auto y = 0; y < glyph_bitmap_height; ++y) {
241  for (auto x = 0; x < glyph_bitmap_width; ++x) {
242  // Color bitmaps write as White (i.e. what is 0 in an alpha bitmap is
243  // 255 in a color bitmap) But not alpha. Alpha still carries
244  // transparency info in the normal way.
245  // There's some issue with color fonts, in that if the pixel color is
246  // nonzero, the alpha is ignored during rendering. That is, partially
247  // (or fully) transparent pixels with nonzero color are rendered as
248  // fully opaque.
249  uint8_t a = glyph_pixels[x + y * glyph_bitmap_width];
250  uint8_t c = 255 - a;
251 
252  // Red channel
253  *write_pos = c;
254  write_pos++;
255  // Green channel
256  *write_pos = c;
257  write_pos++;
258  // Blue channel
259  *write_pos = c;
260  write_pos++;
261  // Alpha channel
262  *write_pos = a;
263  write_pos++;
264  }
265  // next row
266  write_pos = output + (y * bitmap->GetRowBytes());
267  }
268  stbtt_FreeBitmap(glyph_pixels, nullptr);
269  }
270 }
271 
272 static bool UpdateAtlasBitmap(const GlyphAtlas& atlas,
273  const std::shared_ptr<BitmapSTB>& bitmap,
274  const std::vector<FontGlyphPair>& new_pairs) {
275  TRACE_EVENT0("impeller", __FUNCTION__);
276  FML_DCHECK(bitmap != nullptr);
277 
278  bool has_color = atlas.GetType() == GlyphAtlas::Type::kColorBitmap;
279 
280  for (const FontGlyphPair& pair : new_pairs) {
281  auto pos = atlas.FindFontGlyphBounds(pair);
282  if (!pos.has_value()) {
283  continue;
284  }
285  DrawGlyph(bitmap.get(), pair.scaled_font, pair.glyph, pos.value(),
286  has_color);
287  }
288  return true;
289 }
290 
291 static std::shared_ptr<BitmapSTB> CreateAtlasBitmap(const GlyphAtlas& atlas,
292  const ISize& atlas_size) {
293  TRACE_EVENT0("impeller", __FUNCTION__);
294 
295  size_t bytes_per_pixel = 1;
296  if (atlas.GetType() == GlyphAtlas::Type::kColorBitmap &&
298  bytes_per_pixel = kColorFontBitsPerPixel;
299  }
300  auto bitmap = std::make_shared<BitmapSTB>(atlas_size.width, atlas_size.height,
301  bytes_per_pixel);
302 
303  bool has_color = atlas.GetType() == GlyphAtlas::Type::kColorBitmap;
304 
305  atlas.IterateGlyphs([&bitmap, has_color](const ScaledFont& scaled_font,
306  const Glyph& glyph,
307  const Rect& location) -> bool {
308  DrawGlyph(bitmap.get(), scaled_font, glyph, location, has_color);
309  return true;
310  });
311 
312  return bitmap;
313 }
314 
315 // static bool UpdateGlyphTextureAtlas(std::shared_ptr<SkBitmap> bitmap,
316 static bool UpdateGlyphTextureAtlas(std::shared_ptr<BitmapSTB>& bitmap,
317  const std::shared_ptr<Texture>& texture) {
318  TRACE_EVENT0("impeller", __FUNCTION__);
319 
320  FML_DCHECK(bitmap != nullptr);
321 
322  auto texture_descriptor = texture->GetTextureDescriptor();
323 
324  auto mapping = std::make_shared<fml::NonOwnedMapping>(
325  reinterpret_cast<const uint8_t*>(bitmap->GetPixels()), // data
326  texture_descriptor.GetByteSizeOfBaseMipLevel() // size
327  // As the bitmap is static in this module I believe we don't need to
328  // specify a release proc.
329  );
330 
331  return texture->SetContents(mapping);
332 }
333 
334 static std::shared_ptr<Texture> UploadGlyphTextureAtlas(
335  const std::shared_ptr<Allocator>& allocator,
336  std::shared_ptr<BitmapSTB>& bitmap,
337  const ISize& atlas_size,
338  PixelFormat format) {
339  TRACE_EVENT0("impeller", __FUNCTION__);
340  if (!allocator) {
341  return nullptr;
342  }
343 
344  FML_DCHECK(bitmap != nullptr);
345 
346  TextureDescriptor texture_descriptor;
347  texture_descriptor.storage_mode = StorageMode::kHostVisible;
348  texture_descriptor.format = format;
349  texture_descriptor.size = atlas_size;
350 
351  if (bitmap->GetRowBytes() * bitmap->GetHeight() !=
352  texture_descriptor.GetByteSizeOfBaseMipLevel()) {
353  return nullptr;
354  }
355 
356  auto texture = allocator->CreateTexture(texture_descriptor);
357  if (!texture || !texture->IsValid()) {
358  return nullptr;
359  }
360  texture->SetLabel("GlyphAtlas");
361 
362  auto mapping = std::make_shared<fml::NonOwnedMapping>(
363  reinterpret_cast<const uint8_t*>(bitmap->GetPixels()), // data
364  texture_descriptor.GetByteSizeOfBaseMipLevel() // size
365  // As the bitmap is static in this module I believe we don't need to
366  // specify a release proc.
367  );
368 
369  if (!texture->SetContents(mapping)) {
370  return nullptr;
371  }
372  return texture;
373 }
374 
375 std::shared_ptr<GlyphAtlas> TypographerContextSTB::CreateGlyphAtlas(
376  Context& context,
377  GlyphAtlas::Type type,
378  const std::shared_ptr<GlyphAtlasContext>& atlas_context,
379  const FontGlyphMap& font_glyph_map) const {
380  TRACE_EVENT0("impeller", __FUNCTION__);
381  if (!IsValid()) {
382  return nullptr;
383  }
384  auto& atlas_context_stb = GlyphAtlasContextSTB::Cast(*atlas_context);
385  std::shared_ptr<GlyphAtlas> last_atlas = atlas_context->GetGlyphAtlas();
386 
387  if (font_glyph_map.empty()) {
388  return last_atlas;
389  }
390 
391  // ---------------------------------------------------------------------------
392  // Step 1: Determine if the atlas type and font glyph pairs are compatible
393  // with the current atlas and reuse if possible.
394  // ---------------------------------------------------------------------------
395  std::vector<FontGlyphPair> new_glyphs;
396  for (const auto& font_value : font_glyph_map) {
397  const ScaledFont& scaled_font = font_value.first;
398  const FontGlyphAtlas* font_glyph_atlas =
399  last_atlas->GetFontGlyphAtlas(scaled_font.font, scaled_font.scale);
400  if (font_glyph_atlas) {
401  for (const Glyph& glyph : font_value.second) {
402  if (!font_glyph_atlas->FindGlyphBounds(glyph)) {
403  new_glyphs.emplace_back(scaled_font, glyph);
404  }
405  }
406  } else {
407  for (const Glyph& glyph : font_value.second) {
408  new_glyphs.emplace_back(scaled_font, glyph);
409  }
410  }
411  }
412  if (last_atlas->GetType() == type && new_glyphs.size() == 0) {
413  return last_atlas;
414  }
415 
416  // ---------------------------------------------------------------------------
417  // Step 2: Determine if the additional missing glyphs can be appended to the
418  // existing bitmap without recreating the atlas. This requires that
419  // the type is identical.
420  // ---------------------------------------------------------------------------
421  std::vector<Rect> glyph_positions;
422  if (last_atlas->GetType() == type &&
423  CanAppendToExistingAtlas(last_atlas, new_glyphs, glyph_positions,
424  atlas_context->GetAtlasSize(),
425  atlas_context->GetRectPacker())) {
426  // The old bitmap will be reused and only the additional glyphs will be
427  // added.
428 
429  // ---------------------------------------------------------------------------
430  // Step 3a: Record the positions in the glyph atlas of the newly added
431  // glyphs.
432  // ---------------------------------------------------------------------------
433  for (size_t i = 0, count = glyph_positions.size(); i < count; i++) {
434  last_atlas->AddTypefaceGlyphPosition(new_glyphs[i], glyph_positions[i]);
435  }
436 
437  // ---------------------------------------------------------------------------
438  // Step 4a: Draw new font-glyph pairs into the existing bitmap.
439  // ---------------------------------------------------------------------------
440  // auto bitmap = atlas_context->GetBitmap();
441  auto bitmap = atlas_context_stb.GetBitmap();
442  if (!UpdateAtlasBitmap(*last_atlas, bitmap, new_glyphs)) {
443  return nullptr;
444  }
445 
446  // ---------------------------------------------------------------------------
447  // Step 5a: Update the existing texture with the updated bitmap.
448  // ---------------------------------------------------------------------------
449  if (!UpdateGlyphTextureAtlas(bitmap, last_atlas->GetTexture())) {
450  return nullptr;
451  }
452  return last_atlas;
453  }
454  // A new glyph atlas must be created.
455 
456  // ---------------------------------------------------------------------------
457  // Step 3b: Get the optimum size of the texture atlas.
458  // ---------------------------------------------------------------------------
459  std::vector<FontGlyphPair> font_glyph_pairs;
460  font_glyph_pairs.reserve(std::accumulate(
461  font_glyph_map.begin(), font_glyph_map.end(), 0,
462  [](const int a, const auto& b) { return a + b.second.size(); }));
463  for (const auto& font_value : font_glyph_map) {
464  const ScaledFont& scaled_font = font_value.first;
465  for (const Glyph& glyph : font_value.second) {
466  font_glyph_pairs.push_back({scaled_font, glyph});
467  }
468  }
469  auto glyph_atlas = std::make_shared<GlyphAtlas>(type);
470  auto atlas_size = OptimumAtlasSizeForFontGlyphPairs(
471  font_glyph_pairs, //
472  glyph_positions, //
473  atlas_context, //
474  type, //
475  context.GetResourceAllocator()->GetMaxTextureSizeSupported() //
476  );
477 
478  atlas_context->UpdateGlyphAtlas(glyph_atlas, atlas_size);
479  if (atlas_size.IsEmpty()) {
480  return nullptr;
481  }
482 
483  // ---------------------------------------------------------------------------
484  // Step 4b: Find location of font-glyph pairs in the atlas. We have this from
485  // the last step. So no need to do create another rect packer. But just do a
486  // sanity check of counts. This could also be just an assertion as only a
487  // construction issue would cause such a failure.
488  // ---------------------------------------------------------------------------
489  if (glyph_positions.size() != font_glyph_pairs.size()) {
490  return nullptr;
491  }
492 
493  // ---------------------------------------------------------------------------
494  // Step 5b: Record the positions in the glyph atlas.
495  // ---------------------------------------------------------------------------
496  {
497  size_t i = 0;
498  for (auto it = font_glyph_pairs.begin(); it != font_glyph_pairs.end();
499  ++i, ++it) {
500  glyph_atlas->AddTypefaceGlyphPosition(*it, glyph_positions[i]);
501  }
502  }
503 
504  // ---------------------------------------------------------------------------
505  // Step 6b: Draw font-glyph pairs in the correct spot in the atlas.
506  // ---------------------------------------------------------------------------
507  auto bitmap = CreateAtlasBitmap(*glyph_atlas, atlas_size);
508  if (!bitmap) {
509  return nullptr;
510  }
511  atlas_context_stb.UpdateBitmap(bitmap);
512 
513  // ---------------------------------------------------------------------------
514  // Step 7b: Upload the atlas as a texture.
515  // ---------------------------------------------------------------------------
516  PixelFormat format;
517  switch (type) {
519  format = context.GetCapabilities()->GetDefaultGlyphAtlasFormat();
520  break;
523  ? context.GetCapabilities()->GetDefaultGlyphAtlasFormat()
525  break;
526  }
527  auto texture = UploadGlyphTextureAtlas(context.GetResourceAllocator(), bitmap,
528  atlas_size, format);
529  if (!texture) {
530  return nullptr;
531  }
532 
533  // ---------------------------------------------------------------------------
534  // Step 8b: Record the texture in the glyph atlas.
535  // ---------------------------------------------------------------------------
536  glyph_atlas->SetTexture(std::move(texture));
537 
538  return glyph_atlas;
539 }
540 
541 } // namespace impeller
impeller::GlyphAtlas::Type::kColorBitmap
@ kColorBitmap
typeface_stb.h
impeller::TypographerContext
The graphics context necessary to render text.
Definition: typographer_context.h:23
impeller::Font
Describes a typeface along with any modifications to its intrinsic properties.
Definition: font.h:22
impeller::GlyphAtlas::Type::kAlphaBitmap
@ kAlphaBitmap
impeller::GlyphAtlas::FindFontGlyphBounds
std::optional< Rect > FindFontGlyphBounds(const FontGlyphPair &pair) const
Find the location of a specific font-glyph pair in the atlas.
Definition: glyph_atlas.cc:66
allocation.h
impeller::TRect< Scalar >::MakeXYWH
constexpr static TRect MakeXYWH(Type x, Type y, Type width, Type height)
Definition: rect.h:136
impeller::FontGlyphAtlas
An object that can look up glyph locations within the GlyphAtlas for a particular typeface.
Definition: glyph_atlas.h:185
impeller::TypographerContextSTB::TypographerContextSTB
TypographerContextSTB()
Definition: typographer_context_stb.cc:33
impeller::Allocation::NextPowerOfTwoSize
static uint32_t NextPowerOfTwoSize(uint32_t x)
Definition: allocation.cc:41
impeller::Context::GetCapabilities
virtual const std::shared_ptr< const Capabilities > & GetCapabilities() const =0
Get the capabilities of Impeller context. All optionally supported feature of the platform,...
impeller::CreateAtlasBitmap
static std::shared_ptr< SkBitmap > CreateAtlasBitmap(const GlyphAtlas &atlas, const ISize &atlas_size)
Definition: typographer_context_skia.cc:217
impeller::TextureDescriptor::format
PixelFormat format
Definition: texture_descriptor.h:40
impeller::ScaledFont::font
Font font
Definition: font_glyph_pair.h:25
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::RectanglePacker::Factory
static std::unique_ptr< RectanglePacker > Factory(int width, int height)
Return an empty packer with area specified by width and height.
Definition: rectangle_packer.cc:169
impeller::PairsFitInAtlasOfSize
static size_t PairsFitInAtlasOfSize(const std::vector< FontGlyphPair > &pairs, const ISize &atlas_size, std::vector< Rect > &glyph_positions, const std::shared_ptr< RectanglePacker > &rect_packer)
Definition: typographer_context_skia.cc:45
impeller::FontGlyphMap
std::unordered_map< ScaledFont, std::unordered_set< Glyph > > FontGlyphMap
Definition: font_glyph_pair.h:29
impeller::IPoint16::x
int16_t x() const
Definition: rectangle_packer.h:15
impeller::TRect::GetX
constexpr Type GetX() const
Returns the X coordinate of the upper left corner, equivalent to |GetOrigin().x|.
Definition: rect.h:300
impeller::UpdateAtlasBitmap
static bool UpdateAtlasBitmap(const GlyphAtlas &atlas, const std::shared_ptr< SkBitmap > &bitmap, const std::vector< FontGlyphPair > &new_pairs)
Definition: typographer_context_skia.cc:190
impeller::StorageMode::kHostVisible
@ kHostVisible
impeller::BitmapSTB::GetPixelAddress
uint8_t * GetPixelAddress(TPoint< size_t > coords)
Definition: glyph_atlas_context_stb.cc:23
impeller::BitmapSTB
Definition: glyph_atlas_context_stb.h:13
impeller::TRect::GetHeight
constexpr Type GetHeight() const
Returns the height of the rectangle, equivalent to |GetSize().height|.
Definition: rect.h:314
kColorFontBitsPerPixel
constexpr auto kColorFontBitsPerPixel
Definition: typographer_context_stb.cc:20
impeller::IPoint16::y
int16_t y() const
Definition: rectangle_packer.h:16
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:100
impeller::Font::GetTypeface
const std::shared_ptr< Typeface > & GetTypeface() const
The typeface whose intrinsic properties this font modifies.
Definition: font.cc:23
impeller::GlyphAtlas::IterateGlyphs
size_t IterateGlyphs(const std::function< bool(const ScaledFont &scaled_font, const Glyph &glyph, const Rect &rect)> &iterator) const
Iterate of all the glyphs along with their locations in the atlas.
Definition: glyph_atlas.cc:91
impeller::CanAppendToExistingAtlas
static bool CanAppendToExistingAtlas(const std::shared_ptr< GlyphAtlas > &atlas, const std::vector< FontGlyphPair > &extra_pairs, std::vector< Rect > &glyph_positions, ISize atlas_size, const std::shared_ptr< RectanglePacker > &rect_packer)
Definition: typographer_context_skia.cc:80
impeller::Glyph
The glyph index in the typeface.
Definition: glyph.h:20
impeller::TSize< int64_t >
impeller::UpdateGlyphTextureAtlas
static bool UpdateGlyphTextureAtlas(std::shared_ptr< SkBitmap > bitmap, const std::shared_ptr< Texture > &texture)
Definition: typographer_context_skia.cc:260
impeller::FontGlyphPair::glyph
const Glyph & glyph
Definition: font_glyph_pair.h:39
impeller::TypographerContextSTB::~TypographerContextSTB
~TypographerContextSTB() override
impeller::BitmapSTB::GetRowBytes
size_t GetRowBytes() const
Definition: glyph_atlas_context_stb.cc:30
impeller::TypographerContextSTB::CreateGlyphAtlas
std::shared_ptr< GlyphAtlas > CreateGlyphAtlas(Context &context, GlyphAtlas::Type type, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const FontGlyphMap &font_glyph_map) const override
Definition: typographer_context_stb.cc:375
impeller::FontGlyphPair::scaled_font
const ScaledFont & scaled_font
Definition: font_glyph_pair.h:38
impeller::GlyphAtlas::GetType
Type GetType() const
Describes how the glyphs are represented in the texture.
Definition: glyph_atlas.cc:49
impeller::TRect::GetWidth
constexpr Type GetWidth() const
Returns the width of the rectangle, equivalent to |GetSize().width|.
Definition: rect.h:308
glyph_atlas_context_stb.h
impeller::GlyphAtlas::Type
Type
Describes how the glyphs are represented in the texture.
Definition: glyph_atlas.h:32
font_glyph_pair.h
impeller::TypographerContextSTB::Make
static std::unique_ptr< TypographerContext > Make()
Definition: typographer_context_stb.cc:29
impeller::UploadGlyphTextureAtlas
static std::shared_ptr< Texture > UploadGlyphTextureAtlas(const std::shared_ptr< Allocator > &allocator, std::shared_ptr< SkBitmap > bitmap, const ISize &atlas_size, PixelFormat format)
Definition: typographer_context_skia.cc:276
impeller::Font::Metrics::point_size
Scalar point_size
Definition: font.h:35
impeller::Glyph::index
uint16_t index
Definition: glyph.h:26
impeller::FontGlyphPair
A font along with a glyph in that font rendered at a particular scale.
Definition: font_glyph_pair.h:35
impeller::Font::GetMetrics
const Metrics & GetMetrics() const
Definition: font.cc:37
impeller::kPadding
constexpr auto kPadding
Definition: typographer_context_skia.cc:30
impeller::TSize::width
Type width
Definition: size.h:22
impeller::ISize
TSize< int64_t > ISize
Definition: size.h:138
impeller::TextureDescriptor::size
ISize size
Definition: texture_descriptor.h:41
impeller::ScaledFont::scale
Scalar scale
Definition: font_glyph_pair.h:26
allocator.h
impeller::TypographerContextSTB::CreateGlyphAtlasContext
std::shared_ptr< GlyphAtlasContext > CreateGlyphAtlasContext() const override
Definition: typographer_context_stb.cc:38
impeller::GlyphAtlas
A texture containing the bitmap representation of glyphs in different fonts along with the ability to...
Definition: glyph_atlas.h:28
impeller::Context
To do anything rendering related with Impeller, you need a context.
Definition: context.h:46
impeller::TextureDescriptor::GetByteSizeOfBaseMipLevel
constexpr size_t GetByteSizeOfBaseMipLevel() const
Definition: texture_descriptor.h:47
impeller::TypefaceSTB::kPointsToPixels
static constexpr float kPointsToPixels
Definition: typeface_stb.h:21
DISABLE_COLOR_FONT_SUPPORT
#define DISABLE_COLOR_FONT_SUPPORT
Definition: typographer_context_stb.cc:18
impeller::saturated::b
SI b
Definition: saturated_math.h:87
impeller::BackendCast< GlyphAtlasContextSTB, GlyphAtlasContext >::Cast
static GlyphAtlasContextSTB & Cast(GlyphAtlasContext &base)
Definition: backend_cast.h:13
impeller::IPoint16
Definition: rectangle_packer.h:14
scale
const Scalar scale
Definition: stroke_path_geometry.cc:297
impeller::OptimumAtlasSizeForFontGlyphPairs
static ISize OptimumAtlasSizeForFontGlyphPairs(const std::vector< FontGlyphPair > &pairs, std::vector< Rect > &glyph_positions, const std::shared_ptr< GlyphAtlasContext > &atlas_context, GlyphAtlas::Type type, const ISize &max_texture_size)
Definition: typographer_context_skia.cc:118
impeller::FontGlyphAtlas::FindGlyphBounds
std::optional< Rect > FindGlyphBounds(const Glyph &glyph) const
Find the location of a glyph in the atlas.
Definition: glyph_atlas.cc:111
impeller::TextureDescriptor::storage_mode
StorageMode storage_mode
Definition: texture_descriptor.h:38
impeller::TSize::height
Type height
Definition: size.h:23
typographer_context_stb.h
impeller::TextureDescriptor
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
Definition: texture_descriptor.h:37
impeller::TSize::IsEmpty
constexpr bool IsEmpty() const
Returns true if either of the width or height are 0, negative, or NaN.
Definition: size.h:105
impeller::TSize< int64_t >::MakeWH
static constexpr TSize MakeWH(Type width, Type height)
Definition: size.h:34
impeller::TRect::GetY
constexpr Type GetY() const
Returns the Y coordinate of the upper left corner, equivalent to |GetOrigin().y|.
Definition: rect.h:304
impeller
Definition: aiks_blur_unittests.cc:20
impeller::Context::GetResourceAllocator
virtual std::shared_ptr< Allocator > GetResourceAllocator() const =0
Returns the allocator used to create textures and buffers on the device.
impeller::TRect
Definition: rect.h:122
impeller::DrawGlyph
static void DrawGlyph(SkCanvas *canvas, const ScaledFont &scaled_font, const Glyph &glyph, const Rect &location, bool has_color)
Definition: typographer_context_skia.cc:157
impeller::ScaledFont
A font and a scale. Used as a key that represents a typeface within a glyph atlas.
Definition: font_glyph_pair.h:24
impeller::TypographerContext::IsValid
virtual bool IsValid() const
Definition: typographer_context.cc:17