From 9d54aeb8a192845f1f8122dba780d40ee6a0de1b Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Fri, 9 Aug 2013 19:48:26 +0000 Subject: [PATCH] All rSomethingTo() immediately following a close() are relative to the point we closed from, not the point we close to. Fix that. Seems like this has been broken since the stone ages. BUG=skia:1474, code.google.com/p/android/issues/detail?id=41216 R=bsalomon@google.com Author: mtklein@google.com Review URL: https://chromiumcodereview.appspot.com/22681006 git-svn-id: http://skia.googlecode.com/svn/trunk@10666 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/core/SkPath.cpp | 4 ++++ tests/PathTest.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp index 97204bb..ed2f555 100644 --- a/src/core/SkPath.cpp +++ b/src/core/SkPath.cpp @@ -749,6 +749,7 @@ void SkPath::lineTo(SkScalar x, SkScalar y) { } void SkPath::rLineTo(SkScalar x, SkScalar y) { + this->injectMoveToIfNeeded(); // This can change the result of this->getLastPt(). SkPoint pt; this->getLastPt(&pt); this->lineTo(pt.fX + x, pt.fY + y); @@ -770,6 +771,7 @@ void SkPath::quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) { } void SkPath::rQuadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) { + this->injectMoveToIfNeeded(); // This can change the result of this->getLastPt(). SkPoint pt; this->getLastPt(&pt); this->quadTo(pt.fX + x1, pt.fY + y1, pt.fX + x2, pt.fY + y2); @@ -803,6 +805,7 @@ void SkPath::conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, void SkPath::rConicTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2, SkScalar w) { + this->injectMoveToIfNeeded(); // This can change the result of this->getLastPt(). SkPoint pt; this->getLastPt(&pt); this->conicTo(pt.fX + dx1, pt.fY + dy1, pt.fX + dx2, pt.fY + dy2, w); @@ -827,6 +830,7 @@ void SkPath::cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, void SkPath::rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3) { + this->injectMoveToIfNeeded(); // This can change the result of this->getLastPt(). SkPoint pt; this->getLastPt(&pt); this->cubicTo(pt.fX + x1, pt.fY + y1, pt.fX + x2, pt.fY + y2, diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp index e698c7c..4637e92 100644 --- a/tests/PathTest.cpp +++ b/tests/PathTest.cpp @@ -32,6 +32,56 @@ static SkSurface* new_surface(int w, int h) { return SkSurface::NewRaster(info); } +static void test_path_close_issue1474(skiatest::Reporter* reporter) { + // This test checks that r{Line,Quad,Conic,Cubic}To following a close() + // are relative to the point we close to, not relative to the point we close from. + SkPath path; + SkPoint last; + + // Test rLineTo(). + path.rLineTo(0, 100); + path.rLineTo(100, 0); + path.close(); // Returns us back to 0,0. + path.rLineTo(50, 50); // This should go to 50,50. + + path.getLastPt(&last); + REPORTER_ASSERT(reporter, 50 == last.fX); + REPORTER_ASSERT(reporter, 50 == last.fY); + + // Test rQuadTo(). + path.rewind(); + path.rLineTo(0, 100); + path.rLineTo(100, 0); + path.close(); + path.rQuadTo(50, 50, 75, 75); + + path.getLastPt(&last); + REPORTER_ASSERT(reporter, 75 == last.fX); + REPORTER_ASSERT(reporter, 75 == last.fY); + + // Test rConicTo(). + path.rewind(); + path.rLineTo(0, 100); + path.rLineTo(100, 0); + path.close(); + path.rConicTo(50, 50, 85, 85, 2); + + path.getLastPt(&last); + REPORTER_ASSERT(reporter, 85 == last.fX); + REPORTER_ASSERT(reporter, 85 == last.fY); + + // Test rCubicTo(). + path.rewind(); + path.rLineTo(0, 100); + path.rLineTo(100, 0); + path.close(); + path.rCubicTo(50, 50, 85, 85, 95, 95); + + path.getLastPt(&last); + REPORTER_ASSERT(reporter, 95 == last.fX); + REPORTER_ASSERT(reporter, 95 == last.fY); +} + static void test_android_specific_behavior(skiatest::Reporter* reporter) { #ifdef SK_BUILD_FOR_ANDROID // Copy constructor should preserve generation ID, but assignment shouldn't. @@ -2469,6 +2519,7 @@ static void TestPath(skiatest::Reporter* reporter) { test_bad_cubic_crbug229478(); test_bad_cubic_crbug234190(); test_android_specific_behavior(reporter); + test_path_close_issue1474(reporter); } #include "TestClassDef.h" -- 2.7.4