From f4f6bbfadac327619a3832acad9c8afe06629b55 Mon Sep 17 00:00:00 2001 From: Herb Derby Date: Fri, 27 Jul 2018 11:58:37 -0400 Subject: Duplicate drawDFPosText into drawDFGlyphRun This CL has duplicate code, but this should be a small CL to judge how glyphRuns will change the code. Change-Id: Ib4700aa9d19ae3811090796a2c59bbe746361202 Reviewed-on: https://skia-review.googlesource.com/144022 Auto-Submit: Herb Derby Commit-Queue: Brian Salomon Reviewed-by: Brian Salomon --- src/core/SkGlyphRun.h | 1 + src/gpu/SkGpuDevice.cpp | 2 + src/gpu/text/GrTextContext.cpp | 121 +++++++++++++++++++++++++++++++++++++++-- src/gpu/text/GrTextContext.h | 41 ++++++++++++++ 4 files changed, 161 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/core/SkGlyphRun.h b/src/core/SkGlyphRun.h index 1456e6c290..fc85c3ec03 100644 --- a/src/core/SkGlyphRun.h +++ b/src/core/SkGlyphRun.h @@ -209,6 +209,7 @@ public: const uint32_t* clusters() const { return fList[fIndex].clusters().data(); } uint32_t textSize() const { return fList[fIndex].text().size(); } const char* text() const { return fList[fIndex].text().data(); } + const SkGlyphRun& glyphRun() const { return fList[fIndex]; } bool isLCD() const { return fList[fIndex].paint().isLCDRenderText(); } diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 39704e5174..0686d61d18 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -1628,6 +1628,8 @@ void SkGpuDevice::drawAtlas(const SkImage* atlas, const SkRSXform xform[], void SkGpuDevice::drawPosText(const void* text, size_t byteLength, const SkScalar pos[], int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) { + + SK_ABORT("Oh no!!! There is not drawPosText for GPU device anymore!"); ASSERT_SINGLE_OWNER GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawPosText", fContext.get()); SkDEBUGCODE(this->validate();) diff --git a/src/gpu/text/GrTextContext.cpp b/src/gpu/text/GrTextContext.cpp index d57055a511..4631991985 100644 --- a/src/gpu/text/GrTextContext.cpp +++ b/src/gpu/text/GrTextContext.cpp @@ -196,12 +196,10 @@ void GrTextContext::regenerateGlyphRunList(GrTextBlob* cacheBlob, } cacheBlob->setRunPaintFlags(run, runPaint.skPaint().getFlags()); - SkASSERT(it.positioning() == SkTextBlobRunIterator::kFull_Positioning); if (CanDrawAsDistanceFields(runPaint, viewMatrix, props, shaderCaps.supportsDistanceFieldText(), fOptions)) { - this->drawDFPosText(cacheBlob, run, glyphCache, props, runPaint, - scalerContextFlags, viewMatrix, (const char*)it.glyphs(), - textLen, it.pos(), 2, origin); + this->drawDFGlyphRun(cacheBlob, run, glyphCache, props, runPaint, + scalerContextFlags, viewMatrix, it.glyphRun(), origin); } else { DrawBmpPosText(cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags, viewMatrix, (const char*)it.glyphs(), textLen, it.pos(), 2, @@ -577,6 +575,50 @@ void GrTextContext::drawDFPosText(GrTextBlob* blob, int runIndex, fallbackTextHelper.drawText(blob, runIndex, glyphCache, props, paint, scalerContextFlags); } +void GrTextContext::drawDFGlyphRun(GrTextBlob* blob, int runIndex, + GrGlyphCache* glyphCache, const SkSurfaceProps& props, + const GrTextUtils::Paint& paint, + SkScalerContextFlags scalerContextFlags, + const SkMatrix& viewMatrix, const SkGlyphRun& glyphRun, + const SkPoint& offset) const { + bool hasWCoord = viewMatrix.hasPerspective() || fOptions.fDistanceFieldVerticesAlwaysHaveW; + + // Setup distance field paint and text ratio + SkScalar textRatio; + SkPaint dfPaint(paint); + SkScalerContextFlags flags; + InitDistanceFieldPaint(blob, &dfPaint, viewMatrix, fOptions, &textRatio, &flags); + blob->setHasDistanceField(); + blob->setSubRunHasDistanceFields(runIndex, paint.skPaint().isLCDRenderText(), + paint.skPaint().isAntiAlias(), hasWCoord); + + FallbackGlyphRunHelper fallbackTextHelper(viewMatrix, paint, glyphCache->getGlyphSizeLimit(), + textRatio); + + sk_sp currStrike; + + { + auto cache = blob->setupCache(runIndex, props, flags, dfPaint, nullptr); + + const SkPoint* positionCursor = glyphRun.positions().data(); + for (auto glyphID : glyphRun.shuntGlyphsIDs()) { + const SkGlyph& glyph = cache->getGlyphIDMetrics(glyphID); + SkPoint glyphPos = offset + *positionCursor++; + if (glyph.fWidth > 0) { + if (glyph.fMaskFormat == SkMask::kSDF_Format) { + DfAppendGlyph(blob, runIndex, glyphCache, &currStrike, glyph, glyphPos.fX, + glyphPos.fY, paint.filteredPremulColor(), cache.get(), textRatio); + } else { + // can't append non-SDF glyph to SDF batch, send to fallback + fallbackTextHelper.appendText(glyph, glyphID, glyphPos); + } + } + } + } + + fallbackTextHelper.drawText(blob, runIndex, glyphCache, props, paint, scalerContextFlags); +} + // TODO: merge with BmpAppendGlyph void GrTextContext::DfAppendGlyph(GrTextBlob* blob, int runIndex, GrGlyphCache* grGlyphCache, sk_sp* strike, @@ -689,6 +731,77 @@ void GrTextContext::FallbackTextHelper::initializeForDraw(SkPaint* paint, SkScal /////////////////////////////////////////////////////////////////////////////////////////////////// +void GrTextContext::FallbackGlyphRunHelper::appendText( + const SkGlyph& glyph, SkGlyphID glyphID, SkPoint glyphPos) { + SkScalar maxDim = SkTMax(glyph.fWidth, glyph.fHeight)*fTextRatio; + if (SkScalarNearlyZero(maxDim)) return; + + if (!fUseTransformedFallback) { + if (!fViewMatrix.isScaleTranslate() || maxDim*fMaxScale > fMaxTextSize) { + fUseTransformedFallback = true; + fMaxTextSize -= 2; // Subtract 2 to account for the bilerp pad around the glyph + } + } + + fFallbackTxt.push_back(glyphID); + if (fUseTransformedFallback) { + // If there's a glyph in the font that's particularly large, it's possible + // that fScaledFallbackTextSize may end up minimizing too much. We'd rather skip + // that glyph than make the others blurry, so we set a minimum size of half the + // maximum text size to avoid this case. + SkScalar glyphTextSize = + SkTMax(SkScalarFloorToScalar(fTextSize * fMaxTextSize/maxDim), 0.5f*fMaxTextSize); + fTransformedFallbackTextSize = SkTMin(glyphTextSize, fTransformedFallbackTextSize); + } + fFallbackPos.push_back(glyphPos); +} + +void GrTextContext::FallbackGlyphRunHelper::drawText( + GrTextBlob* blob, int runIndex, GrGlyphCache* glyphCache, const SkSurfaceProps& props, + const GrTextUtils::Paint& paint, SkScalerContextFlags scalerContextFlags) { + if (!fFallbackTxt.empty()) { + blob->initOverride(runIndex); + blob->setHasBitmap(); + blob->setSubRunHasW(runIndex, fViewMatrix.hasPerspective()); + const SkPaint& skPaint = paint.skPaint(); + SkColor textColor = paint.filteredPremulColor(); + + SkScalar textRatio = SK_Scalar1; + SkPaint fallbackPaint(skPaint); + SkMatrix matrix = fViewMatrix; + this->initializeForDraw(&fallbackPaint, &textRatio, &matrix); + SkExclusiveStrikePtr cache = + blob->setupCache(runIndex, props, scalerContextFlags, fallbackPaint, &matrix); + + sk_sp currStrike; + auto glyphPos = fFallbackPos.begin(); + for (auto glyphID : fFallbackTxt) { + const SkGlyph& glyph = cache->getGlyphIDMetrics(glyphID); + if (!fUseTransformedFallback) { + fViewMatrix.mapPoints(&*glyphPos, 1); + glyphPos->fX = SkScalarFloorToScalar(glyphPos->fX); + glyphPos->fY = SkScalarFloorToScalar(glyphPos->fY); + } + GrTextContext::BmpAppendGlyph(blob, runIndex, glyphCache, &currStrike, glyph, + glyphPos->fX, glyphPos->fY, textColor, + cache.get(), textRatio, fUseTransformedFallback); + glyphPos++; + } + } +} + +void GrTextContext::FallbackGlyphRunHelper::initializeForDraw( + SkPaint* paint, SkScalar* textRatio, SkMatrix* matrix) const { + if (!fUseTransformedFallback) return; + + paint->setTextSize(fTransformedFallbackTextSize); + *textRatio = fTextSize / fTransformedFallbackTextSize; + *matrix = SkMatrix::I(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + + #if GR_TEST_UTILS #include "GrRenderTargetContext.h" diff --git a/src/gpu/text/GrTextContext.h b/src/gpu/text/GrTextContext.h index 0093f846b4..7c8c576041 100644 --- a/src/gpu/text/GrTextContext.h +++ b/src/gpu/text/GrTextContext.h @@ -107,6 +107,41 @@ public: bool fUseTransformedFallback; }; + class FallbackGlyphRunHelper { + public: + FallbackGlyphRunHelper(const SkMatrix& viewMatrix, + const SkPaint& pathPaint, + SkScalar maxTextSize, + SkScalar textRatio) + : fViewMatrix(viewMatrix) + , fTextSize(pathPaint.getTextSize()) + , fMaxTextSize(maxTextSize) + , fTextRatio(textRatio) + , fTransformedFallbackTextSize(fMaxTextSize) + , fUseTransformedFallback(false) { + fMaxScale = viewMatrix.getMaxScale(); + } + + void appendText(const SkGlyph& glyph, SkGlyphID, SkPoint glyphPos); + void drawText(GrTextBlob* blob, int runIndex, GrGlyphCache*, const SkSurfaceProps&, + const GrTextUtils::Paint&, SkScalerContextFlags); + + void initializeForDraw(SkPaint* paint, SkScalar* textRatio, SkMatrix* matrix) const; + const std::vector& fallbackText() const { return fFallbackTxt; } + + private: + std::vector fFallbackTxt; + std::vector fFallbackPos; + + const SkMatrix& fViewMatrix; + SkScalar fTextSize; + SkScalar fMaxTextSize; + SkScalar fTextRatio; + SkScalar fTransformedFallbackTextSize; + SkScalar fMaxScale; + bool fUseTransformedFallback; + }; + private: GrTextContext(const Options& options); @@ -158,6 +193,12 @@ private: size_t byteLength, const SkScalar pos[], int scalarsPerPosition, const SkPoint& offset) const; + void drawDFGlyphRun(GrTextBlob* blob, int runIndex, GrGlyphCache*, + const SkSurfaceProps&, const GrTextUtils::Paint& paint, + SkScalerContextFlags scalerContextFlags, + const SkMatrix& viewMatrix, const SkGlyphRun& glyphRun, + const SkPoint& offset) const; + static void BmpAppendGlyph(GrTextBlob*, int runIndex, GrGlyphCache*, sk_sp*, const SkGlyph&, SkScalar sx, SkScalar sy, GrColor color, SkGlyphCache*, SkScalar textRatio, bool needsXform); -- cgit v1.2.3