diff options
-rw-r--r-- | gyp/tests.gypi | 1 | ||||
-rw-r--r-- | src/core/SkDraw.cpp | 39 | ||||
-rw-r--r-- | tests/RectTest.cpp | 51 |
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); +} |