From c0c625cf3757dcd4f5e9dc72a352dbf0fff40482 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Tue, 22 May 2012 11:32:08 -0400 Subject: [PATCH] Bug 757039. Handle non-uniform scales when doing device space blurs. r=roc The Java screenshoting code draws pages at non-uniform scales. It's not much work to handle these so let's do it. --HG-- extra : rebase_source : 6b3a2a6db21f9cff4ce97a5a10c368d95f730387 --- layout/base/nsCSSRendering.cpp | 35 +++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp index e18f7612f69..f4014ad5911 100644 --- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -4107,18 +4107,18 @@ nsImageRenderer::GetContainer() #define MAX_SPREAD_RADIUS 50 static inline gfxIntSize -ComputeBlurRadius(nscoord aBlurRadius, PRInt32 aAppUnitsPerDevPixel, gfxFloat scale = 1.0) +ComputeBlurRadius(nscoord aBlurRadius, PRInt32 aAppUnitsPerDevPixel, gfxFloat aScaleX = 1.0, gfxFloat aScaleY = 1.0) { // http://dev.w3.org/csswg/css3-background/#box-shadow says that the // standard deviation of the blur should be half the given blur value. gfxFloat blurStdDev = gfxFloat(aBlurRadius) / gfxFloat(aAppUnitsPerDevPixel); - blurStdDev *= scale; - - blurStdDev = NS_MIN(blurStdDev, - gfxFloat(MAX_BLUR_RADIUS)) / 2.0; + gfxPoint scaledBlurStdDev = gfxPoint(NS_MIN((blurStdDev * aScaleX), + gfxFloat(MAX_BLUR_RADIUS)) / 2.0, + NS_MIN((blurStdDev * aScaleY), + gfxFloat(MAX_BLUR_RADIUS)) / 2.0); return - gfxAlphaBoxBlur::CalculateBlurRadius(gfxPoint(blurStdDev, blurStdDev)); + gfxAlphaBoxBlur::CalculateBlurRadius(scaledBlurStdDev); } // ----- @@ -4138,27 +4138,32 @@ nsContextBoxBlur::Init(const nsRect& aRect, nscoord aSpreadRadius, return nsnull; } - gfxFloat scale = 1; + gfxFloat scaleX = 1; + gfxFloat scaleY = 1; // Do blurs in device space when possible // If the scale is not uniform we fall back to transforming on paint. // Chrome/Skia always does the blurs in device space // and will sometimes get incorrect results (e.g. rotated blurs) gfxMatrix transform = aDestinationCtx->CurrentMatrix(); - if (transform.HasNonAxisAlignedTransform() || transform.xx != transform.yy) { + if (transform.HasNonAxisAlignedTransform()) { transform = gfxMatrix(); } else { - scale = transform.xx; + scaleX = transform.xx; + scaleY = transform.yy; } // compute a large or smaller blur radius - gfxIntSize blurRadius = ComputeBlurRadius(aBlurRadius, aAppUnitsPerDevPixel, scale); - PRInt32 spreadRadius = NS_MIN(PRInt32(aSpreadRadius / aAppUnitsPerDevPixel), - PRInt32(MAX_SPREAD_RADIUS)); + gfxIntSize blurRadius = ComputeBlurRadius(aBlurRadius, aAppUnitsPerDevPixel, scaleX, scaleY); + gfxIntSize spreadRadius = gfxIntSize(NS_MIN(PRInt32(aSpreadRadius * scaleX / aAppUnitsPerDevPixel), + PRInt32(MAX_SPREAD_RADIUS)), + NS_MIN(PRInt32(aSpreadRadius * scaleY / aAppUnitsPerDevPixel), + PRInt32(MAX_SPREAD_RADIUS))); mDestinationCtx = aDestinationCtx; // If not blurring, draw directly onto the destination device - if (blurRadius.width <= 0 && blurRadius.height <= 0 && spreadRadius <= 0 && + if (blurRadius.width <= 0 && blurRadius.height <= 0 && + spreadRadius.width <= 0 && spreadRadius.height <= 0 && !(aFlags & FORCE_MASK)) { mContext = aDestinationCtx; return mContext; @@ -4179,10 +4184,10 @@ nsContextBoxBlur::Init(const nsRect& aRect, nscoord aSpreadRadius, dirtyRect = transform.TransformBounds(dirtyRect); if (aSkipRect) { gfxRect skipRect = transform.TransformBounds(*aSkipRect); - mContext = blur.Init(rect, gfxIntSize(spreadRadius, spreadRadius), + mContext = blur.Init(rect, spreadRadius, blurRadius, &dirtyRect, &skipRect); } else { - mContext = blur.Init(rect, gfxIntSize(spreadRadius, spreadRadius), + mContext = blur.Init(rect, spreadRadius, blurRadius, &dirtyRect, NULL); }