Chromium Code Reviews| Index: tests/GrShapeTest.cpp |
| diff --git a/tests/GrShapeTest.cpp b/tests/GrShapeTest.cpp |
| index 9246c73f40f3419141bea2a97dbca5a1b3f8aba1..6ccc595fcf440e90debd73d4228ad0838e4e7b7a 100644 |
| --- a/tests/GrShapeTest.cpp |
| +++ b/tests/GrShapeTest.cpp |
| @@ -74,14 +74,186 @@ static bool test_bounds_by_rasterizing(const SkPath& path, const SkRect& bounds) |
| } |
| namespace { |
| +/** |
|
robertphillips
2016/08/24 23:00:58
Geom -> Geo ?
intputs -> inputs ?
bsalomon
2016/08/24 23:51:25
nah, I like intputs :)
|
| + * Geom is a factory for creating a GrShape from another representation. It also answers some |
| + * questions about expected behavior for GrShape given the intputs. |
| + */ |
| +class Geo { |
|
bsalomon
2016/08/24 17:25:21
This class replaces the templated GEO types in the
|
| +public: |
| + virtual ~Geo() {}; |
| + virtual GrShape makeShape(const SkPaint&) const = 0; |
| + virtual SkPath path() const = 0; |
| + // These functions allow tests to check for special cases where style gets |
| + // applied by GrShape in its constructor (without calling GrShape::applyStyle). |
| + // These unfortunately rely on knowing details of GrShape's implementation. |
| + // These predicates are factored out here to avoid littering the rest of the |
| + // test code with GrShape implementation details. |
| + virtual bool fillChangesGeom() const { return false; } |
| + virtual bool strokeIsConvertedToFill() const { return false; } |
| + virtual bool strokeAndFillIsConvertedToFill(const SkPaint&) const { return false; } |
| + // Is this something we expect GrShape to recognize as something simpler than a path. |
| + virtual bool isNonPath(const SkPaint& paint) const { return true; } |
| +}; |
| + |
| +class RectGeo : public Geo { |
| +public: |
| + RectGeo(const SkRect& rect) : fRect(rect) {} |
| + |
| + SkPath path() const override { |
| + SkPath path; |
| + path.addRect(fRect); |
| + return path; |
| + } |
| + |
| + GrShape makeShape(const SkPaint& paint) const override { |
| + return GrShape(fRect, paint); |
| + } |
| + |
| + bool strokeAndFillIsConvertedToFill(const SkPaint& paint) const override { |
| + SkASSERT(paint.getStyle() == SkPaint::kStrokeAndFill_Style); |
| + // Converted to an outset rectangle. |
|
robertphillips
2016/08/24 23:00:58
Is the conversion of a stroke & fill rect w/ round
bsalomon
2016/08/24 23:51:25
Bevel and round joins aren't yet handled. They wil
|
| + return paint.getStrokeJoin() == SkPaint::kMiter_Join && |
| + paint.getStrokeMiter() >= SK_ScalarSqrt2; |
| + } |
| + |
| +private: |
| + SkRect fRect; |
| +}; |
| + |
| +class RRectGeo : public Geo { |
| +public: |
| + RRectGeo(const SkRRect& rrect) : fRRect(rrect) {} |
| + |
| + GrShape makeShape(const SkPaint& paint) const override { |
| + return GrShape(fRRect, paint); |
| + } |
| + |
| + SkPath path() const override { |
| + SkPath path; |
| + path.addRRect(fRRect); |
| + return path; |
| + } |
| + |
| + bool strokeAndFillIsConvertedToFill(const SkPaint& paint) const override { |
| + SkASSERT(paint.getStyle() == SkPaint::kStrokeAndFill_Style); |
|
robertphillips
2016/08/24 23:00:58
isCircle handling ?
bsalomon
2016/08/24 23:51:25
No, not yet. Definitely more to do here.
|
| + if (fRRect.isRect()) { |
| + return RectGeo(fRRect.rect()).strokeAndFillIsConvertedToFill(paint); |
| + } |
| + return false; |
| + } |
| + |
| +private: |
| + SkRRect fRRect; |
| +}; |
| + |
| +class PathGeo : public Geo { |
| +public: |
| + enum class Invert { kNo, kYes }; |
| + |
| + PathGeo(const SkPath& path, Invert invert) : fPath(path) { |
| + SkASSERT(!path.isInverseFillType()); |
| + if (Invert::kYes == invert) { |
| + if (fPath.getFillType() == SkPath::kEvenOdd_FillType) { |
| + fPath.setFillType(SkPath::kInverseEvenOdd_FillType); |
| + } else { |
| + SkASSERT(fPath.getFillType() == SkPath::kWinding_FillType); |
| + fPath.setFillType(SkPath::kInverseWinding_FillType); |
| + } |
| + } |
| + } |
| + |
| + GrShape makeShape(const SkPaint& paint) const override { |
| + return GrShape(fPath, paint); |
| + } |
| + |
| + SkPath path() const override { return fPath; } |
| + |
| + bool fillChangesGeom() const override { |
| + // unclosed rects get closed. Lines get turned into empty geometry |
| + return this->isUnclosedRect() || (fPath.isLine(nullptr) && !fPath.isInverseFillType()); |
| + } |
| + |
| + bool strokeIsConvertedToFill() const override { |
| + return this->isAxisAlignedLine(); |
| + } |
| + |
| + bool strokeAndFillIsConvertedToFill(const SkPaint& paint) const override { |
| + SkASSERT(paint.getStyle() == SkPaint::kStrokeAndFill_Style); |
| + if (this->isAxisAlignedLine()) { |
| + // The fill is ignored (zero area) and the stroke is converted to a rrect. |
| + return true; |
| + } |
| + SkRect rect; |
| + unsigned start; |
| + SkPath::Direction dir; |
| + if (SkPathPriv::IsSimpleClosedRect(fPath, &rect, &dir, &start)) { |
| + return RectGeo(rect).strokeAndFillIsConvertedToFill(paint); |
| + } |
| + return false; |
| + } |
| + |
| + bool isNonPath(const SkPaint& paint) const override { |
| + return fPath.isLine(nullptr) || fPath.isEmpty(); |
| + } |
| + |
| +private: |
| + bool isAxisAlignedLine() const { |
| + SkPoint pts[2]; |
| + if (!fPath.isLine(pts)) { |
| + return false; |
| + } |
| + return pts[0].fX == pts[1].fX || pts[0].fY == pts[1].fY; |
| + } |
| + |
| + bool isUnclosedRect() const { |
| + bool closed; |
| + return fPath.isRect(nullptr, &closed, nullptr) && !closed; |
| + } |
| + |
| + SkPath fPath; |
| +}; |
| + |
| +class RRectPathGeo : public PathGeo { |
| +public: |
| + enum class RRectForStroke { kNo, kYes }; |
| + |
| + RRectPathGeo(const SkPath& path, const SkRRect& equivalentRRect, RRectForStroke rrectForStroke, |
| + Invert invert) |
| + : PathGeo(path, invert) |
| + , fRRect(equivalentRRect) |
| + , fRRectForStroke(rrectForStroke) {} |
| + |
| + RRectPathGeo(const SkPath& path, const SkRect& equivalentRect, RRectForStroke rrectForStroke, |
| + Invert invert) |
| + : RRectPathGeo(path, SkRRect::MakeRect(equivalentRect), rrectForStroke, invert) {} |
| + |
| + bool isNonPath(const SkPaint& paint) const override { |
| + if (SkPaint::kFill_Style == paint.getStyle() || RRectForStroke::kYes == fRRectForStroke) { |
| + return true; |
| + } |
| + return false; |
| + } |
| + |
| + const SkRRect& rrect() const { return fRRect; } |
| + |
| +private: |
| + SkRRect fRRect; |
| + RRectForStroke fRRectForStroke; |
| +}; |
| + |
| class TestCase { |
| public: |
| - template <typename GEO> |
| - TestCase(const GEO& geo, const SkPaint& paint, skiatest::Reporter* r, |
| - SkScalar scale = SK_Scalar1) : fBase(geo, paint) { |
| + TestCase(const Geo& geo, const SkPaint& paint, skiatest::Reporter* r, |
| + SkScalar scale = SK_Scalar1) : fBase(geo.makeShape(paint)) { |
| this->init(r, scale); |
| } |
| + template<typename... ShapeArgs> |
| + TestCase(skiatest::Reporter* r, ShapeArgs... shapeArgs) |
| + : fBase(shapeArgs...) { |
| + this->init(r, SK_Scalar1); |
| + } |
| + |
| TestCase(const GrShape& shape, skiatest::Reporter* r, SkScalar scale = SK_Scalar1) |
| : fBase(shape) { |
| this->init(r, scale); |
| @@ -433,78 +605,7 @@ static sk_sp<SkPathEffect> make_null_dash() { |
| return SkDashPathEffect::Make(kNullIntervals, SK_ARRAY_COUNT(kNullIntervals), 0.f); |
| } |
| -////////////////////////////////////////////////////////////////////////////// |
| -// These functions allow tests to check for special cases where style gets |
| -// applied by GrShape in its constructor (without calling GrShape::applyStyle). |
| -// These unfortunately rely on knowing details of GrShape's implementation. |
| -// These predicates are factored out here to avoid littering the rest of the |
| -// test code with GrShape implementation details. |
| - |
| -static bool path_is_axis_aligned_line(const SkPath& path) { |
| - SkPoint pts[2]; |
| - if (!path.isLine(pts)) { |
| - return false; |
| - } |
| - return pts[0].fX == pts[1].fX || pts[0].fY == pts[1].fY; |
| -} |
| - |
| -static bool path_is_unclosed_rect(const SkPath& path) { |
| - bool closed; |
| - return path.isRect(nullptr, &closed, nullptr) && !closed; |
| -} |
| - |
| -// Will a GrShape constructed from a geometry perform a geometric transformation if the style is |
| -// simple fill that would not otherwise be applied. |
| -template <typename GEO> static bool fill_changes_geom(const GEO& geo) { return false; } |
| -template <> bool fill_changes_geom<SkPath>(const SkPath& path) { |
| - // unclosed rects get closed. Lines get turned into empty geometry |
| - return path_is_unclosed_rect(path) || (path.isLine(nullptr) && !path.isInverseFillType()); |
| -} |
| - |
| -// Will a GrShape constructed from the geometry with a stroke style (without path effect) perform a |
| -// geometric transformation that applies the the stroke immediately without storing a stroke style. |
| -template <typename GEO> static bool stroke_is_converted_to_fill(const GEO& geo) { return false; } |
| -template <> bool stroke_is_converted_to_fill(const SkPath& path) { |
| - // converted to a rrect. |
| - return path_is_axis_aligned_line(path); |
| -} |
| - |
| -// Will a GrShape constructed from the geometry with a stroke-and-fill style (without path effect) |
| -// perform a geometric transformation that applies the the stroke immediately without storing a |
| -// stroke-and-fill style. |
| -template <typename GEO> static bool stroke_and_fill_is_converted_to_fill(const GEO& geo, const SkPaint& paint); |
| -template <> bool stroke_and_fill_is_converted_to_fill(const SkRect& rect, const SkPaint& paint) { |
| - SkASSERT(paint.getStyle() == SkPaint::kStrokeAndFill_Style); |
| - // Converted to an outset rectangle. |
| - return paint.getStrokeJoin() == SkPaint::kMiter_Join && |
| - paint.getStrokeMiter() >= SK_ScalarSqrt2; |
| -} |
| -template <> bool stroke_and_fill_is_converted_to_fill(const SkPath& path, const SkPaint& paint) { |
| - SkASSERT(paint.getStyle() == SkPaint::kStrokeAndFill_Style); |
| - if (path_is_axis_aligned_line(path)) { |
| - // The fill is ignored (zero area) and the stroke is converted to a rrect. |
| - return true; |
| - } |
| - SkRect rect; |
| - unsigned start; |
| - SkPath::Direction dir; |
| - if (SkPathPriv::IsSimpleClosedRect(path, &rect, &dir, &start)) { |
| - return stroke_and_fill_is_converted_to_fill<SkRect>(rect, paint); |
| - } |
| - return false; |
| -} |
| -template <> bool stroke_and_fill_is_converted_to_fill(const SkRRect& rr, const SkPaint& paint) { |
| - SkASSERT(paint.getStyle() == SkPaint::kStrokeAndFill_Style); |
| - if (rr.isRect()) { |
| - return stroke_and_fill_is_converted_to_fill<SkRect>(rr.rect(), paint); |
| - } |
| - return false; |
| -} |
| - |
| -////////////////////////////////////////////////////////////////////////////// |
| - |
| -template<typename GEO> |
| -static void test_basic(skiatest::Reporter* reporter, const GEO& geo) { |
| +static void test_basic(skiatest::Reporter* reporter, const Geo& geo) { |
| sk_sp<SkPathEffect> dashPE = make_dash(); |
| TestCase::SelfExpectations expectations; |
| @@ -527,7 +628,7 @@ static void test_basic(skiatest::Reporter* reporter, const GEO& geo) { |
| TestCase stroke2RoundBevelCase(geo, stroke2RoundBevel, reporter); |
| expectations.fPEHasValidKey = true; |
| expectations.fPEHasEffect = false; |
| - expectations.fStrokeApplies = !stroke_is_converted_to_fill(geo); |
| + expectations.fStrokeApplies = !geo.strokeIsConvertedToFill(); |
| stroke2RoundBevelCase.testExpectations(reporter, expectations); |
| TestCase(geo, stroke2RoundBevel, reporter).compare(reporter, stroke2RoundBevelCase, |
| TestCase::kAllSame_ComparisonExpecation); |
| @@ -542,7 +643,7 @@ static void test_basic(skiatest::Reporter* reporter, const GEO& geo) { |
| TestCase(geo, stroke2RoundBevelDash, reporter).compare(reporter, stroke2RoundBevelDashCase, |
| TestCase::kAllSame_ComparisonExpecation); |
| - if (fill_changes_geom(geo) || stroke_is_converted_to_fill(geo)) { |
| + if (geo.fillChangesGeom() || geo.strokeIsConvertedToFill()) { |
| fillCase.compare(reporter, stroke2RoundBevelCase, |
| TestCase::kAllDifferent_ComparisonExpecation); |
| fillCase.compare(reporter, stroke2RoundBevelDashCase, |
| @@ -553,7 +654,7 @@ static void test_basic(skiatest::Reporter* reporter, const GEO& geo) { |
| fillCase.compare(reporter, stroke2RoundBevelDashCase, |
| TestCase::kSameUpToPE_ComparisonExpecation); |
| } |
| - if (stroke_is_converted_to_fill(geo)) { |
| + if (geo.strokeIsConvertedToFill()) { |
| stroke2RoundBevelCase.compare(reporter, stroke2RoundBevelDashCase, |
| TestCase::kAllDifferent_ComparisonExpecation); |
| } else { |
| @@ -567,7 +668,7 @@ static void test_basic(skiatest::Reporter* reporter, const GEO& geo) { |
| TestCase stroke2RoundBevelAndFillCase(geo, stroke2RoundBevelAndFill, reporter); |
| expectations.fPEHasValidKey = true; |
| expectations.fPEHasEffect = false; |
| - expectations.fStrokeApplies = !stroke_is_converted_to_fill(geo); |
| + expectations.fStrokeApplies = !geo.strokeIsConvertedToFill(); |
| stroke2RoundBevelAndFillCase.testExpectations(reporter, expectations); |
| TestCase(geo, stroke2RoundBevelAndFill, reporter).compare(reporter, |
| stroke2RoundBevelAndFillCase, TestCase::kAllSame_ComparisonExpecation); |
| @@ -577,7 +678,7 @@ static void test_basic(skiatest::Reporter* reporter, const GEO& geo) { |
| TestCase stroke2RoundBevelAndFillDashCase(geo, stroke2RoundBevelAndFillDash, reporter); |
| expectations.fPEHasValidKey = true; |
| expectations.fPEHasEffect = false; |
| - expectations.fStrokeApplies = !stroke_is_converted_to_fill(geo); |
| + expectations.fStrokeApplies = !geo.strokeIsConvertedToFill(); |
| stroke2RoundBevelAndFillDashCase.testExpectations(reporter, expectations); |
| TestCase(geo, stroke2RoundBevelAndFillDash, reporter).compare( |
| reporter, stroke2RoundBevelAndFillDashCase, TestCase::kAllSame_ComparisonExpecation); |
| @@ -590,7 +691,7 @@ static void test_basic(skiatest::Reporter* reporter, const GEO& geo) { |
| TestCase hairlineCase(geo, hairline, reporter); |
| // Since hairline style doesn't change the SkPath data, it is keyed identically to fill (except |
| // in the line and unclosed rect cases). |
| - if (fill_changes_geom(geo)) { |
| + if (geo.fillChangesGeom()) { |
| hairlineCase.compare(reporter, fillCase, TestCase::kAllDifferent_ComparisonExpecation); |
| } else { |
| hairlineCase.compare(reporter, fillCase, TestCase::kAllSame_ComparisonExpecation); |
| @@ -601,8 +702,7 @@ static void test_basic(skiatest::Reporter* reporter, const GEO& geo) { |
| } |
| -template<typename GEO> |
| -static void test_scale(skiatest::Reporter* reporter, const GEO& geo) { |
| +static void test_scale(skiatest::Reporter* reporter, const Geo& geo) { |
| sk_sp<SkPathEffect> dashPE = make_dash(); |
| static const SkScalar kS1 = 1.f; |
| @@ -628,7 +728,7 @@ static void test_scale(skiatest::Reporter* reporter, const GEO& geo) { |
| TestCase strokeCase1(geo, stroke, reporter, kS1); |
| TestCase strokeCase2(geo, stroke, reporter, kS2); |
| // Scale affects the stroke |
| - if (stroke_is_converted_to_fill(geo)) { |
| + if (geo.strokeIsConvertedToFill()) { |
| REPORTER_ASSERT(reporter, !strokeCase1.baseShape().style().applies()); |
| strokeCase1.compare(reporter, strokeCase2, TestCase::kAllSame_ComparisonExpecation); |
| } else { |
| @@ -656,7 +756,7 @@ static void test_scale(skiatest::Reporter* reporter, const GEO& geo) { |
| // Scale affects the stroke, but check to make sure this didn't become a simpler shape (e.g. |
| // stroke-and-filled rect can become a rect), in which case the scale shouldn't matter and the |
| // geometries should agree. |
| - if (stroke_and_fill_is_converted_to_fill(geo, strokeAndFillDash)) { |
| + if (geo.strokeAndFillIsConvertedToFill(strokeAndFillDash)) { |
| REPORTER_ASSERT(reporter, !strokeAndFillCase1.baseShape().style().applies()); |
| strokeAndFillCase1.compare(reporter, strokeAndFillCase2, |
| TestCase::kAllSame_ComparisonExpecation); |
| @@ -672,8 +772,8 @@ static void test_scale(skiatest::Reporter* reporter, const GEO& geo) { |
| TestCase::kAllSame_ComparisonExpecation); |
| } |
| -template <typename GEO, typename T> |
| -static void test_stroke_param_impl(skiatest::Reporter* reporter, const GEO& geo, |
| +template <typename T> |
| +static void test_stroke_param_impl(skiatest::Reporter* reporter, const Geo& geo, |
| std::function<void(SkPaint*, T)> setter, T a, T b, |
| bool paramAffectsStroke, |
| bool paramAffectsDashAndStroke) { |
| @@ -693,7 +793,7 @@ static void test_stroke_param_impl(skiatest::Reporter* reporter, const GEO& geo, |
| if (paramAffectsStroke) { |
| // If stroking is immediately incorporated into a geometric transformation then the base |
| // shapes will differ. |
| - if (stroke_is_converted_to_fill(geo)) { |
| + if (geo.strokeIsConvertedToFill()) { |
| strokeACase.compare(reporter, strokeBCase, |
| TestCase::kAllDifferent_ComparisonExpecation); |
| } else { |
| @@ -713,8 +813,8 @@ static void test_stroke_param_impl(skiatest::Reporter* reporter, const GEO& geo, |
| if (paramAffectsStroke) { |
| // If stroking is immediately incorporated into a geometric transformation then the base |
| // shapes will differ. |
| - if (stroke_and_fill_is_converted_to_fill(geo, strokeAndFillA) || |
| - stroke_and_fill_is_converted_to_fill(geo, strokeAndFillB)) { |
| + if (geo.strokeAndFillIsConvertedToFill(strokeAndFillA) || |
| + geo.strokeAndFillIsConvertedToFill(strokeAndFillB)) { |
| strokeAndFillACase.compare(reporter, strokeAndFillBCase, |
| TestCase::kAllDifferent_ComparisonExpecation); |
| } else { |
| @@ -748,20 +848,22 @@ static void test_stroke_param_impl(skiatest::Reporter* reporter, const GEO& geo, |
| } |
| } |
| -template <typename GEO, typename T> |
| -static void test_stroke_param(skiatest::Reporter* reporter, const GEO& geo, |
| +template <typename T> |
| +static void test_stroke_param(skiatest::Reporter* reporter, const Geo& geo, |
| std::function<void(SkPaint*, T)> setter, T a, T b) { |
| test_stroke_param_impl(reporter, geo, setter, a, b, true, true); |
| }; |
| -template <typename GEO> |
| -static void test_stroke_cap(skiatest::Reporter* reporter, const GEO& geo) { |
| - GrShape shape(geo, GrStyle(SkStrokeRec::kHairline_InitStyle)); |
| +static void test_stroke_cap(skiatest::Reporter* reporter, const Geo& geo) { |
| + SkPaint hairline; |
| + hairline.setStrokeWidth(0); |
| + hairline.setStyle(SkPaint::kStroke_Style); |
| + GrShape shape = geo.makeShape(hairline); |
| // The cap should only affect shapes that may be open. |
| bool affectsStroke = !shape.knownToBeClosed(); |
| // Dashing adds ends that need caps. |
| bool affectsDashAndStroke = true; |
| - test_stroke_param_impl<GEO, SkPaint::Cap>( |
| + test_stroke_param_impl<SkPaint::Cap>( |
| reporter, |
| geo, |
| [](SkPaint* p, SkPaint::Cap c) { p->setStrokeCap(c);}, |
| @@ -774,15 +876,17 @@ static bool shape_known_not_to_have_joins(const GrShape& shape) { |
| return shape.asLine(nullptr, nullptr) || shape.isEmpty(); |
| } |
| -template <typename GEO> |
| -static void test_stroke_join(skiatest::Reporter* reporter, const GEO& geo) { |
| - GrShape shape(geo, GrStyle(SkStrokeRec::kHairline_InitStyle)); |
| +static void test_stroke_join(skiatest::Reporter* reporter, const Geo& geo) { |
| + SkPaint hairline; |
| + hairline.setStrokeWidth(0); |
| + hairline.setStyle(SkPaint::kStroke_Style); |
| + GrShape shape = geo.makeShape(hairline); |
| // GrShape recognizes certain types don't have joins and will prevent the join type from |
| // affecting the style key. |
| // Dashing doesn't add additional joins. However, GrShape currently loses track of this |
| // after applying the dash. |
| bool affectsStroke = !shape_known_not_to_have_joins(shape); |
| - test_stroke_param_impl<GEO, SkPaint::Join>( |
| + test_stroke_param_impl<SkPaint::Join>( |
| reporter, |
| geo, |
| [](SkPaint* p, SkPaint::Join j) { p->setStrokeJoin(j);}, |
| @@ -790,8 +894,7 @@ static void test_stroke_join(skiatest::Reporter* reporter, const GEO& geo) { |
| affectsStroke, true); |
| }; |
| -template <typename GEO> |
| -static void test_miter_limit(skiatest::Reporter* reporter, const GEO& geo) { |
| +static void test_miter_limit(skiatest::Reporter* reporter, const Geo& geo) { |
| auto setMiterJoinAndLimit = [](SkPaint* p, SkScalar miter) { |
| p->setStrokeJoin(SkPaint::kMiter_Join); |
| p->setStrokeMiter(miter); |
| @@ -802,12 +905,15 @@ static void test_miter_limit(skiatest::Reporter* reporter, const GEO& geo) { |
| p->setStrokeMiter(miter); |
| }; |
| - GrShape shape(geo, GrStyle(SkStrokeRec::kHairline_InitStyle)); |
| + SkPaint hairline; |
| + hairline.setStrokeWidth(0); |
| + hairline.setStyle(SkPaint::kStroke_Style); |
| + GrShape shape = geo.makeShape(hairline); |
| bool mayHaveJoins = !shape_known_not_to_have_joins(shape); |
| // The miter limit should affect stroked and dashed-stroked cases when the join type is |
| // miter. |
| - test_stroke_param_impl<GEO, SkScalar>( |
| + test_stroke_param_impl<SkScalar>( |
| reporter, |
| geo, |
| setMiterJoinAndLimit, |
| @@ -817,7 +923,7 @@ static void test_miter_limit(skiatest::Reporter* reporter, const GEO& geo) { |
| // The miter limit should not affect stroked and dashed-stroked cases when the join type is |
| // not miter. |
| - test_stroke_param_impl<GEO, SkScalar>( |
| + test_stroke_param_impl<SkScalar>( |
| reporter, |
| geo, |
| setOtherJoinAndLimit, |
| @@ -826,8 +932,7 @@ static void test_miter_limit(skiatest::Reporter* reporter, const GEO& geo) { |
| false); |
| } |
| -template<typename GEO> |
| -static void test_dash_fill(skiatest::Reporter* reporter, const GEO& geo) { |
| +static void test_dash_fill(skiatest::Reporter* reporter, const Geo& geo) { |
| // A dash with no stroke should have no effect |
| using DashFactoryFn = sk_sp<SkPathEffect>(*)(); |
| for (DashFactoryFn md : {&make_dash, &make_null_dash}) { |
| @@ -840,8 +945,7 @@ static void test_dash_fill(skiatest::Reporter* reporter, const GEO& geo) { |
| } |
| } |
| -template<typename GEO> |
| -void test_null_dash(skiatest::Reporter* reporter, const GEO& geo) { |
| +void test_null_dash(skiatest::Reporter* reporter, const Geo& geo) { |
| SkPaint fill; |
| SkPaint stroke; |
| stroke.setStyle(SkPaint::kStroke_Style); |
| @@ -864,21 +968,20 @@ void test_null_dash(skiatest::Reporter* reporter, const GEO& geo) { |
| nullDashCase.compare(reporter, strokeCase, TestCase::kAllSame_ComparisonExpecation); |
| // Check whether the fillCase or strokeCase/nullDashCase would undergo a geometric tranformation |
| // on construction in order to determine how to compare the fill and stroke. |
| - if (fill_changes_geom(geo) || stroke_is_converted_to_fill(geo)) { |
| + if (geo.fillChangesGeom() || geo.strokeIsConvertedToFill()) { |
| nullDashCase.compare(reporter, fillCase, TestCase::kAllDifferent_ComparisonExpecation); |
| } else { |
| nullDashCase.compare(reporter, fillCase, TestCase::kSameUpToStroke_ComparisonExpecation); |
| } |
| // In the null dash case we may immediately convert to a fill, but not for the normal dash case. |
| - if (stroke_is_converted_to_fill(geo)) { |
| + if (geo.strokeIsConvertedToFill()) { |
| nullDashCase.compare(reporter, dashCase, TestCase::kAllDifferent_ComparisonExpecation); |
| } else { |
| nullDashCase.compare(reporter, dashCase, TestCase::kSameUpToPE_ComparisonExpecation); |
| } |
| } |
| -template <typename GEO> |
| -void test_path_effect_makes_rrect(skiatest::Reporter* reporter, const GEO& geo) { |
| +void test_path_effect_makes_rrect(skiatest::Reporter* reporter, const Geo& geo) { |
| /** |
| * This path effect takes any input path and turns it into a rrect. It passes through stroke |
| * info. |
| @@ -921,7 +1024,7 @@ void test_path_effect_makes_rrect(skiatest::Reporter* reporter, const GEO& geo) |
| // Check whether constructing the filled case would cause the base shape to have a different |
| // geometry (because of a geometric transformation upon initial GrShape construction). |
| - if (fill_changes_geom(geo)) { |
| + if (geo.fillChangesGeom()) { |
| fillGeoCase.compare(reporter, geoPECase, TestCase::kAllDifferent_ComparisonExpecation); |
| fillGeoCase.compare(reporter, geoPEStrokeCase, |
| TestCase::kAllDifferent_ComparisonExpecation); |
| @@ -932,10 +1035,10 @@ void test_path_effect_makes_rrect(skiatest::Reporter* reporter, const GEO& geo) |
| geoPECase.compare(reporter, geoPEStrokeCase, |
| TestCase::kSameUpToStroke_ComparisonExpecation); |
| - TestCase rrectFillCase(RRectPathEffect::RRect(), fill, reporter); |
| + TestCase rrectFillCase(reporter, RRectPathEffect::RRect(), fill); |
| SkPaint stroke = peStroke; |
| stroke.setPathEffect(nullptr); |
| - TestCase rrectStrokeCase(RRectPathEffect::RRect(), stroke, reporter); |
| + TestCase rrectStrokeCase(reporter, RRectPathEffect::RRect(), stroke); |
| SkRRect rrect; |
| // Applying the path effect should make a SkRRect shape. There is no further stroking in the |
| @@ -962,8 +1065,7 @@ void test_path_effect_makes_rrect(skiatest::Reporter* reporter, const GEO& geo) |
| rrectStrokeCase.appliedFullStyleKey()); |
| } |
| -template <typename GEO> |
| -void test_unknown_path_effect(skiatest::Reporter* reporter, const GEO& geo) { |
| +void test_unknown_path_effect(skiatest::Reporter* reporter, const Geo& geo) { |
| /** |
| * This path effect just adds two lineTos to the input path. |
| */ |
| @@ -1003,8 +1105,7 @@ void test_unknown_path_effect(skiatest::Reporter* reporter, const GEO& geo) { |
| geoPEStrokeCase.testExpectations(reporter, expectations); |
| } |
| -template <typename GEO> |
| -void test_make_hairline_path_effect(skiatest::Reporter* reporter, const GEO& geo, bool isNonPath) { |
| +void test_make_hairline_path_effect(skiatest::Reporter* reporter, const Geo& geo) { |
| /** |
| * This path effect just changes the stroke rec to hairline. |
| */ |
| @@ -1036,7 +1137,7 @@ void test_make_hairline_path_effect(skiatest::Reporter* reporter, const GEO& geo |
| peCase.baseShape().asPath(&a); |
| peCase.appliedPathEffectShape().asPath(&b); |
| peCase.appliedFullStyleShape().asPath(&c); |
| - if (isNonPath) { |
| + if (geo.isNonPath(pe)) { |
| // RRect types can have a change in start index or direction after the PE is applied. This |
| // is because once the PE is applied, GrShape may canonicalize the dir and index since it |
| // is not germane to the styling any longer. |
| @@ -1058,26 +1159,21 @@ void test_make_hairline_path_effect(skiatest::Reporter* reporter, const GEO& geo |
| REPORTER_ASSERT(reporter, peCase.appliedFullStyleShape().style().isSimpleHairline()); |
| } |
| -/** |
| - * isNonPath indicates whether the initial shape made from the path is expected to be recognized |
| - * as a simpler shape type (e.g. rrect) |
| - */ |
| -void test_volatile_path(skiatest::Reporter* reporter, const SkPath& path, |
| - bool isNonPath) { |
| - SkPath vPath(path); |
| +void test_volatile_path(skiatest::Reporter* reporter, const Geo& geo) { |
| + SkPath vPath = geo.path(); |
| vPath.setIsVolatile(true); |
| SkPaint dashAndStroke; |
| dashAndStroke.setPathEffect(make_dash()); |
| dashAndStroke.setStrokeWidth(2.f); |
| dashAndStroke.setStyle(SkPaint::kStroke_Style); |
| - TestCase volatileCase(vPath, dashAndStroke, reporter); |
| + TestCase volatileCase(reporter, vPath, dashAndStroke); |
| // We expect a shape made from a volatile path to have a key iff the shape is recognized |
| // as a specialized geometry. |
| - if (isNonPath) { |
| + if (geo.isNonPath(dashAndStroke)) { |
| REPORTER_ASSERT(reporter, SkToBool(volatileCase.baseKey().count())); |
| // In this case all the keys should be identical to the non-volatile case. |
| - TestCase nonVolatileCase(path, dashAndStroke, reporter); |
| + TestCase nonVolatileCase(reporter, geo.path(), dashAndStroke); |
| volatileCase.compare(reporter, nonVolatileCase, TestCase::kAllSame_ComparisonExpecation); |
| } else { |
| // None of the keys should be valid. |
| @@ -1088,8 +1184,7 @@ void test_volatile_path(skiatest::Reporter* reporter, const SkPath& path, |
| } |
| } |
| -template <typename GEO> |
| -void test_path_effect_makes_empty_shape(skiatest::Reporter* reporter, const GEO& geo) { |
| +void test_path_effect_makes_empty_shape(skiatest::Reporter* reporter, const Geo& geo) { |
| /** |
| * This path effect returns an empty path. |
| */ |
| @@ -1137,8 +1232,7 @@ void test_path_effect_makes_empty_shape(skiatest::Reporter* reporter, const GEO& |
| REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedFullStyleShape().isEmpty()); |
| } |
| -template <typename GEO> |
| -void test_path_effect_fails(skiatest::Reporter* reporter, const GEO& geo) { |
| +void test_path_effect_fails(skiatest::Reporter* reporter, const Geo& geo) { |
| /** |
| * This path effect always fails to apply. |
| */ |
| @@ -1203,7 +1297,7 @@ void test_path_effect_fails(skiatest::Reporter* reporter, const GEO& geo) { |
| void test_empty_shape(skiatest::Reporter* reporter) { |
| SkPath emptyPath; |
| SkPaint fill; |
| - TestCase fillEmptyCase(emptyPath, fill, reporter); |
| + TestCase fillEmptyCase(reporter, emptyPath, fill); |
| REPORTER_ASSERT(reporter, fillEmptyCase.baseShape().isEmpty()); |
| REPORTER_ASSERT(reporter, fillEmptyCase.appliedPathEffectShape().isEmpty()); |
| REPORTER_ASSERT(reporter, fillEmptyCase.appliedFullStyleShape().isEmpty()); |
| @@ -1221,7 +1315,7 @@ void test_empty_shape(skiatest::Reporter* reporter) { |
| SkPaint stroke; |
| stroke.setStrokeWidth(2.f); |
| stroke.setStyle(SkPaint::kStroke_Style); |
| - TestCase strokeEmptyCase(emptyPath2, stroke, reporter); |
| + TestCase strokeEmptyCase(reporter, emptyPath2, stroke); |
| strokeEmptyCase.compare(reporter, fillEmptyCase, TestCase::kAllSame_ComparisonExpecation); |
| // Dashing and stroking an empty path should have no effect |
| @@ -1230,20 +1324,20 @@ void test_empty_shape(skiatest::Reporter* reporter) { |
| dashAndStroke.setPathEffect(make_dash()); |
| dashAndStroke.setStrokeWidth(2.f); |
| dashAndStroke.setStyle(SkPaint::kStroke_Style); |
| - TestCase dashAndStrokeEmptyCase(emptyPath3, dashAndStroke, reporter); |
| + TestCase dashAndStrokeEmptyCase(reporter, emptyPath3, dashAndStroke); |
| dashAndStrokeEmptyCase.compare(reporter, fillEmptyCase, |
| TestCase::kAllSame_ComparisonExpecation); |
| // A shape made from an empty rrect should behave the same as an empty path. |
| SkRRect emptyRRect = SkRRect::MakeRect(SkRect::MakeEmpty()); |
| REPORTER_ASSERT(reporter, emptyRRect.getType() == SkRRect::kEmpty_Type); |
| - TestCase dashAndStrokeEmptyRRectCase(emptyRRect, dashAndStroke, reporter); |
| + TestCase dashAndStrokeEmptyRRectCase(reporter, emptyRRect, dashAndStroke); |
| dashAndStrokeEmptyRRectCase.compare(reporter, fillEmptyCase, |
| TestCase::kAllSame_ComparisonExpecation); |
| // Same for a rect. |
| SkRect emptyRect = SkRect::MakeEmpty(); |
| - TestCase dashAndStrokeEmptyRectCase(emptyRect, dashAndStroke, reporter); |
| + TestCase dashAndStrokeEmptyRectCase(reporter, emptyRect, dashAndStroke); |
| dashAndStrokeEmptyRectCase.compare(reporter, fillEmptyCase, |
| TestCase::kAllSame_ComparisonExpecation); |
| } |
| @@ -1535,22 +1629,22 @@ void test_lines(skiatest::Reporter* r) { |
| SkPaint dash = stroke; |
| dash.setPathEffect(make_dash()); |
| - TestCase fillAB(lineAB, fill, r); |
| - TestCase fillEmpty(SkPath(), fill, r); |
| + TestCase fillAB(r, lineAB, fill); |
| + TestCase fillEmpty(r, SkPath(), fill); |
| fillAB.compare(r, fillEmpty, TestCase::kAllSame_ComparisonExpecation); |
| REPORTER_ASSERT(r, !fillAB.baseShape().asLine(nullptr, nullptr)); |
| - TestCase strokeAB(lineAB, stroke, r); |
| - TestCase strokeBA(lineBA, stroke, r); |
| - TestCase strokeAC(lineAC, stroke, r); |
| + TestCase strokeAB(r, lineAB, stroke); |
| + TestCase strokeBA(r, lineBA, stroke); |
| + TestCase strokeAC(r, lineAC, stroke); |
| - TestCase hairlineAB(lineAB, hairline, r); |
| - TestCase hairlineBA(lineBA, hairline, r); |
| - TestCase hairlineAC(lineAC, hairline, r); |
| + TestCase hairlineAB(r, lineAB, hairline); |
| + TestCase hairlineBA(r, lineBA, hairline); |
| + TestCase hairlineAC(r, lineAC, hairline); |
| - TestCase dashAB(lineAB, dash, r); |
| - TestCase dashBA(lineBA, dash, r); |
| - TestCase dashAC(lineAC, dash, r); |
| + TestCase dashAB(r, lineAB, dash); |
| + TestCase dashBA(r, lineBA, dash); |
| + TestCase dashAC(r, lineAC, dash); |
| strokeAB.compare(r, fillAB, TestCase::kAllDifferent_ComparisonExpecation); |
| @@ -1595,9 +1689,9 @@ void test_lines(skiatest::Reporter* r) { |
| pts[0] == kB && pts[1] == kA); |
| - TestCase strokeInvAB(invLineAB, stroke, r); |
| - TestCase hairlineInvAB(invLineAB, hairline, r); |
| - TestCase dashInvAB(invLineAB, dash, r); |
| + TestCase strokeInvAB(r, invLineAB, stroke); |
| + TestCase hairlineInvAB(r, invLineAB, hairline); |
| + TestCase dashInvAB(r, invLineAB, dash); |
| strokeInvAB.compare(r, strokeAB, TestCase::kAllDifferent_ComparisonExpecation); |
| hairlineInvAB.compare(r, hairlineAB, TestCase::kAllDifferent_ComparisonExpecation); |
| // Dashing ignores inverse. |
| @@ -1633,14 +1727,14 @@ static void test_stroked_lines(skiatest::Reporter* r) { |
| SkPaint fill; |
| - TestCase(linePath, buttCap, r).compare(r, TestCase(SkRect::MakeLTRB(2, 4, 6, 5), fill, r), |
| + TestCase(r, linePath, buttCap).compare(r, TestCase(r, SkRect::MakeLTRB(2, 4, 6, 5), fill), |
| TestCase::kAllSame_ComparisonExpecation); |
| - TestCase(linePath, squareCap, r).compare(r, TestCase(SkRect::MakeLTRB(2, 2, 6, 7), fill, r), |
| + TestCase(r, linePath, squareCap).compare(r, TestCase(r, SkRect::MakeLTRB(2, 2, 6, 7), fill), |
| TestCase::kAllSame_ComparisonExpecation); |
| - TestCase(linePath, roundCap, r).compare(r, |
| - TestCase(SkRRect::MakeRectXY(SkRect::MakeLTRB(2, 2, 6, 7), 2, 2), fill, r), |
| + TestCase(r, linePath, roundCap).compare(r, |
| + TestCase(r, SkRRect::MakeRectXY(SkRect::MakeLTRB(2, 2, 6, 7), 2, 2), fill), |
| TestCase::kAllSame_ComparisonExpecation); |
| // horizontal |
| @@ -1648,12 +1742,12 @@ static void test_stroked_lines(skiatest::Reporter* r) { |
| linePath.moveTo(4, 4); |
| linePath.lineTo(5, 4); |
| - TestCase(linePath, buttCap, r).compare(r, TestCase(SkRect::MakeLTRB(4, 2, 5, 6), fill, r), |
| + TestCase(r, linePath, buttCap).compare(r, TestCase(r, SkRect::MakeLTRB(4, 2, 5, 6), fill), |
| TestCase::kAllSame_ComparisonExpecation); |
| - TestCase(linePath, squareCap, r).compare(r, TestCase(SkRect::MakeLTRB(2, 2, 7, 6), fill, r), |
| + TestCase(r, linePath, squareCap).compare(r, TestCase(r, SkRect::MakeLTRB(2, 2, 7, 6), fill), |
| TestCase::kAllSame_ComparisonExpecation); |
| - TestCase(linePath, roundCap, r).compare(r, |
| - TestCase(SkRRect::MakeRectXY(SkRect::MakeLTRB(2, 2, 7, 6), 2, 2), fill, r), |
| + TestCase(r, linePath, roundCap).compare(r, |
| + TestCase(r, SkRRect::MakeRectXY(SkRect::MakeLTRB(2, 2, 7, 6), 2, 2), fill), |
| TestCase::kAllSame_ComparisonExpecation); |
| // point |
| @@ -1661,183 +1755,135 @@ static void test_stroked_lines(skiatest::Reporter* r) { |
| linePath.moveTo(4, 4); |
| linePath.lineTo(4, 4); |
| - TestCase(linePath, buttCap, r).compare(r, TestCase(SkRect::MakeEmpty(), fill, r), |
| + TestCase(r, linePath, buttCap).compare(r, TestCase(r, SkRect::MakeEmpty(), fill), |
| TestCase::kAllSame_ComparisonExpecation); |
| - TestCase(linePath, squareCap, r).compare(r, TestCase(SkRect::MakeLTRB(2, 2, 6, 6), fill, r), |
| + TestCase(r, linePath, squareCap).compare(r, TestCase(r, SkRect::MakeLTRB(2, 2, 6, 6), fill), |
| TestCase::kAllSame_ComparisonExpecation); |
| - TestCase(linePath, roundCap, r).compare(r, |
| - TestCase(SkRRect::MakeRectXY(SkRect::MakeLTRB(2, 2, 6, 6), 2, 2), fill, r), |
| + TestCase(r, linePath, roundCap).compare(r, |
| + TestCase(r, SkRRect::MakeRectXY(SkRect::MakeLTRB(2, 2, 6, 6), 2, 2), fill), |
| TestCase::kAllSame_ComparisonExpecation); |
| } |
| DEF_TEST(GrShape, reporter) { |
| + SkTArray<std::unique_ptr<Geo>> geos; |
| + SkTArray<std::unique_ptr<RRectPathGeo>> rrectPathGeos; |
| + |
| for (auto r : { SkRect::MakeWH(10, 20), |
| SkRect::MakeWH(-10, -20), |
| SkRect::MakeWH(-10, 20), |
| SkRect::MakeWH(10, -20)}) { |
| - test_basic(reporter, r); |
| - test_scale(reporter, r); |
| - test_dash_fill(reporter, r); |
| - test_null_dash(reporter, r); |
| - // Test modifying various stroke params. |
| - test_stroke_param<SkRect, SkScalar>( |
| - reporter, r, |
| - [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, |
| - SkIntToScalar(2), SkIntToScalar(4)); |
| - test_stroke_join(reporter, r); |
| - test_stroke_cap(reporter, r); |
| - test_miter_limit(reporter, r); |
| - test_path_effect_makes_rrect(reporter, r); |
| - test_unknown_path_effect(reporter, r); |
| - test_path_effect_makes_empty_shape(reporter, r); |
| - test_path_effect_fails(reporter, r); |
| - test_make_hairline_path_effect(reporter, r, true); |
| - GrShape shape(r); |
| - REPORTER_ASSERT(reporter, !shape.asLine(nullptr, nullptr)); |
| + geos.emplace_back(new RectGeo(r)); |
| + SkPath rectPath; |
| + rectPath.addRect(r); |
| + geos.emplace_back(new RRectPathGeo(rectPath, r, RRectPathGeo::RRectForStroke::kYes, |
| + PathGeo::Invert::kNo)); |
| + geos.emplace_back(new RRectPathGeo(rectPath, r, RRectPathGeo::RRectForStroke::kYes, |
| + PathGeo::Invert::kYes)); |
| + rrectPathGeos.emplace_back(new RRectPathGeo(rectPath, r, RRectPathGeo::RRectForStroke::kYes, |
| + PathGeo::Invert::kNo)); |
| } |
| - |
| for (auto rr : { SkRRect::MakeRect(SkRect::MakeWH(10, 10)), |
| SkRRect::MakeRectXY(SkRect::MakeWH(10, 10), 3, 4), |
| SkRRect::MakeOval(SkRect::MakeWH(20, 20))}) { |
| - test_basic(reporter, rr); |
| + geos.emplace_back(new RRectGeo(rr)); |
| test_rrect(reporter, rr); |
| - test_scale(reporter, rr); |
| - test_dash_fill(reporter, rr); |
| - test_null_dash(reporter, rr); |
| - // Test modifying various stroke params. |
| - test_stroke_param<SkRRect, SkScalar>( |
| - reporter, rr, |
| - [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, |
| - SkIntToScalar(2), SkIntToScalar(4)); |
| - test_stroke_join(reporter, rr); |
| - test_stroke_cap(reporter, rr); |
| - test_miter_limit(reporter, rr); |
| - test_path_effect_makes_rrect(reporter, rr); |
| - test_unknown_path_effect(reporter, rr); |
| - test_path_effect_makes_empty_shape(reporter, rr); |
| - test_path_effect_fails(reporter, rr); |
| - test_make_hairline_path_effect(reporter, rr, true); |
| - GrShape shape(rr); |
| - REPORTER_ASSERT(reporter, !shape.asLine(nullptr, nullptr)); |
| + SkPath rectPath; |
| + rectPath.addRRect(rr); |
| + geos.emplace_back(new RRectPathGeo(rectPath, rr, RRectPathGeo::RRectForStroke::kYes, |
| + PathGeo::Invert::kNo)); |
| + geos.emplace_back(new RRectPathGeo(rectPath, rr, RRectPathGeo::RRectForStroke::kYes, |
| + PathGeo::Invert::kYes)); |
| + rrectPathGeos.emplace_back(new RRectPathGeo(rectPath, rr, |
| + RRectPathGeo::RRectForStroke::kYes, |
| + PathGeo::Invert::kNo)); |
| } |
| - struct TestPath { |
| - TestPath(const SkPath& path, bool isRRectFill, bool isRRectStroke, bool isLine, |
| - const SkRRect& rrect) |
| - : fPath(path) |
| - , fIsRRectForFill(isRRectFill) |
| - , fIsRRectForStroke(isRRectStroke) |
| - , fIsLine(isLine) |
| - , fRRect(rrect) {} |
| - SkPath fPath; |
| - bool fIsRRectForFill; |
| - bool fIsRRectForStroke; |
| - bool fIsLine; |
| - SkRRect fRRect; |
| - }; |
| - SkTArray<TestPath> paths; |
| - |
| - SkPath circlePath; |
|
bsalomon
2016/08/24 17:25:21
These two (circlePath and rectPath) are subsumed i
|
| - circlePath.addCircle(10, 10, 10); |
| - paths.emplace_back(circlePath, true, true, false, SkRRect::MakeOval(SkRect::MakeWH(20,20))); |
| - |
| - SkPath rectPath; |
| - rectPath.addRect(SkRect::MakeWH(10, 10)); |
| - paths.emplace_back(rectPath, true, true, false, SkRRect::MakeRect(SkRect::MakeWH(10, 10))); |
| - |
| SkPath openRectPath; |
| openRectPath.moveTo(0, 0); |
| openRectPath.lineTo(10, 0); |
| openRectPath.lineTo(10, 10); |
| openRectPath.lineTo(0, 10); |
| - paths.emplace_back(openRectPath, true, false, false, SkRRect::MakeRect(SkRect::MakeWH(10, 10))); |
| + geos.emplace_back(new RRectPathGeo(openRectPath, SkRect::MakeWH(10, 10), |
| + RRectPathGeo::RRectForStroke::kNo, PathGeo::Invert::kNo)); |
| + geos.emplace_back(new RRectPathGeo(openRectPath, SkRect::MakeWH(10, 10), |
| + RRectPathGeo::RRectForStroke::kNo, PathGeo::Invert::kYes)); |
| + rrectPathGeos.emplace_back(new RRectPathGeo(openRectPath, SkRect::MakeWH(10, 10), |
| + RRectPathGeo::RRectForStroke::kNo, |
| + PathGeo::Invert::kNo)); |
| SkPath quadPath; |
| quadPath.quadTo(10, 10, 5, 8); |
| - paths.emplace_back(quadPath, false, false, false, SkRRect()); |
| + geos.emplace_back(new PathGeo(quadPath, PathGeo::Invert::kNo)); |
| + geos.emplace_back(new PathGeo(quadPath, PathGeo::Invert::kYes)); |
| SkPath linePath; |
| linePath.lineTo(10, 10); |
| - paths.emplace_back(linePath, false, false, true, SkRRect()); |
| + geos.emplace_back(new PathGeo(linePath, PathGeo::Invert::kNo)); |
| + geos.emplace_back(new PathGeo(linePath, PathGeo::Invert::kYes)); |
| // Horizontal and vertical paths become rrects when stroked. |
| SkPath vLinePath; |
| vLinePath.lineTo(0, 10); |
| - paths.emplace_back(vLinePath, false, false, true, SkRRect()); |
| + geos.emplace_back(new PathGeo(vLinePath, PathGeo::Invert::kNo)); |
| + geos.emplace_back(new PathGeo(vLinePath, PathGeo::Invert::kYes)); |
| SkPath hLinePath; |
| hLinePath.lineTo(10, 0); |
| - paths.emplace_back(hLinePath, false, false, true, SkRRect()); |
| - |
| - for (auto testPath : paths) { |
| - for (bool inverseFill : {false, true}) { |
| - if (inverseFill) { |
| - if (testPath.fPath.getFillType() == SkPath::kEvenOdd_FillType) { |
| - testPath.fPath.setFillType(SkPath::kInverseEvenOdd_FillType); |
| - } else { |
| - SkASSERT(testPath.fPath.getFillType() == SkPath::kWinding_FillType); |
| - testPath.fPath.setFillType(SkPath::kInverseWinding_FillType); |
| - } |
| - } |
| - const SkPath& path = testPath.fPath; |
| - test_basic(reporter, path); |
| - test_null_dash(reporter, path); |
| - test_path_effect_makes_rrect(reporter, path); |
| - test_scale(reporter, path); |
| - // This test uses a stroking paint, hence use of fIsRRectForStroke |
| - test_volatile_path(reporter, path, testPath.fIsRRectForStroke || testPath.fIsLine); |
| - test_dash_fill(reporter, path); |
| - // Test modifying various stroke params. |
| - test_stroke_param<SkPath, SkScalar>( |
| - reporter, path, |
| + geos.emplace_back(new PathGeo(hLinePath, PathGeo::Invert::kNo)); |
| + geos.emplace_back(new PathGeo(hLinePath, PathGeo::Invert::kYes)); |
| + |
| + for (int i = 0; i < geos.count(); ++i) { |
| + test_basic(reporter, *geos[i]); |
| + test_scale(reporter, *geos[i]); |
| + test_dash_fill(reporter, *geos[i]); |
| + test_null_dash(reporter, *geos[i]); |
| + // Test modifying various stroke params. |
| + test_stroke_param<SkScalar>( |
| + reporter, *geos[i], |
| [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);}, |
| SkIntToScalar(2), SkIntToScalar(4)); |
| - test_stroke_join(reporter, path); |
| - test_stroke_cap(reporter, path); |
| - test_miter_limit(reporter, path); |
| - test_unknown_path_effect(reporter, path); |
| - test_path_effect_makes_empty_shape(reporter, path); |
| - test_path_effect_fails(reporter, path); |
| - test_make_hairline_path_effect(reporter, path, testPath.fIsRRectForStroke || |
| - testPath.fIsLine); |
| - } |
| + test_stroke_join(reporter, *geos[i]); |
| + test_stroke_cap(reporter, *geos[i]); |
| + test_miter_limit(reporter, *geos[i]); |
| + test_path_effect_makes_rrect(reporter, *geos[i]); |
| + test_unknown_path_effect(reporter, *geos[i]); |
| + test_path_effect_makes_empty_shape(reporter, *geos[i]); |
| + test_path_effect_fails(reporter, *geos[i]); |
| + test_make_hairline_path_effect(reporter, *geos[i]); |
| + test_volatile_path(reporter, *geos[i]); |
| } |
| - for (auto testPath : paths) { |
| - const SkPath& path = testPath.fPath; |
| - |
| + for (int i = 0; i < rrectPathGeos.count(); ++i) { |
| + const RRectPathGeo& rrgeo = *rrectPathGeos[i]; |
| SkPaint fillPaint; |
| - TestCase fillPathCase(path, fillPaint, reporter); |
| + TestCase fillPathCase(reporter, rrgeo.path(), fillPaint); |
| SkRRect rrect; |
| - REPORTER_ASSERT(reporter, testPath.fIsRRectForFill == |
| + REPORTER_ASSERT(reporter, rrgeo.isNonPath(fillPaint) == |
| fillPathCase.baseShape().asRRect(&rrect, nullptr, nullptr, |
| nullptr)); |
| - if (testPath.fIsRRectForFill) { |
| - TestCase fillPathCase2(testPath.fPath, fillPaint, reporter); |
| - REPORTER_ASSERT(reporter, rrect == testPath.fRRect); |
| - TestCase fillRRectCase(rrect, fillPaint, reporter); |
| + if (rrgeo.isNonPath(fillPaint)) { |
| + TestCase fillPathCase2(reporter, rrgeo.path(), fillPaint); |
| + REPORTER_ASSERT(reporter, rrect == rrgeo.rrect()); |
| + TestCase fillRRectCase(reporter, rrect, fillPaint); |
| fillPathCase2.compare(reporter, fillRRectCase, |
| TestCase::kAllSame_ComparisonExpecation); |
| } |
| SkPaint strokePaint; |
| strokePaint.setStrokeWidth(3.f); |
| strokePaint.setStyle(SkPaint::kStroke_Style); |
| - TestCase strokePathCase(path, strokePaint, reporter); |
| - if (testPath.fIsRRectForStroke) { |
| + TestCase strokePathCase(reporter, rrgeo.path(), strokePaint); |
| + if (rrgeo.isNonPath(strokePaint)) { |
| REPORTER_ASSERT(reporter, strokePathCase.baseShape().asRRect(&rrect, nullptr, nullptr, |
| nullptr)); |
| - } |
| - |
| - if (testPath.fIsRRectForStroke) { |
| - REPORTER_ASSERT(reporter, rrect == testPath.fRRect); |
| - TestCase strokeRRectCase(rrect, strokePaint, reporter); |
| + REPORTER_ASSERT(reporter, rrect == rrgeo.rrect()); |
| + TestCase strokeRRectCase(reporter, rrect, strokePaint); |
| strokePathCase.compare(reporter, strokeRRectCase, |
| TestCase::kAllSame_ComparisonExpecation); |
| } |
| } |
| // Test a volatile empty path. |
| - test_volatile_path(reporter, SkPath(), true); |
| + test_volatile_path(reporter, PathGeo(SkPath(), PathGeo::Invert::kNo)); |
| test_empty_shape(reporter); |