diff options
author | Brian Salomon <bsalomon@google.com> | 2017-02-01 12:23:25 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-02-01 20:14:18 +0000 |
commit | 0bd699e497819344083df4715928a54a597cd630 (patch) | |
tree | 27ab41441f650a3912d9bf21d7e7937e4950721b /src/utils/SkShadowUtils.cpp | |
parent | 44f80a24f010e99de773dad89fb9f50100898969 (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-x | src/utils/SkShadowUtils.cpp | 28 |
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(¢er, 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(); } |