Bug 276431 Patch 3b: Make nsImageFrame compute its transform on-demand. r=roc a=blocking
This commit is contained in:
@@ -55,6 +55,7 @@
|
||||
#include "nsStyleContext.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsStyleCoord.h"
|
||||
#include "nsTransform2D.h"
|
||||
#include "nsImageMap.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsIURL.h"
|
||||
@@ -325,36 +326,33 @@ nsImageFrame::UpdateIntrinsicRatio(imgIContainer* aImage)
|
||||
return mIntrinsicRatio != oldIntrinsicRatio;
|
||||
}
|
||||
|
||||
void
|
||||
nsImageFrame::RecalculateTransform(PRBool aInnerAreaChanged)
|
||||
PRBool
|
||||
nsImageFrame::GetSourceToDestTransform(nsTransform2D& aTransform)
|
||||
{
|
||||
// In any case, we need to translate this over appropriately. Set
|
||||
// translation _before_ setting scaling so that it does not get
|
||||
// scaled!
|
||||
|
||||
// Set the translation components.
|
||||
// XXXbz does this introduce rounding errors because of the cast to
|
||||
// float? Should we just manually add that stuff in every time
|
||||
// instead?
|
||||
if (aInnerAreaChanged) {
|
||||
nsRect innerArea = GetInnerArea();
|
||||
mTransform.SetToTranslate(float(innerArea.x),
|
||||
float(innerArea.y - GetContinuationOffset()));
|
||||
}
|
||||
|
||||
// Set the scale factors
|
||||
nsRect innerArea = GetInnerArea();
|
||||
aTransform.SetToTranslate(float(innerArea.x),
|
||||
float(innerArea.y - GetContinuationOffset()));
|
||||
|
||||
// Set the scale factors.
|
||||
if (mIntrinsicSize.width.GetUnit() == eStyleUnit_Coord &&
|
||||
mIntrinsicSize.width.GetCoordValue() != 0 &&
|
||||
mIntrinsicSize.height.GetUnit() == eStyleUnit_Coord &&
|
||||
mIntrinsicSize.height.GetCoordValue() != 0 &&
|
||||
mIntrinsicSize.width.GetCoordValue() != mComputedSize.width &&
|
||||
mIntrinsicSize.height.GetCoordValue() != mComputedSize.height) {
|
||||
mTransform.SetScale(float(mComputedSize.width) /
|
||||
|
||||
aTransform.SetScale(float(mComputedSize.width) /
|
||||
float(mIntrinsicSize.width.GetCoordValue()),
|
||||
float(mComputedSize.height) /
|
||||
float(mIntrinsicSize.height.GetCoordValue()));
|
||||
} else {
|
||||
mTransform.SetScale(1.0f, 1.0f);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -418,10 +416,18 @@ nsImageFrame::SourceRectToDest(const nsIntRect& aRect)
|
||||
nsPresContext::CSSPixelsToAppUnits(aRect.width + 2),
|
||||
nsPresContext::CSSPixelsToAppUnits(aRect.height + 2));
|
||||
|
||||
mTransform.TransformCoord(&r.x, &r.y, &r.width, &r.height);
|
||||
nsTransform2D sourceToDest;
|
||||
if (!GetSourceToDestTransform(sourceToDest)) {
|
||||
// Failed to generate transform matrix. Return our whole inner area,
|
||||
// to be on the safe side (since this method is used for generating
|
||||
// invalidation rects).
|
||||
return GetInnerArea();
|
||||
}
|
||||
|
||||
sourceToDest.TransformCoord(&r.x, &r.y, &r.width, &r.height);
|
||||
|
||||
// Now, round the edges out to the pixel boundary.
|
||||
int scale = nsPresContext::CSSPixelsToAppUnits(1);
|
||||
nscoord scale = nsPresContext::CSSPixelsToAppUnits(1);
|
||||
nscoord right = r.x + r.width;
|
||||
nscoord bottom = r.y + r.height;
|
||||
|
||||
@@ -528,14 +534,6 @@ nsImageFrame::OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage)
|
||||
UpdateIntrinsicRatio(aImage);
|
||||
|
||||
if (mState & IMAGE_GOTINITIALREFLOW) {
|
||||
// If we previously set the intrinsic size (in EnsureIntrinsicSizeAndRatio)
|
||||
// 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)) {
|
||||
@@ -810,7 +808,6 @@ nsImageFrame::Reflow(nsPresContext* aPresContext,
|
||||
|
||||
mComputedSize =
|
||||
nsSize(aReflowState.ComputedWidth(), aReflowState.ComputedHeight());
|
||||
RecalculateTransform(PR_TRUE);
|
||||
|
||||
aMetrics.width = mComputedSize.width;
|
||||
aMetrics.height = mComputedSize.height;
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
#include "nsIIOService.h"
|
||||
#include "nsIObserver.h"
|
||||
|
||||
#include "nsTransform2D.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "nsStubImageDecoderObserver.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
@@ -62,8 +61,8 @@ struct nsHTMLReflowMetrics;
|
||||
struct nsSize;
|
||||
class nsDisplayImage;
|
||||
class nsPresContext;
|
||||
|
||||
class nsImageFrame;
|
||||
class nsTransform2D;
|
||||
|
||||
class nsImageListener : public nsStubImageDecoderObserver
|
||||
{
|
||||
@@ -257,9 +256,15 @@ private:
|
||||
PRBool UpdateIntrinsicRatio(imgIContainer* aImage);
|
||||
|
||||
/**
|
||||
* This function will recalculate mTransform.
|
||||
* This function calculates the transform for converting between
|
||||
* source space & destination space. May fail if our image has a
|
||||
* percent-valued or zero-valued height or width.
|
||||
*
|
||||
* @param aTransform The transform object to populate.
|
||||
*
|
||||
* @return whether we succeeded in creating the transform.
|
||||
*/
|
||||
void RecalculateTransform(PRBool aInnerAreaChanged);
|
||||
PRBool GetSourceToDestTransform(nsTransform2D& aTransform);
|
||||
|
||||
/**
|
||||
* Helper functions to check whether the request or image container
|
||||
@@ -283,7 +288,6 @@ private:
|
||||
nsIFrame::IntrinsicSize mIntrinsicSize;
|
||||
nsSize mIntrinsicRatio;
|
||||
|
||||
nsTransform2D mTransform;
|
||||
PRBool mDisplayingIcon;
|
||||
|
||||
static nsIIOService* sIOService;
|
||||
|
||||
Reference in New Issue
Block a user