add size limit for using glyphcache. above that, draw using paths
BUG=
R=bungeman@google.com
Review URL: https://codereview.chromium.org/16336024
git-svn-id: http://skia.googlecode.com/svn/trunk@9429 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index fc615ab..f313c4b 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -31,6 +31,22 @@
#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)
@@ -1663,9 +1679,7 @@
// SkScalarRec doesn't currently have a way of representing hairline stroke and
// will fill if its frame-width is 0.
- if (/*paint.isLinearText() ||*/
- (fMatrix->hasPerspective()) ||
- (0 == paint.getStrokeWidth() && SkPaint::kStroke_Style == paint.getStyle())) {
+ if (ShouldDrawTextAsPaths(paint, *fMatrix)) {
this->drawText_asPaths(text, byteLength, x, y, paint);
return;
}
@@ -1839,6 +1853,50 @@
//////////////////////////////////////////////////////////////////////////////
+void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength,
+ const SkScalar pos[], SkScalar constY,
+ int scalarsPerPosition,
+ const SkPaint& origPaint) const {
+ // setup our std paint, in hopes of getting hits in the cache
+ SkPaint paint(origPaint);
+ SkScalar matrixScale = paint.setupForAsPaths();
+
+ SkDraw draw(*this);
+
+ // Now modify our matrix to account for the canonical text size
+ SkMatrix matrix = *fMatrix;
+ matrix.preScale(matrixScale, matrixScale);
+ const SkScalar posScale = SkScalarInvert(matrixScale);
+
+ SkDrawCacheProc glyphCacheProc = paint.getDrawCacheProc();
+ SkAutoGlyphCache autoCache(paint, NULL, NULL);
+ SkGlyphCache* cache = autoCache.getCache();
+
+ const char* stop = text + byteLength;
+ AlignProc alignProc = pick_align_proc(paint.getTextAlign());
+ TextMapState tms(SkMatrix::I(), constY);
+ TextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition);
+
+ while (text < stop) {
+ const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0);
+ if (glyph.fWidth) {
+ const SkPath* path = cache->findPath(glyph);
+ if (path) {
+ tmsProc(tms, pos);
+ SkIPoint fixedLoc;
+ alignProc(tms.fLoc, glyph, &fixedLoc);
+
+ SkMatrix localMatrix = matrix;
+ localMatrix.preTranslate(SkFixedToScalar(fixedLoc.fX) * posScale,
+ SkFixedToScalar(fixedLoc.fY) * posScale);
+ draw.fMatrix = &localMatrix;
+ draw.drawPath(*path, paint);
+ }
+ }
+ pos += scalarsPerPosition;
+ }
+}
+
void SkDraw::drawPosText(const char text[], size_t byteLength,
const SkScalar pos[], SkScalar constY,
int scalarsPerPosition, const SkPaint& paint) const {
@@ -1852,10 +1910,9 @@
return;
}
- if (/*paint.isLinearText() ||*/
- (fMatrix->hasPerspective())) {
- // TODO !!!!
-// this->drawText_asPaths(text, byteLength, x, y, paint);
+ if (ShouldDrawTextAsPaths(paint, *fMatrix)) {
+ this->drawPosText_asPaths(text, byteLength, pos, constY,
+ scalarsPerPosition, paint);
return;
}