Bug 1200611 - Size ImageLayers correctly for <img>s using object-fit. r=dholbert

This changes nsDisplayImage::GetDestRect and nsImageFrame::PredictedDestRect to return
the true dest rect of the image, without intersecting it with the image content box.
The only caller of these functions that actually requires a rectangle that's within
the image's content bounds is nsDisplayImage::GetOpaqueRegion, so I'm changing that
to intersect with the display item's bounds.
I'm pretty sure nsImageFrame::MaybeDecodeForPredictedSize() also prefers the unclipped
dest rect, because it cares about the scale at which the image is painted, and not
about which parts of the image are painted.

--HG--
extra : commitid : CDJJnfN7vF3
extra : rebase_source : 5b59f81ab60290f508b83db7e942559da621cb70
This commit is contained in:
Markus Stange 2015-12-03 15:20:10 +01:00
parent ff1b756ddd
commit 21ce2dd228
4 changed files with 47 additions and 13 deletions

View File

@ -756,22 +756,15 @@ nsImageFrame::MaybeDecodeForPredictedSize()
nsRect
nsImageFrame::PredictedDestRect(const nsRect& aFrameContentBox)
{
// What is the rect painted by the image? It's the image's "dest rect" (the
// rect where a full copy of the image is mapped), clipped to the container's
// content box. So, we intersect those rects.
// Note: To get the "dest rect", we have to provide the "constraint rect"
// (which is the content-box, with the effects of fragmentation undone).
nsRect constraintRect(aFrameContentBox.TopLeft(), mComputedSize);
constraintRect.y -= GetContinuationOffset();
const nsRect destRect =
nsLayoutUtils::ComputeObjectDestRect(constraintRect,
mIntrinsicSize,
mIntrinsicRatio,
StylePosition());
return destRect.Intersect(aFrameContentBox);
return nsLayoutUtils::ComputeObjectDestRect(constraintRect,
mIntrinsicSize,
mIntrinsicRatio,
StylePosition());
}
void
@ -1644,7 +1637,8 @@ nsDisplayImage::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap)
{
if (mImage && mImage->IsOpaque()) {
return nsRegion(GetDestRect(aSnap));
const nsRect frameContentBox = GetBounds(aSnap);
return GetDestRect().Intersect(frameContentBox);
}
return nsRegion();
}

View File

@ -248,6 +248,7 @@ protected:
* Computes the predicted dest rect that we'll draw into, in app units, based
* upon the provided frame content box. (The content box is what
* nsDisplayImage::GetBounds() returns.)
* The result is not necessarily contained in the frame content box.
*/
nsRect PredictedDestRect(const nsRect& aFrameContentBox);
@ -425,7 +426,8 @@ public:
nsDisplayListBuilder* aBuilder) override;
/**
* @return the dest rect we'll use when drawing this image, in app units.
* @return The dest rect we'll use when drawing this image, in app units.
* Not necessarily contained in this item's bounds.
*/
nsRect GetDestRect(bool* aSnap = nullptr);

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Reference: Make sure the ImageLayer is sized correctly when using object-fit</title>
<style type="text/css">
.clip {
display: inline-block;
overflow: hidden;
}
img {
will-change: transform;
margin: -64px 0;
display: block;
}
</style>
<span class="clip">
<img src="repeatable-diagonal-gradient.png">
</span>

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Make sure the ImageLayer is sized correctly when using object-fit</title>
<style type="text/css">
img {
object-fit: cover;
width: 256px;
height: 128px;
will-change: transform;
}
</style>
<img src="repeatable-diagonal-gradient.png">