Index: src/core/SkDraw.cpp |
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp |
index 84899789cfcbf92e42b10caaeeef5bf0c10163bc..b77eb430c7be6ea33700a193a376d1b47ca719b8 100644 |
--- a/src/core/SkDraw.cpp |
+++ b/src/core/SkDraw.cpp |
@@ -23,6 +23,7 @@ |
#include "SkSmallAllocator.h" |
#include "SkString.h" |
#include "SkStroke.h" |
+#include "SkTextMapStateProc.h" |
#include "SkTLazy.h" |
#include "SkUtils.h" |
#include "SkVertState.h" |
@@ -1638,119 +1639,6 @@ void SkDraw::drawText(const char text[], size_t byteLength, |
} |
} |
-// last parameter is interpreted as SkFixed [x, y] |
-// return the fixed position, which may be rounded or not by the caller |
-// e.g. subpixel doesn't round |
-typedef void (*AlignProc)(const SkPoint&, const SkGlyph&, SkIPoint*); |
- |
-static void leftAlignProc(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* dst) { |
- dst->set(SkScalarToFixed(loc.fX), SkScalarToFixed(loc.fY)); |
-} |
- |
-static void centerAlignProc(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* dst) { |
- dst->set(SkScalarToFixed(loc.fX) - (glyph.fAdvanceX >> 1), |
- SkScalarToFixed(loc.fY) - (glyph.fAdvanceY >> 1)); |
-} |
- |
-static void rightAlignProc(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* dst) { |
- dst->set(SkScalarToFixed(loc.fX) - glyph.fAdvanceX, |
- SkScalarToFixed(loc.fY) - glyph.fAdvanceY); |
-} |
- |
-static AlignProc pick_align_proc(SkPaint::Align align) { |
- static const AlignProc gProcs[] = { |
- leftAlignProc, centerAlignProc, rightAlignProc |
- }; |
- |
- SkASSERT((unsigned)align < SK_ARRAY_COUNT(gProcs)); |
- |
- return gProcs[align]; |
-} |
- |
-typedef void (*AlignProc_scalar)(const SkPoint&, const SkGlyph&, SkPoint*); |
- |
-static void leftAlignProc_scalar(const SkPoint& loc, const SkGlyph& glyph, SkPoint* dst) { |
- dst->set(loc.fX, loc.fY); |
-} |
- |
-static void centerAlignProc_scalar(const SkPoint& loc, const SkGlyph& glyph, SkPoint* dst) { |
- dst->set(loc.fX - SkFixedToScalar(glyph.fAdvanceX >> 1), |
- loc.fY - SkFixedToScalar(glyph.fAdvanceY >> 1)); |
-} |
- |
-static void rightAlignProc_scalar(const SkPoint& loc, const SkGlyph& glyph, SkPoint* dst) { |
- dst->set(loc.fX - SkFixedToScalar(glyph.fAdvanceX), |
- loc.fY - SkFixedToScalar(glyph.fAdvanceY)); |
-} |
- |
-static AlignProc_scalar pick_align_proc_scalar(SkPaint::Align align) { |
- static const AlignProc_scalar gProcs[] = { |
- leftAlignProc_scalar, centerAlignProc_scalar, rightAlignProc_scalar |
- }; |
- |
- SkASSERT((unsigned)align < SK_ARRAY_COUNT(gProcs)); |
- |
- return gProcs[align]; |
-} |
- |
-class TextMapState { |
-public: |
- mutable SkPoint fLoc; |
- |
- TextMapState(const SkMatrix& matrix, SkScalar y) |
- : fMatrix(matrix), fProc(matrix.getMapXYProc()), fY(y) {} |
- |
- typedef void (*Proc)(const TextMapState&, const SkScalar pos[]); |
- |
- Proc pickProc(int scalarsPerPosition); |
- |
-private: |
- const SkMatrix& fMatrix; |
- SkMatrix::MapXYProc fProc; |
- SkScalar fY; // ignored by MapXYProc |
- // these are only used by Only... procs |
- SkScalar fScaleX, fTransX, fTransformedY; |
- |
- static void MapXProc(const TextMapState& state, const SkScalar pos[]) { |
- state.fProc(state.fMatrix, *pos, state.fY, &state.fLoc); |
- } |
- |
- static void MapXYProc(const TextMapState& state, const SkScalar pos[]) { |
- state.fProc(state.fMatrix, pos[0], pos[1], &state.fLoc); |
- } |
- |
- static void MapOnlyScaleXProc(const TextMapState& state, |
- const SkScalar pos[]) { |
- state.fLoc.set(SkScalarMul(state.fScaleX, *pos) + state.fTransX, |
- state.fTransformedY); |
- } |
- |
- static void MapOnlyTransXProc(const TextMapState& state, |
- const SkScalar pos[]) { |
- state.fLoc.set(*pos + state.fTransX, state.fTransformedY); |
- } |
-}; |
- |
-TextMapState::Proc TextMapState::pickProc(int scalarsPerPosition) { |
- SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
- |
- if (1 == scalarsPerPosition) { |
- unsigned mtype = fMatrix.getType(); |
- if (mtype & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)) { |
- return MapXProc; |
- } else { |
- fScaleX = fMatrix.getScaleX(); |
- fTransX = fMatrix.getTranslateX(); |
- fTransformedY = SkScalarMul(fY, fMatrix.getScaleY()) + |
- fMatrix.getTranslateY(); |
- return (mtype & SkMatrix::kScale_Mask) ? |
- MapOnlyScaleXProc : MapOnlyTransXProc; |
- } |
- } else { |
- return MapXYProc; |
- } |
-} |
- |
////////////////////////////////////////////////////////////////////////////// |
void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength, |
@@ -1773,9 +1661,8 @@ void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength, |
SkGlyphCache* cache = autoCache.getCache(); |
const char* stop = text + byteLength; |
- AlignProc_scalar alignProc = pick_align_proc_scalar(paint.getTextAlign()); |
- TextMapState tms(SkMatrix::I(), constY); |
- TextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition); |
+ SkTextAlignProcScalar alignProc(paint.getTextAlign()); |
+ SkTextMapStateProc tmsProc(SkMatrix::I(), constY, scalarsPerPosition); |
// Now restore the original settings, so we "draw" with whatever style/stroking. |
paint.setStyle(origPaint.getStyle()); |
@@ -1786,9 +1673,10 @@ void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength, |
if (glyph.fWidth) { |
const SkPath* path = cache->findPath(glyph); |
if (path) { |
- tmsProc(tms, pos); |
+ SkPoint tmsLoc; |
+ tmsProc(pos, &tmsLoc); |
SkPoint loc; |
- alignProc(tms.fLoc, glyph, &loc); |
+ alignProc(tmsLoc, glyph, &loc); |
matrix[SkMatrix::kMTransX] = loc.fX; |
matrix[SkMatrix::kMTransY] = loc.fY; |
@@ -1839,11 +1727,10 @@ void SkDraw::drawPosText(const char text[], size_t byteLength, |
} |
const char* stop = text + byteLength; |
- AlignProc alignProc = pick_align_proc(paint.getTextAlign()); |
+ SkTextAlignProc alignProc(paint.getTextAlign()); |
SkDraw1Glyph d1g; |
SkDraw1Glyph::Proc proc = d1g.init(this, blitter, cache, paint); |
- TextMapState tms(*fMatrix, constY); |
- TextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition); |
+ SkTextMapStateProc tmsProc(*fMatrix, constY, scalarsPerPosition); |
if (cache->isSubpixel()) { |
// maybe we should skip the rounding if linearText is set |
@@ -1865,9 +1752,10 @@ void SkDraw::drawPosText(const char text[], size_t byteLength, |
if (SkPaint::kLeft_Align == paint.getTextAlign()) { |
while (text < stop) { |
- tmsProc(tms, pos); |
- SkFixed fx = SkScalarToFixed(tms.fLoc.fX) + d1g.fHalfSampleX; |
- SkFixed fy = SkScalarToFixed(tms.fLoc.fY) + d1g.fHalfSampleY; |
+ SkPoint tmsLoc; |
+ tmsProc(pos, &tmsLoc); |
+ SkFixed fx = SkScalarToFixed(tmsLoc.fX) + d1g.fHalfSampleX; |
+ SkFixed fy = SkScalarToFixed(tmsLoc.fY) + d1g.fHalfSampleY; |
const SkGlyph& glyph = glyphCacheProc(cache, &text, |
fx & fxMask, fy & fyMask); |
@@ -1885,10 +1773,10 @@ void SkDraw::drawPosText(const char text[], size_t byteLength, |
if (metricGlyph.fWidth) { |
SkDEBUGCODE(SkFixed prevAdvX = metricGlyph.fAdvanceX;) |
SkDEBUGCODE(SkFixed prevAdvY = metricGlyph.fAdvanceY;) |
- |
- tmsProc(tms, pos); |
+ SkPoint tmsLoc; |
+ tmsProc(pos, &tmsLoc); |
SkIPoint fixedLoc; |
- alignProc(tms.fLoc, metricGlyph, &fixedLoc); |
+ alignProc(tmsLoc, metricGlyph, &fixedLoc); |
SkFixed fx = fixedLoc.fX + d1g.fHalfSampleX; |
SkFixed fy = fixedLoc.fY + d1g.fHalfSampleY; |
@@ -1913,11 +1801,12 @@ void SkDraw::drawPosText(const char text[], size_t byteLength, |
const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
if (glyph.fWidth) { |
- tmsProc(tms, pos); |
+ SkPoint tmsLoc; |
+ tmsProc(pos, &tmsLoc); |
proc(d1g, |
- SkScalarToFixed(tms.fLoc.fX) + SK_FixedHalf, //d1g.fHalfSampleX, |
- SkScalarToFixed(tms.fLoc.fY) + SK_FixedHalf, //d1g.fHalfSampleY, |
+ SkScalarToFixed(tmsLoc.fX) + SK_FixedHalf, //d1g.fHalfSampleX, |
+ SkScalarToFixed(tmsLoc.fY) + SK_FixedHalf, //d1g.fHalfSampleY, |
glyph); |
} |
pos += scalarsPerPosition; |
@@ -1928,10 +1817,11 @@ void SkDraw::drawPosText(const char text[], size_t byteLength, |
const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
if (glyph.fWidth) { |
- tmsProc(tms, pos); |
+ SkPoint tmsLoc; |
+ tmsProc(pos, &tmsLoc); |
SkIPoint fixedLoc; |
- alignProc(tms.fLoc, glyph, &fixedLoc); |
+ alignProc(tmsLoc, glyph, &fixedLoc); |
proc(d1g, |
fixedLoc.fX + SK_FixedHalf, //d1g.fHalfSampleX, |