| Index: src/gpu/GrTextContext.cpp
|
| diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
|
| index ad5e7c0aa5e1e21347641625d5fb982895adbbe9..28e10e398c1d0d6b978a241e6050ae7293e15dca 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,
|
|
|