| 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
5 #include "impeller/typographer/backends/stb/typographer_context_stb.h"
6
7 #include <numeric>
8 #include <utility>
9
10 #include "flutter/fml/logging.h"
11 #include "flutter/fml/trace_event.h"
12 #include "impeller/base/allocation.h"
13 #include "impeller/core/allocator.h"
14 #include "impeller/typographer/backends/stb/glyph_atlas_context_stb.h"
15 #include "impeller/typographer/font_glyph_pair.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
33 TypographerContextSTB::TypographerContextSTB() : TypographerContext() {}
34
35 TypographerContextSTB::~TypographerContextSTB() = default;
36
37 std::shared_ptr<GlyphAtlasContext>
38 TypographerContextSTB::CreateGlyphAtlasContext() const {
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 =
68 font.GetMetrics().point_size * TypefaceSTB::kPointsToPixels;
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
100 static bool CanAppendToExistingAtlas(
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 =
126 font.GetMetrics().point_size * TypefaceSTB::kPointsToPixels;
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
159 static ISize OptimumAtlasSizeForFontGlyphPairs(
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),
186 Allocation::NextPowerOfTwoSize(
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 =
218 bitmap->GetPixelAddress({static_cast<size_t>(location.origin.x),
219 static_cast<size_t>(location.origin.y)});
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.size.width - kPadding,
225 location.size.height - kPadding,
226 bitmap->GetRowBytes(), scale_x, scale_y, glyph.index);
227 } else {
228 // But for color bitmaps we need to get the glyph pixels and then carry all
229 // channels into the atlas bitmap. This may not be performant but I'm unsure
230 // of any other approach currently.
231 int glyph_bitmap_width = 0;
232 int glyph_bitmap_height = 0;
233 int glyph_bitmap_xoff = 0;
234 int glyph_bitmap_yoff = 0;
235 auto glyph_pixels = stbtt_GetGlyphBitmap(
236 typeface_stb->GetFontInfo(), scale_x, scale_y, glyph.index,
237 &glyph_bitmap_width, &glyph_bitmap_height, &glyph_bitmap_xoff,
238 &glyph_bitmap_yoff);
239
240 uint8_t* write_pos = output;
241 for (auto y = 0; y < glyph_bitmap_height; ++y) {
242 for (auto x = 0; x < glyph_bitmap_width; ++x) {
243 // Color bitmaps write as White (i.e. what is 0 in an alpha bitmap is
244 // 255 in a color bitmap) But not alpha. Alpha still carries
245 // transparency info in the normal way.
246 // There's some issue with color fonts, in that if the pixel color is
247 // nonzero, the alpha is ignored during rendering. That is, partially
248 // (or fully) transparent pixels with nonzero color are rendered as
249 // fully opaque.
250 uint8_t a = glyph_pixels[x + y * glyph_bitmap_width];
251 uint8_t c = 255 - a;
252
253 // Red channel
254 *write_pos = c;
255 write_pos++;
256 // Green channel
257 *write_pos = c;
258 write_pos++;
259 // Blue channel
260 *write_pos = c;
261 write_pos++;
262 // Alpha channel
263 *write_pos = a;
264 write_pos++;
265 }
266 // next row
267 write_pos = output + (y * bitmap->GetRowBytes());
268 }
269 stbtt_FreeBitmap(glyph_pixels, nullptr);
270 }
271 }
272
273 static bool UpdateAtlasBitmap(const GlyphAtlas& atlas,
274 const std::shared_ptr<BitmapSTB>& bitmap,
275 const std::vector<FontGlyphPair>& new_pairs) {
276 TRACE_EVENT0("impeller", __FUNCTION__);
277 FML_DCHECK(bitmap != nullptr);
278
279 bool has_color = atlas.GetType() == GlyphAtlas::Type::kColorBitmap;
280
281 for (const FontGlyphPair& pair : new_pairs) {
282 auto pos = atlas.FindFontGlyphBounds(pair);
283 if (!pos.has_value()) {
284 continue;
285 }
286 DrawGlyph(bitmap.get(), pair.scaled_font, pair.glyph, pos.value(),
287 has_color);
288 }
289 return true;
290 }
291
292 static std::shared_ptr<BitmapSTB> CreateAtlasBitmap(const GlyphAtlas& atlas,
293 const ISize& atlas_size) {
294 TRACE_EVENT0("impeller", __FUNCTION__);
295
296 size_t bytes_per_pixel = 1;
297 if (atlas.GetType() == GlyphAtlas::Type::kColorBitmap &&
298 !DISABLE_COLOR_FONT_SUPPORT) {
299 bytes_per_pixel = kColorFontBitsPerPixel;
300 }
301 auto bitmap = std::make_shared<BitmapSTB>(atlas_size.width, atlas_size.height,
302 bytes_per_pixel);
303
304 bool has_color = atlas.GetType() == GlyphAtlas::Type::kColorBitmap;
305
306 atlas.IterateGlyphs([&bitmap, has_color](const ScaledFont& scaled_font,
307 const Glyph& glyph,
308 const Rect& location) -> bool {
309 DrawGlyph(bitmap.get(), scaled_font, glyph, location, has_color);
310 return true;
311 });
312
313 return bitmap;
314 }
315
316 // static bool UpdateGlyphTextureAtlas(std::shared_ptr<SkBitmap> bitmap,
317 static bool UpdateGlyphTextureAtlas(std::shared_ptr<BitmapSTB>& bitmap,
318 const std::shared_ptr<Texture>& texture) {
319 TRACE_EVENT0("impeller", __FUNCTION__);
320
321 FML_DCHECK(bitmap != nullptr);
322
323 auto texture_descriptor = texture->GetTextureDescriptor();
324
325 auto mapping = std::make_shared<fml::NonOwnedMapping>(
326 reinterpret_cast<const uint8_t*>(bitmap->GetPixels()), // data
327 texture_descriptor.GetByteSizeOfBaseMipLevel() // size
328 // As the bitmap is static in this module I believe we don't need to
329 // specify a release proc.
330 );
331
332 return texture->SetContents(mapping);
333 }
334
335 static std::shared_ptr<Texture> UploadGlyphTextureAtlas(
336 const std::shared_ptr<Allocator>& allocator,
337 std::shared_ptr<BitmapSTB>& bitmap,
338 const ISize& atlas_size,
339 PixelFormat format) {
340 TRACE_EVENT0("impeller", __FUNCTION__);
341 if (!allocator) {
342 return nullptr;
343 }
344
345 FML_DCHECK(bitmap != nullptr);
346
347 TextureDescriptor texture_descriptor;
348 texture_descriptor.storage_mode = StorageMode::kHostVisible;
349 texture_descriptor.format = format;
350 texture_descriptor.size = atlas_size;
351
352 if (bitmap->GetRowBytes() * bitmap->GetHeight() !=
353 texture_descriptor.GetByteSizeOfBaseMipLevel()) {
354 return nullptr;
355 }
356
357 auto texture = allocator->CreateTexture(texture_descriptor);
358 if (!texture || !texture->IsValid()) {
359 return nullptr;
360 }
361 texture->SetLabel("GlyphAtlas");
362
363 auto mapping = std::make_shared<fml::NonOwnedMapping>(
364 reinterpret_cast<const uint8_t*>(bitmap->GetPixels()), // data
365 texture_descriptor.GetByteSizeOfBaseMipLevel() // size
366 // As the bitmap is static in this module I believe we don't need to
367 // specify a release proc.
368 );
369
370 if (!texture->SetContents(mapping)) {
371 return nullptr;
372 }
373 return texture;
374 }
375
376 std::shared_ptr<GlyphAtlas> TypographerContextSTB::CreateGlyphAtlas(
377 Context& context,
378 GlyphAtlas::Type type,
379 std::shared_ptr<GlyphAtlasContext> atlas_context,
380 const FontGlyphMap& font_glyph_map) const {
381 TRACE_EVENT0("impeller", __FUNCTION__);
382 if (!IsValid()) {
383 return nullptr;
384 }
385 auto& atlas_context_stb = GlyphAtlasContextSTB::Cast(*atlas_context);
386 std::shared_ptr<GlyphAtlas> last_atlas = atlas_context->GetGlyphAtlas();
387
388 if (font_glyph_map.empty()) {
389 return last_atlas;
390 }
391
392 // ---------------------------------------------------------------------------
393 // Step 1: Determine if the atlas type and font glyph pairs are compatible
394 // with the current atlas and reuse if possible.
395 // ---------------------------------------------------------------------------
396 std::vector<FontGlyphPair> new_glyphs;
397 for (const auto& font_value : font_glyph_map) {
398 const ScaledFont& scaled_font = font_value.first;
399 const FontGlyphAtlas* font_glyph_atlas =
400 last_atlas->GetFontGlyphAtlas(scaled_font.font, scaled_font.scale);
401 if (font_glyph_atlas) {
402 for (const Glyph& glyph : font_value.second) {
403 if (!font_glyph_atlas->FindGlyphBounds(glyph)) {
404 new_glyphs.emplace_back(scaled_font, glyph);
405 }
406 }
407 } else {
408 for (const Glyph& glyph : font_value.second) {
409 new_glyphs.emplace_back(scaled_font, glyph);
410 }
411 }
412 }
413 if (last_atlas->GetType() == type && new_glyphs.size() == 0) {
414 return last_atlas;
415 }
416
417 // ---------------------------------------------------------------------------
418 // Step 2: Determine if the additional missing glyphs can be appended to the
419 // existing bitmap without recreating the atlas. This requires that
420 // the type is identical.
421 // ---------------------------------------------------------------------------
422 std::vector<Rect> glyph_positions;
423 if (last_atlas->GetType() == type &&
424 CanAppendToExistingAtlas(last_atlas, new_glyphs, glyph_positions,
425 atlas_context->GetAtlasSize(),
426 atlas_context->GetRectPacker())) {
427 // The old bitmap will be reused and only the additional glyphs will be
428 // added.
429
430 // ---------------------------------------------------------------------------
431 // Step 3a: Record the positions in the glyph atlas of the newly added
432 // glyphs.
433 // ---------------------------------------------------------------------------
434 for (size_t i = 0, count = glyph_positions.size(); i < count; i++) {
435 last_atlas->AddTypefaceGlyphPosition(new_glyphs[i], glyph_positions[i]);
436 }
437
438 // ---------------------------------------------------------------------------
439 // Step 4a: Draw new font-glyph pairs into the existing bitmap.
440 // ---------------------------------------------------------------------------
441 // auto bitmap = atlas_context->GetBitmap();
442 auto bitmap = atlas_context_stb.GetBitmap();
443 if (!UpdateAtlasBitmap(*last_atlas, bitmap, new_glyphs)) {
444 return nullptr;
445 }
446
447 // ---------------------------------------------------------------------------
448 // Step 5a: Update the existing texture with the updated bitmap.
449 // ---------------------------------------------------------------------------
450 if (!UpdateGlyphTextureAtlas(bitmap, last_atlas->GetTexture())) {
451 return nullptr;
452 }
453 return last_atlas;
454 }
455 // A new glyph atlas must be created.
456
457 // ---------------------------------------------------------------------------
458 // Step 3b: Get the optimum size of the texture atlas.
459 // ---------------------------------------------------------------------------
460 std::vector<FontGlyphPair> font_glyph_pairs;
461 font_glyph_pairs.reserve(std::accumulate(
462 font_glyph_map.begin(), font_glyph_map.end(), 0,
463 [](const int a, const auto& b) { return a + b.second.size(); }));
464 for (const auto& font_value : font_glyph_map) {
465 const ScaledFont& scaled_font = font_value.first;
466 for (const Glyph& glyph : font_value.second) {
467 font_glyph_pairs.push_back({scaled_font, glyph});
468 }
469 }
470 auto glyph_atlas = std::make_shared<GlyphAtlas>(type);
471 auto atlas_size = OptimumAtlasSizeForFontGlyphPairs(
472 font_glyph_pairs, //
473 glyph_positions, //
474 atlas_context, //
475 type, //
476 context.GetResourceAllocator()->GetMaxTextureSizeSupported() //
477 );
478
479 atlas_context->UpdateGlyphAtlas(glyph_atlas, atlas_size);
480 if (atlas_size.IsEmpty()) {
481 return nullptr;
482 }
483
484 // ---------------------------------------------------------------------------
485 // Step 4b: Find location of font-glyph pairs in the atlas. We have this from
486 // the last step. So no need to do create another rect packer. But just do a
487 // sanity check of counts. This could also be just an assertion as only a
488 // construction issue would cause such a failure.
489 // ---------------------------------------------------------------------------
490 if (glyph_positions.size() != font_glyph_pairs.size()) {
491 return nullptr;
492 }
493
494 // ---------------------------------------------------------------------------
495 // Step 5b: Record the positions in the glyph atlas.
496 // ---------------------------------------------------------------------------
497 {
498 size_t i = 0;
499 for (auto it = font_glyph_pairs.begin(); it != font_glyph_pairs.end();
500 ++i, ++it) {
501 glyph_atlas->AddTypefaceGlyphPosition(*it, glyph_positions[i]);
502 }
503 }
504
505 // ---------------------------------------------------------------------------
506 // Step 6b: Draw font-glyph pairs in the correct spot in the atlas.
507 // ---------------------------------------------------------------------------
508 auto bitmap = CreateAtlasBitmap(*glyph_atlas, atlas_size);
509 if (!bitmap) {
510 return nullptr;
511 }
512 atlas_context_stb.UpdateBitmap(bitmap);
513
514 // ---------------------------------------------------------------------------
515 // Step 7b: Upload the atlas as a texture.
516 // ---------------------------------------------------------------------------
517 PixelFormat format;
518 switch (type) {
519 case GlyphAtlas::Type::kAlphaBitmap:
520 format = PixelFormat::kA8UNormInt;
521 break;
522 case GlyphAtlas::Type::kColorBitmap:
523 format = DISABLE_COLOR_FONT_SUPPORT ? PixelFormat::kA8UNormInt
524 : PixelFormat::kR8G8B8A8UNormInt;
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::TRect::size
TSize< Type > size
Definition: rect.h:24
impeller::TPoint::y
Type y
Definition: point.h:24
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:21
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:47
impeller::FontGlyphAtlas
An object that can look up glyph locations within the GlyphAtlas for a particular typeface.
Definition: glyph_atlas.h:179
impeller::TypographerContextSTB::TypographerContextSTB
TypographerContextSTB()
Definition: typographer_context_stb.cc:33
impeller::Allocation::NextPowerOfTwoSize
static uint32_t NextPowerOfTwoSize(uint32_t x)
Definition: allocation.cc:42
impeller::CreateAtlasBitmap
static std::shared_ptr< SkBitmap > CreateAtlasBitmap(const GlyphAtlas &atlas, const ISize &atlas_size)
Definition: typographer_context_skia.cc:215
impeller::TextureDescriptor::format
PixelFormat format
Definition: texture_descriptor.h:42
impeller::ScaledFont::font
Font font
Definition: font_glyph_pair.h:24
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:43
impeller::FontGlyphMap
std::unordered_map< ScaledFont, std::unordered_set< Glyph > > FontGlyphMap
Definition: font_glyph_pair.h:28
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::IPoint16::x
int16_t x() const
Definition: rectangle_packer.h:14
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:188
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:12
kColorFontBitsPerPixel
constexpr auto kColorFontBitsPerPixel
Definition: typographer_context_stb.cc:20
impeller::IPoint16::y
int16_t y() const
Definition: rectangle_packer.h:15
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:78
impeller::Glyph
The glyph index in the typeface.
Definition: glyph.h:19
impeller::TSize
Definition: size.h:18
impeller::UpdateGlyphTextureAtlas
static bool UpdateGlyphTextureAtlas(std::shared_ptr< SkBitmap > bitmap, const std::shared_ptr< Texture > &texture)
Definition: typographer_context_skia.cc:256
impeller::FontGlyphPair::glyph
const Glyph & glyph
Definition: font_glyph_pair.h:38
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:37
impeller::GlyphAtlas::GetType
Type GetType() const
Describes how the glyphs are represented in the texture.
Definition: glyph_atlas.cc:49
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:272
impeller::Font::Metrics::point_size
Scalar point_size
Definition: font.h:34
impeller::TRect::origin
TPoint< Type > origin
Definition: rect.h:23
impeller::Glyph::index
uint16_t index
Definition: glyph.h:25
impeller::FontGlyphPair
A font along with a glyph in that font rendered at a particular scale.
Definition: font_glyph_pair.h:34
impeller::Font::GetMetrics
const Metrics & GetMetrics() const
Definition: font.cc:37
impeller::kPadding
constexpr auto kPadding
Definition: typographer_context_skia.cc:28
impeller::TSize::width
Type width
Definition: size.h:21
impeller::TPoint::x
Type x
Definition: point.h:23
impeller::ISize
TSize< int64_t > ISize
Definition: size.h:136
impeller::TextureDescriptor::size
ISize size
Definition: texture_descriptor.h:43
impeller::RectanglePacker::Factory
static RectanglePacker * Factory(int width, int height)
Return an empty packer with area specified by width and height.
Definition: rectangle_packer.cc:169
impeller::ScaledFont::scale
Scalar scale
Definition: font_glyph_pair.h:25
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::TypographerContextSTB::CreateGlyphAtlas
std::shared_ptr< GlyphAtlas > CreateGlyphAtlas(Context &context, GlyphAtlas::Type type, std::shared_ptr< GlyphAtlasContext > atlas_context, const FontGlyphMap &font_glyph_map) const override
Definition: typographer_context_stb.cc:376
impeller::Context
To do anything rendering related with Impeller, you need a context.
Definition: context.h:47
impeller::TextureDescriptor::GetByteSizeOfBaseMipLevel
constexpr size_t GetByteSizeOfBaseMipLevel() const
Definition: texture_descriptor.h:50
impeller::TypefaceSTB::kPointsToPixels
static constexpr float kPointsToPixels
Definition: typeface_stb.h:20
DISABLE_COLOR_FONT_SUPPORT
#define DISABLE_COLOR_FONT_SUPPORT
Definition: typographer_context_stb.cc:18
impeller::BackendCast< GlyphAtlasContextSTB, GlyphAtlasContext >::Cast
static GlyphAtlasContextSTB & Cast(GlyphAtlasContext &base)
Definition: backend_cast.h:14
impeller::IPoint16
Definition: rectangle_packer.h:13
impeller::PixelFormat::kA8UNormInt
@ kA8UNormInt
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:116
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:40
impeller::TSize::height
Type height
Definition: size.h:22
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:39
impeller::TSize::IsEmpty
constexpr bool IsEmpty() const
Definition: size.h:105
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:94
impeller::TSize< int64_t >::MakeWH
static constexpr TSize MakeWH(Type width, Type height)
Definition: size.h:33
impeller
Definition: aiks_context.cc:10
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:20
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:155
impeller::ScaledFont
A font and a scale. Used as a key that represents a typeface within a glyph atlas.
Definition: font_glyph_pair.h:23
impeller::TypographerContext::IsValid
virtual bool IsValid() const
Definition: typographer_context.cc:17