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.
This commit is contained in:
Markus Stange 2015-12-03 15:20:10 +01:00
parent 721114d8a6
commit 2f88224e05
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">