Bug 189077, make nsImageFrame smaller by using frame state bits, r=paper@animecity.nu, sr=roc+moz@cs.cmu.edu.

This commit is contained in:
heikki%netscape.com 2003-02-24 22:20:26 +00:00
parent d71c529a47
commit 0741694152
4 changed files with 76 additions and 74 deletions

View File

@ -189,14 +189,11 @@ nsImageFrame::GetImageLoad(imgIRequest *aRequest)
} }
nsImageFrame::nsImageFrame() : nsImageFrame::nsImageFrame() :
mIntrinsicSize(0, 0), mIntrinsicSize(0, 0)
mGotInitialReflow(PR_FALSE),
mImageBlocked(PR_FALSE),
mFailureReplace(PR_TRUE)
{ {
// Size is constrained if we have a width and height. // Size is constrained if we have a width and height.
// - Set in reflow in case the attributes are changed // - Set in reflow in case the attributes are changed
mSizeConstrained = PR_FALSE; mState |= IMAGE_FAILUREREPLACE;
} }
nsImageFrame::~nsImageFrame() nsImageFrame::~nsImageFrame()
@ -324,8 +321,8 @@ nsImageFrame::Init(nsIPresContext* aPresContext,
NS_IF_RELEASE(tag); NS_IF_RELEASE(tag);
} }
mInitialLoadCompleted = PR_FALSE; mState &= ~IMAGE_INITIALLOADCOMPLETED;
mCanSendLoadEvent = PR_TRUE; mState |= IMAGE_CANSENDLOADEVENT;
LoadIcons(aPresContext); LoadIcons(aPresContext);
@ -347,7 +344,7 @@ NS_IMETHODIMP nsImageFrame::OnStartContainer(imgIRequest *aRequest, nsIPresConte
{ {
if (!aImage) return NS_ERROR_INVALID_ARG; if (!aImage) return NS_ERROR_INVALID_ARG;
mInitialLoadCompleted = PR_TRUE; mState |= IMAGE_INITIALLOADCOMPLETED;
// handle iconLoads first... // handle iconLoads first...
if (HandleIconLoads(aRequest, PR_FALSE)) { if (HandleIconLoads(aRequest, PR_FALSE)) {
@ -387,12 +384,12 @@ NS_IMETHODIMP nsImageFrame::OnStartContainer(imgIRequest *aRequest, nsIPresConte
load->mTransform.SetToScale((float(mComputedSize.width) / float(load->mIntrinsicSize.width)), load->mTransform.SetToScale((float(mComputedSize.width) / float(load->mIntrinsicSize.width)),
(float(mComputedSize.height) / float(load->mIntrinsicSize.height))); (float(mComputedSize.height) / float(load->mIntrinsicSize.height)));
if (!mSizeConstrained) { if (!(mState & IMAGE_SIZECONSTRAINED)) {
nsCOMPtr<nsIPresShell> presShell; nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell)); aPresContext->GetShell(getter_AddRefs(presShell));
NS_ASSERTION(mParent, "No parent to pass the reflow request up to."); NS_ASSERTION(mParent, "No parent to pass the reflow request up to.");
NS_ASSERTION(presShell, "No PresShell."); NS_ASSERTION(presShell, "No PresShell.");
if (mParent && presShell && mGotInitialReflow && whichLoad == 0) { // don't reflow if we havn't gotten the inital reflow yet if (mParent && presShell && (mState & IMAGE_GOTINITIALREFLOW) && whichLoad == 0) { // don't reflow if we havn't gotten the inital reflow yet
mState |= NS_FRAME_IS_DIRTY; mState |= NS_FRAME_IS_DIRTY;
mParent->ReflowDirtyChild(presShell, NS_STATIC_CAST(nsIFrame*, this)); mParent->ReflowDirtyChild(presShell, NS_STATIC_CAST(nsIFrame*, this));
} }
@ -636,12 +633,12 @@ NS_IMETHODIMP nsImageFrame::OnStopDecode(imgIRequest *aRequest, nsIPresContext *
imageFailedToLoad = PR_TRUE; imageFailedToLoad = PR_TRUE;
} }
if (!mSizeConstrained && (mLoads[0].mIntrinsicSize != mIntrinsicSize)) { if (!(mState & IMAGE_SIZECONSTRAINED) && (mLoads[0].mIntrinsicSize != mIntrinsicSize)) {
nsCOMPtr<nsIPresShell> presShell; nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell)); aPresContext->GetShell(getter_AddRefs(presShell));
NS_ASSERTION(mParent, "No parent to pass the reflow request up to."); NS_ASSERTION(mParent, "No parent to pass the reflow request up to.");
NS_ASSERTION(presShell, "No PresShell."); NS_ASSERTION(presShell, "No PresShell.");
if (mParent && presShell && mGotInitialReflow) { // don't reflow if we havn't gotten the inital reflow yet if (mParent && presShell && (mState & IMAGE_GOTINITIALREFLOW)) { // don't reflow if we havn't gotten the inital reflow yet
mState |= NS_FRAME_IS_DIRTY; mState |= NS_FRAME_IS_DIRTY;
mParent->ReflowDirtyChild(presShell, NS_STATIC_CAST(nsIFrame*, this)); mParent->ReflowDirtyChild(presShell, NS_STATIC_CAST(nsIFrame*, this));
} }
@ -665,7 +662,7 @@ NS_IMETHODIMP nsImageFrame::OnStopDecode(imgIRequest *aRequest, nsIPresContext *
// if src failed to load, determine how to handle it: // if src failed to load, determine how to handle it:
// - either render the ALT text in this frame, or let the presShell handle it // - either render the ALT text in this frame, or let the presShell handle it
if (imageFailedToLoad && presShell) { if (imageFailedToLoad && presShell) {
if (mFailureReplace) { if (mState & IMAGE_FAILUREREPLACE) {
// first check for image map // first check for image map
nsAutoString usemap; nsAutoString usemap;
mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::usemap, usemap); mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::usemap, usemap);
@ -702,7 +699,7 @@ NS_IMETHODIMP nsImageFrame::OnStopDecode(imgIRequest *aRequest, nsIPresContext *
(!prefForceInlineAltText && (!prefForceInlineAltText &&
HaveFixedSize(*stylePosition) && HaveFixedSize(*stylePosition) &&
mode == eCompatibility_NavQuirks && mode == eCompatibility_NavQuirks &&
!mImageBlocked); !(mState & IMAGE_BLOCKED));
if (!useSizedBox) { if (!useSizedBox) {
// let the presShell handle converting this into the inline alt text frame // let the presShell handle converting this into the inline alt text frame
@ -714,7 +711,7 @@ NS_IMETHODIMP nsImageFrame::OnStopDecode(imgIRequest *aRequest, nsIPresContext *
} }
} }
} }
mFailureReplace = PR_TRUE; mState |= IMAGE_FAILUREREPLACE;
} }
// After these DOM events are fired its possible that this frame may be deleted. As a result // After these DOM events are fired its possible that this frame may be deleted. As a result
@ -723,9 +720,9 @@ NS_IMETHODIMP nsImageFrame::OnStopDecode(imgIRequest *aRequest, nsIPresContext *
if (imageFailedToLoad) { if (imageFailedToLoad) {
// Send error event // Send error event
FireDOMEvent(NS_IMAGE_ERROR); FireDOMEvent(NS_IMAGE_ERROR);
} else if (mCanSendLoadEvent) { } else if (mState & IMAGE_CANSENDLOADEVENT) {
// Send load event // Send load event
mCanSendLoadEvent = PR_FALSE; mState &= ~IMAGE_CANSENDLOADEVENT;
FireDOMEvent(NS_IMAGE_LOAD); FireDOMEvent(NS_IMAGE_LOAD);
} }
@ -950,10 +947,14 @@ nsImageFrame::Reflow(nsIPresContext* aPresContext,
aStatus = NS_FRAME_COMPLETE; aStatus = NS_FRAME_COMPLETE;
// see if we have a frozen size (i.e. a fixed width and height) // see if we have a frozen size (i.e. a fixed width and height)
mSizeConstrained = HaveFixedSize(aReflowState); if (HaveFixedSize(aReflowState)) {
mState |= IMAGE_SIZECONSTRAINED;
} else {
mState &= ~IMAGE_SIZECONSTRAINED;
}
if (aReflowState.reason == eReflowReason_Initial) if (aReflowState.reason == eReflowReason_Initial)
mGotInitialReflow = PR_TRUE; mState |= IMAGE_GOTINITIALREFLOW;
// get the desired size of the complete image // get the desired size of the complete image
GetDesiredSize(aPresContext, aReflowState, aMetrics); GetDesiredSize(aPresContext, aReflowState, aMetrics);
@ -979,7 +980,7 @@ nsImageFrame::Reflow(nsIPresContext* aPresContext,
mLoads[0].mRequest->GetImageStatus(&loadStatus); mLoads[0].mRequest->GetImageStatus(&loadStatus);
} }
if (isPaginated && if (isPaginated &&
((loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE) || mSizeConstrained) && ((loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE) || (mState & IMAGE_SIZECONSTRAINED)) &&
(NS_UNCONSTRAINEDSIZE != aReflowState.availableHeight) && (NS_UNCONSTRAINEDSIZE != aReflowState.availableHeight) &&
(aMetrics.height > aReflowState.availableHeight)) { (aMetrics.height > aReflowState.availableHeight)) {
nsCOMPtr<nsIAtom> fType; nsCOMPtr<nsIAtom> fType;
@ -1318,10 +1319,10 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
#ifndef SUPPRESS_LOADING_ICON #ifndef SUPPRESS_LOADING_ICON
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer && if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer &&
(!mImageBlocked || mIconLoad->mPrefAllImagesBlocked)) { (!(mState & IMAGE_BLOCKED) || mIconLoad->mPrefAllImagesBlocked)) {
#else #else
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer && if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer &&
mInitialLoadCompleted) { (mState & IMAGE_INITIALLOADCOMPLETED)) {
#endif #endif
DisplayAltFeedback(aPresContext, aRenderingContext, DisplayAltFeedback(aPresContext, aRenderingContext,
(loadStatus & imgIRequest::STATUS_ERROR) (loadStatus & imgIRequest::STATUS_ERROR)
@ -1331,7 +1332,7 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
} }
else { else {
PRBool paintOutline = PR_FALSE; PRBool paintOutline = PR_FALSE;
mInitialLoadCompleted = PR_TRUE; mState |= IMAGE_INITIALLOADCOMPLETED;
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) { if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
// Now render the image into our content area (the area inside the // Now render the image into our content area (the area inside the
// borders and padding) // borders and padding)
@ -1799,13 +1800,13 @@ nsImageFrame::AttributeChanged(nsIPresContext* aPresContext,
mLoads[0].mRequest->GetImageStatus(&loadStatus); mLoads[0].mRequest->GetImageStatus(&loadStatus);
if (!(loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE)) { if (!(loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE)) {
mFailureReplace = PR_FALSE; // don't cause a CantRenderReplacedElement call mState &= ~IMAGE_FAILUREREPLACE; // don't cause a CantRenderReplacedElement call
mLoads[0].mRequest->Cancel(NS_ERROR_FAILURE); mLoads[0].mRequest->Cancel(NS_ERROR_FAILURE);
mLoads[0].mRequest = nsnull; mLoads[0].mRequest = nsnull;
} }
} }
mCanSendLoadEvent = PR_TRUE; mState |= IMAGE_CANSENDLOADEVENT;
if (mLoads[1].mRequest) { if (mLoads[1].mRequest) {
mLoads[1].mRequest->Cancel(NS_ERROR_FAILURE); mLoads[1].mRequest->Cancel(NS_ERROR_FAILURE);
@ -1950,7 +1951,7 @@ nsImageFrame::RealLoadImage(const nsAString& aSpec, nsIPresContext *aPresContext
nsresult rv = NS_OK; nsresult rv = NS_OK;
/* set this to TRUE here in case we return early */ /* set this to TRUE here in case we return early */
mInitialLoadCompleted = PR_TRUE; mState |= IMAGE_INITIALLOADCOMPLETED;
/* don't load the image if aSpec is empty */ /* don't load the image if aSpec is empty */
if (aSpec.IsEmpty()) return NS_ERROR_FAILURE; if (aSpec.IsEmpty()) return NS_ERROR_FAILURE;
@ -1994,7 +1995,7 @@ nsImageFrame::RealLoadImage(const nsAString& aSpec, nsIPresContext *aPresContext
} }
/* set this back to FALSE before we do the real load */ /* set this back to FALSE before we do the real load */
mInitialLoadCompleted = PR_FALSE; mState &= ~IMAGE_INITIALLOADCOMPLETED;
nsCOMPtr<nsIURI> baseURI; nsCOMPtr<nsIURI> baseURI;
rv = aPresContext->GetBaseURL(getter_AddRefs(baseURI)); rv = aPresContext->GetBaseURL(getter_AddRefs(baseURI));
@ -2142,7 +2143,7 @@ nsImageFrame::CanLoadImage(nsIURI *aURI)
aURI, element, domWin, &shouldLoad); aURI, element, domWin, &shouldLoad);
if (NS_SUCCEEDED(rv) && !shouldLoad) { if (NS_SUCCEEDED(rv) && !shouldLoad) {
// this image has been blocked, so flag it // this image has been blocked, so flag it
mImageBlocked = PR_TRUE; mState |= IMAGE_BLOCKED;
return shouldLoad; return shouldLoad;
} }
} }

View File

@ -83,6 +83,14 @@ struct ImageLoad {
nsTransform2D mTransform; nsTransform2D mTransform;
}; };
// Image Frame state
#define IMAGE_SIZECONSTRAINED 0x00100000
#define IMAGE_GOTINITIALREFLOW 0x00200000
#define IMAGE_INITIALLOADCOMPLETED 0x00400000
#define IMAGE_CANSENDLOADEVENT 0x00800000
#define IMAGE_BLOCKED 0x01000000
#define IMAGE_FAILUREREPLACE 0x02000000
#define ImageFrameSuper nsSplittableFrame #define ImageFrameSuper nsSplittableFrame
class nsImageFrame : public ImageFrameSuper, public nsIImageFrame { class nsImageFrame : public ImageFrameSuper, public nsIImageFrame {
@ -238,14 +246,6 @@ private:
nsSize mComputedSize; nsSize mComputedSize;
nsSize mIntrinsicSize; nsSize mIntrinsicSize;
PRPackedBool mSizeConstrained;
PRPackedBool mGotInitialReflow;
PRPackedBool mInitialLoadCompleted;
PRPackedBool mCanSendLoadEvent;
PRPackedBool mImageBlocked; // true if the image has been blocked
PRPackedBool mFailureReplace;
nsMargin mBorderPadding; nsMargin mBorderPadding;
PRUint32 mNaturalImageWidth, PRUint32 mNaturalImageWidth,
mNaturalImageHeight; mNaturalImageHeight;
@ -275,7 +275,7 @@ private:
PRPackedBool mPrefAllImagesBlocked; PRPackedBool mPrefAllImagesBlocked;
PRPackedBool mPrefShowPlaceholders; PRPackedBool mPrefShowPlaceholders;
}; };
static IconLoad* mIconLoad; // singleton patern: one LoadIcons instance is used static IconLoad* mIconLoad; // singleton pattern: one LoadIcons instance is used
}; };
#endif /* nsImageFrame_h___ */ #endif /* nsImageFrame_h___ */

View File

@ -189,14 +189,11 @@ nsImageFrame::GetImageLoad(imgIRequest *aRequest)
} }
nsImageFrame::nsImageFrame() : nsImageFrame::nsImageFrame() :
mIntrinsicSize(0, 0), mIntrinsicSize(0, 0)
mGotInitialReflow(PR_FALSE),
mImageBlocked(PR_FALSE),
mFailureReplace(PR_TRUE)
{ {
// Size is constrained if we have a width and height. // Size is constrained if we have a width and height.
// - Set in reflow in case the attributes are changed // - Set in reflow in case the attributes are changed
mSizeConstrained = PR_FALSE; mState |= IMAGE_FAILUREREPLACE;
} }
nsImageFrame::~nsImageFrame() nsImageFrame::~nsImageFrame()
@ -324,8 +321,8 @@ nsImageFrame::Init(nsIPresContext* aPresContext,
NS_IF_RELEASE(tag); NS_IF_RELEASE(tag);
} }
mInitialLoadCompleted = PR_FALSE; mState &= ~IMAGE_INITIALLOADCOMPLETED;
mCanSendLoadEvent = PR_TRUE; mState |= IMAGE_CANSENDLOADEVENT;
LoadIcons(aPresContext); LoadIcons(aPresContext);
@ -347,7 +344,7 @@ NS_IMETHODIMP nsImageFrame::OnStartContainer(imgIRequest *aRequest, nsIPresConte
{ {
if (!aImage) return NS_ERROR_INVALID_ARG; if (!aImage) return NS_ERROR_INVALID_ARG;
mInitialLoadCompleted = PR_TRUE; mState |= IMAGE_INITIALLOADCOMPLETED;
// handle iconLoads first... // handle iconLoads first...
if (HandleIconLoads(aRequest, PR_FALSE)) { if (HandleIconLoads(aRequest, PR_FALSE)) {
@ -387,12 +384,12 @@ NS_IMETHODIMP nsImageFrame::OnStartContainer(imgIRequest *aRequest, nsIPresConte
load->mTransform.SetToScale((float(mComputedSize.width) / float(load->mIntrinsicSize.width)), load->mTransform.SetToScale((float(mComputedSize.width) / float(load->mIntrinsicSize.width)),
(float(mComputedSize.height) / float(load->mIntrinsicSize.height))); (float(mComputedSize.height) / float(load->mIntrinsicSize.height)));
if (!mSizeConstrained) { if (!(mState & IMAGE_SIZECONSTRAINED)) {
nsCOMPtr<nsIPresShell> presShell; nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell)); aPresContext->GetShell(getter_AddRefs(presShell));
NS_ASSERTION(mParent, "No parent to pass the reflow request up to."); NS_ASSERTION(mParent, "No parent to pass the reflow request up to.");
NS_ASSERTION(presShell, "No PresShell."); NS_ASSERTION(presShell, "No PresShell.");
if (mParent && presShell && mGotInitialReflow && whichLoad == 0) { // don't reflow if we havn't gotten the inital reflow yet if (mParent && presShell && (mState & IMAGE_GOTINITIALREFLOW) && whichLoad == 0) { // don't reflow if we havn't gotten the inital reflow yet
mState |= NS_FRAME_IS_DIRTY; mState |= NS_FRAME_IS_DIRTY;
mParent->ReflowDirtyChild(presShell, NS_STATIC_CAST(nsIFrame*, this)); mParent->ReflowDirtyChild(presShell, NS_STATIC_CAST(nsIFrame*, this));
} }
@ -636,12 +633,12 @@ NS_IMETHODIMP nsImageFrame::OnStopDecode(imgIRequest *aRequest, nsIPresContext *
imageFailedToLoad = PR_TRUE; imageFailedToLoad = PR_TRUE;
} }
if (!mSizeConstrained && (mLoads[0].mIntrinsicSize != mIntrinsicSize)) { if (!(mState & IMAGE_SIZECONSTRAINED) && (mLoads[0].mIntrinsicSize != mIntrinsicSize)) {
nsCOMPtr<nsIPresShell> presShell; nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell)); aPresContext->GetShell(getter_AddRefs(presShell));
NS_ASSERTION(mParent, "No parent to pass the reflow request up to."); NS_ASSERTION(mParent, "No parent to pass the reflow request up to.");
NS_ASSERTION(presShell, "No PresShell."); NS_ASSERTION(presShell, "No PresShell.");
if (mParent && presShell && mGotInitialReflow) { // don't reflow if we havn't gotten the inital reflow yet if (mParent && presShell && (mState & IMAGE_GOTINITIALREFLOW)) { // don't reflow if we havn't gotten the inital reflow yet
mState |= NS_FRAME_IS_DIRTY; mState |= NS_FRAME_IS_DIRTY;
mParent->ReflowDirtyChild(presShell, NS_STATIC_CAST(nsIFrame*, this)); mParent->ReflowDirtyChild(presShell, NS_STATIC_CAST(nsIFrame*, this));
} }
@ -665,7 +662,7 @@ NS_IMETHODIMP nsImageFrame::OnStopDecode(imgIRequest *aRequest, nsIPresContext *
// if src failed to load, determine how to handle it: // if src failed to load, determine how to handle it:
// - either render the ALT text in this frame, or let the presShell handle it // - either render the ALT text in this frame, or let the presShell handle it
if (imageFailedToLoad && presShell) { if (imageFailedToLoad && presShell) {
if (mFailureReplace) { if (mState & IMAGE_FAILUREREPLACE) {
// first check for image map // first check for image map
nsAutoString usemap; nsAutoString usemap;
mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::usemap, usemap); mContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::usemap, usemap);
@ -702,7 +699,7 @@ NS_IMETHODIMP nsImageFrame::OnStopDecode(imgIRequest *aRequest, nsIPresContext *
(!prefForceInlineAltText && (!prefForceInlineAltText &&
HaveFixedSize(*stylePosition) && HaveFixedSize(*stylePosition) &&
mode == eCompatibility_NavQuirks && mode == eCompatibility_NavQuirks &&
!mImageBlocked); !(mState & IMAGE_BLOCKED));
if (!useSizedBox) { if (!useSizedBox) {
// let the presShell handle converting this into the inline alt text frame // let the presShell handle converting this into the inline alt text frame
@ -714,7 +711,7 @@ NS_IMETHODIMP nsImageFrame::OnStopDecode(imgIRequest *aRequest, nsIPresContext *
} }
} }
} }
mFailureReplace = PR_TRUE; mState |= IMAGE_FAILUREREPLACE;
} }
// After these DOM events are fired its possible that this frame may be deleted. As a result // After these DOM events are fired its possible that this frame may be deleted. As a result
@ -723,9 +720,9 @@ NS_IMETHODIMP nsImageFrame::OnStopDecode(imgIRequest *aRequest, nsIPresContext *
if (imageFailedToLoad) { if (imageFailedToLoad) {
// Send error event // Send error event
FireDOMEvent(NS_IMAGE_ERROR); FireDOMEvent(NS_IMAGE_ERROR);
} else if (mCanSendLoadEvent) { } else if (mState & IMAGE_CANSENDLOADEVENT) {
// Send load event // Send load event
mCanSendLoadEvent = PR_FALSE; mState &= ~IMAGE_CANSENDLOADEVENT;
FireDOMEvent(NS_IMAGE_LOAD); FireDOMEvent(NS_IMAGE_LOAD);
} }
@ -950,10 +947,14 @@ nsImageFrame::Reflow(nsIPresContext* aPresContext,
aStatus = NS_FRAME_COMPLETE; aStatus = NS_FRAME_COMPLETE;
// see if we have a frozen size (i.e. a fixed width and height) // see if we have a frozen size (i.e. a fixed width and height)
mSizeConstrained = HaveFixedSize(aReflowState); if (HaveFixedSize(aReflowState)) {
mState |= IMAGE_SIZECONSTRAINED;
} else {
mState &= ~IMAGE_SIZECONSTRAINED;
}
if (aReflowState.reason == eReflowReason_Initial) if (aReflowState.reason == eReflowReason_Initial)
mGotInitialReflow = PR_TRUE; mState |= IMAGE_GOTINITIALREFLOW;
// get the desired size of the complete image // get the desired size of the complete image
GetDesiredSize(aPresContext, aReflowState, aMetrics); GetDesiredSize(aPresContext, aReflowState, aMetrics);
@ -979,7 +980,7 @@ nsImageFrame::Reflow(nsIPresContext* aPresContext,
mLoads[0].mRequest->GetImageStatus(&loadStatus); mLoads[0].mRequest->GetImageStatus(&loadStatus);
} }
if (isPaginated && if (isPaginated &&
((loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE) || mSizeConstrained) && ((loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE) || (mState & IMAGE_SIZECONSTRAINED)) &&
(NS_UNCONSTRAINEDSIZE != aReflowState.availableHeight) && (NS_UNCONSTRAINEDSIZE != aReflowState.availableHeight) &&
(aMetrics.height > aReflowState.availableHeight)) { (aMetrics.height > aReflowState.availableHeight)) {
nsCOMPtr<nsIAtom> fType; nsCOMPtr<nsIAtom> fType;
@ -1318,10 +1319,10 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
#ifndef SUPPRESS_LOADING_ICON #ifndef SUPPRESS_LOADING_ICON
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer && if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer &&
(!mImageBlocked || mIconLoad->mPrefAllImagesBlocked)) { (!(mState & IMAGE_BLOCKED) || mIconLoad->mPrefAllImagesBlocked)) {
#else #else
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer && if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer &&
mInitialLoadCompleted) { (mState & IMAGE_INITIALLOADCOMPLETED)) {
#endif #endif
DisplayAltFeedback(aPresContext, aRenderingContext, DisplayAltFeedback(aPresContext, aRenderingContext,
(loadStatus & imgIRequest::STATUS_ERROR) (loadStatus & imgIRequest::STATUS_ERROR)
@ -1331,7 +1332,7 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
} }
else { else {
PRBool paintOutline = PR_FALSE; PRBool paintOutline = PR_FALSE;
mInitialLoadCompleted = PR_TRUE; mState |= IMAGE_INITIALLOADCOMPLETED;
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) { if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) {
// Now render the image into our content area (the area inside the // Now render the image into our content area (the area inside the
// borders and padding) // borders and padding)
@ -1799,13 +1800,13 @@ nsImageFrame::AttributeChanged(nsIPresContext* aPresContext,
mLoads[0].mRequest->GetImageStatus(&loadStatus); mLoads[0].mRequest->GetImageStatus(&loadStatus);
if (!(loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE)) { if (!(loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE)) {
mFailureReplace = PR_FALSE; // don't cause a CantRenderReplacedElement call mState &= ~IMAGE_FAILUREREPLACE; // don't cause a CantRenderReplacedElement call
mLoads[0].mRequest->Cancel(NS_ERROR_FAILURE); mLoads[0].mRequest->Cancel(NS_ERROR_FAILURE);
mLoads[0].mRequest = nsnull; mLoads[0].mRequest = nsnull;
} }
} }
mCanSendLoadEvent = PR_TRUE; mState |= IMAGE_CANSENDLOADEVENT;
if (mLoads[1].mRequest) { if (mLoads[1].mRequest) {
mLoads[1].mRequest->Cancel(NS_ERROR_FAILURE); mLoads[1].mRequest->Cancel(NS_ERROR_FAILURE);
@ -1950,7 +1951,7 @@ nsImageFrame::RealLoadImage(const nsAString& aSpec, nsIPresContext *aPresContext
nsresult rv = NS_OK; nsresult rv = NS_OK;
/* set this to TRUE here in case we return early */ /* set this to TRUE here in case we return early */
mInitialLoadCompleted = PR_TRUE; mState |= IMAGE_INITIALLOADCOMPLETED;
/* don't load the image if aSpec is empty */ /* don't load the image if aSpec is empty */
if (aSpec.IsEmpty()) return NS_ERROR_FAILURE; if (aSpec.IsEmpty()) return NS_ERROR_FAILURE;
@ -1994,7 +1995,7 @@ nsImageFrame::RealLoadImage(const nsAString& aSpec, nsIPresContext *aPresContext
} }
/* set this back to FALSE before we do the real load */ /* set this back to FALSE before we do the real load */
mInitialLoadCompleted = PR_FALSE; mState &= ~IMAGE_INITIALLOADCOMPLETED;
nsCOMPtr<nsIURI> baseURI; nsCOMPtr<nsIURI> baseURI;
rv = aPresContext->GetBaseURL(getter_AddRefs(baseURI)); rv = aPresContext->GetBaseURL(getter_AddRefs(baseURI));
@ -2142,7 +2143,7 @@ nsImageFrame::CanLoadImage(nsIURI *aURI)
aURI, element, domWin, &shouldLoad); aURI, element, domWin, &shouldLoad);
if (NS_SUCCEEDED(rv) && !shouldLoad) { if (NS_SUCCEEDED(rv) && !shouldLoad) {
// this image has been blocked, so flag it // this image has been blocked, so flag it
mImageBlocked = PR_TRUE; mState |= IMAGE_BLOCKED;
return shouldLoad; return shouldLoad;
} }
} }

View File

@ -83,6 +83,14 @@ struct ImageLoad {
nsTransform2D mTransform; nsTransform2D mTransform;
}; };
// Image Frame state
#define IMAGE_SIZECONSTRAINED 0x00100000
#define IMAGE_GOTINITIALREFLOW 0x00200000
#define IMAGE_INITIALLOADCOMPLETED 0x00400000
#define IMAGE_CANSENDLOADEVENT 0x00800000
#define IMAGE_BLOCKED 0x01000000
#define IMAGE_FAILUREREPLACE 0x02000000
#define ImageFrameSuper nsSplittableFrame #define ImageFrameSuper nsSplittableFrame
class nsImageFrame : public ImageFrameSuper, public nsIImageFrame { class nsImageFrame : public ImageFrameSuper, public nsIImageFrame {
@ -238,14 +246,6 @@ private:
nsSize mComputedSize; nsSize mComputedSize;
nsSize mIntrinsicSize; nsSize mIntrinsicSize;
PRPackedBool mSizeConstrained;
PRPackedBool mGotInitialReflow;
PRPackedBool mInitialLoadCompleted;
PRPackedBool mCanSendLoadEvent;
PRPackedBool mImageBlocked; // true if the image has been blocked
PRPackedBool mFailureReplace;
nsMargin mBorderPadding; nsMargin mBorderPadding;
PRUint32 mNaturalImageWidth, PRUint32 mNaturalImageWidth,
mNaturalImageHeight; mNaturalImageHeight;
@ -275,7 +275,7 @@ private:
PRPackedBool mPrefAllImagesBlocked; PRPackedBool mPrefAllImagesBlocked;
PRPackedBool mPrefShowPlaceholders; PRPackedBool mPrefShowPlaceholders;
}; };
static IconLoad* mIconLoad; // singleton patern: one LoadIcons instance is used static IconLoad* mIconLoad; // singleton pattern: one LoadIcons instance is used
}; };
#endif /* nsImageFrame_h___ */ #endif /* nsImageFrame_h___ */