Index: tests/GrShapeTest.cpp |
diff --git a/tests/GrShapeTest.cpp b/tests/GrShapeTest.cpp |
index 9246c73f40f3419141bea2a97dbca5a1b3f8aba1..8ac27b4f98a5dbb32679d3afa1fc189c0ed47406 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 { |
+/** |
+ * Geo is a factory for creating a GrShape from another representation. It also answers some |
+ * questions about expected behavior for GrShape given the inputs. |
+ */ |
+class Geo { |
+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. |
+ 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); |
+ 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; |
- 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); |