Chromium Code Reviews| Index: src/core/SkDraw.cpp |
| diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp |
| index fc615ab0ef967e5ec03d6b5ded6397a191974e5f..1275c492a097061d184691c3f87c2c3a2bd251da 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 @@ void SkDraw::drawText(const char text[], size_t byteLength, |
| // 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,66 @@ TextMapState::Proc TextMapState::pickProc(int scalarsPerPosition) { |
| ////////////////////////////////////////////////////////////////////////////// |
| +#define TEXT_AS_PATHS_PAINT_FLAGS_TO_IGNORE ( \ |
| + SkPaint::kDevKernText_Flag | \ |
| + SkPaint::kLinearText_Flag | \ |
| + SkPaint::kLCDRenderText_Flag | \ |
| + SkPaint::kEmbeddedBitmapText_Flag | \ |
| + SkPaint::kAutoHinting_Flag | \ |
| + SkPaint::kGenA8FromLCD_Flag ) |
| + |
| +#define TEXT_AS_PATHS_PAINT_FLAGS_TO_SET ( \ |
| + SkPaint::kSubpixelText_Flag ) |
|
bungeman-skia
2013/06/04 14:27:58
I think you also want kNo_Hinting.
reed1
2013/06/04 15:58:22
Done.
|
| + |
| +void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength, |
| + const SkScalar pos[], SkScalar constY, |
| + int scalarsPerPosition, |
| + const SkPaint& origPaint) const { |
| + const SkScalar stdSize = SkIntToScalar(SkPaint::kCanonicalTextSizeForPaths); |
| + |
| + // setup our std paint, in hopes of getting hits in the cache |
| + SkPaint paint(origPaint); |
| + paint.setFlags((paint.getFlags() & ~TEXT_AS_PATHS_PAINT_FLAGS_TO_IGNORE) |
| + | TEXT_AS_PATHS_PAINT_FLAGS_TO_SET); |
| + paint.setTextSize(stdSize); |
| + |
| + SkDraw draw(*this); |
| + |
| + // Now modify our matrix to account for the canonical text size |
| + SkMatrix matrix = *fMatrix; |
| + const SkScalar matrixScale = origPaint.getTextSize() / stdSize; |
| + 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 +1926,9 @@ void SkDraw::drawPosText(const char text[], size_t byteLength, |
| 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; |
| } |