From 1f99d933e5dab98c5047c7fe19fd4d7180c2cad4 Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Sun, 4 May 2014 03:43:20 +0000 Subject: [PATCH] fix the error that path is inversed for stroke and strokeAndFill styles. However, because hairline stroke + fill = fill (see src/core/SkStrokeRec.cpp), strokeAndFill will be thought as fill style when paint.getStrokeWidth() <= 0, this edge case can be inverse-filled. BUG=skia:2222 R=bsalomon@google.com, reed@google.com Author: yunchao.he@intel.com Review URL: https://codereview.chromium.org/183683010 git-svn-id: http://skia.googlecode.com/svn/trunk@14561 2bbb7eff-a529-9590-31e7-b0007b416f81 --- expectations/gm/ignored-tests.txt | 13 +++++++++++++ src/core/SkCanvas.cpp | 2 +- src/core/SkDraw.cpp | 7 +++++++ src/core/SkStroke.cpp | 10 ++++++---- src/gpu/GrStencilAndCoverPathRenderer.cpp | 2 +- 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/expectations/gm/ignored-tests.txt b/expectations/gm/ignored-tests.txt index 8a4dcc97e1..d059490edd 100644 --- a/expectations/gm/ignored-tests.txt +++ b/expectations/gm/ignored-tests.txt @@ -37,3 +37,16 @@ # This change removes an API that this GM was testing. If/when it lands and sticks, # I will likely just delete the GM. canvas-layer-state + +# yunchao: https://codereview.chromium.org/183683010/ +# This change fixed the error that path is inversed for Stroke and StrokeAndFill +# styles. These GM cases need to be rebaselined: +inverse_paths +degeneratesegments +quadclosepath +quadpath +lineclosepath +linepath +cubicclosepath +cubicpath +emptypath diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp index 6c0fc884e1..34559795e4 100644 --- a/src/core/SkCanvas.cpp +++ b/src/core/SkCanvas.cpp @@ -2076,7 +2076,7 @@ void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { const SkRect& r = path.getBounds(); if (r.width() <= 0 && r.height() <= 0) { - if (path.isInverseFillType()) { + if (path.isInverseFillType() && SkPaint::kFill_Style == paint.getStyle()) { this->internalDrawPaint(paint); } return; diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index c4f5f74eef..ee2e1125ea 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -1119,6 +1119,13 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint, SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, *paint, drawCoverage); + // make sure the path will not be inverse-stroked. hairlineStroke + fill = fill, + // they can be inverse-filled. + if (devPathPtr->isInverseFillType() && (SkPaint::kStroke_Style == paint->getStyle() || + (SkPaint::kStrokeAndFill_Style == paint->getStyle() && paint->getStrokeWidth() > 0))) { + devPathPtr->toggleInverseFillType(); + } + if (paint->getMaskFilter()) { SkPaint::Style style = doFill ? SkPaint::kFill_Style : SkPaint::kStroke_Style; diff --git a/src/core/SkStroke.cpp b/src/core/SkStroke.cpp index b138c326ba..7d8d707752 100644 --- a/src/core/SkStroke.cpp +++ b/src/core/SkStroke.cpp @@ -562,8 +562,9 @@ void SkStroke::strokePath(const SkPath& src, SkPath* dst) const { SkPath::Direction dir; if (src.isRect(&isClosed, &dir) && isClosed) { this->strokeRect(src.getBounds(), dst, dir); - // our answer should preserve the inverseness of the src - if (src.isInverseFillType()) { + // our answer should preserve the inverseness of the src, but the + // rect should not be inverse-stroked. + if (src.isInverseFillType() && fWidth < 0) { SkASSERT(!dst->isInverseFillType()); dst->toggleInverseFillType(); } @@ -646,8 +647,9 @@ DONE: #endif } - // our answer should preserve the inverseness of the src - if (src.isInverseFillType()) { + // our answer should preserve the inverseness of the src, but the path + // should not be inverse-stroked. + if (src.isInverseFillType() && fWidth < 0) { SkASSERT(!dst->isInverseFillType()); dst->toggleInverseFillType(); } diff --git a/src/gpu/GrStencilAndCoverPathRenderer.cpp b/src/gpu/GrStencilAndCoverPathRenderer.cpp index 273c01b861..ad6192ae3b 100644 --- a/src/gpu/GrStencilAndCoverPathRenderer.cpp +++ b/src/gpu/GrStencilAndCoverPathRenderer.cpp @@ -71,7 +71,7 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path, SkAutoTUnref p(fGpu->getContext()->createPath(path, stroke)); - if (path.isInverseFillType()) { + if (path.isInverseFillType() && SkStrokeRec::kFill_Style == stroke.getStyle()) { GR_STATIC_CONST_SAME_STENCIL(kInvertedStencilPass, kZero_StencilOp, kZero_StencilOp,