Bug 629857 - When invalidating transformed items, round the original area out to the nearest pixel. r=roc a=roc

This commit is contained in:
Matt Woodrow 2011-02-25 11:55:23 +13:00
parent 604c0a7512
commit 0ce267f38b
6 changed files with 56 additions and 5 deletions

View File

@ -449,6 +449,11 @@ inline double NSAppUnitsToDoublePixels(nscoord aAppUnits, nscoord aAppUnitsPerPi
return (double(aAppUnits) / double(aAppUnitsPerPixel));
}
inline double NSAppUnitsToDoublePixels(nscoord aAppUnits, double aAppUnitsPerPixel)
{
return (double(aAppUnits) / aAppUnitsPerPixel);
}
inline PRInt32 NSAppUnitsToIntPixels(nscoord aAppUnits, float aAppUnitsPerPixel)
{
return NSToIntRound(float(aAppUnits) / aAppUnitsPerPixel);

View File

@ -2406,6 +2406,22 @@ nsRect nsDisplayTransform::TransformRect(const nsRect &aUntransformedBounds,
factor);
}
nsRect nsDisplayTransform::TransformRectOut(const nsRect &aUntransformedBounds,
const nsIFrame* aFrame,
const nsPoint &aOrigin,
const nsRect* aBoundsOverride)
{
NS_PRECONDITION(aFrame, "Can't take the transform based on a null frame!");
NS_PRECONDITION(aFrame->GetStyleDisplay()->HasTransform(),
"Cannot transform a rectangle if there's no transformation!");
float factor = nsPresContext::AppUnitsPerCSSPixel();
return nsLayoutUtils::MatrixTransformRectOut
(aUntransformedBounds,
GetResultingTransformMatrix(aFrame, aOrigin, factor, aBoundsOverride),
factor);
}
nsRect nsDisplayTransform::UntransformRect(const nsRect &aUntransformedBounds,
const nsIFrame* aFrame,
const nsPoint &aOrigin)

View File

@ -2049,6 +2049,11 @@ public:
const nsPoint &aOrigin,
const nsRect* aBoundsOverride = nsnull);
static nsRect TransformRectOut(const nsRect &aUntransformedBounds,
const nsIFrame* aFrame,
const nsPoint &aOrigin,
const nsRect* aBoundsOverride = nsnull);
/* UntransformRect is like TransformRect, except that it inverts the
* transform.
*/

View File

@ -1009,14 +1009,27 @@ nsLayoutUtils::RoundedRectIntersectRect(const nsRect& aRoundedRect,
return result;
}
nsRect
nsLayoutUtils::MatrixTransformRectOut(const nsRect &aBounds,
const gfxMatrix &aMatrix, float aFactor)
{
nsRect outside = aBounds;
outside.ScaleRoundOut(1/aFactor);
gfxRect image = aMatrix.TransformBounds(gfxRect(outside.x,
outside.y,
outside.width,
outside.height));
return RoundGfxRectToAppRect(image, aFactor);
}
nsRect
nsLayoutUtils::MatrixTransformRect(const nsRect &aBounds,
const gfxMatrix &aMatrix, float aFactor)
{
gfxRect image = aMatrix.TransformBounds(gfxRect(NSAppUnitsToFloatPixels(aBounds.x, aFactor),
NSAppUnitsToFloatPixels(aBounds.y, aFactor),
NSAppUnitsToFloatPixels(aBounds.width, aFactor),
NSAppUnitsToFloatPixels(aBounds.height, aFactor)));
gfxRect image = aMatrix.TransformBounds(gfxRect(NSAppUnitsToDoublePixels(aBounds.x, aFactor),
NSAppUnitsToDoublePixels(aBounds.y, aFactor),
NSAppUnitsToDoublePixels(aBounds.width, aFactor),
NSAppUnitsToDoublePixels(aBounds.height, aFactor)));
return RoundGfxRectToAppRect(image, aFactor);
}

View File

@ -521,6 +521,18 @@ public:
static nsRect MatrixTransformRect(const nsRect &aBounds,
const gfxMatrix &aMatrix, float aFactor);
/**
* Helper function that, given a rectangle and a matrix, returns the smallest
* rectangle containing the image of the source rectangle rounded out to the nearest
* pixel value.
*
* @param aBounds The rectangle to transform.
* @param aMatrix The matrix to transform it with.
* @param aFactor The number of app units per graphics unit.
* @return The smallest rect that contains the image of aBounds.
*/
static nsRect MatrixTransformRectOut(const nsRect &aBounds,
const gfxMatrix &aMatrix, float aFactor);
/**
* Helper function that, given a point and a matrix, returns the image
* of that point under the matrix transform.

View File

@ -4132,7 +4132,7 @@ nsIFrame::InvalidateInternalAfterResize(const nsRect& aDamageRect, nscoord aX,
}
if (IsTransformed()) {
nsRect newDamageRect;
newDamageRect.UnionRect(nsDisplayTransform::TransformRect
newDamageRect.UnionRect(nsDisplayTransform::TransformRectOut
(aDamageRect, this, nsPoint(-aX, -aY)), aDamageRect);
GetParent()->
InvalidateInternal(newDamageRect, aX + mRect.x, aY + mRect.y, this,