| 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 = 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 &&
297 !DISABLE_COLOR_FONT_SUPPORT) {
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) {
518 case GlyphAtlas::Type::kAlphaBitmap:
519 format = context.GetCapabilities()->GetDefaultGlyphAtlasFormat();
520 break;
521 case GlyphAtlas::Type::kColorBitmap:
522 format = DISABLE_COLOR_FONT_SUPPORT
523 ? context.GetCapabilities()->GetDefaultGlyphAtlasFormat()
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::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