aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar joshualitt <joshualitt@chromium.org>2015-03-20 10:30:14 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-03-20 10:30:14 -0700
commit6e8cd9671958c69babde9338c5c18a4c3d895575 (patch)
treeeab4eb9c66a7b1831f589fac0bffc5c08f6852f6
parent1b600d3446b3d236bfa06cf116ec41960bea6ac8 (diff)
Let text contexts fall back directly to paths
-rw-r--r--include/core/SkPaint.h1
-rw-r--r--include/gpu/GrContext.h28
-rwxr-xr-xsrc/gpu/GrBitmapTextContext.cpp19
-rw-r--r--src/gpu/GrBitmapTextContext.h11
-rwxr-xr-xsrc/gpu/GrContext.cpp6
-rwxr-xr-xsrc/gpu/GrDistanceFieldTextContext.cpp32
-rw-r--r--src/gpu/GrDistanceFieldTextContext.h12
-rw-r--r--src/gpu/GrStencilAndCoverTextContext.cpp35
-rw-r--r--src/gpu/GrStencilAndCoverTextContext.h12
-rw-r--r--src/gpu/GrTextContext.cpp114
-rw-r--r--src/gpu/GrTextContext.h32
-rw-r--r--src/gpu/SkGpuDevice.cpp18
-rw-r--r--src/gpu/SkGpuDevice.h1
13 files changed, 223 insertions, 98 deletions
diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h
index 79821e5769..4bf8c059ac 100644
--- a/include/core/SkPaint.h
+++ b/include/core/SkPaint.h
@@ -1125,6 +1125,7 @@ private:
friend class GrDistanceFieldTextContext;
friend class GrStencilAndCoverTextContext;
friend class GrPathRendering;
+ friend class GrTextContext;
friend class GrGLPathRendering;
friend class SkTextToPathIter;
friend class SkCanonicalizePaint;
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 6a225c2538..335b4169cc 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -41,6 +41,7 @@ class GrVertexBuffer;
class GrVertexBufferAllocPool;
class GrStrokeInfo;
class GrSoftwarePathRenderer;
+class SkGpuDevice;
class SkStrokeRec;
class SK_API GrContext : public SkRefCnt {
@@ -201,16 +202,6 @@ public:
*/
bool isResourceInCache(const GrUniqueKey& key) const;
- /**
- * Creates a new text rendering context that is optimal for the
- * render target and the context. Caller assumes the ownership
- * of the returned object. The returned object must be deleted
- * before the context is destroyed.
- */
- GrTextContext* createTextContext(GrRenderTarget*,
- const SkDeviceProperties&,
- bool enableDistanceFieldFonts);
-
///////////////////////////////////////////////////////////////////////////
// Textures
@@ -763,6 +754,20 @@ private:
GrTexture* internalRefScratchTexture(const GrSurfaceDesc&, uint32_t flags);
/**
+ * Creates a new text rendering context that is optimal for the
+ * render target and the context. Caller assumes the ownership
+ * of the returned object. The returned object must be deleted
+ * before the context is destroyed.
+ * TODO we can possibly bury this behind context, but we need to be able to use the
+ * drawText_asPaths logic on SkGpuDevice
+ */
+ GrTextContext* createTextContext(GrRenderTarget*,
+ SkGpuDevice*,
+ const SkDeviceProperties&,
+ bool enableDistanceFieldFonts);
+
+
+ /**
* These functions create premul <-> unpremul effects if it is possible to generate a pair
* of effects that make a readToUPM->writeToPM->readToUPM cycle invariant. Otherwise, they
* return NULL.
@@ -776,6 +781,9 @@ private:
*/
static void OverBudgetCB(void* data);
+ // TODO see note on createTextContext
+ friend class SkGpuDevice;
+
typedef SkRefCnt INHERITED;
};
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp
index ed3ed09642..4061c48821 100755
--- a/src/gpu/GrBitmapTextContext.cpp
+++ b/src/gpu/GrBitmapTextContext.cpp
@@ -46,8 +46,9 @@ static const int kIndicesPerGlyph = 6;
};
GrBitmapTextContext::GrBitmapTextContext(GrContext* context,
+ SkGpuDevice* gpuDevice,
const SkDeviceProperties& properties)
- : GrTextContext(context, properties) {
+ : GrTextContext(context, gpuDevice, properties) {
fStrike = NULL;
fCurrTexture = NULL;
@@ -62,8 +63,9 @@ GrBitmapTextContext::GrBitmapTextContext(GrContext* context,
}
GrBitmapTextContext* GrBitmapTextContext::Create(GrContext* context,
+ SkGpuDevice* gpuDevice,
const SkDeviceProperties& props) {
- return SkNEW_ARGS(GrBitmapTextContext, (context, props));
+ return SkNEW_ARGS(GrBitmapTextContext, (context, gpuDevice, props));
}
bool GrBitmapTextContext::canDraw(const SkPaint& paint, const SkMatrix& viewMatrix) {
@@ -71,8 +73,9 @@ bool GrBitmapTextContext::canDraw(const SkPaint& paint, const SkMatrix& viewMatr
}
inline void GrBitmapTextContext::init(GrRenderTarget* rt, const GrClip& clip,
- const GrPaint& paint, const SkPaint& skPaint) {
- GrTextContext::init(rt, clip, paint, skPaint);
+ const GrPaint& paint, const SkPaint& skPaint,
+ const SkIRect& regionClipBounds) {
+ GrTextContext::init(rt, clip, paint, skPaint, regionClipBounds);
fStrike = NULL;
@@ -88,7 +91,7 @@ void GrBitmapTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip,
const GrPaint& paint, const SkPaint& skPaint,
const SkMatrix& viewMatrix,
const char text[], size_t byteLength,
- SkScalar x, SkScalar y) {
+ SkScalar x, SkScalar y, const SkIRect& regionClipBounds) {
SkASSERT(byteLength == 0 || text != NULL);
// nothing to draw
@@ -96,7 +99,7 @@ void GrBitmapTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip,
return;
}
- this->init(rt, clip, paint, skPaint);
+ this->init(rt, clip, paint, skPaint, regionClipBounds);
SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
@@ -190,7 +193,7 @@ void GrBitmapTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip,
const SkMatrix& viewMatrix,
const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset) {
+ const SkPoint& offset, const SkIRect& regionClipBounds) {
SkASSERT(byteLength == 0 || text != NULL);
SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
@@ -199,7 +202,7 @@ void GrBitmapTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip,
return;
}
- this->init(rt, clip, paint, skPaint);
+ this->init(rt, clip, paint, skPaint, regionClipBounds);
SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
diff --git a/src/gpu/GrBitmapTextContext.h b/src/gpu/GrBitmapTextContext.h
index e181fd2b69..e389f81480 100644
--- a/src/gpu/GrBitmapTextContext.h
+++ b/src/gpu/GrBitmapTextContext.h
@@ -19,7 +19,7 @@ class GrTextStrike;
*/
class GrBitmapTextContext : public GrTextContext {
public:
- static GrBitmapTextContext* Create(GrContext*, const SkDeviceProperties&);
+ static GrBitmapTextContext* Create(GrContext*, SkGpuDevice*, const SkDeviceProperties&);
virtual ~GrBitmapTextContext() {}
@@ -37,20 +37,21 @@ private:
uint32_t fEffectTextureUniqueID;
SkMatrix fLocalMatrix;
- GrBitmapTextContext(GrContext*, const SkDeviceProperties&);
+ GrBitmapTextContext(GrContext*, SkGpuDevice*, const SkDeviceProperties&);
bool canDraw(const SkPaint& paint, const SkMatrix& viewMatrix) SK_OVERRIDE;
virtual void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
const SkMatrix& viewMatrix, const char text[], size_t byteLength,
- SkScalar x, SkScalar y) SK_OVERRIDE;
+ SkScalar x, SkScalar y, const SkIRect& regionClipBounds) SK_OVERRIDE;
virtual void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
const SkMatrix& viewMatrix,
const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset) SK_OVERRIDE;
+ const SkPoint& offset, const SkIRect& regionClipBounds) SK_OVERRIDE;
- void init(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&);
+ void init(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
+ const SkIRect& regionClipBounds);
void appendGlyph(GrGlyph::PackedID, SkFixed left, SkFixed top, GrFontScaler*);
bool uploadGlyph(GrGlyph*, GrFontScaler*);
void flush(); // automatically called by destructor
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 78f29e73bc..35b34e392d 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -215,17 +215,19 @@ void GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes)
}
GrTextContext* GrContext::createTextContext(GrRenderTarget* renderTarget,
+ SkGpuDevice* gpuDevice,
const SkDeviceProperties&
leakyProperties,
bool enableDistanceFieldFonts) {
if (fGpu->caps()->pathRenderingSupport() && renderTarget->isMultisampled()) {
GrStencilBuffer* sb = renderTarget->renderTargetPriv().attachStencilBuffer();
if (sb) {
- return GrStencilAndCoverTextContext::Create(this, leakyProperties);
+ return GrStencilAndCoverTextContext::Create(this, gpuDevice, leakyProperties);
}
}
- return GrDistanceFieldTextContext::Create(this, leakyProperties, enableDistanceFieldFonts);
+ return GrDistanceFieldTextContext::Create(this, gpuDevice, leakyProperties,
+ enableDistanceFieldFonts);
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
index 7e93892a68..28c76954da 100755
--- a/src/gpu/GrDistanceFieldTextContext.cpp
+++ b/src/gpu/GrDistanceFieldTextContext.cpp
@@ -43,9 +43,10 @@ static const int kVerticesPerGlyph = 4;
static const int kIndicesPerGlyph = 6;
GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
+ SkGpuDevice* gpuDevice,
const SkDeviceProperties& properties,
bool enable)
- : GrTextContext(context, properties) {
+ : GrTextContext(context, gpuDevice, properties) {
#if SK_FORCE_DISTANCE_FIELD_TEXT
fEnableDFRendering = true;
#else
@@ -68,11 +69,12 @@ GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context,
}
GrDistanceFieldTextContext* GrDistanceFieldTextContext::Create(GrContext* context,
+ SkGpuDevice* gpuDevice,
const SkDeviceProperties& props,
bool enable) {
GrDistanceFieldTextContext* textContext = SkNEW_ARGS(GrDistanceFieldTextContext,
- (context, props, enable));
- textContext->fFallbackTextContext = GrBitmapTextContext::Create(context, props);
+ (context, gpuDevice, props, enable));
+ textContext->fFallbackTextContext = GrBitmapTextContext::Create(context, gpuDevice, props);
return textContext;
}
@@ -116,8 +118,9 @@ bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint, const SkMatrix& v
}
inline void GrDistanceFieldTextContext::init(GrRenderTarget* rt, const GrClip& clip,
- const GrPaint& paint, const SkPaint& skPaint) {
- GrTextContext::init(rt, clip, paint, skPaint);
+ const GrPaint& paint, const SkPaint& skPaint,
+ const SkIRect& regionClipBounds) {
+ GrTextContext::init(rt, clip, paint, skPaint, regionClipBounds);
fStrike = NULL;
@@ -214,7 +217,8 @@ void GrDistanceFieldTextContext::onDrawText(GrRenderTarget* rt, const GrClip& cl
const GrPaint& paint,
const SkPaint& skPaint, const SkMatrix& viewMatrix,
const char text[], size_t byteLength,
- SkScalar x, SkScalar y) {
+ SkScalar x, SkScalar y,
+ const SkIRect& regionClipBounds) {
SkASSERT(byteLength == 0 || text != NULL);
// nothing to draw
@@ -272,8 +276,8 @@ void GrDistanceFieldTextContext::onDrawText(GrRenderTarget* rt, const GrClip& cl
y -= alignY;
SkPoint offset = SkPoint::Make(x, y);
- this->drawPosText(rt, clip, paint, skPaint, viewMatrix, text, byteLength, positions.begin(), 2,
- offset);
+ this->onDrawPosText(rt, clip, paint, skPaint, viewMatrix, text, byteLength, positions.begin(),
+ 2, offset, regionClipBounds);
}
void GrDistanceFieldTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip,
@@ -281,7 +285,8 @@ void GrDistanceFieldTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip&
const SkPaint& skPaint, const SkMatrix& viewMatrix,
const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset) {
+ const SkPoint& offset,
+ const SkIRect& regionClipBounds) {
SkASSERT(byteLength == 0 || text != NULL);
SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
@@ -292,7 +297,7 @@ void GrDistanceFieldTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip&
}
fViewMatrix = viewMatrix;
- this->init(rt, clip, paint, skPaint);
+ this->init(rt, clip, paint, skPaint, regionClipBounds);
SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
@@ -369,9 +374,10 @@ void GrDistanceFieldTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip&
this->finish();
if (fallbackTxt.count() > 0) {
- fFallbackTextContext->drawPosText(rt, clip, paint, skPaint, viewMatrix, fallbackTxt.begin(),
- fallbackTxt.count(), fallbackPos.begin(),
- scalarsPerPosition, offset);
+ fFallbackTextContext->drawPosText(rt, clip, paint, skPaint, viewMatrix,
+ fallbackTxt.begin(), fallbackTxt.count(),
+ fallbackPos.begin(), scalarsPerPosition, offset,
+ regionClipBounds);
}
}
diff --git a/src/gpu/GrDistanceFieldTextContext.h b/src/gpu/GrDistanceFieldTextContext.h
index 129c6e9d85..3fe44888ce 100644
--- a/src/gpu/GrDistanceFieldTextContext.h
+++ b/src/gpu/GrDistanceFieldTextContext.h
@@ -18,7 +18,8 @@ class GrTextStrike;
*/
class GrDistanceFieldTextContext : public GrTextContext {
public:
- static GrDistanceFieldTextContext* Create(GrContext*, const SkDeviceProperties&, bool enable);
+ static GrDistanceFieldTextContext* Create(GrContext*, SkGpuDevice*, const SkDeviceProperties&,
+ bool enable);
virtual ~GrDistanceFieldTextContext();
@@ -48,21 +49,22 @@ private:
SkRect fVertexBounds;
SkMatrix fViewMatrix;
- GrDistanceFieldTextContext(GrContext*, const SkDeviceProperties&, bool enable);
+ GrDistanceFieldTextContext(GrContext*, SkGpuDevice*, const SkDeviceProperties&, bool enable);
bool canDraw(const SkPaint& paint, const SkMatrix& viewMatrix) SK_OVERRIDE;
virtual void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
const SkMatrix& viewMatrix,
const char text[], size_t byteLength,
- SkScalar x, SkScalar y) SK_OVERRIDE;
+ SkScalar x, SkScalar y, const SkIRect& regionClipBounds) SK_OVERRIDE;
virtual void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
const SkMatrix& viewMatrix,
const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset) SK_OVERRIDE;
+ const SkPoint& offset, const SkIRect& regionClipBounds) SK_OVERRIDE;
- void init(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&);
+ void init(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
+ const SkIRect& regionClipBounds);
bool appendGlyph(GrGlyph::PackedID, SkScalar left, SkScalar top, GrFontScaler*);
bool uploadGlyph(GrGlyph*, GrFontScaler*);
void setupCoverageEffect(const SkColor& filteredColor);
diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp
index ec2fa21af0..db41c02239 100644
--- a/src/gpu/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/GrStencilAndCoverTextContext.cpp
@@ -20,19 +20,21 @@
#include "SkTextMapStateProc.h"
#include "SkTextFormatParams.h"
-GrStencilAndCoverTextContext::GrStencilAndCoverTextContext(
- GrContext* context, const SkDeviceProperties& properties)
- : GrTextContext(context, properties)
+GrStencilAndCoverTextContext::GrStencilAndCoverTextContext(GrContext* context,
+ SkGpuDevice* gpuDevice,
+ const SkDeviceProperties& properties)
+ : GrTextContext(context, gpuDevice, properties)
, fStroke(SkStrokeRec::kFill_InitStyle)
, fQueuedGlyphCount(0)
, fFallbackGlyphsIdx(kGlyphBufferSize) {
}
-GrStencilAndCoverTextContext* GrStencilAndCoverTextContext::Create(GrContext* context,
- const SkDeviceProperties& props) {
+GrStencilAndCoverTextContext*
+GrStencilAndCoverTextContext::Create(GrContext* context, SkGpuDevice* gpuDevice,
+ const SkDeviceProperties& props) {
GrStencilAndCoverTextContext* textContext = SkNEW_ARGS(GrStencilAndCoverTextContext,
- (context, props));
- textContext->fFallbackTextContext = GrBitmapTextContext::Create(context, props);
+ (context, gpuDevice, props));
+ textContext->fFallbackTextContext = GrBitmapTextContext::Create(context, gpuDevice, props);
return textContext;
}
@@ -71,7 +73,8 @@ void GrStencilAndCoverTextContext::onDrawText(GrRenderTarget* rt,
const SkMatrix& viewMatrix,
const char text[],
size_t byteLength,
- SkScalar x, SkScalar y) {
+ SkScalar x, SkScalar y,
+ const SkIRect& regionClipBounds) {
SkASSERT(byteLength == 0 || text != NULL);
if (text == NULL || byteLength == 0 /*|| fRC->isEmpty()*/) {
@@ -93,7 +96,8 @@ void GrStencilAndCoverTextContext::onDrawText(GrRenderTarget* rt,
// will turn off the use of device-space glyphs when perspective transforms
// are in use.
- this->init(rt, clip, paint, skPaint, byteLength, kMaxAccuracy_RenderMode, viewMatrix);
+ this->init(rt, clip, paint, skPaint, byteLength, kMaxAccuracy_RenderMode, viewMatrix,
+ regionClipBounds);
// Transform our starting point.
if (fUsingDeviceSpaceGlyphs) {
@@ -164,7 +168,8 @@ void GrStencilAndCoverTextContext::onDrawPosText(GrRenderTarget* rt,
size_t byteLength,
const SkScalar pos[],
int scalarsPerPosition,
- const SkPoint& offset) {
+ const SkPoint& offset,
+ const SkIRect& regionClipBounds) {
SkASSERT(byteLength == 0 || text != NULL);
SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
@@ -181,7 +186,8 @@ void GrStencilAndCoverTextContext::onDrawPosText(GrRenderTarget* rt,
// transform is not part of SkPaint::measureText API, and thus we use the
// same glyphs as what were measured.
- this->init(rt, clip, paint, skPaint, byteLength, kMaxPerformance_RenderMode, viewMatrix);
+ this->init(rt, clip, paint, skPaint, byteLength, kMaxPerformance_RenderMode, viewMatrix,
+ regionClipBounds);
SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
@@ -239,8 +245,9 @@ void GrStencilAndCoverTextContext::init(GrRenderTarget* rt,
const SkPaint& skPaint,
size_t textByteLength,
RenderMode renderMode,
- const SkMatrix& viewMatrix) {
- GrTextContext::init(rt, clip, paint, skPaint);
+ const SkMatrix& viewMatrix,
+ const SkIRect& regionClipBounds) {
+ GrTextContext::init(rt, clip, paint, skPaint, regionClipBounds);
fContextInitialMatrix = viewMatrix;
fViewMatrix = viewMatrix;
@@ -449,7 +456,7 @@ void GrStencilAndCoverTextContext::flush() {
fViewMatrix, (char*)&fGlyphIndices[fFallbackGlyphsIdx],
2 * fallbackGlyphCount,
get_xy_scalar_array(&fGlyphPositions[fFallbackGlyphsIdx]),
- 2, SkPoint::Make(0, 0));
+ 2, SkPoint::Make(0, 0), fRegionClipBounds);
fFallbackGlyphsIdx = kGlyphBufferSize;
}
diff --git a/src/gpu/GrStencilAndCoverTextContext.h b/src/gpu/GrStencilAndCoverTextContext.h
index d7871dcc31..e42989b90f 100644
--- a/src/gpu/GrStencilAndCoverTextContext.h
+++ b/src/gpu/GrStencilAndCoverTextContext.h
@@ -23,7 +23,8 @@ class GrPathRange;
*/
class GrStencilAndCoverTextContext : public GrTextContext {
public:
- static GrStencilAndCoverTextContext* Create(GrContext*, const SkDeviceProperties&);
+ static GrStencilAndCoverTextContext* Create(GrContext*, SkGpuDevice*,
+ const SkDeviceProperties&);
virtual ~GrStencilAndCoverTextContext();
@@ -67,22 +68,23 @@ private:
SkMatrix fLocalMatrix;
bool fUsingDeviceSpaceGlyphs;
- GrStencilAndCoverTextContext(GrContext*, const SkDeviceProperties&);
+ GrStencilAndCoverTextContext(GrContext*, SkGpuDevice*, const SkDeviceProperties&);
bool canDraw(const SkPaint& paint, const SkMatrix& viewMatrix) SK_OVERRIDE;
virtual void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
const SkMatrix& viewMatrix,
const char text[], size_t byteLength,
- SkScalar x, SkScalar y) SK_OVERRIDE;
+ SkScalar x, SkScalar y, const SkIRect& regionClipBounds) SK_OVERRIDE;
virtual void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
const SkMatrix& viewMatrix,
const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset) SK_OVERRIDE;
+ const SkPoint& offset, const SkIRect& regionClipBounds) SK_OVERRIDE;
void init(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
- size_t textByteLength, RenderMode, const SkMatrix& viewMatrix);
+ size_t textByteLength, RenderMode, const SkMatrix& viewMatrix,
+ const SkIRect& regionClipBounds);
bool mapToFallbackContext(SkMatrix* inverse);
void appendGlyph(const SkGlyph&, const SkPoint&);
void flush();
diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
index ad5e7c0aa5..28e10e398c 100644
--- a/src/gpu/GrTextContext.cpp
+++ b/src/gpu/GrTextContext.cpp
@@ -11,11 +11,19 @@
#include "GrFontScaler.h"
#include "SkAutoKern.h"
+#include "SkDrawProcs.h"
#include "SkGlyphCache.h"
-
-GrTextContext::GrTextContext(GrContext* context, const SkDeviceProperties& properties) :
- fFallbackTextContext(NULL),
- fContext(context), fDeviceProperties(properties), fDrawTarget(NULL) {
+#include "SkGpuDevice.h"
+#include "SkTextMapStateProc.h"
+#include "SkTextToPathIter.h"
+
+GrTextContext::GrTextContext(GrContext* context, SkGpuDevice* gpuDevice,
+ const SkDeviceProperties& properties)
+ : fFallbackTextContext(NULL)
+ , fContext(context)
+ , fGpuDevice(gpuDevice)
+ , fDeviceProperties(properties)
+ , fDrawTarget(NULL) {
}
GrTextContext::~GrTextContext() {
@@ -23,11 +31,12 @@ GrTextContext::~GrTextContext() {
}
void GrTextContext::init(GrRenderTarget* rt, const GrClip& clip, const GrPaint& grPaint,
- const SkPaint& skPaint) {
+ const SkPaint& skPaint, const SkIRect& regionClipBounds) {
fClip = clip;
fRenderTarget.reset(SkRef(rt));
+ fRegionClipBounds = regionClipBounds;
fClip.getConservativeBounds(fRenderTarget->width(), fRenderTarget->height(), &fClipRect);
fDrawTarget = fContext->getTextTarget();
@@ -36,48 +45,119 @@ void GrTextContext::init(GrRenderTarget* rt, const GrClip& clip, const GrPaint&
fSkPaint = skPaint;
}
-bool GrTextContext::drawText(GrRenderTarget* rt, const GrClip& clip, const GrPaint& paint,
+void GrTextContext::drawText(GrRenderTarget* rt, const GrClip& clip, const GrPaint& paint,
const SkPaint& skPaint, const SkMatrix& viewMatrix,
const char text[], size_t byteLength,
- SkScalar x, SkScalar y) {
+ SkScalar x, SkScalar y, const SkIRect& clipBounds) {
if (!fContext->getTextTarget()) {
- return false;
+ return;
}
GrTextContext* textContext = this;
do {
if (textContext->canDraw(skPaint, viewMatrix)) {
- textContext->onDrawText(rt, clip, paint, skPaint, viewMatrix, text, byteLength, x, y);
- return true;
+ textContext->onDrawText(rt, clip, paint, skPaint, viewMatrix, text, byteLength, x, y,
+ clipBounds);
+ return;
}
textContext = textContext->fFallbackTextContext;
} while (textContext);
- return false;
+ // fall back to drawing as a path
+ this->drawTextAsPath(skPaint, viewMatrix, text, byteLength, x, y, clipBounds);
}
-bool GrTextContext::drawPosText(GrRenderTarget* rt, const GrClip& clip, const GrPaint& paint,
+void GrTextContext::drawPosText(GrRenderTarget* rt, const GrClip& clip, const GrPaint& paint,
const SkPaint& skPaint, const SkMatrix& viewMatrix,
const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset) {
+ const SkPoint& offset, const SkIRect& clipBounds) {
if (!fContext->getTextTarget()) {
- return false;
+ return;
}
GrTextContext* textContext = this;
do {
if (textContext->canDraw(skPaint, viewMatrix)) {
textContext->onDrawPosText(rt, clip, paint, skPaint, viewMatrix, text, byteLength, pos,
- scalarsPerPosition, offset);
- return true;
+ scalarsPerPosition, offset, clipBounds);
+ return;
}
textContext = textContext->fFallbackTextContext;
} while (textContext);
- return false;
+ // fall back to drawing as a path
+ this->drawPosTextAsPath(skPaint, viewMatrix, text, byteLength, pos, scalarsPerPosition, offset,
+ clipBounds);
+}
+
+void GrTextContext::drawTextAsPath(const SkPaint& skPaint, const SkMatrix& viewMatrix,
+ const char text[], size_t byteLength, SkScalar x, SkScalar y,
+ const SkIRect& clipBounds) {
+ SkTextToPathIter iter(text, byteLength, skPaint, true);
+
+ SkMatrix matrix;
+ matrix.setScale(iter.getPathScale(), iter.getPathScale());
+ matrix.postTranslate(x, y);
+
+ const SkPath* iterPath;
+ SkScalar xpos, prevXPos = 0;
+
+ while (iter.next(&iterPath, &xpos)) {
+ matrix.postTranslate(xpos - prevXPos, 0);
+ if (iterPath) {
+ const SkPaint& pnt = iter.getPaint();
+ fGpuDevice->internalDrawPath(*iterPath, pnt, viewMatrix, &matrix, clipBounds, false);
+ }
+ prevXPos = xpos;
+ }
}
+void GrTextContext::drawPosTextAsPath(const SkPaint& origPaint, const SkMatrix& viewMatrix,
+ const char text[], size_t byteLength,
+ const SkScalar pos[], int scalarsPerPosition,
+ const SkPoint& offset, const SkIRect& clipBounds) {
+ // setup our std paint, in hopes of getting hits in the cache
+ SkPaint paint(origPaint);
+ SkScalar matrixScale = paint.setupForAsPaths();
+
+ SkMatrix matrix;
+ matrix.setScale(matrixScale, matrixScale);
+
+ // Temporarily jam in kFill, so we only ever ask for the raw outline from the cache.
+ paint.setStyle(SkPaint::kFill_Style);
+ paint.setPathEffect(NULL);
+
+ SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc();
+ SkAutoGlyphCache autoCache(paint, NULL, NULL);
+ SkGlyphCache* cache = autoCache.getCache();
+
+ const char* stop = text + byteLength;
+ SkTextAlignProc alignProc(paint.getTextAlign());
+ SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition);
+
+ // Now restore the original settings, so we "draw" with whatever style/stroking.
+ paint.setStyle(origPaint.getStyle());
+ paint.setPathEffect(origPaint.getPathEffect());
+
+ while (text < stop) {
+ const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
+ if (glyph.fWidth) {
+ const SkPath* path = cache->findPath(glyph);
+ if (path) {
+ SkPoint tmsLoc;
+ tmsProc(pos, &tmsLoc);
+ SkPoint loc;
+ alignProc(tmsLoc, glyph, &loc);
+
+ matrix[SkMatrix::kMTransX] = loc.fX;
+ matrix[SkMatrix::kMTransY] = loc.fY;
+ fGpuDevice->internalDrawPath(*path, paint, viewMatrix, &matrix, clipBounds, false);
+ }
+ }
+ pos += scalarsPerPosition;
+ }
+}
//*** change to output positions?
int GrTextContext::MeasureText(SkGlyphCache* cache, SkDrawCacheProc glyphCacheProc,
diff --git a/src/gpu/GrTextContext.h b/src/gpu/GrTextContext.h
index d333c63141..56a113daed 100644
--- a/src/gpu/GrTextContext.h
+++ b/src/gpu/GrTextContext.h
@@ -19,6 +19,7 @@ class GrClip;
class GrContext;
class GrDrawTarget;
class GrFontScaler;
+class SkGpuDevice;
/*
* This class wraps the state for a single text render
@@ -27,41 +28,56 @@ class GrTextContext {
public:
virtual ~GrTextContext();
- bool drawText(GrRenderTarget* rt, const GrClip&, const GrPaint&, const SkPaint&,
+ void drawText(GrRenderTarget* rt, const GrClip&, const GrPaint&, const SkPaint&,
const SkMatrix& viewMatrix, const char text[], size_t byteLength, SkScalar x,
- SkScalar y);
- bool drawPosText(GrRenderTarget* rt, const GrClip&, const GrPaint&, const SkPaint&,
+ SkScalar y, const SkIRect& clipBounds);
+ void drawPosText(GrRenderTarget* rt, const GrClip&, const GrPaint&, const SkPaint&,
const SkMatrix& viewMatrix,
const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset);
+ const SkPoint& offset, const SkIRect& clipBounds);
protected:
GrTextContext* fFallbackTextContext;
GrContext* fContext;
+ // TODO we probably don't really need to store a back pointer to the owning SkGpuDevice, except
+ // we need to be able to call drawPath on it in the event no other text context can draw the
+ // text. We might be able to move this logic to context though. This is unreffed because
+ // GrTextContext is completely owned by SkGpuDevice
+ SkGpuDevice* fGpuDevice;
SkDeviceProperties fDeviceProperties;
SkAutoTUnref<GrRenderTarget> fRenderTarget;
GrClip fClip;
GrDrawTarget* fDrawTarget;
SkIRect fClipRect;
+ SkIRect fRegionClipBounds;
GrPaint fPaint;
SkPaint fSkPaint;
- GrTextContext(GrContext*, const SkDeviceProperties&);
+ GrTextContext(GrContext*, SkGpuDevice*, const SkDeviceProperties&);
virtual bool canDraw(const SkPaint& paint, const SkMatrix& viewMatrix) = 0;
virtual void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
const SkMatrix& viewMatrix, const char text[], size_t byteLength,
- SkScalar x, SkScalar y) = 0;
+ SkScalar x, SkScalar y, const SkIRect& clipBounds) = 0;
virtual void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
const SkMatrix& viewMatrix,
const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset) = 0;
+ const SkPoint& offset, const SkIRect& clipBounds) = 0;
- void init(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&);
+ void drawTextAsPath(const SkPaint& origPaint, const SkMatrix& viewMatrix,
+ const char text[], size_t byteLength, SkScalar x, SkScalar y,
+ const SkIRect& clipBounds);
+ void drawPosTextAsPath(const SkPaint& origPaint, const SkMatrix& viewMatrix,
+ const char text[], size_t byteLength,
+ const SkScalar pos[], int scalarsPerPosition,
+ const SkPoint& offset, const SkIRect& clipBounds);
+
+ void init(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
+ const SkIRect& regionClipBounds);
void finish() { fDrawTarget = NULL; }
static GrFontScaler* GetGrFontScaler(SkGlyphCache* cache);
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index a97e42ece0..0335bcfa6b 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -160,7 +160,8 @@ SkGpuDevice::SkGpuDevice(GrRenderTarget* rt, const SkSurfaceProps* props, unsign
fLegacyBitmap.setPixelRef(pr)->unref();
bool useDFT = fSurfaceProps.isUseDistanceFieldFonts();
- fTextContext = fContext->createTextContext(fRenderTarget, this->getLeakyProperties(), useDFT);
+ fTextContext = fContext->createTextContext(fRenderTarget, this, this->getLeakyProperties(),
+ useDFT);
}
GrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkSurface::Budgeted budgeted,
@@ -1824,11 +1825,8 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
SkDEBUGCODE(this->validate();)
- if (!fTextContext->drawText(fRenderTarget, fClip, grPaint, paint, *draw.fMatrix,
- (const char *)text, byteLength, x, y)) {
- // this will just call our drawPath()
- draw.drawText_asPaths((const char*)text, byteLength, x, y, paint);
- }
+ fTextContext->drawText(fRenderTarget, fClip, grPaint, paint, *draw.fMatrix,
+ (const char *)text, byteLength, x, y, draw.fClip->getBounds());
}
void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, size_t byteLength,
@@ -1842,11 +1840,9 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, size_t byteL
SkDEBUGCODE(this->validate();)
- if (!fTextContext->drawPosText(fRenderTarget, fClip, grPaint, paint, *draw.fMatrix,
- (const char *)text, byteLength, pos, scalarsPerPos, offset)) {
- // this will just call our drawPath()
- draw.drawPosText_asPaths((const char*)text, byteLength, pos, scalarsPerPos, offset, paint);
- }
+ fTextContext->drawPosText(fRenderTarget, fClip, grPaint, paint, *draw.fMatrix,
+ (const char *)text, byteLength, pos, scalarsPerPos, offset,
+ draw.fClip->getBounds());
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
index af6dd0bcc2..be7857aadb 100644
--- a/src/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -210,6 +210,7 @@ private:
static GrRenderTarget* CreateRenderTarget(GrContext*, SkSurface::Budgeted, const SkImageInfo&,
int sampleCount);
+ friend class GrTextContext;
typedef SkBaseDevice INHERITED;
};