зеркало из https://github.com/mozilla/gecko-dev.git
Bug 984460 - Fill in a missing piece of code to compute the right dirty rect in the face of CSS transforms. r=mattwoodrow
This commit is contained in:
Родитель
bf96d695e0
Коммит
a15a9aedef
|
@ -5098,6 +5098,36 @@ nsRect nsDisplayTransform::TransformRectOut(const nsRect &aUntransformedBounds,
|
|||
factor);
|
||||
}
|
||||
|
||||
bool nsDisplayTransform::UntransformRect(const nsRect &aTransformedBounds,
|
||||
const nsRect &aChildBounds,
|
||||
const nsIFrame* aFrame,
|
||||
const nsPoint &aOrigin,
|
||||
nsRect *aOutRect)
|
||||
{
|
||||
NS_PRECONDITION(aFrame, "Can't take the transform based on a null frame!");
|
||||
|
||||
float factor = aFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
|
||||
gfx3DMatrix transform = GetResultingTransformMatrix(aFrame, aOrigin, factor, nullptr);
|
||||
if (transform.IsSingular()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
gfxRect result(NSAppUnitsToFloatPixels(aTransformedBounds.x, factor),
|
||||
NSAppUnitsToFloatPixels(aTransformedBounds.y, factor),
|
||||
NSAppUnitsToFloatPixels(aTransformedBounds.width, factor),
|
||||
NSAppUnitsToFloatPixels(aTransformedBounds.height, factor));
|
||||
|
||||
gfxRect childGfxBounds(NSAppUnitsToFloatPixels(aChildBounds.x, factor),
|
||||
NSAppUnitsToFloatPixels(aChildBounds.y, factor),
|
||||
NSAppUnitsToFloatPixels(aChildBounds.width, factor),
|
||||
NSAppUnitsToFloatPixels(aChildBounds.height, factor));
|
||||
|
||||
result = transform.UntransformBounds(result, childGfxBounds);
|
||||
*aOutRect = nsLayoutUtils::RoundGfxRectToAppRect(result, factor);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool nsDisplayTransform::UntransformVisibleRect(nsDisplayListBuilder* aBuilder,
|
||||
nsRect *aOutRect)
|
||||
{
|
||||
|
|
|
@ -3258,6 +3258,12 @@ public:
|
|||
/* UntransformRect is like TransformRect, except that it inverts the
|
||||
* transform.
|
||||
*/
|
||||
static bool UntransformRect(const nsRect &aTransformedBounds,
|
||||
const nsRect &aChildBounds,
|
||||
const nsIFrame* aFrame,
|
||||
const nsPoint &aOrigin,
|
||||
nsRect *aOutRect);
|
||||
|
||||
bool UntransformVisibleRect(nsDisplayListBuilder* aBuilder,
|
||||
nsRect* aOutRect);
|
||||
|
||||
|
|
|
@ -1929,22 +1929,16 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||
if (overflow.IsEmpty() && !Preserves3DChildren()) {
|
||||
return;
|
||||
}
|
||||
// Trying to back-transform arbitrary rects gives us really weird results. I believe
|
||||
// this is from points that lie beyond the vanishing point. As a workaround we transform
|
||||
// the overflow rect into screen space and compare in that coordinate system.
|
||||
|
||||
// Transform the overflow rect into screen space.
|
||||
nsPoint offset = aBuilder->ToReferenceFrame(this);
|
||||
nsRect trans = nsDisplayTransform::TransformRect(overflow + offset, this, offset);
|
||||
dirtyRect += offset;
|
||||
if (dirtyRect.Intersects(trans)) {
|
||||
// If they intersect, we take our whole overflow rect. We could instead take the intersection
|
||||
// and then reverse transform it but I doubt this extra work is worthwhile.
|
||||
dirtyRect = overflow;
|
||||
|
||||
nsRect untransformedDirtyRect;
|
||||
if (nsDisplayTransform::UntransformRect(dirtyRect, overflow, this, offset, &untransformedDirtyRect)) {
|
||||
dirtyRect = untransformedDirtyRect;
|
||||
} else {
|
||||
if (!Preserves3DChildren()) {
|
||||
return;
|
||||
}
|
||||
NS_WARNING("Unable to untransform dirty rect!");
|
||||
// This should only happen if the transform is singular, in which case nothing is visible anyway
|
||||
dirtyRect.SetEmpty();
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче