aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gyp/tests.gypi1
-rw-r--r--src/core/SkDraw.cpp39
-rw-r--r--tests/RectTest.cpp51
3 files changed, 75 insertions, 16 deletions
diff --git a/gyp/tests.gypi b/gyp/tests.gypi
index ad8525c782..d59b26204a 100644
--- a/gyp/tests.gypi
+++ b/gyp/tests.gypi
@@ -177,6 +177,7 @@
'../tests/RecordTest.cpp',
'../tests/RecorderTest.cpp',
'../tests/RecordingXfermodeTest.cpp',
+ '../tests/RectTest.cpp',
'../tests/RefCntTest.cpp',
'../tests/RefDictTest.cpp',
'../tests/RegionTest.cpp',
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 60075322b6..f69137f6b8 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -735,6 +735,16 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
}
}
+static inline SkPoint compute_stroke_size(const SkPaint& paint, const SkMatrix& matrix) {
+ SkASSERT(matrix.rectStaysRect());
+ SkASSERT(SkPaint::kFill_Style != paint.getStyle());
+
+ SkVector size;
+ SkPoint pt = { paint.getStrokeWidth(), paint.getStrokeWidth() };
+ matrix.mapVectors(&size, &pt, 1);
+ return SkPoint::Make(SkScalarAbs(size.fX), SkScalarAbs(size.fY));
+}
+
static bool easy_rect_join(const SkPaint& paint, const SkMatrix& matrix,
SkPoint* strokeSize) {
if (SkPaint::kMiter_Join != paint.getStrokeJoin() ||
@@ -742,11 +752,7 @@ static bool easy_rect_join(const SkPaint& paint, const SkMatrix& matrix,
return false;
}
- SkASSERT(matrix.rectStaysRect());
- SkPoint pt = { paint.getStrokeWidth(), paint.getStrokeWidth() };
- matrix.mapVectors(strokeSize, &pt, 1);
- strokeSize->fX = SkScalarAbs(strokeSize->fX);
- strokeSize->fY = SkScalarAbs(strokeSize->fY);
+ *strokeSize = compute_stroke_size(paint, matrix);
return true;
}
@@ -822,26 +828,27 @@ void SkDraw::drawRect(const SkRect& prePaintRect, const SkPaint& paint,
}
SkRect devRect;
- if (paintMatrix) {
- // skip the paintMatrix when transforming the rect by the CTM
- fMatrix->mapPoints(rect_points(devRect), rect_points(*postPaintRect), 2);
- } else {
- fMatrix->mapPoints(rect_points(devRect), rect_points(prePaintRect), 2);
- }
- // transform rect into devRect
+ const SkRect& paintRect = paintMatrix ? *postPaintRect : prePaintRect;
+ // skip the paintMatrix when transforming the rect by the CTM
+ fMatrix->mapPoints(rect_points(devRect), rect_points(paintRect), 2);
devRect.sort();
// look for the quick exit, before we build a blitter
- SkIRect ir = devRect.roundOut();
+ SkRect bbox = devRect;
if (paint.getStyle() != SkPaint::kFill_Style) {
// extra space for hairlines
if (paint.getStrokeWidth() == 0) {
- ir.outset(1, 1);
+ bbox.outset(1, 1);
} else {
- SkScalar radius = SkScalarHalf(paint.getStrokeWidth());
- ir.outset(radius, radius);
+ // For kStroke_RectType, strokeSize is already computed.
+ const SkPoint& ssize = (kStroke_RectType == rtype)
+ ? strokeSize
+ : compute_stroke_size(paint, *fMatrix);
+ bbox.outset(SkScalarHalf(ssize.x()), SkScalarHalf(ssize.y()));
}
}
+
+ SkIRect ir = bbox.roundOut();
if (fRC->quickReject(ir)) {
return;
}
diff --git a/tests/RectTest.cpp b/tests/RectTest.cpp
new file mode 100644
index 0000000000..be77a87406
--- /dev/null
+++ b/tests/RectTest.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkRect.h"
+#include "Test.h"
+
+static bool has_green_pixels(const SkBitmap& bm) {
+ for (int j = 0; j < bm.height(); ++j) {
+ for (int i = 0; i < bm.width(); ++i) {
+ if (SkColorGetG(bm.getColor(i, j))) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static void test_stroke_width_clipping(skiatest::Reporter* reporter) {
+ SkBitmap bm;
+ bm.allocN32Pixels(100, 10);
+ bm.eraseColor(SK_ColorTRANSPARENT);
+
+ SkCanvas canvas(bm);
+ SkPaint paint;
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(10);
+ paint.setColor(0xff00ff00);
+
+ // clip out the left half of our canvas
+ canvas.clipRect(SkRect::MakeXYWH(51, 0, 49, 100));
+
+ // no stroke bleed should be visible
+ canvas.drawRect(SkRect::MakeWH(44, 100), paint);
+ REPORTER_ASSERT(reporter, !has_green_pixels(bm));
+
+ // right stroke edge should bleed into the visible area
+ canvas.scale(2, 2);
+ canvas.drawRect(SkRect::MakeWH(22, 50), paint);
+ REPORTER_ASSERT(reporter, has_green_pixels(bm));
+}
+
+DEF_TEST(Rect, reporter) {
+ test_stroke_width_clipping(reporter);
+}