From 8128d8c119382279918b90ad8d80ccb3aaebb8a0 Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Thu, 19 Dec 2013 16:12:25 +0000 Subject: [PATCH] Move distance field font code into GrDistanceFieldTextContext. This avoids the SkDraw path and renders the distance field glyphs directly from GrDistanceFieldTextContext. It also disables LCD, subpixel and autohinting, and removes the supporting code when rendering DF fonts. R=reed@google.com, bsalomon@google.com, robertphillips@google.com Author: jvanverth@google.com Review URL: https://codereview.chromium.org/85653004 git-svn-id: http://skia.googlecode.com/svn/trunk@12770 2bbb7eff-a529-9590-31e7-b0007b416f81 --- include/core/SkDevice.h | 16 ++-- include/core/SkDraw.h | 13 ++- include/core/SkPaint.h | 1 + include/gpu/GrDistanceFieldTextContext.h | 13 ++- src/core/SkDraw.cpp | 104 ++++----------------- src/core/SkDrawProcs.h | 16 ---- src/device/xps/SkXPSDevice.cpp | 3 - src/gpu/GrDistanceFieldTextContext.cpp | 150 ++++++++++++++++++++++++++++--- src/gpu/SkGpuDevice.cpp | 91 ++++++++++--------- 9 files changed, 229 insertions(+), 178 deletions(-) diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h index d63af04..3764ff3 100644 --- a/include/core/SkDevice.h +++ b/include/core/SkDevice.h @@ -375,6 +375,15 @@ protected: // either is identical to kNative_Premul_Config8888. Otherwise, -1. static const SkCanvas::Config8888 kPMColorAlias; +protected: + /** + * Leaky properties are those which the device should be applying but it isn't. + * These properties will be applied by the draw, when and as it can. + * If the device does handle a property, that property should be set to the identity value + * for that property, effectively making it non-leaky. + */ + SkDeviceProperties fLeakyProperties; + private: friend class SkCanvas; friend struct DeviceCM; //for setMatrixClip @@ -412,13 +421,6 @@ private: SkIPoint fOrigin; SkMetaData* fMetaData; - /** - * Leaky properties are those which the device should be applying but it isn't. - * These properties will be applied by the draw, when and as it can. - * If the device does handle a property, that property should be set to the identity value - * for that property, effectively making it non-leaky. - */ - SkDeviceProperties fLeakyProperties; #ifdef SK_DEBUG bool fAttachedToCanvas; diff --git a/include/core/SkDraw.h b/include/core/SkDraw.h index 8ccb1c0..f0759dc 100644 --- a/include/core/SkDraw.h +++ b/include/core/SkDraw.h @@ -107,11 +107,12 @@ public: static RectType ComputeRectType(const SkPaint&, const SkMatrix&, SkPoint* strokeSize); - void drawText_asPaths(const char text[], size_t byteLength, - SkScalar x, SkScalar y, const SkPaint&) const; - void drawPosText_asPaths(const char text[], size_t byteLength, - const SkScalar pos[], SkScalar constY, - int scalarsPerPosition, const SkPaint&) const; + static bool ShouldDrawTextAsPaths(const SkPaint&, const SkMatrix&); + void drawText_asPaths(const char text[], size_t byteLength, + SkScalar x, SkScalar y, const SkPaint&) const; + void drawPosText_asPaths(const char text[], size_t byteLength, + const SkScalar pos[], SkScalar constY, + int scalarsPerPosition, const SkPaint&) const; private: void drawDevMask(const SkMask& mask, const SkPaint&) const; @@ -131,8 +132,6 @@ private: bool SK_WARN_UNUSED_RESULT computeConservativeLocalClipBounds(SkRect* bounds) const; - static bool ShouldDrawTextAsPaths(const SkPaint&, const SkMatrix&); - public: const SkBitmap* fBitmap; // required const SkMatrix* fMatrix; // required diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h index 4930842..7dc3a4e 100644 --- a/include/core/SkPaint.h +++ b/include/core/SkPaint.h @@ -1070,6 +1070,7 @@ private: friend class SkDraw; friend class SkGraphics; // So Term() can be called. friend class SkPDFDevice; + friend class GrDistanceFieldTextContext; friend class SkTextToPathIter; friend class SkCanonicalizePaint; diff --git a/include/gpu/GrDistanceFieldTextContext.h b/include/gpu/GrDistanceFieldTextContext.h index 217faf3..3e00ff2 100755 --- a/include/gpu/GrDistanceFieldTextContext.h +++ b/include/gpu/GrDistanceFieldTextContext.h @@ -17,12 +17,21 @@ class GrTextStrike; */ class GrDistanceFieldTextContext : public GrTextContext { public: - GrDistanceFieldTextContext(GrContext*, const GrPaint&, SkColor, SkScalar textRatio); + GrDistanceFieldTextContext(GrContext*, const GrPaint&, const SkPaint&); virtual ~GrDistanceFieldTextContext(); virtual void drawPackedGlyph(GrGlyph::PackedID, GrFixed left, GrFixed top, GrFontScaler*) SK_OVERRIDE; + void drawText(const char text[], size_t byteLength, + SkScalar x, SkScalar y, SkGlyphCache*, GrFontScaler*); + void drawPosText(const char text[], size_t byteLength, + const SkScalar pos[], SkScalar constY, + int scalarsPerPosition, + SkGlyphCache* cache, GrFontScaler* fontScaler); + + const SkPaint& getSkPaint() { return fSkPaint; } + private: GrTextStrike* fStrike; SkScalar fTextRatio; @@ -36,7 +45,7 @@ private: kDefaultRequestedVerts = kDefaultRequestedGlyphs * 4, }; - SkColor fSkPaintColor; + SkPaint fSkPaint; SkPoint* fVertices; int32_t fMaxVertices; GrTexture* fCurrTexture; diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index d9bdd8e..1d75ca3 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -32,22 +32,6 @@ #include "SkDrawProcs.h" #include "SkMatrixUtils.h" -bool SkDraw::ShouldDrawTextAsPaths(const SkPaint& paint, const SkMatrix& ctm) { - // we don't cache hairlines in the cache - if (SkPaint::kStroke_Style == paint.getStyle() && - 0 == paint.getStrokeWidth()) { - return true; - } - - // we don't cache perspective - if (ctm.hasPerspective()) { - return true; - } - - SkMatrix textM; - return SkPaint::TooBigToUseCache(ctm, *paint.setTextMatrix(&textM)); -} - //#define TRACE_BITMAP_DRAWS #define kBlitterStorageLongCount (sizeof(SkBitmapProcShader) >> 2) @@ -1458,6 +1442,21 @@ static void measure_text(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc, SkASSERT(text == stop); } +bool SkDraw::ShouldDrawTextAsPaths(const SkPaint& paint, const SkMatrix& ctm) { + // hairline glyphs are fast enough so we don't need to cache them + if (SkPaint::kStroke_Style == paint.getStyle() && 0 == paint.getStrokeWidth()) { + return true; + } + + // we don't cache perspective + if (ctm.hasPerspective()) { + return true; + } + + SkMatrix textM; + return SkPaint::TooBigToUseCache(ctm, *paint.setTextMatrix(&textM)); +} + void SkDraw::drawText_asPaths(const char text[], size_t byteLength, SkScalar x, SkScalar y, const SkPaint& paint) const { @@ -1716,30 +1715,10 @@ void SkDraw::drawText(const char text[], size_t byteLength, SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); -#if SK_DISTANCEFIELD_FONTS - const SkMatrix* ctm = fMatrix; - const SkPaint* paintRef = &paint; - SkPaint paintCopy; - uint32_t procFlags = fProcs ? fProcs->fFlags : 0; - if (procFlags & SkDrawProcs::kUseScaledGlyphs_Flag) { - paintCopy = paint; - paintCopy.setTextSize(SkDrawProcs::kBaseDFFontSize); - paintCopy.setLCDRenderText(false); - paintRef = &paintCopy; - } - if (procFlags & SkDrawProcs::kSkipBakedGlyphTransform_Flag) { - ctm = NULL; - } - SkAutoGlyphCache autoCache(*paintRef, &fDevice->fLeakyProperties, ctm); -#else SkAutoGlyphCache autoCache(paint, &fDevice->fLeakyProperties, fMatrix); -#endif SkGlyphCache* cache = autoCache.getCache(); // transform our starting point -#if SK_DISTANCEFIELD_FONTS - if (!(procFlags & SkDrawProcs::kSkipBakedGlyphTransform_Flag)) -#endif { SkPoint loc; fMatrix->mapXY(x, y, &loc); @@ -1798,41 +1777,17 @@ void SkDraw::drawText(const char text[], size_t byteLength, SkFixed fx = SkScalarToFixed(x) + d1g.fHalfSampleX; SkFixed fy = SkScalarToFixed(y) + d1g.fHalfSampleY; -#if SK_DISTANCEFIELD_FONTS - SkFixed fixedScale; - if (procFlags & SkDrawProcs::kUseScaledGlyphs_Flag) { - fixedScale = SkScalarToFixed(paint.getTextSize()/(float)SkDrawProcs::kBaseDFFontSize); - } -#endif while (text < stop) { const SkGlyph& glyph = glyphCacheProc(cache, &text, fx & fxMask, fy & fyMask); -#if SK_DISTANCEFIELD_FONTS - if (procFlags & SkDrawProcs::kUseScaledGlyphs_Flag) { - fx += SkFixedMul_portable(autokern.adjust(glyph), fixedScale); - } else { - fx += autokern.adjust(glyph); - } -#else fx += autokern.adjust(glyph); -#endif if (glyph.fWidth) { proc(d1g, fx, fy, glyph); } -#if SK_DISTANCEFIELD_FONTS - if (procFlags & SkDrawProcs::kUseScaledGlyphs_Flag) { - fx += SkFixedMul_portable(glyph.fAdvanceX, fixedScale); - fy += SkFixedMul_portable(glyph.fAdvanceY, fixedScale); - } else { - fx += glyph.fAdvanceX; - fy += glyph.fAdvanceY; - } -#else fx += glyph.fAdvanceX; fy += glyph.fAdvanceY; -#endif } } @@ -2013,23 +1968,7 @@ void SkDraw::drawPosText(const char text[], size_t byteLength, } SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc(); -#if SK_DISTANCEFIELD_FONTS - const SkMatrix* ctm = fMatrix; - const SkPaint* paintRef = &paint; - SkPaint paintCopy; - uint32_t procFlags = fProcs ? fProcs->fFlags : 0; - if (procFlags & SkDrawProcs::kUseScaledGlyphs_Flag) { - paintCopy = paint; - paintCopy.setTextSize(SkDrawProcs::kBaseDFFontSize); - paintRef = &paintCopy; - } - if (procFlags & SkDrawProcs::kSkipBakedGlyphTransform_Flag) { - ctm = &SkMatrix::I(); - } - SkAutoGlyphCache autoCache(*paintRef, &fDevice->fLeakyProperties, ctm); -#else SkAutoGlyphCache autoCache(paint, &fDevice->fLeakyProperties, fMatrix); -#endif SkGlyphCache* cache = autoCache.getCache(); SkAAClipBlitterWrapper wrapper; @@ -2048,11 +1987,7 @@ void SkDraw::drawPosText(const char text[], size_t byteLength, AlignProc alignProc = pick_align_proc(paint.getTextAlign()); SkDraw1Glyph d1g; SkDraw1Glyph::Proc proc = d1g.init(this, blitter, cache, paint); -#if SK_DISTANCEFIELD_FONTS - TextMapState tms(*ctm, constY); -#else TextMapState tms(*fMatrix, constY); -#endif TextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition); if (cache->isSubpixel()) { @@ -2075,16 +2010,7 @@ void SkDraw::drawPosText(const char text[], size_t byteLength, if (SkPaint::kLeft_Align == paint.getTextAlign()) { while (text < stop) { -#if SK_DISTANCEFIELD_FONTS - if (procFlags & SkDrawProcs::kSkipBakedGlyphTransform_Flag) { - tms.fLoc.fX = *pos; - tms.fLoc.fY = *(pos+1); - } else { - tmsProc(tms, pos); - } -#else tmsProc(tms, pos); -#endif SkFixed fx = SkScalarToFixed(tms.fLoc.fX) + d1g.fHalfSampleX; SkFixed fy = SkScalarToFixed(tms.fLoc.fY) + d1g.fHalfSampleY; diff --git a/src/core/SkDrawProcs.h b/src/core/SkDrawProcs.h index 6911e5b..4453229 100644 --- a/src/core/SkDrawProcs.h +++ b/src/core/SkDrawProcs.h @@ -57,22 +57,6 @@ struct SkDraw1Glyph { struct SkDrawProcs { SkDraw1Glyph::Proc fD1GProc; -#if SK_DISTANCEFIELD_FONTS - uint32_t fFlags; - - enum Flags { - /** - * Disable baked glyph transforms - */ - kSkipBakedGlyphTransform_Flag = 0x1, - /** - * Scale glyphs to get different point sizes - */ - kUseScaledGlyphs_Flag = 0x2, - }; - - static const int kBaseDFFontSize = 32; -#endif }; bool SkDrawTreatAAStrokeAsHairline(SkScalar strokeWidth, const SkMatrix&, diff --git a/src/device/xps/SkXPSDevice.cpp b/src/device/xps/SkXPSDevice.cpp index e7f5a8c..c407e2c 100644 --- a/src/device/xps/SkXPSDevice.cpp +++ b/src/device/xps/SkXPSDevice.cpp @@ -2242,9 +2242,6 @@ static void text_draw_init(const SkPaint& paint, SkBitSet& glyphsUsed, SkDraw& myDraw, SkXPSDrawProcs& procs) { procs.fD1GProc = xps_draw_1_glyph; -#if SK_DISTANCEFIELD_FONTS - procs.fFlags = 0; -#endif size_t numGlyphGuess; switch (paint.getTextEncoding()) { case SkPaint::kUTF8_TextEncoding: diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp index 2f67c49..d04e52e 100755 --- a/src/gpu/GrDistanceFieldTextContext.cpp +++ b/src/gpu/GrDistanceFieldTextContext.cpp @@ -9,6 +9,7 @@ #include "GrAtlas.h" #include "GrDrawTarget.h" #include "GrFontScaler.h" +#include "SkGlyphCache.h" #include "GrIndexBuffer.h" #include "GrTextStrike.h" #include "GrTextStrike_impl.h" @@ -19,18 +20,16 @@ static const int kGlyphCoordsAttributeIndex = 1; +static const int kBaseDFFontSize = 32; + SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false, "Dump the contents of the font cache before every purge."); - GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context, - const GrPaint& paint, - SkColor color, - SkScalar textRatio) - : GrTextContext(context, paint) - , fTextRatio(textRatio) { - fSkPaintColor = color; - + const GrPaint& grPaint, + const SkPaint& skPaint) + : GrTextContext(context, grPaint), + fSkPaint(skPaint) { fStrike = NULL; fCurrTexture = NULL; @@ -38,6 +37,13 @@ GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context, fVertices = NULL; fMaxVertices = 0; + + fTextRatio = fSkPaint.getTextSize()/kBaseDFFontSize; + + fSkPaint.setTextSize(SkIntToScalar(kBaseDFFontSize)); + fSkPaint.setLCDRenderText(false); + fSkPaint.setAutohinted(false); + fSkPaint.setSubpixelText(false); } GrDistanceFieldTextContext::~GrDistanceFieldTextContext() { @@ -81,11 +87,11 @@ void GrDistanceFieldTextContext::flushGlyphs() { // alpha. Instead we feed in a non-premultiplied color, and multiply its alpha by // the mask texture color. The end result is that we get // mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstColor - int a = SkColorGetA(fSkPaintColor); + int a = SkColorGetA(fSkPaint.getColor()); // paintAlpha drawState->setColor(SkColorSetARGB(a, a, a, a)); // paintColor - drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaintColor)); + drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaint.getColor())); drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff); } else { // set back to normal in case we took LCD path previously. @@ -276,3 +282,127 @@ HAS_ATLAS: 2 * sizeof(SkPoint)); fCurrVertex += 4; } + +void GrDistanceFieldTextContext::drawText(const char text[], size_t byteLength, + SkScalar x, SkScalar y, SkGlyphCache* cache, + GrFontScaler* fontScaler) { + SkASSERT(byteLength == 0 || text != NULL); + + // nothing to draw + if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/) { + return; + } + + SkScalar sizeRatio = fTextRatio; + + SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); + + // 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) + SK_FixedHalf; + SkFixed fy = SkScalarToFixed(y) + SK_FixedHalf; + SkFixed fixedScale = SkScalarToFixed(sizeRatio); + while (text < stop) { + const SkGlyph& glyph = glyphCacheProc(cache, &text, fx, fy); + + if (glyph.fWidth) { + this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(), + glyph.getSubXFixed(), + glyph.getSubYFixed()), + SkFixedFloorToFixed(fx), + SkFixedFloorToFixed(fy), + fontScaler); + } + + fx += SkFixedMul_portable(glyph.fAdvanceX, fixedScale); + fy += SkFixedMul_portable(glyph.fAdvanceY, fixedScale); + } +} + +void GrDistanceFieldTextContext::drawPosText(const char text[], size_t byteLength, + const SkScalar pos[], SkScalar constY, + int scalarsPerPosition, + SkGlyphCache* cache, GrFontScaler* fontScaler) { + + SkASSERT(byteLength == 0 || text != NULL); + SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); + + // nothing to draw + if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/) { + return; + } + + SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); + + const char* stop = text + byteLength; + + if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { + while (text < stop) { + // the last 2 parameters are ignored + const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); + + if (glyph.fWidth) { + SkScalar x = pos[0]; + SkScalar y = scalarsPerPosition == 1 ? constY : pos[1]; + + this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(), + glyph.getSubXFixed(), + glyph.getSubYFixed()), + SkScalarToFixed(x) + SK_FixedHalf, //d1g.fHalfSampleX, + SkScalarToFixed(y) + SK_FixedHalf, //d1g.fHalfSampleY, + fontScaler); + } + pos += scalarsPerPosition; + } + } else { + int alignShift = SkPaint::kCenter_Align == fSkPaint.getTextAlign() ? 1 : 0; + while (text < stop) { + // the last 2 parameters are ignored + const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); + + if (glyph.fWidth) { + SkScalar x = pos[0]; + SkScalar y = scalarsPerPosition == 1 ? constY : pos[1]; + + this->drawPackedGlyph(GrGlyph::Pack(glyph.getGlyphID(), + glyph.getSubXFixed(), + glyph.getSubYFixed()), + SkScalarToFixed(x) - (glyph.fAdvanceX >> alignShift) + + SK_FixedHalf, //d1g.fHalfSampleX, + SkScalarToFixed(y) - (glyph.fAdvanceY >> alignShift) + + SK_FixedHalf, //d1g.fHalfSampleY, + fontScaler); + } + pos += scalarsPerPosition; + } + } +} + diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 71d0ebf..fe036fe 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -1751,9 +1751,6 @@ SkDrawProcs* SkGpuDevice::initDrawForText(GrTextContext* context) { fDrawProcs = SkNEW(GrSkDrawProcs); fDrawProcs->fD1GProc = SkGPU_Draw1Glyph; fDrawProcs->fContext = fContext; -#if SK_DISTANCEFIELD_FONTS - fDrawProcs->fFlags = 0; -#endif } // init our (and GL's) state @@ -1767,9 +1764,25 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text, const SkPaint& paint) { CHECK_SHOULD_DRAW(draw, false); - if (fContext->getMatrix().hasPerspective()) { - // this guy will just call our drawPath() - draw.drawText((const char*)text, byteLength, x, y, paint); + if (SkDraw::ShouldDrawTextAsPaths(paint, fContext->getMatrix())) { + draw.drawText_asPaths((const char*)text, byteLength, x, y, paint); +#if SK_DISTANCEFIELD_FONTS + } else if (!paint.getRasterizer()) { + GrPaint grPaint; + if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { + return; + } + + SkDEBUGCODE(this->validate();) + + GrDistanceFieldTextContext context(fContext, grPaint, paint); + + SkAutoGlyphCache autoCache(context.getSkPaint(), &this->fLeakyProperties, NULL); + SkGlyphCache* cache = autoCache.getCache(); + GrFontScaler* fontScaler = get_gr_font_scaler(cache); + + context.drawText((const char *)text, byteLength, x, y, cache, fontScaler); +#endif } else { SkDraw myDraw(draw); @@ -1777,23 +1790,10 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text, if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { return; } -#if SK_DISTANCEFIELD_FONTS - if (paint.getRasterizer()) { -#endif - GrBitmapTextContext context(fContext, grPaint, paint.getColor()); - myDraw.fProcs = this->initDrawForText(&context); - this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint); -#if SK_DISTANCEFIELD_FONTS - } else { - GrDistanceFieldTextContext context(fContext, grPaint, paint.getColor(), - paint.getTextSize()/SkDrawProcs::kBaseDFFontSize); - myDraw.fProcs = this->initDrawForText(&context); - fDrawProcs->fFlags |= SkDrawProcs::kSkipBakedGlyphTransform_Flag; - fDrawProcs->fFlags |= SkDrawProcs::kUseScaledGlyphs_Flag; - this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint); - fDrawProcs->fFlags = 0; - } -#endif + + GrBitmapTextContext context(fContext, grPaint, paint.getColor()); + myDraw.fProcs = this->initDrawForText(&context); + this->INHERITED::drawText(myDraw, text, byteLength, x, y, paint); } } @@ -1803,10 +1803,28 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, const SkPaint& paint) { CHECK_SHOULD_DRAW(draw, false); - if (fContext->getMatrix().hasPerspective()) { + if (SkDraw::ShouldDrawTextAsPaths(paint, fContext->getMatrix())) { // this guy will just call our drawPath() - draw.drawPosText((const char*)text, byteLength, pos, constY, + draw.drawPosText_asPaths((const char*)text, byteLength, pos, constY, scalarsPerPos, paint); +#if SK_DISTANCEFIELD_FONTS + } else if (!paint.getRasterizer()) { + GrPaint grPaint; + if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { + return; + } + + SkDEBUGCODE(this->validate();) + + GrDistanceFieldTextContext context(fContext, grPaint, paint); + + SkAutoGlyphCache autoCache(context.getSkPaint(), &this->fLeakyProperties, NULL); + SkGlyphCache* cache = autoCache.getCache(); + GrFontScaler* fontScaler = get_gr_font_scaler(cache); + + context.drawPosText((const char *)text, byteLength, pos, constY, scalarsPerPos, + cache, fontScaler); +#endif } else { SkDraw myDraw(draw); @@ -1814,25 +1832,10 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { return; } -#if SK_DISTANCEFIELD_FONTS - if (paint.getRasterizer()) { -#endif - GrBitmapTextContext context(fContext, grPaint, paint.getColor()); - myDraw.fProcs = this->initDrawForText(&context); - this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY, - scalarsPerPos, paint); -#if SK_DISTANCEFIELD_FONTS - } else { - GrDistanceFieldTextContext context(fContext, grPaint, paint.getColor(), - paint.getTextSize()/SkDrawProcs::kBaseDFFontSize); - myDraw.fProcs = this->initDrawForText(&context); - fDrawProcs->fFlags |= SkDrawProcs::kSkipBakedGlyphTransform_Flag; - fDrawProcs->fFlags |= SkDrawProcs::kUseScaledGlyphs_Flag; - this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY, - scalarsPerPos, paint); - fDrawProcs->fFlags = 0; - } -#endif + GrBitmapTextContext context(fContext, grPaint, paint.getColor()); + myDraw.fProcs = this->initDrawForText(&context); + this->INHERITED::drawPosText(myDraw, text, byteLength, pos, constY, + scalarsPerPos, paint); } } -- 2.7.4