@@ -282,8 +282,7 @@ static bool BulkUpdateAtlasBitmap(const GlyphAtlas& atlas,
282
282
if (!data.has_value ()) {
283
283
continue ;
284
284
}
285
- auto [pos, bounds, placeholder] = data.value ();
286
- FML_DCHECK (!placeholder);
285
+ auto [pos, bounds] = data.value ();
287
286
Size size = pos.GetSize ();
288
287
if (size.IsEmpty ()) {
289
288
continue ;
@@ -326,9 +325,7 @@ static bool UpdateAtlasBitmap(const GlyphAtlas& atlas,
326
325
if (!data.has_value ()) {
327
326
continue ;
328
327
}
329
- auto [pos, bounds, placeholder] = data.value ();
330
- FML_DCHECK (!placeholder);
331
-
328
+ auto [pos, bounds] = data.value ();
332
329
Size size = pos.GetSize ();
333
330
if (size.IsEmpty ()) {
334
331
continue ;
@@ -405,88 +402,61 @@ static Rect ComputeGlyphSize(const SkFont& font,
405
402
scaled_bounds.fBottom );
406
403
};
407
404
408
- std::pair<std::vector<FontGlyphPair>, std::vector<Rect>>
409
- TypographerContextSkia::CollectNewGlyphs (
410
- const std::shared_ptr<GlyphAtlas>& atlas,
411
- const std::vector<std::shared_ptr<TextFrame>>& text_frames) {
412
- std::vector<FontGlyphPair> new_glyphs;
413
- std::vector<Rect> glyph_sizes;
414
- for (const auto & frame : text_frames) {
415
- // TODO(jonahwilliams): unless we destroy the atlas (which we know about),
416
- // we could probably guarantee that a text frame that is complete does not
417
- // need to be processed unless the scale or properties changed. I'm leaving
418
- // this as a future optimization.
419
- frame->ClearFrameBounds ();
420
-
421
- for (const auto & run : frame->GetRuns ()) {
422
- auto metrics = run.GetFont ().GetMetrics ();
423
-
424
- auto rounded_scale =
425
- TextFrame::RoundScaledFontSize (frame->GetScale (), metrics.point_size );
426
- ScaledFont scaled_font{.font = run.GetFont (), .scale = rounded_scale};
427
-
428
- FontGlyphAtlas* font_glyph_atlas =
429
- atlas->GetOrCreateFontGlyphAtlas (scaled_font);
430
- FML_DCHECK (!!font_glyph_atlas);
431
-
432
- SkFont sk_font (
433
- TypefaceSkia::Cast (*scaled_font.font .GetTypeface ()).GetSkiaTypeface (),
434
- metrics.point_size , metrics.scaleX , metrics.skewX );
435
- sk_font.setEdging (SkFont::Edging::kAntiAlias );
436
- sk_font.setHinting (SkFontHinting::kSlight );
437
- sk_font.setEmbolden (metrics.embolden );
438
- // Rather than computing the bounds at the requested point size and
439
- // scaling up the bounds, we scale up the font size and request the
440
- // bounds. This seems to give more accurate bounds information.
441
- sk_font.setSize (sk_font.getSize () * scaled_font.scale );
442
- sk_font.setSubpixel (true );
443
-
444
- for (const auto & glyph_position : run.GetGlyphPositions ()) {
445
- Point subpixel = TextFrame::ComputeSubpixelPosition (
446
- glyph_position, scaled_font.font .GetAxisAlignment (),
447
- frame->GetOffset (), rounded_scale);
448
- SubpixelGlyph subpixel_glyph (glyph_position.glyph , subpixel,
449
- frame->GetProperties ());
450
- const auto & font_glyph_bounds =
451
- font_glyph_atlas->FindGlyphBounds (subpixel_glyph);
452
-
453
- if (!font_glyph_bounds.has_value ()) {
454
- new_glyphs.push_back (FontGlyphPair{scaled_font, subpixel_glyph});
455
- auto glyph_bounds =
456
- ComputeGlyphSize (sk_font, subpixel_glyph, scaled_font.scale );
457
- glyph_sizes.push_back (glyph_bounds);
458
-
459
- auto frame_bounds = FrameBounds{
460
- Rect::MakeLTRB (0 , 0 , 0 , 0 ), //
461
- glyph_bounds, //
462
- /* placeholder=*/ true //
463
- };
464
-
465
- frame->AppendFrameBounds (frame_bounds);
466
- font_glyph_atlas->AppendGlyph (subpixel_glyph, frame_bounds);
467
- } else {
468
- frame->AppendFrameBounds (font_glyph_bounds.value ());
405
+ static void CollectNewGlyphs (const std::shared_ptr<GlyphAtlas>& atlas,
406
+ const FontGlyphMap& font_glyph_map,
407
+ std::vector<FontGlyphPair>& new_glyphs,
408
+ std::vector<Rect>& glyph_sizes) {
409
+ for (const auto & font_value : font_glyph_map) {
410
+ const ScaledFont& scaled_font = font_value.first ;
411
+ const FontGlyphAtlas* font_glyph_atlas =
412
+ atlas->GetFontGlyphAtlas (scaled_font.font , scaled_font.scale );
413
+
414
+ auto metrics = scaled_font.font .GetMetrics ();
415
+
416
+ SkFont sk_font (
417
+ TypefaceSkia::Cast (*scaled_font.font .GetTypeface ()).GetSkiaTypeface (),
418
+ metrics.point_size , metrics.scaleX , metrics.skewX );
419
+ sk_font.setEdging (SkFont::Edging::kAntiAlias );
420
+ sk_font.setHinting (SkFontHinting::kSlight );
421
+ sk_font.setEmbolden (metrics.embolden );
422
+ // Rather than computing the bounds at the requested point size and scaling
423
+ // up the bounds, we scale up the font size and request the bounds. This
424
+ // seems to give more accurate bounds information.
425
+ sk_font.setSize (sk_font.getSize () * scaled_font.scale );
426
+ sk_font.setSubpixel (true );
427
+
428
+ if (font_glyph_atlas) {
429
+ for (const SubpixelGlyph& glyph : font_value.second ) {
430
+ if (!font_glyph_atlas->FindGlyphBounds (glyph)) {
431
+ new_glyphs.emplace_back (scaled_font, glyph);
432
+ glyph_sizes.push_back (
433
+ ComputeGlyphSize (sk_font, glyph, scaled_font.scale ));
469
434
}
470
435
}
436
+ } else {
437
+ for (const SubpixelGlyph& glyph : font_value.second ) {
438
+ new_glyphs.emplace_back (scaled_font, glyph);
439
+ glyph_sizes.push_back (
440
+ ComputeGlyphSize (sk_font, glyph, scaled_font.scale ));
441
+ }
471
442
}
472
443
}
473
- return {std::move (new_glyphs), std::move (glyph_sizes)};
474
444
}
475
445
476
446
std::shared_ptr<GlyphAtlas> TypographerContextSkia::CreateGlyphAtlas (
477
447
Context& context,
478
448
GlyphAtlas::Type type,
479
449
HostBuffer& host_buffer,
480
450
const std::shared_ptr<GlyphAtlasContext>& atlas_context,
481
- const std::vector<std::shared_ptr<TextFrame>>& text_frames ) const {
451
+ const FontGlyphMap& font_glyph_map ) const {
482
452
TRACE_EVENT0 (" impeller" , __FUNCTION__);
483
453
if (!IsValid ()) {
484
454
return nullptr ;
485
455
}
486
456
std::shared_ptr<GlyphAtlas> last_atlas = atlas_context->GetGlyphAtlas ();
487
457
FML_DCHECK (last_atlas->GetType () == type);
488
458
489
- if (text_frames .empty ()) {
459
+ if (font_glyph_map .empty ()) {
490
460
return last_atlas;
491
461
}
492
462
@@ -495,7 +465,9 @@ std::shared_ptr<GlyphAtlas> TypographerContextSkia::CreateGlyphAtlas(
495
465
// with the current atlas and reuse if possible. For each new font and
496
466
// glyph pair, compute the glyph size at scale.
497
467
// ---------------------------------------------------------------------------
498
- auto [new_glyphs, glyph_sizes] = CollectNewGlyphs (last_atlas, text_frames);
468
+ std::vector<FontGlyphPair> new_glyphs;
469
+ std::vector<Rect> glyph_sizes;
470
+ CollectNewGlyphs (last_atlas, font_glyph_map, new_glyphs, glyph_sizes);
499
471
if (new_glyphs.size () == 0 ) {
500
472
return last_atlas;
501
473
}
@@ -564,11 +536,9 @@ std::shared_ptr<GlyphAtlas> TypographerContextSkia::CreateGlyphAtlas(
564
536
blit_old_atlas = false ;
565
537
new_atlas = std::make_shared<GlyphAtlas>(type);
566
538
567
- auto [update_glyphs, update_sizes] =
568
- CollectNewGlyphs (new_atlas, text_frames);
569
- new_glyphs = std::move (update_glyphs);
570
- glyph_sizes = std::move (update_sizes);
571
-
539
+ new_glyphs.clear ();
540
+ glyph_sizes.clear ();
541
+ CollectNewGlyphs (new_atlas, font_glyph_map, new_glyphs, glyph_sizes);
572
542
glyph_positions.clear ();
573
543
glyph_positions.reserve (new_glyphs.size ());
574
544
first_missing_index = 0 ;
0 commit comments