diff --git a/src/core/SkGlyphRunPainter.cpp b/src/core/SkGlyphRunPainter.cpp index dc42aa60b8..7bd2487356 100644 --- a/src/core/SkGlyphRunPainter.cpp +++ b/src/core/SkGlyphRunPainter.cpp @@ -520,20 +520,28 @@ void GrTextContext::regenerateGlyphRunList(GrTextBlob* cacheBlob, auto cache = SkStrikeCache::FindOrCreateStrikeExclusive( pathPaint, &props, SkScalerContextFlags::kFakeGammaAndBoostContrast, nullptr); - auto drawOnePath = - [&fallbackTextHelper, matrixScale, runIndex, cacheBlob] - (const SkPath* path, const SkGlyph& glyph, SkPoint position) { - if (glyph.fMaskFormat == SkMask::kARGB32_Format) { - fallbackTextHelper.appendGlyph(glyph, glyph.getGlyphID(), position); - } else { - if (path != nullptr) { - cacheBlob->appendPathGlyph( - runIndex, *path, position.fX, position.fY, matrixScale, false); - } - } - }; + auto perPath = [matrixScale, runIndex, cacheBlob, &cache] + (const SkGlyph& glyph, SkPoint position) { + const SkPath* path = cache->findPath(glyph); + if (path != nullptr) { + cacheBlob->appendPathGlyph( + runIndex, *path, position.fX, position.fY, matrixScale, false); + } + }; - glyphPainter->drawUsingPaths(glyphRun, origin, cache.get(), drawOnePath); + auto fallbackARGB = [cache{cache.get()}, &fallbackTextHelper] + (SkSpan glyphIDs, + SkSpanpositions) { + const SkPoint* pos = positions.data(); + for (auto glyphID : glyphIDs) { + SkPoint position = *pos++; + const SkGlyph& glyph = cache->getGlyphMetrics(glyphID, {0, 0}); + fallbackTextHelper.appendGlyph(glyph, glyph.getGlyphID(), position); + } + }; + + glyphPainter->drawGlyphRunAsPathWithARGBFallback( + cache.get(), glyphRun, origin, perPath, fallbackARGB); fallbackTextHelper.drawGlyphs( cacheBlob, runIndex, glyphCache, props, diff --git a/src/core/SkGlyphRunPainter.h b/src/core/SkGlyphRunPainter.h index 5e679499a9..ca3e5c4662 100644 --- a/src/core/SkGlyphRunPainter.h +++ b/src/core/SkGlyphRunPainter.h @@ -40,13 +40,23 @@ public: void drawUsingPaths( const SkGlyphRun& glyphRun, SkPoint origin, SkGlyphCache* cache, PerPath perPath) const; - //using PerGlyph = std::function; template void drawGlyphRunAsBMPWithPathFallback( SkGlyphCacheInterface* cache, const SkGlyphRun& glyphRun, SkPoint origin, const SkMatrix& deviceMatrix, PerGlyphT perGlyph, PerPathT perPath); + // Draw glyphs as paths with fallback to scaled ARGB glyphs if color is needed. + // PerPath - perPath(const SkGlyph&, SkPoint position) + // FallbackARGB - fallbackARGB(SkSpan, SkSpan) + // For each glyph that is not ARGB call perPath. If the glyph is ARGB then store the glyphID + // and the position in fallback vectors. After all the glyphs are processed, pass the + // fallback glyphIDs and positions to fallbackARGB. + template + void drawGlyphRunAsPathWithARGBFallback( + SkGlyphCacheInterface* cache, const SkGlyphRun& glyphRun, + SkPoint origin, PerPath perPath, FallbackARGB fallbackARGB); + template void drawGlyphRunAsSDFWithFallback( SkGlyphCache* cache, const SkGlyphRun& glyphRun, @@ -133,6 +143,35 @@ void SkGlyphRunListPainter::forEachMappedDrawableGlyph( } } +template +void SkGlyphRunListPainter::drawGlyphRunAsPathWithARGBFallback( + SkGlyphCacheInterface* cache, const SkGlyphRun& glyphRun, + SkPoint origin, PerPathT perPath, FallbackARGB fallbackARGB) { + std::vector fallbackGlyphIDs; + std::vector fallbackPositions; + + auto eachGlyph = + [cache, origin, perPath{std::move(perPath)}, &fallbackGlyphIDs, &fallbackPositions] + (SkGlyphID glyphID, SkPoint position) { + if (SkScalarsAreFinite(position.x(), position.y())) { + const SkGlyph& glyph = cache->getGlyphMetrics(glyphID, {0, 0}); + if (!glyph.isEmpty()) { + if (glyph.fMaskFormat != SkMask::kARGB32_Format) { + perPath(glyph, origin + position); + } else { + fallbackGlyphIDs.push_back(glyphID); + fallbackPositions.push_back(position); + } + } + } + }; + + glyphRun.forEachGlyphAndPosition(eachGlyph); + + fallbackARGB(SkSpan{fallbackGlyphIDs}, + SkSpan{fallbackPositions}); +} + template void SkGlyphRunListPainter::drawGlyphRunAsBMPWithPathFallback( SkGlyphCacheInterface* cache, const SkGlyphRun& glyphRun,