diff options
author | 2009-09-03 21:45:49 +0000 | |
---|---|---|
committer | 2009-09-03 21:45:49 +0000 | |
commit | ebdeeb8a018f2df01e190fd961d68a94f0e0fcb9 (patch) | |
tree | 5bfd069dc9a8a21dc785bd2e2626e1ee727bc649 | |
parent | e9d0060f4d7b5a07a220182d83aae3a140784c4b (diff) |
don't magically convert to hairline unless we're < 1.0 in both X and Y. The new routine both checks,
and if legal, returns the new width which will be used to compute a modulated alpha.
git-svn-id: http://skia.googlecode.com/svn/trunk@352 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | src/core/SkDraw.cpp | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index 2b7c55f425..7f0cc15ba3 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -760,6 +760,35 @@ private: SkScalar fWidth; }; +static SkScalar fast_len(const SkVector& vec) { + SkScalar x = SkScalarAbs(vec.fX); + SkScalar y = SkScalarAbs(vec.fY); + if (x < y) { + SkTSwap(x, y); + } + return x + SkScalarHalf(y); +} + +// our idea is to return true if there is no appreciable skew or non-square scale +// for that we'll transform (0,1) and (1,0), and check that the resulting dot-prod +// is nearly one +static bool map_radius(const SkMatrix& matrix, SkScalar* value) { + if (matrix.getType() & SkMatrix::kPerspective_Mask) { + return false; + } + SkVector src[2], dst[2]; + src[0].set(*value, 0); + src[1].set(0, *value); + matrix.mapVectors(dst, src, 2); + SkScalar len0 = fast_len(dst[0]); + SkScalar len1 = fast_len(dst[1]); + if (len0 < SK_Scalar1 && len1 < SK_Scalar1) { + *value = SkScalarAve(len0, len1); + return true; + } + return false; +} + void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& paint, const SkMatrix* prePathMatrix, bool pathIsMutable) const { SkDEBUGCODE(this->validate();) @@ -806,22 +835,18 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& paint, SkAutoPaintRestoreColorStrokeWidth aprc(paint); - if (paint.getStyle() == SkPaint::kStroke_Style && - paint.getXfermode() == NULL && - (matrix->getType() & SkMatrix::kPerspective_Mask) == 0) { + // can we approximate a thin (but not hairline) stroke with an alpha-modulated + // hairline? Only if the matrix scales evenly in X and Y, and the device-width is + // less than a pixel + if (paint.getStyle() == SkPaint::kStroke_Style && paint.getXfermode() == NULL) { SkScalar width = paint.getStrokeWidth(); - if (width > 0) { - width = matrix->mapRadius(paint.getStrokeWidth()); - if (width < SK_Scalar1) { - int scale = (int)SkScalarMul(width, 256); - int alpha = paint.getAlpha() * scale >> 8; - - // pretend to be a hairline, with a modulated alpha - ((SkPaint*)&paint)->setAlpha(alpha); - ((SkPaint*)&paint)->setStrokeWidth(0); - -// SkDebugf("------ convert to hairline %d\n", scale); - } + if (width > 0 && map_radius(*matrix, &width)) { + int scale = (int)SkScalarMul(width, 256); + int alpha = paint.getAlpha() * scale >> 8; + + // pretend to be a hairline, with a modulated alpha + ((SkPaint*)&paint)->setAlpha(alpha); + ((SkPaint*)&paint)->setStrokeWidth(0); } } |