aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/text/GrTextContext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/text/GrTextContext.cpp')
-rw-r--r--src/gpu/text/GrTextContext.cpp121
1 files changed, 117 insertions, 4 deletions
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<GrTextStrike> 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<GrTextStrike>* 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<GrTextStrike> 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"