Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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 () const override
 
std::shared_ptr< GlyphAtlasCreateGlyphAtlas (Context &context, GlyphAtlas::Type type, 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
 

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.
 

Detailed Description

Definition at line 15 of file typographer_context_stb.h.

Constructor & Destructor Documentation

◆ TypographerContextSTB()

impeller::TypographerContextSTB::TypographerContextSTB ( )

Definition at line 33 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,
const std::shared_ptr< GlyphAtlasContext > &  atlas_context,
const FontGlyphMap font_glyph_map 
) const
overridevirtual

Implements impeller::TypographerContext.

Definition at line 370 of file typographer_context_stb.cc.

374 {
375 TRACE_EVENT0("impeller", __FUNCTION__);
376 if (!IsValid()) {
377 return nullptr;
378 }
379 auto& atlas_context_stb = GlyphAtlasContextSTB::Cast(*atlas_context);
380 std::shared_ptr<GlyphAtlas> last_atlas = atlas_context->GetGlyphAtlas();
381
382 if (font_glyph_map.empty()) {
383 return last_atlas;
384 }
385
386 // ---------------------------------------------------------------------------
387 // Step 1: Determine if the atlas type and font glyph pairs are compatible
388 // with the current atlas and reuse if possible.
389 // ---------------------------------------------------------------------------
390 std::vector<FontGlyphPair> new_glyphs;
391 for (const auto& font_value : font_glyph_map) {
392 const ScaledFont& scaled_font = font_value.first;
393 const FontGlyphAtlas* font_glyph_atlas =
394 last_atlas->GetFontGlyphAtlas(scaled_font.font, scaled_font.scale);
395 if (font_glyph_atlas) {
396 for (const Glyph& glyph : font_value.second) {
397 if (!font_glyph_atlas->FindGlyphBounds(glyph)) {
398 new_glyphs.emplace_back(scaled_font, glyph);
399 }
400 }
401 } else {
402 for (const Glyph& glyph : font_value.second) {
403 new_glyphs.emplace_back(scaled_font, glyph);
404 }
405 }
406 }
407 if (last_atlas->GetType() == type && new_glyphs.size() == 0) {
408 return last_atlas;
409 }
410
411 // ---------------------------------------------------------------------------
412 // Step 2: Determine if the additional missing glyphs can be appended to the
413 // existing bitmap without recreating the atlas. This requires that
414 // the type is identical.
415 // ---------------------------------------------------------------------------
416 std::vector<Rect> glyph_positions;
417 if (last_atlas->GetType() == type &&
418 CanAppendToExistingAtlas(last_atlas, new_glyphs, glyph_positions,
419 atlas_context->GetAtlasSize(),
420 atlas_context->GetRectPacker())) {
421 // The old bitmap will be reused and only the additional glyphs will be
422 // added.
423
424 // ---------------------------------------------------------------------------
425 // Step 3a: Record the positions in the glyph atlas of the newly added
426 // glyphs.
427 // ---------------------------------------------------------------------------
428 for (size_t i = 0, count = glyph_positions.size(); i < count; i++) {
429 last_atlas->AddTypefaceGlyphPosition(new_glyphs[i], glyph_positions[i]);
430 }
431
432 // ---------------------------------------------------------------------------
433 // Step 4a: Draw new font-glyph pairs into the existing bitmap.
434 // ---------------------------------------------------------------------------
435 // auto bitmap = atlas_context->GetBitmap();
436 auto bitmap = atlas_context_stb.GetBitmap();
437 if (!UpdateAtlasBitmap(*last_atlas, bitmap, new_glyphs)) {
438 return nullptr;
439 }
440
441 // ---------------------------------------------------------------------------
442 // Step 5a: Update the existing texture with the updated bitmap.
443 // ---------------------------------------------------------------------------
444 if (!UpdateGlyphTextureAtlas(bitmap, last_atlas->GetTexture())) {
445 return nullptr;
446 }
447 return last_atlas;
448 }
449 // A new glyph atlas must be created.
450
451 // ---------------------------------------------------------------------------
452 // Step 3b: Get the optimum size of the texture atlas.
453 // ---------------------------------------------------------------------------
454 std::vector<FontGlyphPair> font_glyph_pairs;
455 font_glyph_pairs.reserve(std::accumulate(
456 font_glyph_map.begin(), font_glyph_map.end(), 0,
457 [](const int a, const auto& b) { return a + b.second.size(); }));
458 for (const auto& font_value : font_glyph_map) {
459 const ScaledFont& scaled_font = font_value.first;
460 for (const Glyph& glyph : font_value.second) {
461 font_glyph_pairs.push_back({scaled_font, glyph});
462 }
463 }
464 auto glyph_atlas = std::make_shared<GlyphAtlas>(type);
465 auto atlas_size = OptimumAtlasSizeForFontGlyphPairs(
466 font_glyph_pairs, //
467 glyph_positions, //
468 atlas_context, //
469 type, //
470 context.GetResourceAllocator()->GetMaxTextureSizeSupported() //
471 );
472
473 atlas_context->UpdateGlyphAtlas(glyph_atlas, atlas_size);
474 if (atlas_size.IsEmpty()) {
475 return nullptr;
476 }
477
478 // ---------------------------------------------------------------------------
479 // Step 4b: Find location of font-glyph pairs in the atlas. We have this from
480 // the last step. So no need to do create another rect packer. But just do a
481 // sanity check of counts. This could also be just an assertion as only a
482 // construction issue would cause such a failure.
483 // ---------------------------------------------------------------------------
484 if (glyph_positions.size() != font_glyph_pairs.size()) {
485 return nullptr;
486 }
487
488 // ---------------------------------------------------------------------------
489 // Step 5b: Record the positions in the glyph atlas.
490 // ---------------------------------------------------------------------------
491 {
492 size_t i = 0;
493 for (auto it = font_glyph_pairs.begin(); it != font_glyph_pairs.end();
494 ++i, ++it) {
495 glyph_atlas->AddTypefaceGlyphPosition(*it, glyph_positions[i]);
496 }
497 }
498
499 // ---------------------------------------------------------------------------
500 // Step 6b: Draw font-glyph pairs in the correct spot in the atlas.
501 // ---------------------------------------------------------------------------
502 auto bitmap = CreateAtlasBitmap(*glyph_atlas, atlas_size);
503 if (!bitmap) {
504 return nullptr;
505 }
506 atlas_context_stb.UpdateBitmap(bitmap);
507
508 // ---------------------------------------------------------------------------
509 // Step 7b: Upload the atlas as a texture.
510 // ---------------------------------------------------------------------------
511 PixelFormat format;
512 switch (type) {
514 format = context.GetCapabilities()->GetDefaultGlyphAtlasFormat();
515 break;
518 ? context.GetCapabilities()->GetDefaultGlyphAtlasFormat()
520 break;
521 }
522 auto texture = UploadGlyphTextureAtlas(context.GetResourceAllocator(), bitmap,
523 atlas_size, format);
524 if (!texture) {
525 return nullptr;
526 }
527
528 // ---------------------------------------------------------------------------
529 // Step 8b: Record the texture in the glyph atlas.
530 // ---------------------------------------------------------------------------
531 glyph_atlas->SetTexture(std::move(texture));
532
533 return glyph_atlas;
534}
int count
static GlyphAtlasContextSTB & Cast(GlyphAtlasContext &base)
static bool b
struct MyStruct a[10]
uint32_t uint32_t * format
FlTexture * texture
static std::shared_ptr< Texture > UploadGlyphTextureAtlas(const std::shared_ptr< Allocator > &allocator, std::shared_ptr< SkBitmap > bitmap, const ISize &atlas_size, PixelFormat format)
static std::shared_ptr< SkBitmap > 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< SkBitmap > bitmap, const std::shared_ptr< Texture > &texture)
static bool UpdateAtlasBitmap(const GlyphAtlas &atlas, const std::shared_ptr< SkBitmap > &bitmap, const std::vector< FontGlyphPair > &new_pairs)
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)
#define DISABLE_COLOR_FONT_SUPPORT

◆ CreateGlyphAtlasContext()

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

Implements impeller::TypographerContext.

Definition at line 38 of file typographer_context_stb.cc.

38 {
39 return std::make_shared<GlyphAtlasContextSTB>();
40}

◆ Make()

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

Definition at line 29 of file typographer_context_stb.cc.

29 {
30 return std::make_unique<TypographerContextSTB>();
31}

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