aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2009-09-03 21:45:49 +0000
committerGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2009-09-03 21:45:49 +0000
commitebdeeb8a018f2df01e190fd961d68a94f0e0fcb9 (patch)
tree5bfd069dc9a8a21dc785bd2e2626e1ee727bc649
parente9d0060f4d7b5a07a220182d83aae3a140784c4b (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.cpp55
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);
}
}