From 35c42b97f596d879208c09345952f393c401f625 Mon Sep 17 00:00:00 2001 From: Herb Derby Date: Fri, 10 Jul 2020 10:48:57 -0400 Subject: [PATCH] pullout text path drawing from drawGlyphRunList Change-Id: Icca951e2ce727a79b7973ab37ffc93b5e8cddf43 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/301859 Reviewed-by: Robert Phillips Commit-Queue: Herb Derby --- src/gpu/GrRenderTargetContext.cpp | 103 ++++++++++++++++-------------- src/gpu/GrRenderTargetContext.h | 8 +++ 2 files changed, 64 insertions(+), 47 deletions(-) diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index 31a57804d2..e2eb2599b4 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -424,6 +424,61 @@ static SkColor compute_canonical_color(const SkPaint& paint, bool lcd) { return canonicalColor; } +void GrRenderTargetContext::drawTextPaths(const GrClip* clip, + const SkMatrixProvider& viewMatrix, + const SkGlyphRunList& glyphRunList, + GrTextBlob::SubRun* subRun) { + SkASSERT(!subRun->paths().empty()); + SkPoint drawOrigin = glyphRunList.origin(); + const SkPaint& drawPaint = glyphRunList.paint(); + SkPaint runPaint{drawPaint}; + runPaint.setAntiAlias(subRun->isAntiAliased()); + // If there are shaders, blurs or styles, the path must be scaled into source + // space independently of the CTM. This allows the CTM to be correct for the + // different effects. + GrStyle style(runPaint); + + bool needsExactCTM = runPaint.getShader() + || style.applies() + || runPaint.getMaskFilter(); + + // Calculate the matrix that maps the path glyphs from their size in the strike to + // the graphics source space. + SkScalar scale = subRun->strikeSpec().strikeToSourceRatio(); + SkMatrix strikeToSource = SkMatrix::Scale(scale, scale); + strikeToSource.postTranslate(drawOrigin.x(), drawOrigin.y()); + if (!needsExactCTM) { + for (const auto& pathPos : subRun->paths()) { + const SkPath& path = pathPos.fPath; + const SkPoint pos = pathPos.fOrigin; // Transform the glyph to source space. + SkMatrix pathMatrix = strikeToSource; + pathMatrix.postTranslate(pos.x(), pos.y()); + SkPreConcatMatrixProvider strikeToDevice(viewMatrix, pathMatrix); + + GrStyledShape shape(path, drawPaint); + GrBlurUtils::drawShapeWithMaskFilter( + this->fContext, this, clip, runPaint, strikeToDevice, shape); + } + } else { + // Transform the path to device because the deviceMatrix must be unchanged to + // draw effect, filter or shader paths. + for (const auto& pathPos : subRun->paths()) { + const SkPath& path = pathPos.fPath; + const SkPoint pos = pathPos.fOrigin; + // Transform the glyph to source space. + SkMatrix pathMatrix = strikeToSource; + pathMatrix.postTranslate(pos.x(), pos.y()); + + SkPath deviceOutline; + path.transform(pathMatrix, &deviceOutline); + deviceOutline.setIsVolatile(true); + GrStyledShape shape(deviceOutline, drawPaint); + GrBlurUtils::drawShapeWithMaskFilter( + this->fContext, this, clip, runPaint, viewMatrix, shape); + } + } +} + void GrRenderTargetContext::drawGlyphRunList(const GrClip* clip, const SkMatrixProvider& matrixProvider, const SkGlyphRunList& glyphRunList) { @@ -505,53 +560,7 @@ void GrRenderTargetContext::drawGlyphRunList(const GrClip* clip, for (GrTextBlob::SubRun* subRun : blob->subRunList()) { if (subRun->drawAsPaths()) { - SkASSERT(!subRun->paths().empty()); - SkPaint runPaint{blobPaint}; - runPaint.setAntiAlias(subRun->isAntiAliased()); - // If there are shaders, blurs or styles, the path must be scaled into source - // space independently of the CTM. This allows the CTM to be correct for the - // different effects. - GrStyle style(runPaint); - - bool needsExactCTM = runPaint.getShader() - || style.applies() - || runPaint.getMaskFilter(); - - // Calculate the matrix that maps the path glyphs from their size in the strike to - // the graphics source space. - SkScalar scale = subRun->strikeSpec().strikeToSourceRatio(); - SkMatrix strikeToSource = SkMatrix::Scale(scale, scale); - strikeToSource.postTranslate(drawOrigin.x(), drawOrigin.y()); - if (!needsExactCTM) { - for (const auto& pathPos : subRun->paths()) { - const SkPath& path = pathPos.fPath; - const SkPoint pos = pathPos.fOrigin; // Transform the glyph to source space. - SkMatrix pathMatrix = strikeToSource; - pathMatrix.postTranslate(pos.x(), pos.y()); - SkPreConcatMatrixProvider strikeToDevice(matrixProvider, pathMatrix); - - GrStyledShape shape(path, blobPaint); - GrBlurUtils::drawShapeWithMaskFilter( - this->fContext, this, clip, runPaint, strikeToDevice, shape); - } - } else { - // Transform the path to device because the deviceMatrix must be unchanged to - // draw effect, filter or shader paths. - for (const auto& pathPos : subRun->paths()) { - const SkPath& path = pathPos.fPath; - const SkPoint pos = pathPos.fOrigin; - // Transform the glyph to source space. - SkMatrix pathMatrix = strikeToSource; - pathMatrix.postTranslate(pos.x(), pos.y()); - - SkPath deviceOutline; - path.transform(pathMatrix, &deviceOutline); - deviceOutline.setIsVolatile(true); - GrStyledShape shape(deviceOutline, blobPaint); - GrBlurUtils::drawShapeWithMaskFilter( - this->fContext, this, clip, runPaint, matrixProvider, shape); - } - } + this->drawTextPaths(clip, matrixProvider, glyphRunList, subRun); } else { // Handle the mask and distance field cases. SkASSERT(subRun->glyphCount() != 0); diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h index 556a4a9d08..1a70205b68 100644 --- a/src/gpu/GrRenderTargetContext.h +++ b/src/gpu/GrRenderTargetContext.h @@ -22,6 +22,7 @@ #include "src/gpu/GrSurfaceProxyView.h" #include "src/gpu/GrXferProcessor.h" #include "src/gpu/geometry/GrQuad.h" +#include "src/gpu/text/GrTextBlob.h" class GrBackendSemaphore; class GrClip; @@ -509,6 +510,13 @@ public: GrSamplerState::Filter, std::unique_ptr, const SkRect& dst); + /** + * Draw the paths for text. + */ + void drawTextPaths(const GrClip*, + const SkMatrixProvider& viewMatrix, + const SkGlyphRunList& glyphRunList, + GrTextBlob::SubRun* subRun); /** * Draws the src texture with no matrix. The dstRect is the dstPoint with the width and height