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
This commit is contained in:
Jeff Muizelaar 2012-05-22 11:32:08 -04:00
Родитель 976750f817
Коммит c0c625cf37
1 изменённых файлов: 20 добавлений и 15 удалений

Просмотреть файл

@ -4107,18 +4107,18 @@ nsImageRenderer::GetContainer()
#define MAX_SPREAD_RADIUS 50 #define MAX_SPREAD_RADIUS 50
static inline gfxIntSize 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 // http://dev.w3.org/csswg/css3-background/#box-shadow says that the
// standard deviation of the blur should be half the given blur value. // standard deviation of the blur should be half the given blur value.
gfxFloat blurStdDev = gfxFloat(aBlurRadius) / gfxFloat(aAppUnitsPerDevPixel); gfxFloat blurStdDev = gfxFloat(aBlurRadius) / gfxFloat(aAppUnitsPerDevPixel);
blurStdDev *= scale; gfxPoint scaledBlurStdDev = gfxPoint(NS_MIN((blurStdDev * aScaleX),
gfxFloat(MAX_BLUR_RADIUS)) / 2.0,
blurStdDev = NS_MIN(blurStdDev, NS_MIN((blurStdDev * aScaleY),
gfxFloat(MAX_BLUR_RADIUS)) / 2.0; gfxFloat(MAX_BLUR_RADIUS)) / 2.0);
return return
gfxAlphaBoxBlur::CalculateBlurRadius(gfxPoint(blurStdDev, blurStdDev)); gfxAlphaBoxBlur::CalculateBlurRadius(scaledBlurStdDev);
} }
// ----- // -----
@ -4138,27 +4138,32 @@ nsContextBoxBlur::Init(const nsRect& aRect, nscoord aSpreadRadius,
return nsnull; return nsnull;
} }
gfxFloat scale = 1; gfxFloat scaleX = 1;
gfxFloat scaleY = 1;
// Do blurs in device space when possible // Do blurs in device space when possible
// If the scale is not uniform we fall back to transforming on paint. // If the scale is not uniform we fall back to transforming on paint.
// Chrome/Skia always does the blurs in device space // Chrome/Skia always does the blurs in device space
// and will sometimes get incorrect results (e.g. rotated blurs) // and will sometimes get incorrect results (e.g. rotated blurs)
gfxMatrix transform = aDestinationCtx->CurrentMatrix(); gfxMatrix transform = aDestinationCtx->CurrentMatrix();
if (transform.HasNonAxisAlignedTransform() || transform.xx != transform.yy) { if (transform.HasNonAxisAlignedTransform()) {
transform = gfxMatrix(); transform = gfxMatrix();
} else { } else {
scale = transform.xx; scaleX = transform.xx;
scaleY = transform.yy;
} }
// compute a large or smaller blur radius // compute a large or smaller blur radius
gfxIntSize blurRadius = ComputeBlurRadius(aBlurRadius, aAppUnitsPerDevPixel, scale); gfxIntSize blurRadius = ComputeBlurRadius(aBlurRadius, aAppUnitsPerDevPixel, scaleX, scaleY);
PRInt32 spreadRadius = NS_MIN(PRInt32(aSpreadRadius / aAppUnitsPerDevPixel), gfxIntSize spreadRadius = gfxIntSize(NS_MIN(PRInt32(aSpreadRadius * scaleX / aAppUnitsPerDevPixel),
PRInt32(MAX_SPREAD_RADIUS)); PRInt32(MAX_SPREAD_RADIUS)),
NS_MIN(PRInt32(aSpreadRadius * scaleY / aAppUnitsPerDevPixel),
PRInt32(MAX_SPREAD_RADIUS)));
mDestinationCtx = aDestinationCtx; mDestinationCtx = aDestinationCtx;
// If not blurring, draw directly onto the destination device // 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)) { !(aFlags & FORCE_MASK)) {
mContext = aDestinationCtx; mContext = aDestinationCtx;
return mContext; return mContext;
@ -4179,10 +4184,10 @@ nsContextBoxBlur::Init(const nsRect& aRect, nscoord aSpreadRadius,
dirtyRect = transform.TransformBounds(dirtyRect); dirtyRect = transform.TransformBounds(dirtyRect);
if (aSkipRect) { if (aSkipRect) {
gfxRect skipRect = transform.TransformBounds(*aSkipRect); gfxRect skipRect = transform.TransformBounds(*aSkipRect);
mContext = blur.Init(rect, gfxIntSize(spreadRadius, spreadRadius), mContext = blur.Init(rect, spreadRadius,
blurRadius, &dirtyRect, &skipRect); blurRadius, &dirtyRect, &skipRect);
} else { } else {
mContext = blur.Init(rect, gfxIntSize(spreadRadius, spreadRadius), mContext = blur.Init(rect, spreadRadius,
blurRadius, &dirtyRect, NULL); blurRadius, &dirtyRect, NULL);
} }