diff --git a/gfx/public/nsTransform2D.h b/gfx/public/nsTransform2D.h index dc03406ceaba..304b764d81cf 100644 --- a/gfx/public/nsTransform2D.h +++ b/gfx/public/nsTransform2D.h @@ -111,6 +111,16 @@ public: **/ void AddScale(float ptX, float ptY) { m00 *= ptX; m11 *= ptY; } + + /** + * Set the scale (overriding any previous calls to AddScale, but leaving + * any existing translation). + * + * @param ptX x value to add as x scale + * @param ptY y value to add as y scale + **/ + + void SetScale(float ptX, float ptY) { m00 = ptX; m11 = ptY; } }; #endif diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index f1660e9fcc5c..2b32cf8a744e 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -309,7 +309,7 @@ nsImageFrame::UpdateIntrinsicSize(imgIContainer* aImage) } void -nsImageFrame::RecalculateTransform() +nsImageFrame::RecalculateTransform(PRBool aInnerAreaChanged) { // In any case, we need to translate this over appropriately. Set // translation _before_ setting scaling so that it does not get @@ -318,15 +318,19 @@ nsImageFrame::RecalculateTransform() // XXXbz does this introduce rounding errors because of the cast to // float? Should we just manually add that stuff in every time // instead? - nsRect innerArea = GetInnerArea(); - mTransform.SetToTranslate(float(innerArea.x), - float(innerArea.y - GetContinuationOffset())); + if (aInnerAreaChanged) { + nsRect innerArea = GetInnerArea(); + mTransform.SetToTranslate(float(innerArea.x), + float(innerArea.y - GetContinuationOffset())); + } // Set the scale factors if (mIntrinsicSize.width != 0 && mIntrinsicSize.height != 0 && mIntrinsicSize != mComputedSize) { - mTransform.AddScale(float(mComputedSize.width) / float(mIntrinsicSize.width), + mTransform.SetScale(float(mComputedSize.width) / float(mIntrinsicSize.width), float(mComputedSize.height) / float(mIntrinsicSize.height)); + } else { + mTransform.SetScale(1.0f, 1.0f); } } @@ -506,14 +510,24 @@ nsImageFrame::OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage) UpdateIntrinsicSize(aImage); - // Now we need to reflow if we have an unconstrained size and have - // already gotten the initial reflow - if (!(mState & IMAGE_SIZECONSTRAINED) && (mState & IMAGE_GOTINITIALREFLOW)) { - nsIPresShell *presShell = presContext->GetPresShell(); - NS_ASSERTION(presShell, "No PresShell."); - if (presShell) { - presShell->FrameNeedsReflow(this, nsIPresShell::eStyleChange, - NS_FRAME_IS_DIRTY); + if (mState & IMAGE_GOTINITIALREFLOW) { + // If we previously set the intrinsic size (in EnsureIntrinsicSize) + // to the size of the loading-image icon and reflowed the frame, + // we'll have an mTransform computed from that intrinsic size. But + // if we still have that transform when we get OnDataAvailable + // calls, we'll invalidate the wrong area. So update the transform + // now. + RecalculateTransform(PR_FALSE); + + // Now we need to reflow if we have an unconstrained size and have + // already gotten the initial reflow + if (!(mState & IMAGE_SIZECONSTRAINED)) { + nsIPresShell *presShell = presContext->GetPresShell(); + NS_ASSERTION(presShell, "No PresShell."); + if (presShell) { + presShell->FrameNeedsReflow(this, nsIPresShell::eStyleChange, + NS_FRAME_IS_DIRTY); + } } } @@ -791,7 +805,7 @@ nsImageFrame::Reflow(nsPresContext* aPresContext, mComputedSize = nsSize(aReflowState.ComputedWidth(), aReflowState.ComputedHeight()); - RecalculateTransform(); + RecalculateTransform(PR_TRUE); aMetrics.width = mComputedSize.width; aMetrics.height = mComputedSize.height; diff --git a/layout/generic/nsImageFrame.h b/layout/generic/nsImageFrame.h index 5ca6df5ff736..6b5e66c1a4d4 100644 --- a/layout/generic/nsImageFrame.h +++ b/layout/generic/nsImageFrame.h @@ -253,7 +253,7 @@ private: /** * This function will recalculate mTransform. */ - void RecalculateTransform(); + void RecalculateTransform(PRBool aInnerAreaChanged); /** * Helper functions to check whether the request or image container