Add SkShadowUtils::GetLocalBounds.
Generates a bounding rect that encompasses both shadows for a given path,
relative to the path local space.
Bug: skia:11146
Change-Id: Ib8edb1072ed9cbfe36285523330be95fdf661d6b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/351922
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Yegor Jbanov <yjbanov@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/utils/SkShadowUtils.cpp b/src/utils/SkShadowUtils.cpp
index f65877e..4e30c40 100644
--- a/src/utils/SkShadowUtils.cpp
+++ b/src/utils/SkShadowUtils.cpp
@@ -564,34 +564,61 @@
unPremulScale*spotB);
}
-// Draw an offset spot shadow and outlining ambient shadow for the given path.
-void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoint3& zPlaneParams,
- const SkPoint3& lightPos, SkScalar lightRadius,
- SkColor ambientColor, SkColor spotColor,
- uint32_t flags) {
-
+static bool fill_shadow_rec(const SkPath& path, const SkPoint3& zPlaneParams,
+ const SkPoint3& lightPos, SkScalar lightRadius,
+ SkColor ambientColor, SkColor spotColor,
+ uint32_t flags, const SkMatrix& ctm, SkDrawShadowRec* rec) {
SkPoint pt = { lightPos.fX, lightPos.fY };
if (!SkToBool(flags & kDirectionalLight_ShadowFlag)) {
// If light position is in device space, need to transform to local space
// before applying to SkCanvas.
SkMatrix inverse;
- if (!canvas->getTotalMatrix().invert(&inverse)) {
- return;
+ if (!ctm.invert(&inverse)) {
+ return false;
}
inverse.mapPoints(&pt, 1);
}
+ rec->fZPlaneParams = zPlaneParams;
+ rec->fLightPos = { pt.fX, pt.fY, lightPos.fZ };
+ rec->fLightRadius = lightRadius;
+ rec->fAmbientColor = ambientColor;
+ rec->fSpotColor = spotColor;
+ rec->fFlags = flags;
+
+ return true;
+}
+
+// Draw an offset spot shadow and outlining ambient shadow for the given path.
+void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, const SkPoint3& zPlaneParams,
+ const SkPoint3& lightPos, SkScalar lightRadius,
+ SkColor ambientColor, SkColor spotColor,
+ uint32_t flags) {
SkDrawShadowRec rec;
- rec.fZPlaneParams = zPlaneParams;
- rec.fLightPos = { pt.fX, pt.fY, lightPos.fZ };
- rec.fLightRadius = lightRadius;
- rec.fAmbientColor = ambientColor;
- rec.fSpotColor = spotColor;
- rec.fFlags = flags;
+ if (!fill_shadow_rec(path, zPlaneParams, lightPos, lightRadius, ambientColor, spotColor,
+ flags, canvas->getTotalMatrix(), &rec)) {
+ return;
+ }
canvas->private_draw_shadow_rec(path, rec);
}
+bool SkShadowUtils::GetLocalBounds(const SkMatrix& ctm, const SkPath& path,
+ const SkPoint3& zPlaneParams, const SkPoint3& lightPos,
+ SkScalar lightRadius, uint32_t flags, SkRect* bounds) {
+ SkDrawShadowRec rec;
+ if (!fill_shadow_rec(path, zPlaneParams, lightPos, lightRadius, SK_ColorBLACK, SK_ColorBLACK,
+ flags, ctm, &rec)) {
+ return false;
+ }
+
+ SkDrawShadowMetrics::GetLocalBounds(path, rec, ctm, bounds);
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+
static bool validate_rec(const SkDrawShadowRec& rec) {
return rec.fLightPos.isFinite() && rec.fZPlaneParams.isFinite() &&
SkScalarIsFinite(rec.fLightRadius);