diff options
-rw-r--r-- | expectations/gm/ignored-tests.txt | 12 | ||||
-rw-r--r-- | include/core/SkPaint.h | 1 | ||||
-rwxr-xr-x | src/gpu/GrBitmapTextContext.cpp | 92 | ||||
-rw-r--r-- | src/gpu/GrBitmapTextContext.h | 2 | ||||
-rwxr-xr-x | src/gpu/GrDistanceFieldTextContext.cpp | 88 | ||||
-rw-r--r-- | src/gpu/GrDistanceFieldTextContext.h | 2 | ||||
-rw-r--r-- | src/gpu/GrStencilAndCoverTextContext.cpp | 91 | ||||
-rw-r--r-- | src/gpu/GrStencilAndCoverTextContext.h | 3 | ||||
-rw-r--r-- | src/gpu/GrTextContext.cpp | 65 | ||||
-rw-r--r-- | src/gpu/GrTextContext.h | 2 |
10 files changed, 79 insertions, 279 deletions
diff --git a/expectations/gm/ignored-tests.txt b/expectations/gm/ignored-tests.txt index 5793ba217b..6469aa6e28 100644 --- a/expectations/gm/ignored-tests.txt +++ b/expectations/gm/ignored-tests.txt @@ -54,3 +54,15 @@ megalooper_0x0 megalooper_1x4 megalooper_4x1 imagefiltersbase + +# jvanverth https://codereview.chromium.org/653133004/ +fontscaler +fontmgr_iter +fontmgr_match +fontcache +typefacestyles_kerning +lcdtext +textblobshader +textblob +verttext + diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h index 9f477d867b..21ad3eab20 100644 --- a/include/core/SkPaint.h +++ b/include/core/SkPaint.h @@ -1102,6 +1102,7 @@ private: friend class SkDraw; friend class SkGraphics; // So Term() can be called. friend class SkPDFDevice; + friend class GrTextContext; friend class GrBitmapTextContext; friend class GrDistanceFieldTextContext; friend class GrStencilAndCoverTextContext; diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp index fa70d3270b..a1196dc494 100755 --- a/src/gpu/GrBitmapTextContext.cpp +++ b/src/gpu/GrBitmapTextContext.cpp @@ -16,7 +16,6 @@ #include "GrTextStrike_impl.h" #include "effects/GrCustomCoordsTextureEffect.h" -#include "SkAutoKern.h" #include "SkColorPriv.h" #include "SkDraw.h" #include "SkDrawProcs.h" @@ -91,97 +90,6 @@ inline void GrBitmapTextContext::init(const GrPaint& paint, const SkPaint& skPai fMaxVertices = 0; } -void GrBitmapTextContext::onDrawText(const GrPaint& paint, const SkPaint& skPaint, - const char text[], size_t byteLength, - SkScalar x, SkScalar y) { - SkASSERT(byteLength == 0 || text != NULL); - - // nothing to draw - if (text == NULL || byteLength == 0 /*|| fRC->isEmpty()*/) { - return; - } - - this->init(paint, skPaint); - - SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); - - SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, &fContext->getMatrix()); - SkGlyphCache* cache = autoCache.getCache(); - GrFontScaler* fontScaler = GetGrFontScaler(cache); - - // transform our starting point - { - SkPoint loc; - fContext->getMatrix().mapXY(x, y, &loc); - x = loc.fX; - y = loc.fY; - } - - // need to measure first - if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { - SkVector stop; - - MeasureText(cache, glyphCacheProc, text, byteLength, &stop); - - SkScalar stopX = stop.fX; - SkScalar stopY = stop.fY; - - if (fSkPaint.getTextAlign() == SkPaint::kCenter_Align) { - stopX = SkScalarHalf(stopX); - stopY = SkScalarHalf(stopY); - } - x -= stopX; - y -= stopY; - } - - const char* stop = text + byteLength; - - SkAutoKern autokern; - - SkFixed fxMask = ~0; - SkFixed fyMask = ~0; - SkFixed halfSampleX, halfSampleY; - if (cache->isSubpixel()) { - halfSampleX = halfSampleY = (SK_FixedHalf >> SkGlyph::kSubBits); - SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(fContext->getMatrix()); - if (kX_SkAxisAlignment == baseline) { - fyMask = 0; - halfSampleY = SK_FixedHalf; - } else if (kY_SkAxisAlignment == baseline) { - fxMask = 0; - halfSampleX = SK_FixedHalf; - } - } else { - halfSampleX = halfSampleY = SK_FixedHalf; - } - - SkFixed fx = SkScalarToFixed(x) + halfSampleX; - SkFixed fy = SkScalarToFixed(y) + halfSampleY; - - GrContext::AutoMatrix autoMatrix; - autoMatrix.setIdentity(fContext, &fPaint); - - while (text < stop) { - const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fyMask); - - fx += autokern.adjust(glyph); - - if (glyph.fWidth) { - this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), - glyph.getSubXFixed(), - glyph.getSubYFixed()), - SkFixedFloorToFixed(fx), - SkFixedFloorToFixed(fy), - fontScaler); - } - - fx += glyph.fAdvanceX; - fy += glyph.fAdvanceY; - } - - this->finish(); -} - void GrBitmapTextContext::onDrawPosText(const GrPaint& paint, const SkPaint& skPaint, const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, diff --git a/src/gpu/GrBitmapTextContext.h b/src/gpu/GrBitmapTextContext.h index 7a93820a16..7a73b7b109 100644 --- a/src/gpu/GrBitmapTextContext.h +++ b/src/gpu/GrBitmapTextContext.h @@ -45,8 +45,6 @@ private: virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE; - virtual void onDrawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength, - SkScalar x, SkScalar y) SK_OVERRIDE; virtual void onDrawPosText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp index 9fa0c1d7b8..ce2b1759bc 100755 --- a/src/gpu/GrDistanceFieldTextContext.cpp +++ b/src/gpu/GrDistanceFieldTextContext.cpp @@ -28,6 +28,9 @@ #include "SkStrokeRec.h" #include "effects/GrDistanceFieldTextureEffect.h" +#include "SkDrawProcs.h" +#include "SkTextMapStateProc.h" + SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false, "Dump the contents of the font cache before every purge."); @@ -207,81 +210,6 @@ static void setup_gamma_texture(GrContext* context, const SkGlyphCache* cache, } } -void GrDistanceFieldTextContext::onDrawText(const GrPaint& paint, const SkPaint& skPaint, - const char text[], size_t byteLength, - SkScalar x, SkScalar y) { - SkASSERT(byteLength == 0 || text != NULL); - - // nothing to draw or can't draw - if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/ - || fSkPaint.getRasterizer()) { - return; - } - - this->init(paint, skPaint); - - SkScalar sizeRatio = fTextRatio; - - SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); - - SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); - SkGlyphCache* cache = autoCache.getCache(); - GrFontScaler* fontScaler = GetGrFontScaler(cache); - - setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); - - // need to measure first - // TODO - generate positions and pre-load cache as well? - const char* stop = text + byteLength; - if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { - SkFixed stopX = 0; - SkFixed stopY = 0; - - const char* textPtr = text; - while (textPtr < stop) { - // don't need x, y here, since all subpixel variants will have the - // same advance - const SkGlyph& glyph = glyphCacheProc(cache, &textPtr, 0, 0); - - stopX += glyph.fAdvanceX; - stopY += glyph.fAdvanceY; - } - SkASSERT(textPtr == stop); - - SkScalar alignX = SkFixedToScalar(stopX)*sizeRatio; - SkScalar alignY = SkFixedToScalar(stopY)*sizeRatio; - - if (fSkPaint.getTextAlign() == SkPaint::kCenter_Align) { - alignX = SkScalarHalf(alignX); - alignY = SkScalarHalf(alignY); - } - - x -= alignX; - y -= alignY; - } - - SkFixed fx = SkScalarToFixed(x); - SkFixed fy = SkScalarToFixed(y); - SkFixed fixedScale = SkScalarToFixed(sizeRatio); - while (text < stop) { - const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); - - if (glyph.fWidth) { - this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), - glyph.getSubXFixed(), - glyph.getSubYFixed()), - fx, - fy, - fontScaler); - } - - fx += SkFixedMul_portable(glyph.fAdvanceX, fixedScale); - fy += SkFixedMul_portable(glyph.fAdvanceY, fixedScale); - } - - this->finish(); -} - void GrDistanceFieldTextContext::onDrawPosText(const GrPaint& paint, const SkPaint& skPaint, const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, @@ -326,7 +254,8 @@ void GrDistanceFieldTextContext::onDrawPosText(const GrPaint& paint, const SkPai pos += scalarsPerPosition; } } else { - int alignShift = SkPaint::kCenter_Align == fSkPaint.getTextAlign() ? 1 : 0; + SkScalar alignMul = SkPaint::kCenter_Align == fSkPaint.getTextAlign() ? SK_ScalarHalf + : SK_Scalar1; while (text < stop) { // the last 2 parameters are ignored const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); @@ -335,11 +264,14 @@ void GrDistanceFieldTextContext::onDrawPosText(const GrPaint& paint, const SkPai SkScalar x = offset.x() + pos[0]; SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0); + SkScalar advanceX = SkFixedToScalar(glyph.fAdvanceX)*alignMul*fTextRatio; + SkScalar advanceY = SkFixedToScalar(glyph.fAdvanceY)*alignMul*fTextRatio; + this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), glyph.getSubXFixed(), glyph.getSubYFixed()), - SkScalarToFixed(x) - (glyph.fAdvanceX >> alignShift), - SkScalarToFixed(y) - (glyph.fAdvanceY >> alignShift), + SkScalarToFixed(x - advanceX), + SkScalarToFixed(y - advanceY), fontScaler); } pos += scalarsPerPosition; diff --git a/src/gpu/GrDistanceFieldTextContext.h b/src/gpu/GrDistanceFieldTextContext.h index 6fa2d6f173..b1cf5593e1 100644 --- a/src/gpu/GrDistanceFieldTextContext.h +++ b/src/gpu/GrDistanceFieldTextContext.h @@ -50,8 +50,6 @@ private: virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE; - virtual void onDrawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength, - SkScalar x, SkScalar y) SK_OVERRIDE; virtual void onDrawPosText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp index b53ff797fa..9b4c4d7754 100644 --- a/src/gpu/GrStencilAndCoverTextContext.cpp +++ b/src/gpu/GrStencilAndCoverTextContext.cpp @@ -11,7 +11,6 @@ #include "GrGpu.h" #include "GrPath.h" #include "GrPathRange.h" -#include "SkAutoKern.h" #include "SkDraw.h" #include "SkDrawProcs.h" #include "SkGlyphCache.h" @@ -62,96 +61,6 @@ bool GrStencilAndCoverTextContext::canDraw(const SkPaint& paint) { return rec.getFormat() != SkMask::kARGB32_Format; } -void GrStencilAndCoverTextContext::onDrawText(const GrPaint& paint, - const SkPaint& skPaint, - const char text[], - size_t byteLength, - SkScalar x, SkScalar y) { - SkASSERT(byteLength == 0 || text != NULL); - - if (text == NULL || byteLength == 0 /*|| fRC->isEmpty()*/) { - return; - } - - // This is the slow path, mainly used by Skia unit tests. The other - // backends (8888, gpu, ...) use device-space dependent glyph caches. In - // order to match the glyph positions that the other code paths produce, we - // must also use device-space dependent glyph cache. This has the - // side-effect that the glyph shape outline will be in device-space, - // too. This in turn has the side-effect that NVPR can not stroke the paths, - // as the stroke in NVPR is defined in object-space. - // NOTE: here we have following coincidence that works at the moment: - // - When using the device-space glyphs, the transforms we pass to NVPR - // instanced drawing are the global transforms, and the view transform is - // identity. NVPR can not use non-affine transforms in the instanced - // drawing. This is taken care of by SkDraw::ShouldDrawTextAsPaths since it - // will turn off the use of device-space glyphs when perspective transforms - // are in use. - - this->init(paint, skPaint, byteLength, kMaxAccuracy_RenderMode, SkPoint::Make(0, 0)); - - // Transform our starting point. - if (fNeedsDeviceSpaceGlyphs) { - SkPoint loc; - fContextInitialMatrix.mapXY(x, y, &loc); - x = loc.fX; - y = loc.fY; - } - - SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); - - fTransformType = GrPathRendering::kTranslate_PathTransformType; - - const char* stop = text + byteLength; - - // Measure first if needed. - if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { - SkFixed stopX = 0; - SkFixed stopY = 0; - - const char* textPtr = text; - while (textPtr < stop) { - // We don't need x, y here, since all subpixel variants will have the - // same advance. - const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &textPtr, 0, 0); - - stopX += glyph.fAdvanceX; - stopY += glyph.fAdvanceY; - } - SkASSERT(textPtr == stop); - - SkScalar alignX = SkFixedToScalar(stopX) * fTextRatio; - SkScalar alignY = SkFixedToScalar(stopY) * fTextRatio; - - if (fSkPaint.getTextAlign() == SkPaint::kCenter_Align) { - alignX = SkScalarHalf(alignX); - alignY = SkScalarHalf(alignY); - } - - x -= alignX; - y -= alignY; - } - - SkAutoKern autokern; - - SkFixed fixedSizeRatio = SkScalarToFixed(fTextRatio); - - SkFixed fx = SkScalarToFixed(x); - SkFixed fy = SkScalarToFixed(y); - while (text < stop) { - const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0); - fx += SkFixedMul_portable(autokern.adjust(glyph), fixedSizeRatio); - if (glyph.fWidth) { - this->appendGlyph(glyph.getGlyphID(), SkFixedToScalar(fx), SkFixedToScalar(fy)); - } - - fx += SkFixedMul_portable(glyph.fAdvanceX, fixedSizeRatio); - fy += SkFixedMul_portable(glyph.fAdvanceY, fixedSizeRatio); - } - - this->finish(); -} - void GrStencilAndCoverTextContext::onDrawPosText(const GrPaint& paint, const SkPaint& skPaint, const char text[], diff --git a/src/gpu/GrStencilAndCoverTextContext.h b/src/gpu/GrStencilAndCoverTextContext.h index 40d38c2375..5985c20192 100644 --- a/src/gpu/GrStencilAndCoverTextContext.h +++ b/src/gpu/GrStencilAndCoverTextContext.h @@ -68,9 +68,6 @@ private: virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE; - virtual void onDrawText(const GrPaint&, const SkPaint&, const char text[], - size_t byteLength, - SkScalar x, SkScalar y) SK_OVERRIDE; virtual void onDrawPosText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp index 94c05a7124..869706e652 100644 --- a/src/gpu/GrTextContext.cpp +++ b/src/gpu/GrTextContext.cpp @@ -44,16 +44,63 @@ bool GrTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint, const char text[], size_t byteLength, SkScalar x, SkScalar y) { - GrTextContext* textContext = this; - do { - if (textContext->canDraw(skPaint)) { - textContext->onDrawText(paint, skPaint, text, byteLength, x, y); - return true; - } - textContext = textContext->fFallbackTextContext; - } while (textContext); + SkASSERT(byteLength == 0 || text != NULL); - return false; + // nothing to draw + if (text == NULL || byteLength == 0) { + return true; + } + + SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); + SkAutoGlyphCache autoCache(skPaint, &fDeviceProperties, NULL); + SkGlyphCache* cache = autoCache.getCache(); + + SkTArray<SkScalar> positions; + + const char* textPtr = text; + SkFixed stopX = 0; + SkFixed stopY = 0; + SkFixed origin; + switch (skPaint.getTextAlign()) { + case SkPaint::kRight_Align: origin = SK_Fixed1; break; + case SkPaint::kCenter_Align: origin = SK_FixedHalf; break; + case SkPaint::kLeft_Align: origin = 0; break; + default: SkFAIL("Invalid paint origin"); return false; + } + + SkAutoKern autokern; + const char* stop = text + byteLength; + while (textPtr < stop) { + // don't need x, y here, since all subpixel variants will have the + // same advance + const SkGlyph& glyph = glyphCacheProc(cache, &textPtr, 0, 0); + + SkFixed width = glyph.fAdvanceX + autokern.adjust(glyph); + positions.push_back(SkFixedToScalar(stopX + SkFixedMul_portable(origin, width))); + + SkFixed height = glyph.fAdvanceY; + positions.push_back(SkFixedToScalar(stopY + SkFixedMul_portable(origin, height))); + + stopX += width; + stopY += height; + } + SkASSERT(textPtr == stop); + + // now adjust starting point depending on alignment + SkScalar alignX = SkFixedToScalar(stopX); + SkScalar alignY = SkFixedToScalar(stopY); + if (skPaint.getTextAlign() == SkPaint::kCenter_Align) { + alignX = SkScalarHalf(alignX); + alignY = SkScalarHalf(alignY); + } else if (skPaint.getTextAlign() == SkPaint::kLeft_Align) { + alignX = 0; + alignY = 0; + } + x -= alignX; + y -= alignY; + SkPoint offset = SkPoint::Make(x, y); + + return this->drawPosText(paint, skPaint, text, byteLength, positions.begin(), 2, offset); } bool GrTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPaint, diff --git a/src/gpu/GrTextContext.h b/src/gpu/GrTextContext.h index 95344dd39f..ec24fa7760 100644 --- a/src/gpu/GrTextContext.h +++ b/src/gpu/GrTextContext.h @@ -46,8 +46,6 @@ protected: virtual bool canDraw(const SkPaint& paint) = 0; - virtual void onDrawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength, - SkScalar x, SkScalar y) = 0; virtual void onDrawPosText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, |