aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/utils/SkShadowUtils.cpp
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-02-01 12:23:25 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-01 20:14:18 +0000
commit0bd699e497819344083df4715928a54a597cd630 (patch)
tree27ab41441f650a3912d9bf21d7e7937e4950721b /src/utils/SkShadowUtils.cpp
parent44f80a24f010e99de773dad89fb9f50100898969 (diff)
Add a GM for SkShadowUtils and fix a few issues.
1) Transform the path center to device space before computing the shadow offset. 2) Modulate the shadow color by the color filter's output color. 3) Make the scale of path points in the spot tessellator be relative to the path centroid. 4) Clamp the shadow alphas at 1. Change-Id: I480476df79b959f11c1eca0ba2a49a134d355cbb Reviewed-on: https://skia-review.googlesource.com/7860 Reviewed-by: Jim Van Verth <jvanverth@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src/utils/SkShadowUtils.cpp')
-rwxr-xr-xsrc/utils/SkShadowUtils.cpp28
1 files changed, 16 insertions, 12 deletions
diff --git a/src/utils/SkShadowUtils.cpp b/src/utils/SkShadowUtils.cpp
index 6ad87e5e24..32f1c6f165 100755
--- a/src/utils/SkShadowUtils.cpp
+++ b/src/utils/SkShadowUtils.cpp
@@ -54,7 +54,8 @@ void SkGaussianColorFilter::filterSpan(const SkPMColor src[], int count, SkPMCol
SkScalar factor = SK_Scalar1 - SkGetPackedB32(c) / 255.f;
factor = SkScalarExp(-factor * factor * 4) - 0.018f;
- dst[i] = SkPackARGB32(factor*SkGetPackedG32(c), 0, 0, 0);
+ SkScalar a = factor * SkGetPackedG32(c);
+ dst[i] = SkPackARGB32(a, a, a, a);
}
}
@@ -270,8 +271,11 @@ void draw_shadow(const FACTORY& factory, SkCanvas* canvas, ShadowedPath& path, S
}
SkPaint paint;
- paint.setColor(color);
- paint.setColorFilter(SkGaussianColorFilter::Make());
+ // Run the vertex color through a GaussianColorFilter and then modulate the grayscale result of
+ // that against our 'color' param.
+ paint.setColorFilter(SkColorFilter::MakeComposeFilter(
+ SkColorFilter::MakeModeFilter(color, SkBlendMode::kModulate),
+ SkGaussianColorFilter::Make()));
if (translate->fX || translate->fY) {
canvas->save();
canvas->translate(translate->fX, translate->fY);
@@ -294,12 +298,11 @@ static const float kGeomFactor = 64.0f;
// Draw an offset spot shadow and outlining ambient shadow for the given path.
void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, SkScalar occluderHeight,
- const SkPoint3& lightPos, SkScalar lightRadius,
+ const SkPoint3& devLightPos, SkScalar lightRadius,
SkScalar ambientAlpha, SkScalar spotAlpha, SkColor color,
uint32_t flags) {
+ SkAutoCanvasRestore acr(canvas, true);
SkMatrix viewMatrix = canvas->getTotalMatrix();
-
- canvas->save();
canvas->resetMatrix();
ShadowedPath shadowedPath(&path, &viewMatrix);
@@ -307,6 +310,7 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, SkScalar oc
bool transparent = SkToBool(flags & SkShadowFlags::kTransparentOccluder_ShadowFlag);
if (ambientAlpha > 0) {
+ ambientAlpha = SkTMin(ambientAlpha, 1.f);
AmbientVerticesFactory factory;
factory.fRadius = occluderHeight * kHeightFactor * kGeomFactor;
SkScalar umbraAlpha = SkScalarInvert((1.0f + SkTMax(occluderHeight*kHeightFactor, 0.0f)));
@@ -323,22 +327,22 @@ void SkShadowUtils::DrawShadow(SkCanvas* canvas, const SkPath& path, SkScalar oc
}
if (spotAlpha > 0) {
+ spotAlpha = SkTMin(spotAlpha, 1.f);
SpotVerticesFactory factory;
- float zRatio = SkTPin(occluderHeight / (lightPos.fZ - occluderHeight), 0.0f, 0.95f);
+ float zRatio = SkTPin(occluderHeight / (devLightPos.fZ - occluderHeight), 0.0f, 0.95f);
factory.fRadius = lightRadius * zRatio;
// Compute the scale and translation for the spot shadow.
- factory.fScale = lightPos.fZ / (lightPos.fZ - occluderHeight);
+ factory.fScale = devLightPos.fZ / (devLightPos.fZ - occluderHeight);
SkPoint center = SkPoint::Make(path.getBounds().centerX(), path.getBounds().centerY());
- factory.fOffset = SkVector::Make(zRatio * (center.fX - lightPos.fX),
- zRatio * (center.fY - lightPos.fY));
+ viewMatrix.mapPoints(&center, 1);
+ factory.fOffset = SkVector::Make(zRatio * (center.fX - devLightPos.fX),
+ zRatio * (center.fY - devLightPos.fY));
factory.fUmbraColor = SkColorSetARGB(255, 0, spotAlpha * 255.9999f, 255);
factory.fPenumbraColor = SkColorSetARGB(255, 0, spotAlpha * 255.9999f, 0);
factory.fTransparent = transparent;
draw_shadow(factory, canvas, shadowedPath, color);
}
-
- canvas->restore();
}