@@ -282,8 +282,7 @@ static bool BulkUpdateAtlasBitmap(const GlyphAtlas& atlas,
282282 if (!data.has_value ()) {
283283 continue ;
284284 }
285- auto [pos, bounds, placeholder] = data.value ();
286- FML_DCHECK (!placeholder);
285+ auto [pos, bounds] = data.value ();
287286 Size size = pos.GetSize ();
288287 if (size.IsEmpty ()) {
289288 continue ;
@@ -326,9 +325,7 @@ static bool UpdateAtlasBitmap(const GlyphAtlas& atlas,
326325 if (!data.has_value ()) {
327326 continue ;
328327 }
329- auto [pos, bounds, placeholder] = data.value ();
330- FML_DCHECK (!placeholder);
331-
328+ auto [pos, bounds] = data.value ();
332329 Size size = pos.GetSize ();
333330 if (size.IsEmpty ()) {
334331 continue ;
@@ -405,88 +402,61 @@ static Rect ComputeGlyphSize(const SkFont& font,
405402 scaled_bounds.fBottom );
406403};
407404
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 ));
469434 }
470435 }
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+ }
471442 }
472443 }
473- return {std::move (new_glyphs), std::move (glyph_sizes)};
474444}
475445
476446std::shared_ptr<GlyphAtlas> TypographerContextSkia::CreateGlyphAtlas (
477447 Context& context,
478448 GlyphAtlas::Type type,
479449 HostBuffer& host_buffer,
480450 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 {
482452 TRACE_EVENT0 (" impeller" , __FUNCTION__);
483453 if (!IsValid ()) {
484454 return nullptr ;
485455 }
486456 std::shared_ptr<GlyphAtlas> last_atlas = atlas_context->GetGlyphAtlas ();
487457 FML_DCHECK (last_atlas->GetType () == type);
488458
489- if (text_frames .empty ()) {
459+ if (font_glyph_map .empty ()) {
490460 return last_atlas;
491461 }
492462
@@ -495,7 +465,9 @@ std::shared_ptr<GlyphAtlas> TypographerContextSkia::CreateGlyphAtlas(
495465 // with the current atlas and reuse if possible. For each new font and
496466 // glyph pair, compute the glyph size at scale.
497467 // ---------------------------------------------------------------------------
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);
499471 if (new_glyphs.size () == 0 ) {
500472 return last_atlas;
501473 }
@@ -564,11 +536,9 @@ std::shared_ptr<GlyphAtlas> TypographerContextSkia::CreateGlyphAtlas(
564536 blit_old_atlas = false ;
565537 new_atlas = std::make_shared<GlyphAtlas>(type);
566538
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);
572542 glyph_positions.clear ();
573543 glyph_positions.reserve (new_glyphs.size ());
574544 first_missing_index = 0 ;
0 commit comments