aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/GrShapeTest.cpp
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-08-31 13:27:15 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-08-31 18:14:21 +0000
commitd5a3f7f9673a152928332a38e53a5fc55f590f40 (patch)
tree044a846a2f3755e5bfa47ea22335c9df61b10d64 /tests/GrShapeTest.cpp
parent5d303ed44b611708784f7b05cfa35a270c8d0c09 (diff)
Add a GrShape::Type value for an inverted empty path
Change-Id: Ib34a608db07a2ff1d7bdfbd96867fa5ff0ac9782 Reviewed-on: https://skia-review.googlesource.com/41540 Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'tests/GrShapeTest.cpp')
-rw-r--r--tests/GrShapeTest.cpp110
1 files changed, 94 insertions, 16 deletions
diff --git a/tests/GrShapeTest.cpp b/tests/GrShapeTest.cpp
index 3f97288c1c..719e5cd974 100644
--- a/tests/GrShapeTest.cpp
+++ b/tests/GrShapeTest.cpp
@@ -175,7 +175,7 @@ public:
bool fillChangesGeom() const override {
// unclosed rects get closed. Lines get turned into empty geometry
- return this->isUnclosedRect() || (fPath.isLine(nullptr) && !fPath.isInverseFillType());
+ return this->isUnclosedRect() || fPath.isLine(nullptr);
}
bool strokeIsConvertedToFill() const override {
@@ -1203,23 +1203,29 @@ void test_volatile_path(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.
+ * This path effect returns an empty path (possibly inverted)
*/
class EmptyPathEffect : SkPathEffect {
public:
bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*,
const SkRect* cullR) const override {
dst->reset();
+ if (fInvert) {
+ dst->toggleInverseFillType();
+ }
return true;
}
void computeFastBounds(SkRect* dst, const SkRect& src) const override {
dst->setEmpty();
}
- static sk_sp<SkPathEffect> Make() { return sk_sp<SkPathEffect>(new EmptyPathEffect); }
+ static sk_sp<SkPathEffect> Make(bool invert) {
+ return sk_sp<SkPathEffect>(new EmptyPathEffect(invert));
+ }
Factory getFactory() const override { return nullptr; }
void toString(SkString*) const override {}
private:
- EmptyPathEffect() {}
+ bool fInvert;
+ EmptyPathEffect(bool invert) : fInvert(invert) {}
};
SkPath emptyPath;
@@ -1228,17 +1234,27 @@ void test_path_effect_makes_empty_shape(skiatest::Reporter* reporter, const Geo&
make_key(&emptyKey, emptyShape);
REPORTER_ASSERT(reporter, emptyShape.isEmpty());
+ emptyPath.toggleInverseFillType();
+ GrShape invertedEmptyShape(emptyPath);
+ Key invertedEmptyKey;
+ make_key(&invertedEmptyKey, invertedEmptyShape);
+ REPORTER_ASSERT(reporter, invertedEmptyShape.isEmpty());
+
+ REPORTER_ASSERT(reporter, invertedEmptyKey != emptyKey);
+
SkPaint pe;
- pe.setPathEffect(EmptyPathEffect::Make());
- TestCase geoCase(geo, pe, reporter);
- REPORTER_ASSERT(reporter, geoCase.appliedFullStyleKey() == emptyKey);
- REPORTER_ASSERT(reporter, geoCase.appliedPathEffectKey() == emptyKey);
- REPORTER_ASSERT(reporter, geoCase.appliedPathEffectThenStrokeKey() == emptyKey);
- REPORTER_ASSERT(reporter, geoCase.appliedPathEffectShape().isEmpty());
- REPORTER_ASSERT(reporter, geoCase.appliedFullStyleShape().isEmpty());
+ pe.setPathEffect(EmptyPathEffect::Make(false));
+ TestCase geoPECase(geo, pe, reporter);
+ REPORTER_ASSERT(reporter, geoPECase.appliedFullStyleKey() == emptyKey);
+ REPORTER_ASSERT(reporter, geoPECase.appliedPathEffectKey() == emptyKey);
+ REPORTER_ASSERT(reporter, geoPECase.appliedPathEffectThenStrokeKey() == emptyKey);
+ REPORTER_ASSERT(reporter, geoPECase.appliedPathEffectShape().isEmpty());
+ REPORTER_ASSERT(reporter, geoPECase.appliedFullStyleShape().isEmpty());
+ REPORTER_ASSERT(reporter, !geoPECase.appliedPathEffectShape().inverseFilled());
+ REPORTER_ASSERT(reporter, !geoPECase.appliedFullStyleShape().inverseFilled());
SkPaint peStroke;
- peStroke.setPathEffect(EmptyPathEffect::Make());
+ peStroke.setPathEffect(EmptyPathEffect::Make(false));
peStroke.setStrokeWidth(2.f);
peStroke.setStyle(SkPaint::kStroke_Style);
TestCase geoPEStrokeCase(geo, peStroke, reporter);
@@ -1247,6 +1263,29 @@ void test_path_effect_makes_empty_shape(skiatest::Reporter* reporter, const Geo&
REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectThenStrokeKey() == emptyKey);
REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedPathEffectShape().isEmpty());
REPORTER_ASSERT(reporter, geoPEStrokeCase.appliedFullStyleShape().isEmpty());
+ REPORTER_ASSERT(reporter, !geoPEStrokeCase.appliedPathEffectShape().inverseFilled());
+ REPORTER_ASSERT(reporter, !geoPEStrokeCase.appliedFullStyleShape().inverseFilled());
+ pe.setPathEffect(EmptyPathEffect::Make(true));
+
+ TestCase geoPEInvertCase(geo, pe, reporter);
+ REPORTER_ASSERT(reporter, geoPEInvertCase.appliedFullStyleKey() == invertedEmptyKey);
+ REPORTER_ASSERT(reporter, geoPEInvertCase.appliedPathEffectKey() == invertedEmptyKey);
+ REPORTER_ASSERT(reporter, geoPEInvertCase.appliedPathEffectThenStrokeKey() == invertedEmptyKey);
+ REPORTER_ASSERT(reporter, geoPEInvertCase.appliedPathEffectShape().isEmpty());
+ REPORTER_ASSERT(reporter, geoPEInvertCase.appliedFullStyleShape().isEmpty());
+ REPORTER_ASSERT(reporter, geoPEInvertCase.appliedPathEffectShape().inverseFilled());
+ REPORTER_ASSERT(reporter, geoPEInvertCase.appliedFullStyleShape().inverseFilled());
+
+ peStroke.setPathEffect(EmptyPathEffect::Make(true));
+ TestCase geoPEInvertStrokeCase(geo, peStroke, reporter);
+ REPORTER_ASSERT(reporter, geoPEInvertStrokeCase.appliedFullStyleKey() == invertedEmptyKey);
+ REPORTER_ASSERT(reporter, geoPEInvertStrokeCase.appliedPathEffectKey() == invertedEmptyKey);
+ REPORTER_ASSERT(reporter,
+ geoPEInvertStrokeCase.appliedPathEffectThenStrokeKey() == invertedEmptyKey);
+ REPORTER_ASSERT(reporter, geoPEInvertStrokeCase.appliedPathEffectShape().isEmpty());
+ REPORTER_ASSERT(reporter, geoPEInvertStrokeCase.appliedFullStyleShape().isEmpty());
+ REPORTER_ASSERT(reporter, geoPEInvertStrokeCase.appliedPathEffectShape().inverseFilled());
+ REPORTER_ASSERT(reporter, geoPEInvertStrokeCase.appliedFullStyleShape().inverseFilled());
}
void test_path_effect_fails(skiatest::Reporter* reporter, const Geo& geo) {
@@ -1313,37 +1352,57 @@ void test_path_effect_fails(skiatest::Reporter* reporter, const Geo& geo) {
DEF_TEST(GrShape_empty_shape, reporter) {
SkPath emptyPath;
+ SkPath invertedEmptyPath;
+ invertedEmptyPath.toggleInverseFillType();
SkPaint fill;
TestCase fillEmptyCase(reporter, emptyPath, fill);
REPORTER_ASSERT(reporter, fillEmptyCase.baseShape().isEmpty());
REPORTER_ASSERT(reporter, fillEmptyCase.appliedPathEffectShape().isEmpty());
REPORTER_ASSERT(reporter, fillEmptyCase.appliedFullStyleShape().isEmpty());
+ REPORTER_ASSERT(reporter, !fillEmptyCase.baseShape().inverseFilled());
+ REPORTER_ASSERT(reporter, !fillEmptyCase.appliedPathEffectShape().inverseFilled());
+ REPORTER_ASSERT(reporter, !fillEmptyCase.appliedFullStyleShape().inverseFilled());
+ TestCase fillInvertedEmptyCase(reporter, invertedEmptyPath, fill);
+ REPORTER_ASSERT(reporter, fillInvertedEmptyCase.baseShape().isEmpty());
+ REPORTER_ASSERT(reporter, fillInvertedEmptyCase.appliedPathEffectShape().isEmpty());
+ REPORTER_ASSERT(reporter, fillInvertedEmptyCase.appliedFullStyleShape().isEmpty());
+ REPORTER_ASSERT(reporter, fillInvertedEmptyCase.baseShape().inverseFilled());
+ REPORTER_ASSERT(reporter, fillInvertedEmptyCase.appliedPathEffectShape().inverseFilled());
+ REPORTER_ASSERT(reporter, fillInvertedEmptyCase.appliedFullStyleShape().inverseFilled());
Key emptyKey(fillEmptyCase.baseKey());
REPORTER_ASSERT(reporter, emptyKey.count());
+ Key inverseEmptyKey(fillInvertedEmptyCase.baseKey());
+ REPORTER_ASSERT(reporter, inverseEmptyKey.count());
TestCase::SelfExpectations expectations;
expectations.fStrokeApplies = false;
expectations.fPEHasEffect = false;
// This will test whether applying style preserves emptiness
fillEmptyCase.testExpectations(reporter, expectations);
+ fillInvertedEmptyCase.testExpectations(reporter, expectations);
// Stroking an empty path should have no effect
- SkPath emptyPath2;
SkPaint stroke;
stroke.setStrokeWidth(2.f);
stroke.setStyle(SkPaint::kStroke_Style);
- TestCase strokeEmptyCase(reporter, emptyPath2, stroke);
+ TestCase strokeEmptyCase(reporter, emptyPath, stroke);
strokeEmptyCase.compare(reporter, fillEmptyCase, TestCase::kAllSame_ComparisonExpecation);
+ TestCase strokeInvertedEmptyCase(reporter, invertedEmptyPath, stroke);
+ strokeInvertedEmptyCase.compare(reporter, fillInvertedEmptyCase,
+ TestCase::kAllSame_ComparisonExpecation);
// Dashing and stroking an empty path should have no effect
- SkPath emptyPath3;
SkPaint dashAndStroke;
dashAndStroke.setPathEffect(make_dash());
dashAndStroke.setStrokeWidth(2.f);
dashAndStroke.setStyle(SkPaint::kStroke_Style);
- TestCase dashAndStrokeEmptyCase(reporter, emptyPath3, dashAndStroke);
+ TestCase dashAndStrokeEmptyCase(reporter, emptyPath, dashAndStroke);
dashAndStrokeEmptyCase.compare(reporter, fillEmptyCase,
TestCase::kAllSame_ComparisonExpecation);
+ TestCase dashAndStrokeInvertexEmptyCase(reporter, invertedEmptyPath, dashAndStroke);
+ // Dashing ignores inverseness so this is equivalent to the non-inverted empty fill.
+ dashAndStrokeInvertexEmptyCase.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());
@@ -1351,12 +1410,24 @@ DEF_TEST(GrShape_empty_shape, reporter) {
TestCase dashAndStrokeEmptyRRectCase(reporter, emptyRRect, dashAndStroke);
dashAndStrokeEmptyRRectCase.compare(reporter, fillEmptyCase,
TestCase::kAllSame_ComparisonExpecation);
+ static constexpr SkPath::Direction kDir = SkPath::kCCW_Direction;
+ static constexpr int kStart = 0;
+ TestCase dashAndStrokeEmptyInvertedRRectCase(reporter, emptyRRect, kDir, kStart, true,
+ GrStyle(dashAndStroke));
+ // Dashing ignores inverseness so this is equivalent to the non-inverted empty fill.
+ dashAndStrokeEmptyInvertedRRectCase.compare(reporter, fillEmptyCase,
+ TestCase::kAllSame_ComparisonExpecation);
// Same for a rect.
SkRect emptyRect = SkRect::MakeEmpty();
TestCase dashAndStrokeEmptyRectCase(reporter, emptyRect, dashAndStroke);
dashAndStrokeEmptyRectCase.compare(reporter, fillEmptyCase,
TestCase::kAllSame_ComparisonExpecation);
+ TestCase dashAndStrokeEmptyInvertedRectCase(reporter, SkRRect::MakeRect(emptyRect), kDir,
+ kStart, true, GrStyle(dashAndStroke));
+ // Dashing ignores inverseness so this is equivalent to the non-inverted empty fill.
+ dashAndStrokeEmptyInvertedRectCase.compare(reporter, fillEmptyCase,
+ TestCase::kAllSame_ComparisonExpecation);
}
// rect and oval types have rrect start indices that collapse to the same point. Here we select the
@@ -1651,6 +1722,13 @@ DEF_TEST(GrShape_lines, r) {
fillAB.compare(r, fillEmpty, TestCase::kAllSame_ComparisonExpecation);
REPORTER_ASSERT(r, !fillAB.baseShape().asLine(nullptr, nullptr));
+ SkPath path;
+ path.toggleInverseFillType();
+ TestCase fillEmptyInverted(r, path, fill);
+ TestCase fillABInverted(r, invLineAB, fill);
+ fillABInverted.compare(r, fillEmptyInverted, TestCase::kAllSame_ComparisonExpecation);
+ REPORTER_ASSERT(r, !fillABInverted.baseShape().asLine(nullptr, nullptr));
+
TestCase strokeAB(r, lineAB, stroke);
TestCase strokeBA(r, lineBA, stroke);
TestCase strokeAC(r, lineAC, stroke);