From cbbc481e918c0d32454455626235f67106f216a1 Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Thu, 30 Jan 2014 22:05:47 +0000 Subject: [PATCH] Replace factory generation of TextContexts with persistent objects. BUG=skia:2018 R=bsalomon@google.com Author: jvanverth@google.com Review URL: https://codereview.chromium.org/150743002 git-svn-id: http://skia.googlecode.com/svn/trunk@13249 2bbb7eff-a529-9590-31e7-b0007b416f81 --- include/gpu/SkGpuDevice.h | 5 +- src/gpu/GrBitmapTextContext.cpp | 44 +++++++++++---- src/gpu/GrBitmapTextContext.h | 12 +++-- src/gpu/GrDistanceFieldTextContext.cpp | 65 +++++++++++++++------- src/gpu/GrDistanceFieldTextContext.h | 18 ++++--- src/gpu/GrTextContext.cpp | 19 ++++--- src/gpu/GrTextContext.h | 99 +++++----------------------------- src/gpu/SkGpuDevice.cpp | 43 +++++++-------- 8 files changed, 145 insertions(+), 160 deletions(-) diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h index bfcdba3..e791ca4 100644 --- a/include/gpu/SkGpuDevice.h +++ b/include/gpu/SkGpuDevice.h @@ -20,7 +20,7 @@ struct SkDrawProcs; struct GrSkDrawProcs; -class GrTextContextManager; +class GrTextContext; /** * Subclass of SkBitmapDevice, which directs all drawing to the GrGpu owned by the @@ -150,7 +150,8 @@ private: GrClipData fClipData; - GrTextContextManager* fTextContextManager; + GrTextContext* fMainTextContext; + GrTextContext* fFallbackTextContext; // state for our render-target GrRenderTarget* fRenderTarget; diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp index 488aa13..c7beb14 100755 --- a/src/gpu/GrBitmapTextContext.cpp +++ b/src/gpu/GrBitmapTextContext.cpp @@ -29,15 +29,9 @@ static const int kGlyphCoordsAttributeIndex = 1; SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false, "Dump the contents of the font cache before every purge."); -bool GrBitmapTextContext::CanDraw(const SkPaint& paint, const SkMatrix& ctm) { - return !SkDraw::ShouldDrawTextAsPaths(paint, ctm); -} - GrBitmapTextContext::GrBitmapTextContext(GrContext* context, - const GrPaint& grPaint, - const SkPaint& skPaint, const SkDeviceProperties& properties) - : GrTextContext(context, grPaint, skPaint, properties) { + : GrTextContext(context, properties) { fStrike = NULL; fCurrTexture = NULL; @@ -51,6 +45,10 @@ GrBitmapTextContext::~GrBitmapTextContext() { this->flushGlyphs(); } +bool GrBitmapTextContext::canDraw(const SkPaint& paint) { + return !SkDraw::ShouldDrawTextAsPaths(paint, fContext->getMatrix()); +} + static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { unsigned r = SkColorGetR(c); unsigned g = SkColorGetG(c); @@ -117,7 +115,26 @@ void GrBitmapTextContext::flushGlyphs() { } } -void GrBitmapTextContext::drawText(const char text[], size_t byteLength, +inline void GrBitmapTextContext::init(const GrPaint& paint, const SkPaint& skPaint) { + GrTextContext::init(paint, skPaint); + + fStrike = NULL; + + fCurrTexture = NULL; + fCurrVertex = 0; + + fVertices = NULL; + fMaxVertices = 0; +} + +inline void GrBitmapTextContext::finish() { + flushGlyphs(); + + GrTextContext::finish(); +} + +void GrBitmapTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint, + const char text[], size_t byteLength, SkScalar x, SkScalar y) { SkASSERT(byteLength == 0 || text != NULL); @@ -126,6 +143,8 @@ void GrBitmapTextContext::drawText(const char text[], size_t byteLength, return; } + this->init(paint, skPaint); + SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, &fContext->getMatrix()); @@ -201,6 +220,8 @@ void GrBitmapTextContext::drawText(const char text[], size_t byteLength, fx += glyph.fAdvanceX; fy += glyph.fAdvanceY; } + + this->finish(); } /////////////////////////////////////////////////////////////////////////////// @@ -295,7 +316,8 @@ BitmapTextMapState::Proc BitmapTextMapState::pickProc(int scalarsPerPosition) { /////////////////////////////////////////////////////////////////////////////// -void GrBitmapTextContext::drawPosText(const char text[], size_t byteLength, +void GrBitmapTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPaint, + const char text[], size_t byteLength, const SkScalar pos[], SkScalar constY, int scalarsPerPosition) { SkASSERT(byteLength == 0 || text != NULL); @@ -306,6 +328,8 @@ void GrBitmapTextContext::drawPosText(const char text[], size_t byteLength, return; } + this->init(paint, skPaint); + SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, &fContext->getMatrix()); @@ -439,6 +463,8 @@ void GrBitmapTextContext::drawPosText(const char text[], size_t byteLength, } } } + + this->finish(); } namespace { diff --git a/src/gpu/GrBitmapTextContext.h b/src/gpu/GrBitmapTextContext.h index 6550e3c..8d6edda 100755 --- a/src/gpu/GrBitmapTextContext.h +++ b/src/gpu/GrBitmapTextContext.h @@ -17,21 +17,25 @@ class GrTextStrike; */ class GrBitmapTextContext : public GrTextContext { public: - GrBitmapTextContext(GrContext*, const GrPaint&, const SkPaint&, const SkDeviceProperties&); + GrBitmapTextContext(GrContext*, const SkDeviceProperties&); virtual ~GrBitmapTextContext(); - virtual void drawText(const char text[], size_t byteLength, SkScalar x, SkScalar y) SK_OVERRIDE; - virtual void drawPosText(const char text[], size_t byteLength, + virtual void drawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength, + SkScalar x, SkScalar y) SK_OVERRIDE; + virtual void drawPosText(const GrPaint&, const SkPaint&, + const char text[], size_t byteLength, const SkScalar pos[], SkScalar constY, int scalarsPerPosition) SK_OVERRIDE; - static bool CanDraw(const SkPaint& paint, const SkMatrix& ctm); + virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE; private: GrTextStrike* fStrike; + void init(const GrPaint&, const SkPaint&); void drawPackedGlyph(GrGlyph::PackedID, GrFixed left, GrFixed top, GrFontScaler*); void flushGlyphs(); // automatically called by destructor + void finish(); enum { kMinRequestedGlyphs = 1, diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp index 52b714c..ac93433 100755 --- a/src/gpu/GrDistanceFieldTextContext.cpp +++ b/src/gpu/GrDistanceFieldTextContext.cpp @@ -27,17 +27,9 @@ static const int kBaseDFFontSize = 32; SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false, "Dump the contents of the font cache before every purge."); -bool GrDistanceFieldTextContext::CanDraw(const SkPaint& paint, const SkMatrix& ctm) { - return !paint.getRasterizer() && !paint.getMaskFilter() && - paint.getStyle() == SkPaint::kFill_Style && - !SkDraw::ShouldDrawTextAsPaths(paint, ctm); -} - GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context, - const GrPaint& grPaint, - const SkPaint& skPaint, const SkDeviceProperties& properties) - : GrTextContext(context, grPaint, skPaint, properties) { + : GrTextContext(context, properties) { fStrike = NULL; fCurrTexture = NULL; @@ -45,19 +37,18 @@ 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() { this->flushGlyphs(); } +bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) { + return !paint.getRasterizer() && !paint.getMaskFilter() && + paint.getStyle() == SkPaint::kFill_Style && + !SkDraw::ShouldDrawTextAsPaths(paint, fContext->getMatrix()); +} + static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { unsigned r = SkColorGetR(c); unsigned g = SkColorGetG(c); @@ -291,7 +282,33 @@ HAS_ATLAS: fCurrVertex += 4; } -void GrDistanceFieldTextContext::drawText(const char text[], size_t byteLength, +inline void GrDistanceFieldTextContext::init(const GrPaint& paint, const SkPaint& skPaint) { + GrTextContext::init(paint, skPaint); + + fStrike = NULL; + + fCurrTexture = NULL; + fCurrVertex = 0; + + fVertices = NULL; + fMaxVertices = 0; + + fTextRatio = fSkPaint.getTextSize()/kBaseDFFontSize; + + fSkPaint.setTextSize(SkIntToScalar(kBaseDFFontSize)); + fSkPaint.setLCDRenderText(false); + fSkPaint.setAutohinted(false); + fSkPaint.setSubpixelText(false); +} + +inline void GrDistanceFieldTextContext::finish() { + flushGlyphs(); + + GrTextContext::finish(); +} + +void GrDistanceFieldTextContext::drawText(const GrPaint& paint, const SkPaint& skPaint, + const char text[], size_t byteLength, SkScalar x, SkScalar y) { SkASSERT(byteLength == 0 || text != NULL); @@ -301,6 +318,8 @@ void GrDistanceFieldTextContext::drawText(const char text[], size_t byteLength, return; } + this->init(paint, skPaint); + SkScalar sizeRatio = fTextRatio; SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); @@ -357,9 +376,12 @@ void GrDistanceFieldTextContext::drawText(const char text[], size_t byteLength, fx += SkFixedMul_portable(glyph.fAdvanceX, fixedScale); fy += SkFixedMul_portable(glyph.fAdvanceY, fixedScale); } + + this->finish(); } -void GrDistanceFieldTextContext::drawPosText(const char text[], size_t byteLength, +void GrDistanceFieldTextContext::drawPosText(const GrPaint& paint, const SkPaint& skPaint, + const char text[], size_t byteLength, const SkScalar pos[], SkScalar constY, int scalarsPerPosition) { @@ -367,11 +389,12 @@ void GrDistanceFieldTextContext::drawPosText(const char text[], size_t byteLengt SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); // nothing to draw - if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/ - || fSkPaint.getRasterizer()) { + if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/) { return; } + this->init(paint, skPaint); + SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); SkAutoGlyphCache autoCache(fSkPaint, &fDeviceProperties, NULL); @@ -420,4 +443,6 @@ void GrDistanceFieldTextContext::drawPosText(const char text[], size_t byteLengt pos += scalarsPerPosition; } } + + this->finish(); } diff --git a/src/gpu/GrDistanceFieldTextContext.h b/src/gpu/GrDistanceFieldTextContext.h index 8b94038..2129898 100755 --- a/src/gpu/GrDistanceFieldTextContext.h +++ b/src/gpu/GrDistanceFieldTextContext.h @@ -17,24 +17,26 @@ class GrTextStrike; */ class GrDistanceFieldTextContext : public GrTextContext { public: - virtual void drawText(const char text[], size_t byteLength, SkScalar x, SkScalar y) SK_OVERRIDE; - virtual void drawPosText(const char text[], size_t byteLength, + GrDistanceFieldTextContext(GrContext*, const SkDeviceProperties&); + virtual ~GrDistanceFieldTextContext(); + + virtual void drawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength, + SkScalar x, SkScalar y) SK_OVERRIDE; + virtual void drawPosText(const GrPaint&, const SkPaint&, + const char text[], size_t byteLength, const SkScalar pos[], SkScalar constY, int scalarsPerPosition) SK_OVERRIDE; - static bool CanDraw(const SkPaint& paint, const SkMatrix& ctm); + virtual bool canDraw(const SkPaint& paint) SK_OVERRIDE; private: - GrDistanceFieldTextContext(GrContext*, const GrPaint&, const SkPaint&, - const SkDeviceProperties&); - virtual ~GrDistanceFieldTextContext(); - friend class GrTTextContextManager; - GrTextStrike* fStrike; SkScalar fTextRatio; + void init(const GrPaint&, const SkPaint&); void drawPackedGlyph(GrGlyph::PackedID, GrFixed left, GrFixed top, GrFontScaler*); void flushGlyphs(); // automatically called by destructor + void finish(); enum { kMinRequestedGlyphs = 1, diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp index 0c9e149..bc11671 100644 --- a/src/gpu/GrTextContext.cpp +++ b/src/gpu/GrTextContext.cpp @@ -12,24 +12,27 @@ #include "SkGlyphCache.h" #include "SkGr.h" -GrTextContext::GrTextContext(GrContext* context, const GrPaint& paint, - const SkPaint& skPaint, const SkDeviceProperties& properties) : - fContext(context), fPaint(paint), fSkPaint(skPaint), - fDeviceProperties(properties) { +GrTextContext::GrTextContext(GrContext* context, const SkDeviceProperties& properties) : + fContext(context), fDeviceProperties(properties), fDrawTarget(NULL) { +} - const GrClipData* clipData = context->getClip(); +void GrTextContext::init(const GrPaint& grPaint, const SkPaint& skPaint) { + const GrClipData* clipData = fContext->getClip(); SkRect devConservativeBound; clipData->fClipStack->getConservativeBounds( -clipData->fOrigin.fX, -clipData->fOrigin.fY, - context->getRenderTarget()->width(), - context->getRenderTarget()->height(), + fContext->getRenderTarget()->width(), + fContext->getRenderTarget()->height(), &devConservativeBound); devConservativeBound.roundOut(&fClipRect); - fDrawTarget = context->getTextTarget(); + fDrawTarget = fContext->getTextTarget(); + + fPaint = grPaint; + fSkPaint = skPaint; } //*** change to output positions? diff --git a/src/gpu/GrTextContext.h b/src/gpu/GrTextContext.h index c572d0d..ea089cc 100644 --- a/src/gpu/GrTextContext.h +++ b/src/gpu/GrTextContext.h @@ -25,105 +25,32 @@ class GrFontScaler; class GrTextContext { public: virtual ~GrTextContext() {} - virtual void drawText(const char text[], size_t byteLength, SkScalar x, SkScalar y) = 0; - virtual void drawPosText(const char text[], size_t byteLength, + virtual void drawText(const GrPaint&, const SkPaint&, const char text[], size_t byteLength, + SkScalar x, SkScalar y) = 0; + virtual void drawPosText(const GrPaint&, const SkPaint&, + const char text[], size_t byteLength, const SkScalar pos[], SkScalar constY, int scalarsPerPosition) = 0; + + virtual bool canDraw(const SkPaint& paint) = 0; protected: - GrTextContext(GrContext*, const GrPaint&, const SkPaint&, const SkDeviceProperties&); + GrTextContext(GrContext*, const SkDeviceProperties&); static GrFontScaler* GetGrFontScaler(SkGlyphCache* cache); static void MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc, const char text[], size_t byteLength, SkVector* stopVector); + void init(const GrPaint&, const SkPaint&); + void finish() { fDrawTarget = NULL; } + GrContext* fContext; - GrPaint fPaint; - SkPaint fSkPaint; SkDeviceProperties fDeviceProperties; - GrDrawTarget* fDrawTarget; + GrDrawTarget* fDrawTarget; SkIRect fClipRect; -}; - -/* - * These classes wrap the creation of a single text context for a given GPU device. The - * assumption is that we'll only be using one text context at a time for that device. - */ -class GrTextContextManager { -public: - virtual ~GrTextContextManager() {} - virtual GrTextContext* create(GrContext* grContext, const GrPaint& grPaint, - const SkPaint& skPaint, const SkDeviceProperties& props) = 0; - virtual bool canDraw(const SkPaint& paint, const SkMatrix& ctm) = 0; -}; - -template -class GrTTextContextManager : public GrTextContextManager { -private: - class ManagedTextContext : public TextContextClass { - public: - virtual ~ManagedTextContext() {} - - ManagedTextContext(GrContext* grContext, - const GrPaint& grPaint, - const SkPaint& skPaint, - const SkDeviceProperties& properties, - GrTTextContextManager* manager) : - TextContextClass(grContext, grPaint, skPaint, properties) { - fManager = manager; - } - - static void operator delete(void* ptr) { - if (ptr == NULL) { - return; - } - ManagedTextContext* context = reinterpret_cast(ptr); - context->fManager->recycle(context); - } - - static void operator delete(void*, void*) { - } - - GrTTextContextManager* fManager; - }; - -public: - GrTTextContextManager() { - fAllocation = sk_malloc_throw(sizeof(ManagedTextContext)); - fUsed = false; - } - - virtual ~GrTTextContextManager() { - SkASSERT(!fUsed); - sk_free(fAllocation); - } - - virtual GrTextContext* create(GrContext* grContext, const GrPaint& grPaint, - const SkPaint& skPaint, const SkDeviceProperties& properties) - SK_OVERRIDE { - // add check for usePath here? - SkASSERT(!fUsed); - ManagedTextContext* obj = SkNEW_PLACEMENT_ARGS(fAllocation, ManagedTextContext, - (grContext, grPaint, skPaint, properties, - this)); - fUsed = true; - return obj; - } - - virtual bool canDraw(const SkPaint& paint, const SkMatrix& ctm) SK_OVERRIDE { - return TextContextClass::CanDraw(paint, ctm); - } - -private: - void recycle(GrTextContext* textContext) { - SkASSERT((void*)textContext == fAllocation); - SkASSERT(fUsed); - fUsed = false; - } - - void* fAllocation; - bool fUsed; + GrPaint fPaint; + SkPaint fSkPaint; }; #endif diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index c858403..dfae1c4 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -201,9 +201,11 @@ void SkGpuDevice::initFromRenderTarget(GrContext* context, fContext->ref(); #if SK_DISTANCEFIELD_FONTS - fTextContextManager = SkNEW(GrTTextContextManager); + fMainTextContext = SkNEW_ARGS(GrDistanceFieldTextContext, (fContext, fLeakyProperties)); + fFallbackTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProperties)); #else - fTextContextManager = SkNEW(GrTTextContextManager); + fMainTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProperties)); + fFallbackTextContext = NULL; #endif fRenderTarget = NULL; @@ -242,9 +244,11 @@ SkGpuDevice::SkGpuDevice(GrContext* context, fContext->ref(); #if SK_DISTANCEFIELD_FONTS - fTextContextManager = SkNEW(GrTTextContextManager); + fMainTextContext = SkNEW_ARGS(GrDistanceFieldTextContext, (fContext, fLeakyProperties)); + fFallbackTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProperties)); #else - fTextContextManager = SkNEW(GrTTextContextManager); + fMainTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProperties)); + fFallbackTextContext = NULL; #endif fRenderTarget = NULL; @@ -292,7 +296,8 @@ SkGpuDevice::~SkGpuDevice() { delete fDrawProcs; } - delete fTextContextManager; + delete fMainTextContext; + delete fFallbackTextContext; // The GrContext takes a ref on the target. We don't want to cause the render // target to be unnecessarily kept alive. @@ -1778,7 +1783,7 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text, const SkPaint& paint) { CHECK_SHOULD_DRAW(draw, false); - if (fTextContextManager->canDraw(paint, fContext->getMatrix())) { + if (fMainTextContext->canDraw(paint)) { GrPaint grPaint; if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { return; @@ -1786,11 +1791,8 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text, SkDEBUGCODE(this->validate();) - SkAutoTDelete ctx(fTextContextManager->create(this->context(), - grPaint, paint, - this->getDeviceProperties())); - ctx->drawText((const char *)text, byteLength, x, y); - } else if (GrBitmapTextContext::CanDraw(paint, fContext->getMatrix())) { + fMainTextContext->drawText(grPaint, paint, (const char *)text, byteLength, x, y); + } else if (fFallbackTextContext && fFallbackTextContext->canDraw(paint)) { GrPaint grPaint; if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { return; @@ -1798,9 +1800,7 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text, SkDEBUGCODE(this->validate();) - GrBitmapTextContext textContext(this->context(), grPaint, paint, - this->getDeviceProperties()); - textContext.drawText((const char *)text, byteLength, x, y); + fFallbackTextContext->drawText(grPaint, paint, (const char *)text, byteLength, x, y); } else { // this guy will just call our drawPath() draw.drawText_asPaths((const char*)text, byteLength, x, y, paint); @@ -1813,7 +1813,7 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, const SkPaint& paint) { CHECK_SHOULD_DRAW(draw, false); - if (fTextContextManager->canDraw(paint, fContext->getMatrix())) { + if (fMainTextContext->canDraw(paint)) { GrPaint grPaint; if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { return; @@ -1821,11 +1821,9 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, SkDEBUGCODE(this->validate();) - SkAutoTDelete ctx(fTextContextManager->create(this->context(), - grPaint, paint, - this->getDeviceProperties())); - ctx->drawPosText((const char *)text, byteLength, pos, constY, scalarsPerPos); - } else if (GrBitmapTextContext::CanDraw(paint, fContext->getMatrix())) { + fMainTextContext->drawPosText(grPaint, paint, (const char *)text, byteLength, pos, + constY, scalarsPerPos); + } else if (fFallbackTextContext && fFallbackTextContext->canDraw(paint)) { GrPaint grPaint; if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { return; @@ -1833,9 +1831,8 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, SkDEBUGCODE(this->validate();) - GrBitmapTextContext textContext(this->context(), grPaint, paint, - this->getDeviceProperties()); - textContext.drawPosText((const char *)text, byteLength, pos, constY, scalarsPerPos); + fFallbackTextContext->drawPosText(grPaint, paint, (const char *)text, byteLength, pos, + constY, scalarsPerPos); } else { draw.drawPosText_asPaths((const char*)text, byteLength, pos, constY, scalarsPerPos, paint); -- 2.7.4