aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils')
-rwxr-xr-xsrc/utils/SkShadowTessellator.cpp2
-rw-r--r--src/utils/SkShadowUtils.cpp108
2 files changed, 71 insertions, 39 deletions
diff --git a/src/utils/SkShadowTessellator.cpp b/src/utils/SkShadowTessellator.cpp
index 7d29b063a0..5dee5df3e0 100755
--- a/src/utils/SkShadowTessellator.cpp
+++ b/src/utils/SkShadowTessellator.cpp
@@ -778,7 +778,7 @@ SkSpotShadowTessellator::SkSpotShadowTessellator(const SkPath& path, const SkMat
// if the umbra would collapse, we back off a bit on inner blur and adjust the alpha
SkScalar newRadius = SkScalarSqrt(minDistSq) - kTolerance;
fOffsetAdjust = newRadius - radius;
- SkScalar ratio = 256 * newRadius / radius;
+ SkScalar ratio = 128 * (newRadius + radius) / radius;
// they aren't PMColors, but the interpolation algorithm is the same
fUmbraColor = SkPMLerp(fUmbraColor, fPenumbraColor, (unsigned)ratio);
radius = newRadius;
diff --git a/src/utils/SkShadowUtils.cpp b/src/utils/SkShadowUtils.cpp
index 8206bd3f54..fc0d44a277 100644
--- a/src/utils/SkShadowUtils.cpp
+++ b/src/utils/SkShadowUtils.cpp
@@ -454,33 +454,79 @@ void draw_shadow(const FACTORY& factory, SkCanvas* canvas, ShadowedPath& path, S
}
}
+static bool draw_analytic_shadows(SkCanvas* canvas, const SkPath& path, SkScalar occluderZ,
+ const SkPoint3& devLightPos, SkScalar lightRadius,
+ SkScalar ambientAlpha, SkScalar spotAlpha, SkColor color,
+ uint32_t flags) {
+ SkRect rect;
+ SkRRect rrect;
+ if (canvas->getTotalMatrix().isSimilarity()) {
+ if (path.isRect(&rect)) {
+ SkPaint newPaint;
+ newPaint.setColor(color);
+ if (ambientAlpha > 0) {
+ newPaint.setMaskFilter(SkAmbientShadowMaskFilter::Make(occluderZ,
+ ambientAlpha, flags));
+ canvas->drawRect(rect, newPaint);
+ }
+ if (spotAlpha > 0) {
+ newPaint.setMaskFilter(SkSpotShadowMaskFilter::Make(occluderZ, devLightPos,
+ lightRadius, spotAlpha,
+ flags));
+ canvas->drawRect(rect, newPaint);
+ }
+ return true;
+ } else if (path.isRRect(&rrect) && rrect.isSimpleCircular() &&
+ rrect.radii(SkRRect::kUpperLeft_Corner).fX > SK_ScalarNearlyZero) {
+ SkPaint newPaint;
+ newPaint.setColor(color);
+ if (ambientAlpha > 0) {
+ newPaint.setMaskFilter(SkAmbientShadowMaskFilter::Make(occluderZ,
+ ambientAlpha, flags));
+ canvas->drawRRect(rrect, newPaint);
+ }
+ if (spotAlpha > 0) {
+ newPaint.setMaskFilter(SkSpotShadowMaskFilter::Make(occluderZ, devLightPos,
+ lightRadius, spotAlpha,
+ flags));
+ canvas->drawRRect(rrect, newPaint);
+ }
+ return true;
+ } else if (path.isOval(&rect) && SkScalarNearlyEqual(rect.width(), rect.height()) &&
+ rect.width() > SK_ScalarNearlyZero) {
+ SkPaint newPaint;
+ newPaint.setColor(color);
+ if (ambientAlpha > 0) {
+ newPaint.setMaskFilter(SkAmbientShadowMaskFilter::Make(occluderZ,
+ ambientAlpha, flags));
+ canvas->drawOval(rect, newPaint);
+ }
+ if (spotAlpha > 0) {
+ newPaint.setMaskFilter(SkSpotShadowMaskFilter::Make(occluderZ, devLightPos,
+ lightRadius, spotAlpha,
+ flags));
+ canvas->drawOval(rect, newPaint);
+ }
+ return true;
+ }
+ }
+
+ return false;
+}
+
// 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& devLightPos, SkScalar lightRadius,
SkScalar ambientAlpha, SkScalar spotAlpha, SkColor color,
uint32_t flags, SkResourceCache* cache) {
- SkAutoCanvasRestore acr(canvas, true);
- SkMatrix viewMatrix = canvas->getTotalMatrix();
-
- // try circular fast path
- SkRect rect;
- if (viewMatrix.isSimilarity() &&
- path.isOval(&rect) && rect.width() == rect.height()) {
- SkPaint newPaint;
- newPaint.setColor(color);
- if (ambientAlpha > 0) {
- newPaint.setMaskFilter(SkAmbientShadowMaskFilter::Make(occluderHeight, ambientAlpha,
- flags));
- canvas->drawOval(rect, newPaint);
- }
- if (spotAlpha > 0) {
- newPaint.setMaskFilter(SkSpotShadowMaskFilter::Make(occluderHeight, devLightPos,
- lightRadius, spotAlpha, flags));
- canvas->drawOval(rect, newPaint);
- }
+ // try fast paths
+ if (draw_analytic_shadows(canvas, path, occluderHeight, devLightPos, lightRadius,
+ ambientAlpha, spotAlpha, color, flags)) {
return;
}
+ SkAutoCanvasRestore acr(canvas, true);
+ SkMatrix viewMatrix = canvas->getTotalMatrix();
canvas->resetMatrix();
ShadowedPath shadowedPath(&path, &viewMatrix);
@@ -563,28 +609,14 @@ void SkShadowUtils::DrawUncachedShadow(SkCanvas* canvas, const SkPath& path,
const SkPoint3& lightPos, SkScalar lightRadius,
SkScalar ambientAlpha, SkScalar spotAlpha, SkColor color,
uint32_t flags) {
- SkAutoCanvasRestore acr(canvas, true);
- SkMatrix viewMatrix = canvas->getTotalMatrix();
-
- // try circular fast path
- SkRect rect;
- if (viewMatrix.isSimilarity() &&
- path.isOval(&rect) && rect.width() == rect.height()) {
- SkPaint newPaint;
- newPaint.setColor(color);
- if (ambientAlpha > 0) {
- newPaint.setMaskFilter(SkAmbientShadowMaskFilter::Make(heightFunc(0,0), ambientAlpha,
- flags));
- canvas->drawOval(rect, newPaint);
- }
- if (spotAlpha > 0) {
- newPaint.setMaskFilter(SkSpotShadowMaskFilter::Make(heightFunc(0,0), lightPos,
- lightRadius, spotAlpha, flags));
- canvas->drawOval(rect, newPaint);
- }
+ // try fast paths
+ if (draw_analytic_shadows(canvas, path, heightFunc(0, 0), lightPos, lightRadius,
+ ambientAlpha, spotAlpha, color, flags)) {
return;
}
+ SkAutoCanvasRestore acr(canvas, true);
+ SkMatrix viewMatrix = canvas->getTotalMatrix();
canvas->resetMatrix();
bool transparent = SkToBool(flags & SkShadowFlags::kTransparentOccluder_ShadowFlag);