| Index: tests/GrShapeTest.cpp
|
| diff --git a/tests/GrShapeTest.cpp b/tests/GrShapeTest.cpp
|
| index 246bab65803bde5bb8c761867085e789d63647d6..6c23d6754886e401dcd72e8b20a790ae8984c05c 100644
|
| --- a/tests/GrShapeTest.cpp
|
| +++ b/tests/GrShapeTest.cpp
|
| @@ -82,6 +82,11 @@ public:
|
| this->init(r, scale);
|
| }
|
|
|
| + TestCase(const GrShape& shape, skiatest::Reporter* r, SkScalar scale = SK_Scalar1)
|
| + : fBase(shape) {
|
| + this->init(r, scale);
|
| + }
|
| +
|
| struct SelfExpectations {
|
| bool fPEHasEffect;
|
| bool fPEHasValidKey;
|
| @@ -121,7 +126,10 @@ private:
|
| if (path.isEmpty()) {
|
| return;
|
| }
|
| - REPORTER_ASSERT(r, test_bounds_by_rasterizing(path, bounds));
|
| + // The bounds API explicitly calls out that it does not consider inverseness.
|
| + SkPath p = path;
|
| + p.setFillType(SkPath::ConvertToNonInverseFillType(path.getFillType()));
|
| + REPORTER_ASSERT(r, test_bounds_by_rasterizing(p, bounds));
|
| }
|
|
|
| void init(skiatest::Reporter* r, SkScalar scale) {
|
| @@ -147,7 +155,7 @@ private:
|
| // fAppliedPEThenStroke will have converted the rrect_as_path back to a rrect. However,
|
| // now that there is no longer a path effect, the direction and starting index get
|
| // canonicalized before the stroke.
|
| - if (fAppliedPE.asRRect(nullptr, nullptr, nullptr)) {
|
| + if (fAppliedPE.asRRect(nullptr, nullptr, nullptr, nullptr)) {
|
| REPORTER_ASSERT(r, paths_fill_same(a, b));
|
| } else {
|
| REPORTER_ASSERT(r, a == b);
|
| @@ -261,26 +269,56 @@ void check_equivalence(skiatest::Reporter* r, const GrShape& a, const GrShape& b
|
| SkRRect rrectA = SkRRect::MakeEmpty(), rrectB = SkRRect::MakeEmpty();
|
| SkPath::Direction dirA = SkPath::kCW_Direction, dirB = SkPath::kCW_Direction;
|
| unsigned startA = ~0U, startB = ~0U;
|
| + bool invertedA = true, invertedB = true;
|
|
|
| - bool aIsRRect = a.asRRect(&rrectA, &dirA, &startA);
|
| - bool bIsRRect = b.asRRect(&rrectB, &dirB, &startB);
|
| + bool aIsRRect = a.asRRect(&rrectA, &dirA, &startA, &invertedA);
|
| + bool bIsRRect = b.asRRect(&rrectB, &dirB, &startB, &invertedB);
|
| bool aHasPE = a.style().hasPathEffect();
|
| bool bHasPE = b.style().hasPathEffect();
|
| bool allowSameRRectButDiffStartAndDir = (aIsRRect && bIsRRect) && (aHasPE != bHasPE);
|
| +
|
| SkPath pathA, pathB;
|
| a.asPath(&pathA);
|
| b.asPath(&pathB);
|
| +
|
| + // Having a fill style or non-dash path effect can prevent 'a' but not 'b' from turning an
|
| + // inverse fill type into a non-inverse fill type.
|
| + bool ignoreInversenessDifference = false;
|
| + if (pathA.isInverseFillType() != pathB.isInverseFillType()) {
|
| + const GrShape* s1 = pathA.isInverseFillType() ? &a : &b;
|
| + const GrShape* s2 = pathA.isInverseFillType() ? &b : &a;
|
| + SkStrokeRec::Style style1 = s1->style().strokeRec().getStyle();
|
| + SkStrokeRec::Style style2 = s2->style().strokeRec().getStyle();
|
| + bool canDropInverse1 = !s1->style().hasNonDashPathEffect() &&
|
| + (SkStrokeRec::kStroke_Style == style1 ||
|
| + SkStrokeRec::kHairline_Style == style1);
|
| + bool canDropInverse2 = !s2->style().hasNonDashPathEffect() &&
|
| + (SkStrokeRec::kStroke_Style == style2 ||
|
| + SkStrokeRec::kHairline_Style == style2);
|
| + ignoreInversenessDifference = !canDropInverse1 && canDropInverse2;
|
| + }
|
| +
|
| if (allowSameRRectButDiffStartAndDir) {
|
| REPORTER_ASSERT(r, rrectA == rrectB);
|
| REPORTER_ASSERT(r, paths_fill_same(pathA, pathB));
|
| + REPORTER_ASSERT(r, ignoreInversenessDifference || invertedA == invertedB);
|
| } else {
|
| - REPORTER_ASSERT(r, pathA == pathB);
|
| - REPORTER_ASSERT(r, keyA == keyB);
|
| + SkPath pA = pathA;
|
| + SkPath pB = pathB;
|
| + if (ignoreInversenessDifference) {
|
| + pA.setFillType(SkPath::ConvertToNonInverseFillType(pathA.getFillType()));
|
| + pB.setFillType(SkPath::ConvertToNonInverseFillType(pathB.getFillType()));
|
| + REPORTER_ASSERT(r, keyA != keyB);
|
| + } else {
|
| + REPORTER_ASSERT(r, keyA == keyB);
|
| + }
|
| + REPORTER_ASSERT(r, pA == pB);
|
| REPORTER_ASSERT(r, aIsRRect == bIsRRect);
|
| if (aIsRRect) {
|
| REPORTER_ASSERT(r, rrectA == rrectB);
|
| REPORTER_ASSERT(r, dirA == dirB);
|
| REPORTER_ASSERT(r, startA == startB);
|
| + REPORTER_ASSERT(r, ignoreInversenessDifference || invertedA == invertedB);
|
| }
|
| }
|
| REPORTER_ASSERT(r, a.isEmpty() == b.isEmpty());
|
| @@ -458,11 +496,11 @@ static void test_scale(skiatest::Reporter* reporter, const GEO& geo) {
|
| // Scale affects the stroke. Though, this can wind up creating a rect when the input is a rect.
|
| // In that case we wind up with a pure geometry key and the geometries are the same.
|
| SkRRect rrect;
|
| - if (strokeAndFillCase1.appliedFullStyleShape().asRRect(&rrect, nullptr, nullptr)) {
|
| + if (strokeAndFillCase1.appliedFullStyleShape().asRRect(&rrect, nullptr, nullptr, nullptr)) {
|
| // We currently only expect to get here in the rect->rect case.
|
| REPORTER_ASSERT(reporter, rrect.isRect());
|
| REPORTER_ASSERT(reporter,
|
| - strokeAndFillCase1.baseShape().asRRect(&rrect, nullptr, nullptr) &&
|
| + strokeAndFillCase1.baseShape().asRRect(&rrect, nullptr, nullptr, nullptr) &&
|
| rrect.isRect());
|
| strokeAndFillCase1.compare(reporter, strokeAndFillCase2,
|
| TestCase::kAllSame_ComparisonExpecation);
|
| @@ -687,22 +725,24 @@ void test_path_effect_makes_rrect(skiatest::Reporter* reporter, const GEO& geo)
|
| SkRRect rrect;
|
| // Applying the path effect should make a SkRRect shape. There is no further stroking in the
|
| // geoPECase, so the full style should be the same as just the PE.
|
| - REPORTER_ASSERT(reporter, geoPECase.appliedPathEffectShape().asRRect(&rrect, nullptr, nullptr));
|
| + REPORTER_ASSERT(reporter, geoPECase.appliedPathEffectShape().asRRect(&rrect, nullptr, nullptr,
|
| + nullptr));
|
| REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect());
|
| REPORTER_ASSERT(reporter, geoPECase.appliedPathEffectKey() == rrectFillCase.baseKey());
|
|
|
| - REPORTER_ASSERT(reporter, geoPECase.appliedFullStyleShape().asRRect(&rrect, nullptr, nullptr));
|
| + REPORTER_ASSERT(reporter, geoPECase.appliedFullStyleShape().asRRect(&rrect, nullptr, nullptr,
|
| + nullptr));
|
| REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect());
|
| REPORTER_ASSERT(reporter, geoPECase.appliedFullStyleKey() == rrectFillCase.baseKey());
|
|
|
| // In the PE+stroke case applying the full style should be the same as just stroking the rrect.
|
| - REPORTER_ASSERT(reporter,
|
| - geoPEStrokeCase.appliedPathEffectShape().asRRect(&rrect, nullptr, nullptr));
|
| + REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectShape().asRRect(&rrect, nullptr,
|
| + nullptr, nullptr));
|
| REPORTER_ASSERT(reporter, rrect == RRectPathEffect::RRect());
|
| REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectKey() == rrectFillCase.baseKey());
|
|
|
| - REPORTER_ASSERT(reporter,
|
| - !geoPEStrokeCase.appliedFullStyleShape().asRRect(&rrect, nullptr, nullptr));
|
| + REPORTER_ASSERT(reporter, !geoPEStrokeCase.appliedFullStyleShape().asRRect(&rrect, nullptr,
|
| + nullptr, nullptr));
|
| REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedFullStyleKey() ==
|
| rrectStrokeCase.appliedFullStyleKey());
|
| }
|
| @@ -761,7 +801,7 @@ void test_make_hairline_path_effect(skiatest::Reporter* reporter, const GEO& geo
|
| strokeRec->setHairlineStyle();
|
| return true;
|
| }
|
| - void computeFastBounds(SkRect* dst, const SkRect& src) const override { *dst = src; }
|
| + void computeFastBounds(SkRect* dst, const SkRect& src) const override { *dst = src; }
|
| static sk_sp<SkPathEffect> Make() {
|
| return sk_sp<SkPathEffect>(new MakeHairlinePathEffect);
|
| }
|
| @@ -988,6 +1028,204 @@ void test_empty_shape(skiatest::Reporter* reporter) {
|
| TestCase::kAllSame_ComparisonExpecation);
|
| }
|
|
|
| +// rect and oval types have rrect start indices that collapse to the same point. Here we select the
|
| +// canonical point in these cases.
|
| +unsigned canonicalize_rrect_start(int s, const SkRRect& rrect) {
|
| + switch (rrect.getType()) {
|
| + case SkRRect::kRect_Type:
|
| + return (s + 1) & 0b110;
|
| + case SkRRect::kOval_Type:
|
| + return s & 0b110;
|
| + default:
|
| + return s;
|
| + }
|
| +}
|
| +
|
| +void test_rrect(skiatest::Reporter* r, const SkRRect& rrect) {
|
| + enum {
|
| + kFill,
|
| + kStroke,
|
| + kHairline,
|
| + kStrokeAndFill
|
| + };
|
| +
|
| + // SkStrokeRec has no default cons., so init with kFill before calling the setters below.
|
| + SkStrokeRec strokeRecs[4] { SkStrokeRec::kFill_InitStyle, SkStrokeRec::kFill_InitStyle,
|
| + SkStrokeRec::kFill_InitStyle, SkStrokeRec::kFill_InitStyle};
|
| + strokeRecs[kFill].setFillStyle();
|
| + strokeRecs[kStroke].setStrokeStyle(2.f);
|
| + strokeRecs[kHairline].setHairlineStyle();
|
| + strokeRecs[kStrokeAndFill].setStrokeStyle(3.f, true);
|
| + sk_sp<SkPathEffect> dashEffect = make_dash();
|
| +
|
| + GrShape shapes[2 /* inverted */]
|
| + [2 /* direction */]
|
| + [8 /* start index */]
|
| + [SK_ARRAY_COUNT(strokeRecs)]
|
| + [2 /* dash */];
|
| + for (int inverted = 0; inverted < 2; ++inverted) {
|
| + for (int ccw = 0; ccw < 2; ++ccw) {
|
| + for (unsigned s = 0; s < 8; ++s) {
|
| + for (size_t style = 0; style < SK_ARRAY_COUNT(strokeRecs); ++style) {
|
| + for (int dash = 0; dash < 2; ++dash) {
|
| + SkPath::Direction dir = ccw ? SkPath::kCCW_Direction
|
| + : SkPath::kCW_Direction;
|
| + SkPathEffect* pe = dash ? dashEffect.get() : nullptr;
|
| + shapes[inverted][ccw][s][style][dash] =
|
| + GrShape(rrect, dir, s, SkToBool(inverted),
|
| + GrStyle(strokeRecs[style], pe));
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| +
|
| + const GrShape& exampleFillCase = shapes[0][0][0][kFill][0];
|
| + Key exampleFillCaseKey;
|
| + make_key(&exampleFillCaseKey, exampleFillCase);
|
| +
|
| + const GrShape& exampleStrokeAndFillCase = shapes[0][0][0][kStrokeAndFill][0];
|
| + Key exampleStrokeAndFillCaseKey;
|
| + make_key(&exampleStrokeAndFillCaseKey, exampleStrokeAndFillCase);
|
| +
|
| + const GrShape& exampleInvFillCase = shapes[1][0][0][kFill][0];
|
| + Key exampleInvFillCaseKey;
|
| + make_key(&exampleInvFillCaseKey, exampleInvFillCase);
|
| +
|
| + const GrShape& exampleInvStrokeAndFillCase = shapes[1][0][0][kStrokeAndFill][0];
|
| + Key exampleInvStrokeAndFillCaseKey;
|
| + make_key(&exampleInvStrokeAndFillCaseKey, exampleInvStrokeAndFillCase);
|
| +
|
| + const GrShape& exampleStrokeCase = shapes[0][0][0][kStroke][0];
|
| + Key exampleStrokeCaseKey;
|
| + make_key(&exampleStrokeCaseKey, exampleStrokeCase);
|
| +
|
| + const GrShape& exampleHairlineCase = shapes[0][0][0][kHairline][0];
|
| + Key exampleHairlineCaseKey;
|
| + make_key(&exampleHairlineCaseKey, exampleHairlineCase);
|
| +
|
| + // These are dummy initializations to suppress warnings.
|
| + SkRRect rr = SkRRect::MakeEmpty();
|
| + SkPath::Direction dir = SkPath::kCW_Direction;
|
| + unsigned start = ~0U;
|
| + bool inv = true;
|
| +
|
| + REPORTER_ASSERT(r, exampleFillCase.asRRect(&rr, &dir, &start, &inv));
|
| + REPORTER_ASSERT(r, rr == rrect);
|
| + REPORTER_ASSERT(r, SkPath::kCW_Direction == dir);
|
| + REPORTER_ASSERT(r, 0 == start);
|
| + REPORTER_ASSERT(r, !inv);
|
| +
|
| + REPORTER_ASSERT(r, exampleInvFillCase.asRRect(&rr, &dir, &start, &inv));
|
| + REPORTER_ASSERT(r, rr == rrect);
|
| + REPORTER_ASSERT(r, SkPath::kCW_Direction == dir);
|
| + REPORTER_ASSERT(r, 0 == start);
|
| + REPORTER_ASSERT(r, inv);
|
| +
|
| + REPORTER_ASSERT(r, exampleStrokeAndFillCase.asRRect(&rr, &dir, &start, &inv));
|
| + REPORTER_ASSERT(r, rr == rrect);
|
| + REPORTER_ASSERT(r, SkPath::kCW_Direction == dir);
|
| + REPORTER_ASSERT(r, 0 == start);
|
| + REPORTER_ASSERT(r, !inv);
|
| +
|
| + REPORTER_ASSERT(r, exampleInvStrokeAndFillCase.asRRect(&rr, &dir, &start, &inv));
|
| + REPORTER_ASSERT(r, rr == rrect);
|
| + REPORTER_ASSERT(r, SkPath::kCW_Direction == dir);
|
| + REPORTER_ASSERT(r, 0 == start);
|
| + REPORTER_ASSERT(r, inv);
|
| +
|
| + REPORTER_ASSERT(r, exampleHairlineCase.asRRect(&rr, &dir, &start, &inv));
|
| + REPORTER_ASSERT(r, rr == rrect);
|
| + REPORTER_ASSERT(r, SkPath::kCW_Direction == dir);
|
| + REPORTER_ASSERT(r, 0 == start);
|
| + REPORTER_ASSERT(r, !inv);
|
| +
|
| + REPORTER_ASSERT(r, exampleStrokeCase.asRRect(&rr, &dir, &start, &inv));
|
| + REPORTER_ASSERT(r, rr == rrect);
|
| + REPORTER_ASSERT(r, SkPath::kCW_Direction == dir);
|
| + REPORTER_ASSERT(r, 0 == start);
|
| + REPORTER_ASSERT(r, !inv);
|
| +
|
| + // Remember that the key reflects the geometry before styling is applied.
|
| + REPORTER_ASSERT(r, exampleFillCaseKey != exampleInvFillCaseKey);
|
| + REPORTER_ASSERT(r, exampleFillCaseKey == exampleStrokeAndFillCaseKey);
|
| + REPORTER_ASSERT(r, exampleFillCaseKey != exampleInvStrokeAndFillCaseKey);
|
| + REPORTER_ASSERT(r, exampleFillCaseKey == exampleStrokeCaseKey);
|
| + REPORTER_ASSERT(r, exampleFillCaseKey == exampleHairlineCaseKey);
|
| + REPORTER_ASSERT(r, exampleInvStrokeAndFillCaseKey == exampleInvFillCaseKey);
|
| +
|
| + for (int inverted = 0; inverted < 2; ++inverted) {
|
| + for (int ccw = 0; ccw < 2; ++ccw) {
|
| + for (unsigned s = 0; s < 8; ++s) {
|
| + for (int dash = 0; dash < 2; ++dash) {
|
| + const GrShape& fillCase = shapes[inverted][ccw][s][kFill][dash];
|
| + Key fillCaseKey;
|
| + make_key(&fillCaseKey, fillCase);
|
| +
|
| + const GrShape& strokeAndFillCase =
|
| + shapes[inverted][ccw][s][kStrokeAndFill][dash];
|
| + Key strokeAndFillCaseKey;
|
| + make_key(&strokeAndFillCaseKey, strokeAndFillCase);
|
| +
|
| + // Both fill and stroke-and-fill shapes must respect the inverseness and both
|
| + // ignore dashing.
|
| + REPORTER_ASSERT(r, !fillCase.style().pathEffect());
|
| + REPORTER_ASSERT(r, !strokeAndFillCase.style().pathEffect());
|
| + TestCase a(fillCase, r);
|
| + TestCase b(inverted ? exampleInvFillCase : exampleFillCase, r);
|
| + TestCase c(strokeAndFillCase, r);
|
| + TestCase d(inverted ? exampleInvStrokeAndFillCase
|
| + : exampleStrokeAndFillCase, r);
|
| + a.compare(r, b, TestCase::kAllSame_ComparisonExpecation);
|
| + c.compare(r, d, TestCase::kAllSame_ComparisonExpecation);
|
| +
|
| + const GrShape& strokeCase = shapes[inverted][ccw][s][kStroke][dash];
|
| + const GrShape& hairlineCase = shapes[inverted][ccw][s][kHairline][dash];
|
| +
|
| + TestCase e(strokeCase, r);
|
| + TestCase f(exampleStrokeCase, r);
|
| + TestCase g(hairlineCase, r);
|
| + TestCase h(exampleHairlineCase, r);
|
| +
|
| + // Both hairline and stroke shapes must respect the dashing and both
|
| + // ignore inverseness.
|
| + if (dash) {
|
| + unsigned expectedStart = canonicalize_rrect_start(s, rrect);
|
| + REPORTER_ASSERT(r, strokeCase.style().pathEffect());
|
| + REPORTER_ASSERT(r, hairlineCase.style().pathEffect());
|
| +
|
| + REPORTER_ASSERT(r, strokeCase.asRRect(&rr, &dir, &start, &inv));
|
| + REPORTER_ASSERT(r, rr == rrect);
|
| + REPORTER_ASSERT(r, (SkPath::kCCW_Direction == dir) == ccw);
|
| + REPORTER_ASSERT(r, start == expectedStart);
|
| + REPORTER_ASSERT(r, !inv);
|
| + REPORTER_ASSERT(r, hairlineCase.asRRect(&rr, &dir, &start, &inv));
|
| + REPORTER_ASSERT(r, rr == rrect);
|
| + REPORTER_ASSERT(r, (SkPath::kCCW_Direction == dir) == ccw);
|
| + REPORTER_ASSERT(r, start == expectedStart);
|
| + REPORTER_ASSERT(r, !inv);
|
| +
|
| + // The pre-style case for the dash will match the non-dash example iff the
|
| + // dir and start match (dir=cw, start=0).
|
| + if (0 == expectedStart && 0 == ccw) {
|
| + e.compare(r, f, TestCase::kSameUpToPE_ComparisonExpecation);
|
| + g.compare(r, h, TestCase::kSameUpToPE_ComparisonExpecation);
|
| + } else {
|
| + e.compare(r, f, TestCase::kAllDifferent_ComparisonExpecation);
|
| + g.compare(r, h, TestCase::kAllDifferent_ComparisonExpecation);
|
| + }
|
| + } else {
|
| + REPORTER_ASSERT(r, !strokeCase.style().pathEffect());
|
| + REPORTER_ASSERT(r, !hairlineCase.style().pathEffect());
|
| + e.compare(r, f, TestCase::kAllSame_ComparisonExpecation);
|
| + g.compare(r, h, TestCase::kAllSame_ComparisonExpecation);
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| DEF_TEST(GrShape, reporter) {
|
| for (auto r : { SkRect::MakeWH(10, 20),
|
| SkRect::MakeWH(-10, -20),
|
| @@ -1019,6 +1257,7 @@ DEF_TEST(GrShape, reporter) {
|
| SkRRect::MakeRectXY(SkRect::MakeWH(10, 10), 3, 4),
|
| SkRRect::MakeOval(SkRect::MakeWH(20, 20))}) {
|
| test_basic(reporter, rr);
|
| + test_rrect(reporter, rr);
|
| test_scale(reporter, rr);
|
| test_dash_fill(reporter, rr);
|
| test_null_dash(reporter, rr);
|
| @@ -1041,7 +1280,7 @@ DEF_TEST(GrShape, reporter) {
|
| }
|
|
|
| struct TestPath {
|
| - TestPath(const SkPath& path, bool isRRectFill, bool isRRectStroke ,const SkRRect& rrect)
|
| + TestPath(const SkPath& path, bool isRRectFill, bool isRRectStroke, const SkRRect& rrect)
|
| : fPath(path)
|
| , fIsRRectForFill(isRRectFill)
|
| , fIsRRectForStroke(isRRectStroke)
|
| @@ -1073,53 +1312,69 @@ DEF_TEST(GrShape, reporter) {
|
| paths.emplace_back(quadPath, false, false, SkRRect());
|
|
|
| for (auto testPath : paths) {
|
| - const SkPath& path = testPath.fPath;
|
| - // These tests all assume that the original GrShape for fill and stroke will be the same.
|
| - // However, that is not the case in special cases (e.g. a unclosed rect becomes a RRect
|
| - // GrShape with a fill style but becomes a Path GrShape when stroked).
|
| - if (testPath.fIsRRectForFill == testPath.fIsRRectForStroke) {
|
| - test_basic(reporter, path);
|
| - test_null_dash(reporter, path);
|
| - test_path_effect_makes_rrect(reporter, path);
|
| + 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;
|
| + // These tests all assume that the original GrShape for fill and stroke will be the
|
| + // same.
|
| + // However, that is not the case in special cases (e.g. an unclosed rect becomes a RRect
|
| + // GrShape with a fill style but becomes a Path GrShape when stroked).
|
| + if (testPath.fIsRRectForFill == testPath.fIsRRectForStroke) {
|
| + 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);
|
| + test_dash_fill(reporter, path);
|
| + // Test modifying various stroke params.
|
| + test_stroke_param<SkPath, SkScalar>(
|
| + reporter, path,
|
| + [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);},
|
| + SkIntToScalar(2), SkIntToScalar(4));
|
| + test_stroke_param<SkPath, SkPaint::Join>(
|
| + reporter, path,
|
| + [](SkPaint* p, SkPaint::Join j) { p->setStrokeJoin(j);},
|
| + SkPaint::kMiter_Join, SkPaint::kRound_Join);
|
| + 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);
|
| }
|
| - test_scale(reporter, path);
|
| - // This test uses a stroking paint, hence use of fIsRRectForStroke
|
| - test_volatile_path(reporter, path, testPath.fIsRRectForStroke);
|
| - test_dash_fill(reporter, path);
|
| - // Test modifying various stroke params.
|
| - test_stroke_param<SkPath, SkScalar>(
|
| - reporter, path,
|
| - [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);},
|
| - SkIntToScalar(2), SkIntToScalar(4));
|
| - test_stroke_param<SkPath, SkPaint::Join>(
|
| - reporter, path,
|
| - [](SkPaint* p, SkPaint::Join j) { p->setStrokeJoin(j);},
|
| - SkPaint::kMiter_Join, SkPaint::kRound_Join);
|
| - 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);
|
| + }
|
| + for (auto testPath : paths) {
|
| + const SkPath& path = testPath.fPath;
|
|
|
| SkPaint fillPaint;
|
| TestCase fillPathCase(path, fillPaint, reporter);
|
| SkRRect rrect;
|
| REPORTER_ASSERT(reporter, testPath.fIsRRectForFill ==
|
| - fillPathCase.baseShape().asRRect(&rrect, nullptr, nullptr));
|
| + fillPathCase.baseShape().asRRect(&rrect, nullptr, nullptr,
|
| + nullptr));
|
| if (testPath.fIsRRectForFill) {
|
| - TestCase fillPathCase2(path, fillPaint, reporter);
|
| + TestCase fillPathCase2(testPath.fPath, fillPaint, reporter);
|
| REPORTER_ASSERT(reporter, rrect == testPath.fRRect);
|
| TestCase fillRRectCase(rrect, fillPaint, reporter);
|
| - fillPathCase2.compare(reporter, fillRRectCase, TestCase::kAllSame_ComparisonExpecation);
|
| + fillPathCase2.compare(reporter, fillRRectCase,
|
| + TestCase::kAllSame_ComparisonExpecation);
|
| }
|
| -
|
| SkPaint strokePaint;
|
| strokePaint.setStrokeWidth(3.f);
|
| strokePaint.setStyle(SkPaint::kStroke_Style);
|
| TestCase strokePathCase(path, strokePaint, reporter);
|
| REPORTER_ASSERT(reporter, testPath.fIsRRectForStroke ==
|
| - strokePathCase.baseShape().asRRect(&rrect, nullptr, nullptr));
|
| + strokePathCase.baseShape().asRRect(&rrect, nullptr, nullptr,
|
| + nullptr));
|
| if (testPath.fIsRRectForStroke) {
|
| REPORTER_ASSERT(reporter, rrect == testPath.fRRect);
|
| TestCase strokeRRectCase(rrect, strokePaint, reporter);
|
|
|