Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Unified Diff: src/gpu/GrTextContext.cpp

Issue 1015173002: Let text contexts fall back directly to paths (Closed) Base URL: https://skia.googlesource.com/skia.git@text-blob-to-context
Patch Set: move createTextContext to private Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/GrTextContext.h ('k') | src/gpu/SkGpuDevice.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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,
« no previous file with comments | « src/gpu/GrTextContext.h ('k') | src/gpu/SkGpuDevice.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698