aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/ShadowTest.cpp
diff options
context:
space:
mode:
authorGravatar Jim Van Verth <jvanverth@google.com>2017-07-31 09:34:58 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-07-31 13:55:32 +0000
commit1af03d4396a9567e3ca127830676eb4fd5a76266 (patch)
tree985b377567124e1aab52f46609b4e8ea18919caa /tests/ShadowTest.cpp
parent0d67fafa3eccc31e5187c740ee19e1c55b135152 (diff)
Compute correct bounds for DrawShadowRec.
Bug: skia:6880 Change-Id: Ia8b94e52eec3feb5104d2351bf7a7e6f99101deb Reviewed-on: https://skia-review.googlesource.com/26370 Commit-Queue: Jim Van Verth <jvanverth@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'tests/ShadowTest.cpp')
-rw-r--r--tests/ShadowTest.cpp118
1 files changed, 118 insertions, 0 deletions
diff --git a/tests/ShadowTest.cpp b/tests/ShadowTest.cpp
new file mode 100644
index 0000000000..8a921d8bc8
--- /dev/null
+++ b/tests/ShadowTest.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkCanvas.h"
+#include "SkDrawShadowInfo.h"
+#include "SkPath.h"
+#include "SkShadowTessellator.h"
+#include "SkShadowUtils.h"
+#include "SkVertices.h"
+#include "Test.h"
+
+void tessellate_shadow(skiatest::Reporter* reporter, const SkPath& path, const SkMatrix& ctm,
+ bool expectSuccess) {
+
+ auto heightParams = SkPoint3::Make(0, 0, 4);
+
+ auto verts = SkShadowTessellator::MakeAmbient(path, ctm, heightParams, true);
+ if (expectSuccess != SkToBool(verts)) {
+ ERRORF(reporter, "Expected shadow tessellation to %s but it did not.",
+ expectSuccess ? "succeed" : "fail");
+ }
+ verts = SkShadowTessellator::MakeAmbient(path, ctm, heightParams, false);
+ if (expectSuccess != SkToBool(verts)) {
+ ERRORF(reporter, "Expected shadow tessellation to %s but it did not.",
+ expectSuccess ? "succeed" : "fail");
+ }
+ verts = SkShadowTessellator::MakeSpot(path, ctm, heightParams, {0, 0, 128}, 128.f, false);
+ if (expectSuccess != SkToBool(verts)) {
+ ERRORF(reporter, "Expected shadow tessellation to %s but it did not.",
+ expectSuccess ? "succeed" : "fail");
+ }
+ verts = SkShadowTessellator::MakeSpot(path, ctm, heightParams, {0, 0, 128}, 128.f, false);
+ if (expectSuccess != SkToBool(verts)) {
+ ERRORF(reporter, "Expected shadow tessellation to %s but it did not.",
+ expectSuccess ? "succeed" : "fail");
+ }
+}
+
+DEF_TEST(ShadowUtils, reporter) {
+ SkCanvas canvas(100, 100);
+
+ SkPath path;
+ path.cubicTo(100, 50, 20, 100, 0, 0);
+ tessellate_shadow(reporter, path, canvas.getTotalMatrix(), true);
+
+ // This line segment has no area and no shadow.
+ path.reset();
+ path.lineTo(10.f, 10.f);
+ tessellate_shadow(reporter, path, canvas.getTotalMatrix(), false);
+
+ // A series of colinear line segments
+ path.reset();
+ for (int i = 0; i < 10; ++i) {
+ path.lineTo((SkScalar)i, (SkScalar)i);
+ }
+ tessellate_shadow(reporter, path, canvas.getTotalMatrix(), false);
+}
+
+void check_xformed_bounds(skiatest::Reporter* reporter, const SkPath& path, const SkMatrix& ctm) {
+ const SkDrawShadowRec rec = {
+ SkPoint3::Make(0, 0, 4),
+ SkPoint3::Make(100, 0, 600),
+ 800.f,
+ 0.035f,
+ 0.25f,
+ SK_ColorBLACK,
+ 0
+ };
+ SkRect bounds;
+ SkDrawShadowMetrics::GetLocalBounds(path, rec, ctm, &bounds);
+ ctm.mapRect(&bounds);
+
+ auto verts = SkShadowTessellator::MakeAmbient(path, ctm, rec.fZPlaneParams, true);
+ if (verts) {
+ REPORTER_ASSERT(reporter, bounds.contains(verts->bounds()));
+ }
+
+ SkPoint mapXY = ctm.mapXY(rec.fLightPos.fX, rec.fLightPos.fY);
+ SkPoint3 devLightPos = SkPoint3::Make(mapXY.fX, mapXY.fY, rec.fLightPos.fZ);
+ verts = SkShadowTessellator::MakeSpot(path, ctm, rec.fZPlaneParams, devLightPos,
+ rec.fLightRadius, false);
+ if (verts) {
+ REPORTER_ASSERT(reporter, bounds.contains(verts->bounds()));
+ }
+}
+
+void check_bounds(skiatest::Reporter* reporter, const SkPath& path) {
+ SkMatrix ctm;
+ ctm.setTranslate(100, 100);
+ check_xformed_bounds(reporter, path, ctm);
+ ctm.postScale(2, 2);
+ check_xformed_bounds(reporter, path, ctm);
+ ctm.preRotate(45);
+ check_xformed_bounds(reporter, path, ctm);
+ ctm.preSkew(40, -20);
+ check_xformed_bounds(reporter, path, ctm);
+ ctm[SkMatrix::kMPersp0] = 0.0001f;
+ ctm[SkMatrix::kMPersp1] = 12.f;
+ check_xformed_bounds(reporter, path, ctm);
+}
+
+DEF_TEST(ShadowBounds, reporter) {
+ SkPath path;
+ path.addRRect(SkRRect::MakeRectXY(SkRect::MakeLTRB(-50, -20, 40, 30), 4, 4));
+ check_bounds(reporter, path);
+
+ path.reset();
+ path.addOval(SkRect::MakeLTRB(300, 300, 900, 900));
+ check_bounds(reporter, path);
+
+ path.reset();
+ path.cubicTo(100, 50, 20, 100, 0, 0);
+ check_bounds(reporter, path);
+}