Use SkScalar when aligning glyphs in user space.
Drawing text from paths is done in user space and not in device space.
All operations in user space should be performed with SkScalars.
BUG=327031
R=reed@google.com
Review URL: https://codereview.chromium.org/113123005
git-svn-id: http://skia.googlecode.com/svn/trunk@12682 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 52891ea..ccab56c 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -1841,19 +1841,16 @@
// 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) {
+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) {
+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) {
+static void rightAlignProc(const SkPoint& loc, const SkGlyph& glyph, SkIPoint* dst) {
dst->set(SkScalarToFixed(loc.fX) - glyph.fAdvanceX,
SkScalarToFixed(loc.fY) - glyph.fAdvanceY);
}
@@ -1868,6 +1865,32 @@
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;
@@ -1944,7 +1967,7 @@
SkGlyphCache* cache = autoCache.getCache();
const char* stop = text + byteLength;
- AlignProc alignProc = pick_align_proc(paint.getTextAlign());
+ AlignProc_scalar alignProc = pick_align_proc_scalar(paint.getTextAlign());
TextMapState tms(SkMatrix::I(), constY);
TextMapState::Proc tmsProc = tms.pickProc(scalarsPerPosition);
@@ -1954,11 +1977,11 @@
const SkPath* path = cache->findPath(glyph);
if (path) {
tmsProc(tms, pos);
- SkIPoint fixedLoc;
- alignProc(tms.fLoc, glyph, &fixedLoc);
+ SkPoint loc;
+ alignProc(tms.fLoc, glyph, &loc);
- matrix[SkMatrix::kMTransX] = SkFixedToScalar(fixedLoc.fX);
- matrix[SkMatrix::kMTransY] = SkFixedToScalar(fixedLoc.fY);
+ matrix[SkMatrix::kMTransX] = loc.fX;
+ matrix[SkMatrix::kMTransY] = loc.fY;
if (fDevice) {
fDevice->drawPath(*this, *path, paint, &matrix, false);
} else {