Flutter Engine
The Flutter Engine
Public Member Functions | Static Public Member Functions | List of all members
impeller::TypographerContextSTB Class Reference

#include <typographer_context_stb.h>

Inheritance diagram for impeller::TypographerContextSTB:
impeller::TypographerContext

Public Member Functions

 TypographerContextSTB ()
 
 ~TypographerContextSTB () override
 
std::shared_ptr< GlyphAtlasContextCreateGlyphAtlasContext (GlyphAtlas::Type type) const override
 
std::shared_ptr< GlyphAtlasCreateGlyphAtlas (Context &context, GlyphAtlas::Type type, HostBuffer &host_buffer, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const FontGlyphMap &font_glyph_map) const override
 
- Public Member Functions inherited from impeller::TypographerContext
virtual ~TypographerContext ()
 
virtual bool IsValid () const
 
virtual std::shared_ptr< GlyphAtlasContextCreateGlyphAtlasContext (GlyphAtlas::Type type) const =0
 
virtual std::shared_ptr< GlyphAtlasCreateGlyphAtlas (Context &context, GlyphAtlas::Type type, HostBuffer &host_buffer, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const FontGlyphMap &font_glyph_map) const =0
 

Static Public Member Functions

static std::unique_ptr< TypographerContextMake ()
 

Additional Inherited Members

- Protected Member Functions inherited from impeller::TypographerContext
 TypographerContext ()
 Create a new context to render text that talks to an underlying graphics context. More...
 

Detailed Description

Definition at line 15 of file typographer_context_stb.h.

Constructor & Destructor Documentation

◆ TypographerContextSTB()

impeller::TypographerContextSTB::TypographerContextSTB ( )

Definition at line 36 of file typographer_context_stb.cc.

TypographerContext()
Create a new context to render text that talks to an underlying graphics context.

◆ ~TypographerContextSTB()

impeller::TypographerContextSTB::~TypographerContextSTB ( )
overridedefault

Member Function Documentation

◆ CreateGlyphAtlas()

std::shared_ptr< GlyphAtlas > impeller::TypographerContextSTB::CreateGlyphAtlas ( Context context,
GlyphAtlas::Type  type,
HostBuffer host_buffer,
const std::shared_ptr< GlyphAtlasContext > &  atlas_context,
const FontGlyphMap font_glyph_map 
) const
overridevirtual

Implements impeller::TypographerContext.

Definition at line 399 of file typographer_context_stb.cc.

404 {
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 // ---------------------------------------------------------------------------
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}
int count
Definition: FontMgrTest.cpp:50
GLenum type
Wraps a closure that is invoked in the destructor unless released by the caller.
Definition: closure.h:32
static GlyphAtlasContextSTB & Cast(GlyphAtlasContext &base)
Definition: backend_cast.h:13
static bool b
struct MyStruct a[10]
uint32_t uint32_t * format
FlTexture * texture
Definition: bitmap.py:1
std::function< void()> closure
Definition: closure.h:14
static Rect ComputeGlyphSize(const SkFont &font, const SubpixelGlyph &glyph, Scalar scale)
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
static std::shared_ptr< BitmapSTB > CreateAtlasBitmap(const GlyphAtlas &atlas, const ISize &atlas_size)
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)
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)
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)
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)
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)
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:131
#define DISABLE_COLOR_FONT_SUPPORT

◆ CreateGlyphAtlasContext()

std::shared_ptr< GlyphAtlasContext > impeller::TypographerContextSTB::CreateGlyphAtlasContext ( GlyphAtlas::Type  type) const
overridevirtual

Implements impeller::TypographerContext.

Definition at line 41 of file typographer_context_stb.cc.

41 {
42 return std::make_shared<GlyphAtlasContextSTB>(type);
43}

◆ Make()

std::unique_ptr< TypographerContext > impeller::TypographerContextSTB::Make ( )
static

Definition at line 32 of file typographer_context_stb.cc.

32 {
33 return std::make_unique<TypographerContextSTB>();
34}

The documentation for this class was generated from the following files: