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"
12 #include "fml/closure.h"
13 #include "fml/mapping.h"
19 #include "typeface_stb.h"
20 
21 #define DISABLE_COLOR_FONT_SUPPORT 1
22 #ifdef DISABLE_COLOR_FONT_SUPPORT
23 constexpr auto kColorFontBitsPerPixel = 1;
24 #else
25 constexpr auto kColorFontBitsPerPixel = 4;
26 #endif
27 
28 namespace impeller {
29 
30 constexpr size_t kPadding = 1;
31 
32 std::unique_ptr<TypographerContext> TypographerContextSTB::Make() {
33  return std::make_unique<TypographerContextSTB>();
34 }
35 
37 
39 
40 std::shared_ptr<GlyphAtlasContext>
42  return std::make_shared<GlyphAtlasContextSTB>(type);
43 }
44 
45 // Function returns the count of "remaining pairs" not packed into rect of given
46 // size.
47 static size_t PairsFitInAtlasOfSize(
48  const std::vector<FontGlyphPair>& pairs,
49  const ISize& atlas_size,
50  std::vector<Rect>& glyph_positions,
51  const std::shared_ptr<RectanglePacker>& rect_packer) {
52  if (atlas_size.IsEmpty()) {
53  return false;
54  }
55 
56  glyph_positions.clear();
57  glyph_positions.reserve(pairs.size());
58 
59  size_t i = 0;
60  for (auto it = pairs.begin(); it != pairs.end(); ++i, ++it) {
61  const auto& pair = *it;
62  const Font& font = pair.scaled_font.font;
63 
64  // We downcast to the correct typeface type to access `stb` specific
65  // methods.
66  std::shared_ptr<TypefaceSTB> typeface_stb =
67  std::reinterpret_pointer_cast<TypefaceSTB>(font.GetTypeface());
68  // Conversion factor to scale font size in Points to pixels.
69  // Note this assumes typical DPI.
70  float text_size_pixels =
72 
73  ISize glyph_size;
74  {
75  int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
76  float scale = stbtt_ScaleForMappingEmToPixels(typeface_stb->GetFontInfo(),
77  text_size_pixels);
78  stbtt_GetGlyphBitmapBox(typeface_stb->GetFontInfo(),
79  pair.glyph.glyph.index, scale, scale, &x0, &y0,
80  &x1, &y1);
81 
82  glyph_size = ISize(x1 - x0, y1 - y0);
83  }
84 
85  IPoint16 location_in_atlas;
86  if (!rect_packer->AddRect(glyph_size.width + kPadding, //
87  glyph_size.height + kPadding, //
88  &location_in_atlas //
89  )) {
90  return pairs.size() - i;
91  }
92  glyph_positions.emplace_back(Rect::MakeXYWH(location_in_atlas.x(), //
93  location_in_atlas.y(), //
94  glyph_size.width, //
95  glyph_size.height //
96  ));
97  }
98 
99  return 0;
100 }
101 
103  const std::shared_ptr<GlyphAtlas>& atlas,
104  const std::vector<FontGlyphPair>& extra_pairs,
105  std::vector<Rect>& glyph_positions,
106  ISize atlas_size,
107  const std::shared_ptr<RectanglePacker>& rect_packer) {
108  TRACE_EVENT0("impeller", __FUNCTION__);
109  if (!rect_packer || atlas_size.IsEmpty()) {
110  return false;
111  }
112 
113  // We assume that all existing glyphs will fit. After all, they fit before.
114  // The glyph_positions only contains the values for the additional glyphs
115  // from extra_pairs.
116  FML_DCHECK(glyph_positions.size() == 0);
117  glyph_positions.reserve(extra_pairs.size());
118  for (size_t i = 0; i < extra_pairs.size(); i++) {
119  const FontGlyphPair& pair = extra_pairs[i];
120  const Font& font = pair.scaled_font.font;
121 
122  // We downcast to the correct typeface type to access `stb` specific methods
123  std::shared_ptr<TypefaceSTB> typeface_stb =
124  std::reinterpret_pointer_cast<TypefaceSTB>(font.GetTypeface());
125  // Conversion factor to scale font size in Points to pixels.
126  // Note this assumes typical DPI.
127  float text_size_pixels =
129 
130  ISize glyph_size;
131  {
132  int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
133  float scale_y = stbtt_ScaleForMappingEmToPixels(
134  typeface_stb->GetFontInfo(), text_size_pixels);
135  float scale_x = scale_y;
136  stbtt_GetGlyphBitmapBox(typeface_stb->GetFontInfo(),
137  pair.glyph.glyph.index, scale_x, scale_y, &x0,
138  &y0, &x1, &y1);
139 
140  glyph_size = ISize(x1 - x0, y1 - y0);
141  }
142 
143  IPoint16 location_in_atlas;
144  if (!rect_packer->AddRect(glyph_size.width + kPadding, //
145  glyph_size.height + kPadding, //
146  &location_in_atlas //
147  )) {
148  return false;
149  }
150  glyph_positions.emplace_back(Rect::MakeXYWH(location_in_atlas.x(), //
151  location_in_atlas.y(), //
152  glyph_size.width, //
153  glyph_size.height //
154  ));
155  }
156 
157  return true;
158 }
159 
161  const std::vector<FontGlyphPair>& pairs,
162  std::vector<Rect>& glyph_positions,
163  const std::shared_ptr<GlyphAtlasContext>& atlas_context,
165  const ISize& max_texture_size) {
166  static constexpr auto kMinAtlasSize = 8u;
167  static constexpr auto kMinAlphaBitmapSize = 1024u;
168 
169  TRACE_EVENT0("impeller", __FUNCTION__);
170 
171  ISize current_size = type == GlyphAtlas::Type::kAlphaBitmap
172  ? ISize(kMinAlphaBitmapSize, kMinAlphaBitmapSize)
173  : ISize(kMinAtlasSize, kMinAtlasSize);
174  size_t total_pairs = pairs.size() + 1;
175  do {
176  auto rect_packer = std::shared_ptr<RectanglePacker>(
177  RectanglePacker::Factory(current_size.width, current_size.height));
178 
179  auto remaining_pairs = PairsFitInAtlasOfSize(pairs, current_size,
180  glyph_positions, rect_packer);
181  if (remaining_pairs == 0) {
182  atlas_context->UpdateRectPacker(rect_packer);
183  return current_size;
184  } else if (remaining_pairs < std::ceil(total_pairs / 2)) {
185  current_size = ISize::MakeWH(
186  std::max(current_size.width, current_size.height),
188  std::min(current_size.width, current_size.height) + 1));
189  } else {
190  current_size = ISize::MakeWH(
191  Allocation::NextPowerOfTwoSize(current_size.width + 1),
192  Allocation::NextPowerOfTwoSize(current_size.height + 1));
193  }
194  } while (current_size.width <= max_texture_size.width &&
195  current_size.height <= max_texture_size.height);
196  return ISize{0, 0};
197 }
198 
199 static void DrawGlyph(BitmapSTB* bitmap,
200  const ScaledFont& scaled_font,
201  const Glyph& glyph,
202  const Rect& location,
203  bool has_color) {
204  const auto& metrics = scaled_font.font.GetMetrics();
205 
206  const impeller::Font& font = scaled_font.font;
207  auto typeface = font.GetTypeface();
208  // We downcast to the correct typeface type to access `stb` specific methods
209  std::shared_ptr<TypefaceSTB> typeface_stb =
210  std::reinterpret_pointer_cast<TypefaceSTB>(typeface);
211  // Conversion factor to scale font size in Points to pixels.
212  // Note this assumes typical DPI.
213  float text_size_pixels = metrics.point_size * TypefaceSTB::kPointsToPixels;
214  float scale_y = stbtt_ScaleForMappingEmToPixels(typeface_stb->GetFontInfo(),
215  text_size_pixels);
216  float scale_x = scale_y;
217 
218  auto output = bitmap->GetPixelAddress({static_cast<size_t>(location.GetX()),
219  static_cast<size_t>(location.GetY())});
220  // For Alpha and Signed Distance field bitmaps we can use STB to draw the
221  // Glyph in place
222  if (!has_color || DISABLE_COLOR_FONT_SUPPORT) {
223  stbtt_MakeGlyphBitmap(typeface_stb->GetFontInfo(), output,
224  location.GetWidth(), location.GetHeight(),
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.glyph,
286  pos.value().first, 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 SubpixelGlyph& glyph,
307  const Rect& location) -> bool {
308  DrawGlyph(bitmap.get(), scaled_font, glyph.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<Allocator>& allocator,
318  std::shared_ptr<BlitPass>& blit_pass,
319  const std::shared_ptr<Texture>& texture) {
320  TRACE_EVENT0("impeller", __FUNCTION__);
321 
322  FML_DCHECK(bitmap != nullptr);
323 
324  auto texture_descriptor = texture->GetTextureDescriptor();
325 
326  auto mapping = std::make_shared<fml::NonOwnedMapping>(
327  reinterpret_cast<const uint8_t*>(bitmap->GetPixels()), // data
328  texture_descriptor.GetByteSizeOfBaseMipLevel() // size
329  // As the bitmap is static in this module I believe we don't need to
330  // specify a release proc.
331  );
332 
333  std::shared_ptr<DeviceBuffer> device_buffer =
334  allocator->CreateBufferWithCopy(*mapping);
335  blit_pass->AddCopy(DeviceBuffer::AsBufferView(device_buffer), texture);
336 
337  return blit_pass->EncodeCommands(allocator);
338 }
339 
340 static std::shared_ptr<Texture> UploadGlyphTextureAtlas(
341  const std::shared_ptr<Allocator>& allocator,
342  std::shared_ptr<BlitPass>& blit_pass,
343  std::shared_ptr<BitmapSTB>& bitmap,
344  const ISize& atlas_size,
345  PixelFormat format) {
346  TRACE_EVENT0("impeller", __FUNCTION__);
347  if (!allocator) {
348  return nullptr;
349  }
350 
351  FML_DCHECK(bitmap != nullptr);
352 
353  TextureDescriptor texture_descriptor;
354  texture_descriptor.storage_mode = StorageMode::kDevicePrivate;
355  texture_descriptor.format = format;
356  texture_descriptor.size = atlas_size;
357 
358  if (bitmap->GetRowBytes() * bitmap->GetHeight() !=
359  texture_descriptor.GetByteSizeOfBaseMipLevel()) {
360  return nullptr;
361  }
362 
363  auto texture = allocator->CreateTexture(texture_descriptor);
364  if (!texture || !texture->IsValid()) {
365  return nullptr;
366  }
367  texture->SetLabel("GlyphAtlas");
368 
369  std::shared_ptr<fml::NonOwnedMapping> mapping =
370  std::make_shared<fml::NonOwnedMapping>(
371  reinterpret_cast<const uint8_t*>(bitmap->GetPixels()), // data
372  texture_descriptor.GetByteSizeOfBaseMipLevel() // size
373  // As the bitmap is static in this module I believe we don't need to
374  // specify a release proc.
375  );
376  std::shared_ptr<DeviceBuffer> device_buffer =
377  allocator->CreateBufferWithCopy(*mapping);
378  blit_pass->AddCopy(DeviceBuffer::AsBufferView(device_buffer), texture);
379  if (!blit_pass->EncodeCommands(allocator)) {
380  return nullptr;
381  }
382 
383  return texture;
384 }
385 
386 static Rect ComputeGlyphSize(const ScaledFont& font,
387  const SubpixelGlyph& glyph) {
388  std::shared_ptr<TypefaceSTB> typeface_stb =
389  std::reinterpret_pointer_cast<TypefaceSTB>(font.font.GetTypeface());
390  float scale = stbtt_ScaleForMappingEmToPixels(
391  typeface_stb->GetFontInfo(),
393  int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
394  stbtt_GetGlyphBitmapBox(typeface_stb->GetFontInfo(), glyph.glyph.index, scale,
395  scale, &x0, &y0, &x1, &y1);
396  return Rect::MakeLTRB(0, 0, x1 - x0, y1 - y0);
397 }
398 
399 std::shared_ptr<GlyphAtlas> TypographerContextSTB::CreateGlyphAtlas(
400  Context& context,
402  HostBuffer& host_buffer,
403  const std::shared_ptr<GlyphAtlasContext>& atlas_context,
404  const FontGlyphMap& font_glyph_map) const {
405  TRACE_EVENT0("impeller", __FUNCTION__);
406  if (!IsValid()) {
407  return nullptr;
408  }
409  auto& atlas_context_stb = GlyphAtlasContextSTB::Cast(*atlas_context);
410  std::shared_ptr<GlyphAtlas> last_atlas = atlas_context->GetGlyphAtlas();
411 
412  if (font_glyph_map.empty()) {
413  return last_atlas;
414  }
415 
416  std::shared_ptr<CommandBuffer> cmd_buffer = context.CreateCommandBuffer();
417  std::shared_ptr<BlitPass> blit_pass = cmd_buffer->CreateBlitPass();
418 
419  fml::ScopedCleanupClosure closure([&cmd_buffer, &context]() {
420  context.GetCommandQueue()->Submit({std::move(cmd_buffer)});
421  });
422 
423  // ---------------------------------------------------------------------------
424  // Step 1: Determine if the atlas type and font glyph pairs are compatible
425  // with the current atlas and reuse if possible.
426  // ---------------------------------------------------------------------------
427  std::vector<FontGlyphPair> new_glyphs;
428  std::vector<Rect> new_sizes;
429  for (const auto& font_value : font_glyph_map) {
430  const ScaledFont& scaled_font = font_value.first;
431  const FontGlyphAtlas* font_glyph_atlas =
432  last_atlas->GetFontGlyphAtlas(scaled_font.font, scaled_font.scale);
433  if (font_glyph_atlas) {
434  for (const SubpixelGlyph& glyph : font_value.second) {
435  if (!font_glyph_atlas->FindGlyphBounds(glyph)) {
436  new_glyphs.emplace_back(scaled_font, glyph);
437  new_sizes.push_back(ComputeGlyphSize(scaled_font, glyph));
438  }
439  }
440  } else {
441  for (const SubpixelGlyph& glyph : font_value.second) {
442  new_glyphs.emplace_back(scaled_font, glyph);
443  new_sizes.push_back(ComputeGlyphSize(scaled_font, glyph));
444  }
445  }
446  }
447  if (last_atlas->GetType() == type && new_glyphs.size() == 0) {
448  return last_atlas;
449  }
450 
451  // ---------------------------------------------------------------------------
452  // Step 2: Determine if the additional missing glyphs can be appended to the
453  // existing bitmap without recreating the atlas. This requires that
454  // the type is identical.
455  // ---------------------------------------------------------------------------
456  std::vector<Rect> glyph_positions;
457  if (last_atlas->GetType() == type &&
458  CanAppendToExistingAtlas(last_atlas, new_glyphs, glyph_positions,
459  atlas_context->GetAtlasSize(),
460  atlas_context->GetRectPacker())) {
461  // The old bitmap will be reused and only the additional glyphs will be
462  // added.
463 
464  // ---------------------------------------------------------------------------
465  // Step 3a: Record the positions in the glyph atlas of the newly added
466  // glyphs.
467  // ---------------------------------------------------------------------------
468  for (size_t i = 0, count = glyph_positions.size(); i < count; i++) {
469  last_atlas->AddTypefaceGlyphPositionAndBounds(
470  new_glyphs[i], glyph_positions[i], new_sizes[i]);
471  }
472 
473  // ---------------------------------------------------------------------------
474  // Step 4a: Draw new font-glyph pairs into the existing bitmap.
475  // ---------------------------------------------------------------------------
476  // auto bitmap = atlas_context->GetBitmap();
477  auto bitmap = atlas_context_stb.GetBitmap();
478  if (!UpdateAtlasBitmap(*last_atlas, bitmap, new_glyphs)) {
479  return nullptr;
480  }
481 
482  // ---------------------------------------------------------------------------
483  // Step 5a: Update the existing texture with the updated bitmap.
484  // ---------------------------------------------------------------------------
485  if (!UpdateGlyphTextureAtlas(bitmap, context.GetResourceAllocator(),
486  blit_pass, last_atlas->GetTexture())) {
487  return nullptr;
488  }
489  return last_atlas;
490  }
491  // A new glyph atlas must be created.
492 
493  // ---------------------------------------------------------------------------
494  // Step 3b: Get the optimum size of the texture atlas.
495  // ---------------------------------------------------------------------------
496  std::vector<FontGlyphPair> font_glyph_pairs;
497  font_glyph_pairs.reserve(std::accumulate(
498  font_glyph_map.begin(), font_glyph_map.end(), 0,
499  [](const int a, const auto& b) { return a + b.second.size(); }));
500  for (const auto& font_value : font_glyph_map) {
501  const ScaledFont& scaled_font = font_value.first;
502  for (const SubpixelGlyph& glyph : font_value.second) {
503  font_glyph_pairs.push_back({scaled_font, glyph});
504  }
505  }
506  auto glyph_atlas = std::make_shared<GlyphAtlas>(type);
507  auto atlas_size = OptimumAtlasSizeForFontGlyphPairs(
508  font_glyph_pairs, //
509  glyph_positions, //
510  atlas_context, //
511  type, //
512  context.GetResourceAllocator()->GetMaxTextureSizeSupported() //
513  );
514 
515  atlas_context->UpdateGlyphAtlas(glyph_atlas, atlas_size, 0);
516  if (atlas_size.IsEmpty()) {
517  return nullptr;
518  }
519 
520  // ---------------------------------------------------------------------------
521  // Step 4b: Find location of font-glyph pairs in the atlas. We have this from
522  // the last step. So no need to do create another rect packer. But just do a
523  // sanity check of counts. This could also be just an assertion as only a
524  // construction issue would cause such a failure.
525  // ---------------------------------------------------------------------------
526  if (glyph_positions.size() != font_glyph_pairs.size()) {
527  return nullptr;
528  }
529 
530  // ---------------------------------------------------------------------------
531  // Step 5b: Record the positions in the glyph atlas.
532  // ---------------------------------------------------------------------------
533  {
534  size_t i = 0;
535  for (auto it = font_glyph_pairs.begin(); it != font_glyph_pairs.end();
536  ++i, ++it) {
537  glyph_atlas->AddTypefaceGlyphPositionAndBounds(*it, glyph_positions[i],
538  new_sizes[i]);
539  }
540  }
541 
542  // ---------------------------------------------------------------------------
543  // Step 6b: Draw font-glyph pairs in the correct spot in the atlas.
544  // ---------------------------------------------------------------------------
545  auto bitmap = CreateAtlasBitmap(*glyph_atlas, atlas_size);
546  if (!bitmap) {
547  return nullptr;
548  }
549  atlas_context_stb.UpdateBitmap(bitmap);
550 
551  // ---------------------------------------------------------------------------
552  // Step 7b: Upload the atlas as a texture.
553  // ---------------------------------------------------------------------------
554  PixelFormat format;
555  switch (type) {
557  format = context.GetCapabilities()->GetDefaultGlyphAtlasFormat();
558  break;
561  ? context.GetCapabilities()->GetDefaultGlyphAtlasFormat()
563  break;
564  }
565  auto texture = UploadGlyphTextureAtlas(context.GetResourceAllocator(),
566  blit_pass, bitmap, atlas_size, format);
567  if (!texture) {
568  return nullptr;
569  }
570 
571  // ---------------------------------------------------------------------------
572  // Step 8b: Record the texture in the glyph atlas.
573  // ---------------------------------------------------------------------------
574  glyph_atlas->SetTexture(std::move(texture));
575 
576  return glyph_atlas;
577 }
578 
579 } // namespace impeller
impeller::DeviceBuffer::AsBufferView
static BufferView AsBufferView(std::shared_ptr< DeviceBuffer > buffer)
Create a buffer view of this entire buffer.
Definition: device_buffer.cc:18
impeller::ISize
ISize64 ISize
Definition: size.h:140
impeller::CreateAtlasBitmap
static std::shared_ptr< BitmapSTB > CreateAtlasBitmap(const GlyphAtlas &atlas, const ISize &atlas_size)
Definition: typographer_context_stb.cc:291
impeller::GlyphAtlas::Type::kColorBitmap
@ kColorBitmap
typeface_stb.h
impeller::TypographerContextSTB::CreateGlyphAtlasContext
std::shared_ptr< GlyphAtlasContext > CreateGlyphAtlasContext(GlyphAtlas::Type type) const override
Definition: typographer_context_stb.cc:41
impeller::TypographerContext
The graphics context necessary to render text.
Definition: typographer_context.h:22
impeller::Font
Describes a typeface along with any modifications to its intrinsic properties.
Definition: font.h:35
impeller::UpdateGlyphTextureAtlas
static bool UpdateGlyphTextureAtlas(std::shared_ptr< BitmapSTB > &bitmap, const std::shared_ptr< Allocator > &allocator, std::shared_ptr< BlitPass > &blit_pass, const std::shared_ptr< Texture > &texture)
Definition: typographer_context_stb.cc:316
impeller::GlyphAtlas::Type::kAlphaBitmap
@ kAlphaBitmap
impeller::UpdateAtlasBitmap
static bool UpdateAtlasBitmap(const GlyphAtlas &atlas, std::shared_ptr< BlitPass > &blit_pass, HostBuffer &host_buffer, const std::shared_ptr< Texture > &texture, const std::vector< FontGlyphPair > &new_pairs, size_t start_index, size_t end_index)
Definition: typographer_context_skia.cc:252
allocation.h
impeller::TRect< Scalar >::MakeXYWH
constexpr static TRect MakeXYWH(Type x, Type y, Type width, Type height)
Definition: rect.h:136
device_buffer.h
impeller::FontGlyphAtlas
An object that can look up glyph locations within the GlyphAtlas for a particular typeface.
Definition: glyph_atlas.h:200
impeller::TypographerContextSTB::TypographerContextSTB
TypographerContextSTB()
Definition: typographer_context_stb.cc:36
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::HostBuffer
Definition: host_buffer.h:28
impeller::TextureDescriptor::format
PixelFormat format
Definition: texture_descriptor.h:41
impeller::ScaledFont::font
Font font
Definition: font_glyph_pair.h:33
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::SubpixelGlyph
A glyph and its subpixel position.
Definition: font_glyph_pair.h:40
impeller::UploadGlyphTextureAtlas
static std::shared_ptr< Texture > UploadGlyphTextureAtlas(const std::shared_ptr< Allocator > &allocator, std::shared_ptr< BlitPass > &blit_pass, std::shared_ptr< BitmapSTB > &bitmap, const ISize &atlas_size, PixelFormat format)
Definition: typographer_context_stb.cc:340
impeller::IPoint16::x
int16_t x() const
Definition: rectangle_packer.h:16
impeller::TRect::GetX
constexpr Type GetX() const
Returns the X coordinate of the upper left corner, equivalent to |GetOrigin().x|.
Definition: rect.h:323
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:337
kColorFontBitsPerPixel
constexpr auto kColorFontBitsPerPixel
Definition: typographer_context_stb.cc:23
impeller::IPoint16::y
int16_t y() const
Definition: rectangle_packer.h:17
impeller::TypographerContextSTB::CreateGlyphAtlas
std::shared_ptr< GlyphAtlas > CreateGlyphAtlas(Context &context, GlyphAtlas::Type type, HostBuffer &host_buffer, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const FontGlyphMap &font_glyph_map) const override
Definition: typographer_context_stb.cc:399
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
impeller::Font::GetTypeface
const std::shared_ptr< Typeface > & GetTypeface() const
The typeface whose intrinsic properties this font modifies.
Definition: font.cc:27
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_stb.cc:102
impeller::Glyph
The glyph index in the typeface.
Definition: glyph.h:16
impeller::TSize
Definition: size.h:19
impeller::FontGlyphPair::glyph
const SubpixelGlyph & glyph
Definition: font_glyph_pair.h:64
impeller::TypographerContextSTB::~TypographerContextSTB
~TypographerContextSTB() override
impeller::BitmapSTB::GetRowBytes
size_t GetRowBytes() const
Definition: glyph_atlas_context_stb.cc:30
impeller::FontGlyphPair::scaled_font
const ScaledFont & scaled_font
Definition: font_glyph_pair.h:63
impeller::GlyphAtlas::GetType
Type GetType() const
Describes how the glyphs are represented in the texture.
Definition: glyph_atlas.cc:54
impeller::StorageMode::kDevicePrivate
@ kDevicePrivate
impeller::TRect::GetWidth
constexpr Type GetWidth() const
Returns the width of the rectangle, equivalent to |GetSize().width|.
Definition: rect.h:331
glyph_atlas_context_stb.h
impeller::GlyphAtlas::Type
Type
Describes how the glyphs are represented in the texture.
Definition: glyph_atlas.h:31
impeller::FontGlyphMap
std::unordered_map< ScaledFont, std::unordered_set< SubpixelGlyph > > FontGlyphMap
Definition: font_glyph_pair.h:54
font_glyph_pair.h
impeller::TypographerContextSTB::Make
static std::unique_ptr< TypographerContext > Make()
Definition: typographer_context_stb.cc:32
type
GLenum type
Definition: blit_command_gles.cc:126
impeller::SubpixelGlyph::glyph
Glyph glyph
Definition: font_glyph_pair.h:41
impeller::Font::Metrics::point_size
Scalar point_size
Definition: font.h:48
impeller::RectanglePacker::Factory
static std::shared_ptr< RectanglePacker > Factory(int width, int height)
Return an empty packer with area specified by width and height.
Definition: rectangle_packer.cc:174
impeller::Glyph::index
uint16_t index
Definition: glyph.h:22
impeller::Context::CreateCommandBuffer
virtual std::shared_ptr< CommandBuffer > CreateCommandBuffer() const =0
Create a new command buffer. Command buffers can be used to encode graphics, blit,...
impeller::Context::GetCommandQueue
virtual std::shared_ptr< CommandQueue > GetCommandQueue() const =0
Return the graphics queue for submitting command buffers.
impeller::FontGlyphPair
A font along with a glyph in that font rendered at a particular scale and subpixel position.
Definition: font_glyph_pair.h:60
impeller::Font::GetMetrics
const Metrics & GetMetrics() const
Definition: font.cc:45
impeller::kPadding
constexpr auto kPadding
Definition: typographer_context_skia.cc:50
impeller::TSize::width
Type width
Definition: size.h:22
impeller::TextureDescriptor::size
ISize size
Definition: texture_descriptor.h:42
impeller::ScaledFont::scale
Scalar scale
Definition: font_glyph_pair.h:34
allocator.h
impeller::GlyphAtlas
A texture containing the bitmap representation of glyphs in different fonts along with the ability to...
Definition: glyph_atlas.h:27
impeller::FontGlyphAtlas::FindGlyphBounds
std::optional< std::pair< Rect, Rect > > FindGlyphBounds(const SubpixelGlyph &glyph) const
Find the location of a glyph in the atlas.
Definition: glyph_atlas.cc:119
impeller::Context
To do anything rendering related with Impeller, you need a context.
Definition: context.h:45
impeller::TextureDescriptor::GetByteSizeOfBaseMipLevel
constexpr size_t GetByteSizeOfBaseMipLevel() const
Definition: texture_descriptor.h:48
impeller::TypefaceSTB::kPointsToPixels
static constexpr float kPointsToPixels
Definition: typeface_stb.h:20
impeller::GlyphAtlas::FindFontGlyphBounds
std::optional< std::pair< Rect, Rect > > FindFontGlyphBounds(const FontGlyphPair &pair) const
Find the location of a specific font-glyph pair in the atlas.
Definition: glyph_atlas.cc:73
DISABLE_COLOR_FONT_SUPPORT
#define DISABLE_COLOR_FONT_SUPPORT
Definition: typographer_context_stb.cc:21
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:15
scale
const Scalar scale
Definition: stroke_path_geometry.cc:308
impeller::DrawGlyph
static void DrawGlyph(SkCanvas *canvas, const ScaledFont &scaled_font, const SubpixelGlyph &glyph, const Rect &scaled_bounds, const GlyphProperties &prop, bool has_color)
Definition: typographer_context_skia.cc:209
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_stb.cc:160
impeller::ComputeGlyphSize
static Rect ComputeGlyphSize(const SkFont &font, const SubpixelGlyph &glyph, Scalar scale)
Definition: typographer_context_skia.cc:322
impeller::TextureDescriptor::storage_mode
StorageMode storage_mode
Definition: texture_descriptor.h:39
impeller::TSize::height
Type height
Definition: size.h:23
typographer_context_stb.h
impeller::TRect< Scalar >::MakeLTRB
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:129
impeller::TextureDescriptor
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
Definition: texture_descriptor.h:38
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::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:327
impeller
Definition: aiks_blend_unittests.cc:18
impeller::Context::GetResourceAllocator
virtual std::shared_ptr< Allocator > GetResourceAllocator() const =0
Returns the allocator used to create textures and buffers on the device.
impeller::PairsFitInAtlasOfSize
static size_t PairsFitInAtlasOfSize(const std::vector< FontGlyphPair > &pairs, const ISize &atlas_size, std::vector< Rect > &glyph_positions, const std::vector< Rect > &glyph_sizes, int64_t height_adjustment, const std::shared_ptr< RectanglePacker > &rect_packer, size_t start_index)
Definition: typographer_context_skia.cc:138
impeller::TRect< Scalar >
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:98
impeller::ScaledFont
A font and a scale. Used as a key that represents a typeface within a glyph atlas.
Definition: font_glyph_pair.h:32
impeller::TypographerContext::IsValid
virtual bool IsValid() const
Definition: typographer_context.cc:17