diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp index dce1faa442..ca5bac34df 100644 --- a/src/core/SkGlyphRun.cpp +++ b/src/core/SkGlyphRun.cpp @@ -828,11 +828,11 @@ static bool glyph_too_big_for_atlas(const SkGlyph& glyph) { return glyph.fWidth >= 256 || glyph.fHeight >= 256; } -template -void SkGlyphRunListDrawer::drawGlyphRunAsGlyphWithPathFallback( +template +void SkGlyphRunListDrawer::drawGlyphRunAsBMPWithPathFallback( SkGlyphCache* cache, const SkGlyphRun& glyphRun, SkPoint origin, const SkMatrix& deviceMatrix, - PerGlyph1 perGlyph, PerPath1 perPath) { + PerGlyphT perGlyph, PerPathT perPath) { auto eachGlyph = [cache, perGlyph{std::move(perGlyph)}, perPath{std::move(perPath)}] (const SkGlyph& glyph, SkPoint pt, SkPoint mappedPt) { @@ -852,6 +852,63 @@ void SkGlyphRunListDrawer::drawGlyphRunAsGlyphWithPathFallback( this->forEachMappedDrawableGlyph(glyphRun, origin, deviceMatrix, cache, eachGlyph); } +static SkRect rect_to_draw( + const SkGlyph& glyph, SkPoint origin, SkScalar textScale, GrGlyph::MaskStyle maskStyle) { + + SkScalar dx = SkIntToScalar(glyph.fLeft); + SkScalar dy = SkIntToScalar(glyph.fTop); + SkScalar width = SkIntToScalar(glyph.fWidth); + SkScalar height = SkIntToScalar(glyph.fHeight); + + if (maskStyle == GrGlyph::kDistance_MaskStyle) { + dx += SK_DistanceFieldInset; + dy += SK_DistanceFieldInset; + width -= 2 * SK_DistanceFieldInset; + height -= 2 * SK_DistanceFieldInset; + } + + dx *= textScale; + dy *= textScale; + width *= textScale; + height *= textScale; + + return SkRect::MakeXYWH(origin.x() + dx, origin.y() + dy, width, height); +} + +template +void SkGlyphRunListDrawer::drawGlyphRunAsSDFWithFallback( + SkGlyphCache* cache, const SkGlyphRun& glyphRun, + SkPoint origin, SkScalar textRatio, + PerSDFT perSDF, PerPathT perPath, PerFallbackT perFallback) { + + const SkPoint* positionCursor = glyphRun.positions().data(); + for (auto glyphID : glyphRun.shuntGlyphsIDs()) { + const SkGlyph& glyph = cache->getGlyphIDMetrics(glyphID); + SkPoint glyphPos = origin + *positionCursor++; + if (glyph.fWidth > 0) { + if (glyph.fMaskFormat == SkMask::kSDF_Format) { + + if (glyph_too_big_for_atlas(glyph)) { + SkRect glyphRect = + rect_to_draw(glyph, glyphPos, textRatio, + GrGlyph::kDistance_MaskStyle); + if (!glyphRect.isEmpty()) { + const SkPath* glyphPath = cache->findPath(glyph); + if (glyphPath != nullptr) { + perPath(glyphPath, glyph, glyphPos); + } + } + } else { + perSDF(glyph, glyphPos); + } + + } else { + perFallback(glyph, glyphPos); + } + } + } +} + GrColor generate_filtered_color(const SkPaint& paint, const GrColorSpaceInfo& colorSpaceInfo) { GrColor4f filteredColor = SkColorToUnpremulGrColor4f(paint.getColor(), colorSpaceInfo); if (paint.getColorFilter() != nullptr) { @@ -954,29 +1011,6 @@ void GrTextContext::drawGlyphRunList( clip, viewMatrix, origin.x(), origin.y()); } -static SkRect rect_to_draw( - const SkGlyph& glyph, SkPoint origin, SkScalar textScale, GrGlyph::MaskStyle maskStyle) { - - SkScalar dx = SkIntToScalar(glyph.fLeft); - SkScalar dy = SkIntToScalar(glyph.fTop); - SkScalar width = SkIntToScalar(glyph.fWidth); - SkScalar height = SkIntToScalar(glyph.fHeight); - - if (maskStyle == GrGlyph::kDistance_MaskStyle) { - dx += SK_DistanceFieldInset; - dy += SK_DistanceFieldInset; - width -= 2 * SK_DistanceFieldInset; - height -= 2 * SK_DistanceFieldInset; - } - - dx *= textScale; - dy *= textScale; - width *= textScale; - height *= textScale; - - return SkRect::MakeXYWH(origin.x() + dx, origin.y() + dy, width, height); -} - void GrTextContext::AppendGlyph(GrTextBlob* blob, int runIndex, GrGlyphCache* grGlyphCache, sk_sp* strike, @@ -1049,43 +1083,39 @@ void GrTextContext::regenerateGlyphRunList(GrTextBlob* cacheBlob, sk_sp currStrike; { + auto cache = cacheBlob->setupCache( runIndex, props, flags, distanceFieldPaint, nullptr); - const SkPoint* positionCursor = glyphRun.positions().data(); - for (auto glyphID : glyphRun.shuntGlyphsIDs()) { - const SkGlyph& glyph = cache->getGlyphIDMetrics(glyphID); - SkPoint glyphPos = origin + *positionCursor++; - if (glyph.fWidth > 0) { - if (glyph.fMaskFormat == SkMask::kSDF_Format) { + auto perSDF = + [cacheBlob, runIndex, glyphCache, &currStrike, + filteredColor, cache{cache.get()}, textRatio] + (const SkGlyph& glyph, SkPoint position) { + SkScalar sx = position.fX, + sy = position.fY; + AppendGlyph(cacheBlob, runIndex, glyphCache, &currStrike, + glyph, GrGlyph::kDistance_MaskStyle, sx, sy, + filteredColor, + cache, textRatio, true); + }; - SkScalar sx = glyphPos.fX, - sy = glyphPos.fY; + auto perPath = + [cacheBlob, runIndex, textRatio] + (const SkPath* path, const SkGlyph& glyph, SkPoint position) { + SkScalar sx = position.fX, + sy = position.fY; + cacheBlob->appendPathGlyph( + runIndex, *path, sx, sy, textRatio, false); + }; - if (glyph_too_big_for_atlas(glyph)) { - SkRect glyphRect = - rect_to_draw(glyph, glyphPos, textRatio, - GrGlyph::kDistance_MaskStyle); - if (!glyphRect.isEmpty()) { - const SkPath* glyphPath = cache->findPath(glyph); - if (glyphPath != nullptr) { - cacheBlob->appendPathGlyph( - runIndex, *glyphPath, sx, sy, textRatio, false); - } - } - } else { - AppendGlyph(cacheBlob, runIndex, glyphCache, &currStrike, - glyph, GrGlyph::kDistance_MaskStyle, sx, sy, - filteredColor, - cache.get(), textRatio, true); - } + auto perFallback = + [&fallbackTextHelper] + (const SkGlyph& glyph, SkPoint position) { + fallbackTextHelper.appendGlyph(glyph, glyph.getGlyphID(), position); + }; - } else { - // can't append non-SDF glyph to SDF batch, send to fallback - fallbackTextHelper.appendGlyph(glyph, glyphID, glyphPos); - } - } - } + glyphDrawer->drawGlyphRunAsSDFWithFallback( + cache.get(), glyphRun, origin, textRatio, perSDF, perPath, perFallback); } fallbackTextHelper.drawGlyphs( @@ -1156,7 +1186,7 @@ void GrTextContext::regenerateGlyphRunList(GrTextBlob* cacheBlob, runIndex, *path, sx, sy, SK_Scalar1, true); }; - glyphDrawer->drawGlyphRunAsGlyphWithPathFallback( + glyphDrawer->drawGlyphRunAsBMPWithPathFallback( cache.get(), glyphRun, origin, viewMatrix, perGlyph, perPath); } runIndex += 1; diff --git a/src/core/SkGlyphRun.h b/src/core/SkGlyphRun.h index b9039f74bb..b90c83efbf 100644 --- a/src/core/SkGlyphRun.h +++ b/src/core/SkGlyphRun.h @@ -133,11 +133,17 @@ public: //using PerGlyph = std::function; template - void drawGlyphRunAsGlyphWithPathFallback( + void drawGlyphRunAsBMPWithPathFallback( SkGlyphCache* cache, const SkGlyphRun& glyphRun, SkPoint origin, const SkMatrix& deviceMatrix, PerGlyphT perGlyph, PerPathT perPath); + template + void drawGlyphRunAsSDFWithFallback( + SkGlyphCache* cache, const SkGlyphRun& glyphRun, + SkPoint origin, SkScalar textRatio, + PerSDFT perSDF, PerPathT perPath, PerFallbackT perFallback); + private: static bool ShouldDrawAsPath(const SkPaint& paint, const SkMatrix& matrix); bool ensureBitmapBuffers(size_t runSize);