зеркало из https://github.com/mozilla/pjs.git
fix for bug 92248 r=bryner sr=jst
This commit is contained in:
Родитель
f284bf6dda
Коммит
e15f4f6c5d
|
@ -941,7 +941,7 @@ nsHTMLImageElement::SetSrcInner(nsIURI* aBaseURL,
|
|||
doc->GetDocumentLoadGroup(getter_AddRefs(loadGroup));
|
||||
}
|
||||
|
||||
il->LoadImage(uri, loadGroup, this, sup, nsIRequest::LOAD_NORMAL, nsnull, getter_AddRefs(mRequest));
|
||||
il->LoadImage(uri, loadGroup, this, sup, nsIRequest::LOAD_NORMAL, nsnull, nsnull, getter_AddRefs(mRequest));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -535,7 +535,7 @@ nsXBLPrototypeBinding::LoadResources(PRBool* aResult)
|
|||
|
||||
// Now kick off the image load
|
||||
nsCOMPtr<imgIRequest> req;
|
||||
il->LoadImage(url, nsnull, nsnull, nsnull, nsIRequest::LOAD_BACKGROUND, nsnull, getter_AddRefs(req));
|
||||
il->LoadImage(url, nsnull, nsnull, nsnull, nsIRequest::LOAD_BACKGROUND, nsnull, nsnull, getter_AddRefs(req));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
|
|
@ -119,7 +119,7 @@ nsImageLoader::Load(const nsAReadableString &aURI)
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return il->LoadImage(uri, loadGroup, NS_STATIC_CAST(imgIDecoderObserver *, this),
|
||||
nsnull, nsIRequest::LOAD_BACKGROUND, nsnull, getter_AddRefs(mRequest));
|
||||
nsnull, nsIRequest::LOAD_BACKGROUND, nsnull, nsnull, getter_AddRefs(mRequest));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ nsImageLoader::Load(const nsAReadableString &aURI)
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return il->LoadImage(uri, loadGroup, NS_STATIC_CAST(imgIDecoderObserver *, this),
|
||||
nsnull, nsIRequest::LOAD_BACKGROUND, nsnull, getter_AddRefs(mRequest));
|
||||
nsnull, nsIRequest::LOAD_BACKGROUND, nsnull, nsnull, getter_AddRefs(mRequest));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -145,7 +145,7 @@ nsBulletFrame::Init(nsIPresContext* aPresContext,
|
|||
NS_RELEASE(listener);
|
||||
}
|
||||
|
||||
il->LoadImage(imgURI, loadGroup, mListener, aPresContext, nsIRequest::LOAD_NORMAL, nsnull, getter_AddRefs(mImageRequest));
|
||||
il->LoadImage(imgURI, loadGroup, mListener, aPresContext, nsIRequest::LOAD_NORMAL, nsnull, nsnull, getter_AddRefs(mImageRequest));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1383,7 +1383,7 @@ nsBulletFrame::Reflow(nsIPresContext* aPresContext,
|
|||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
GetLoadGroup(aPresContext, getter_AddRefs(loadGroup));
|
||||
|
||||
il->LoadImage(newURI, loadGroup, mListener, aPresContext, nsIRequest::LOAD_NORMAL, nsnull, getter_AddRefs(mImageRequest));
|
||||
il->LoadImage(newURI, loadGroup, mListener, aPresContext, nsIRequest::LOAD_NORMAL, nsnull, nsnull, getter_AddRefs(mImageRequest));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,6 +131,24 @@ NS_NewImageFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nsImageFrame::GetImageLoad(imgIRequest *aRequest)
|
||||
{
|
||||
if (aRequest == mLoads[0].mRequest)
|
||||
return 0;
|
||||
else if (aRequest == mLoads[1].mRequest)
|
||||
return 1;
|
||||
else if (aRequest == mLoads[2].mRequest)
|
||||
return 2;
|
||||
|
||||
NS_ASSERTION((aRequest == mLoads[0].mRequest &&
|
||||
aRequest == mLoads[1].mRequest &&
|
||||
aRequest == mLoads[2].mRequest), "Failure to figure out which imgIRequest this is!");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
nsImageFrame::nsImageFrame() :
|
||||
mIntrinsicSize(0, 0),
|
||||
mGotInitialReflow(PR_FALSE),
|
||||
|
@ -208,17 +226,17 @@ nsImageFrame::Destroy(nsIPresContext* aPresContext)
|
|||
NS_RELEASE(mImageMap);
|
||||
}
|
||||
|
||||
if (mImageRequest)
|
||||
mImageRequest->Cancel(NS_ERROR_FAILURE); // NS_BINDING_ABORT ?
|
||||
if (mLowImageRequest)
|
||||
mLowImageRequest->Cancel(NS_ERROR_FAILURE); // NS_BINDING_ABORT ?
|
||||
for (int i=0; i != 3; ++i) {
|
||||
if (mLoads[i].mRequest) {
|
||||
mLoads[i].mRequest->Cancel(NS_ERROR_FAILURE);
|
||||
mLoads[i].mRequest = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
// set the frame to null so we don't send messages to a dead object.
|
||||
if (mListener)
|
||||
NS_REINTERPRET_CAST(nsImageListener*, mListener.get())->SetFrame(nsnull);
|
||||
|
||||
mImageRequest = nsnull;
|
||||
mLowImageRequest = nsnull;
|
||||
mListener = nsnull;
|
||||
|
||||
return nsLeafFrame::Destroy(aPresContext);
|
||||
|
@ -258,15 +276,17 @@ nsImageFrame::Init(nsIPresContext* aPresContext,
|
|||
|
||||
// Set the image loader's source URL and base URL
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == lowSrcResult && !lowSrc.IsEmpty()) {
|
||||
LoadImage(lowSrc, aPresContext, getter_AddRefs(mLowImageRequest));
|
||||
mLoads[1].mRequest = do_CreateInstance("@mozilla.org/image/request;1");
|
||||
LoadImage(lowSrc, aPresContext, mLoads[1].mRequest);
|
||||
}
|
||||
|
||||
mInitialLoadCompleted = PR_FALSE;
|
||||
mCanSendLoadEvent = PR_TRUE;
|
||||
|
||||
rv = LoadImage(src, aPresContext, getter_AddRefs(mImageRequest)); // if the image was found in the cache,
|
||||
// it is possible that LoadImage will result in
|
||||
// a call to OnStartContainer()
|
||||
mLoads[0].mRequest = do_CreateInstance("@mozilla.org/image/request;1");
|
||||
rv = LoadImage(src, aPresContext, mLoads[0].mRequest); // if the image was found in the cache,
|
||||
// it is possible that LoadImage will result in
|
||||
// a call to OnStartContainer()
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -279,8 +299,14 @@ NS_IMETHODIMP nsImageFrame::OnStartDecode(imgIRequest *aRequest, nsIPresContext
|
|||
|
||||
NS_IMETHODIMP nsImageFrame::OnStartContainer(imgIRequest *aRequest, nsIPresContext *aPresContext, imgIContainer *aImage)
|
||||
{
|
||||
if (!aImage) return NS_ERROR_INVALID_ARG;
|
||||
|
||||
mInitialLoadCompleted = PR_TRUE;
|
||||
|
||||
int whichLoad = GetImageLoad(aRequest);
|
||||
if (whichLoad == -1) return NS_ERROR_FAILURE;
|
||||
struct ImageLoad *load= &mLoads[whichLoad];
|
||||
|
||||
if (aImage)
|
||||
{
|
||||
/* Get requested animation policy from the pres context:
|
||||
|
@ -295,11 +321,6 @@ NS_IMETHODIMP nsImageFrame::OnStartContainer(imgIRequest *aRequest, nsIPresConte
|
|||
}
|
||||
|
||||
nscoord w, h;
|
||||
#ifdef DEBUG_pavlov
|
||||
NS_ENSURE_ARG_POINTER(aImage);
|
||||
#else
|
||||
if (!aImage) return NS_ERROR_INVALID_ARG;
|
||||
#endif
|
||||
aImage->GetWidth(&w);
|
||||
aImage->GetHeight(&h);
|
||||
|
||||
|
@ -308,19 +329,19 @@ NS_IMETHODIMP nsImageFrame::OnStartContainer(imgIRequest *aRequest, nsIPresConte
|
|||
|
||||
nsSize newsize(NSIntPixelsToTwips(w, p2t), NSIntPixelsToTwips(h, p2t));
|
||||
|
||||
if (mIntrinsicSize != newsize) {
|
||||
mIntrinsicSize = newsize;
|
||||
if (load->mIntrinsicSize != newsize) {
|
||||
load->mIntrinsicSize = newsize;
|
||||
|
||||
if (mIntrinsicSize.width != 0 && mIntrinsicSize.height != 0)
|
||||
mTransform.SetToScale((float(mComputedSize.width) / float(mIntrinsicSize.width)),
|
||||
(float(mComputedSize.height) / float(mIntrinsicSize.height)));
|
||||
if (load->mIntrinsicSize.width != 0 && load->mIntrinsicSize.height != 0)
|
||||
load->mTransform.SetToScale((float(mComputedSize.width) / float(load->mIntrinsicSize.width)),
|
||||
(float(mComputedSize.height) / float(load->mIntrinsicSize.height)));
|
||||
|
||||
if (!mSizeConstrained) {
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
NS_ASSERTION(mParent, "No parent to pass the reflow request up to.");
|
||||
NS_ASSERTION(presShell, "No PresShell.");
|
||||
if (mParent && presShell && mGotInitialReflow) { // don't reflow if we havn't gotten the inital reflow yet
|
||||
if (mParent && presShell && mGotInitialReflow && whichLoad == 0) { // don't reflow if we havn't gotten the inital reflow yet
|
||||
mState |= NS_FRAME_IS_DIRTY;
|
||||
mParent->ReflowDirtyChild(presShell, NS_STATIC_CAST(nsIFrame*, this));
|
||||
}
|
||||
|
@ -343,6 +364,12 @@ NS_IMETHODIMP nsImageFrame::OnDataAvailable(imgIRequest *aRequest, nsIPresContex
|
|||
if (!aRect)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
int whichLoad = GetImageLoad(aRequest);
|
||||
if (whichLoad == -1) return NS_ERROR_FAILURE;
|
||||
if (whichLoad != 0) return NS_OK;
|
||||
struct ImageLoad *load= &mLoads[whichLoad];
|
||||
|
||||
|
||||
nsRect r(aRect->x, aRect->y, aRect->width, aRect->height);
|
||||
|
||||
float p2t;
|
||||
|
@ -352,12 +379,13 @@ NS_IMETHODIMP nsImageFrame::OnDataAvailable(imgIRequest *aRequest, nsIPresContex
|
|||
r.width = NSIntPixelsToTwips(r.width, p2t);
|
||||
r.height = NSIntPixelsToTwips(r.height, p2t);
|
||||
|
||||
mTransform.TransformCoord(&r.x, &r.y, &r.width, &r.height);
|
||||
load->mTransform.TransformCoord(&r.x, &r.y, &r.width, &r.height);
|
||||
|
||||
r.x += mBorderPadding.left;
|
||||
r.y += mBorderPadding.top;
|
||||
|
||||
Invalidate(aPresContext, r, PR_FALSE);
|
||||
if (whichLoad == 0)
|
||||
Invalidate(aPresContext, r, PR_FALSE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -519,18 +547,57 @@ NS_IMETHODIMP nsImageFrame::OnStopDecode(imgIRequest *aRequest, nsIPresContext *
|
|||
// check to see if an image error occurred
|
||||
PRBool imageFailedToLoad = PR_FALSE;
|
||||
|
||||
if (NS_FAILED(aStatus)) { // We failed to load the image. Notify the pres shell
|
||||
int whichLoad = GetImageLoad(aRequest);
|
||||
|
||||
if (whichLoad == -1) return NS_ERROR_FAILURE;
|
||||
|
||||
if (whichLoad == 2) {
|
||||
if (NS_SUCCEEDED(aStatus)) {
|
||||
if (mLoads[0].mRequest) {
|
||||
mLoads[0].mRequest->Cancel(NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
mLoads[0].mRequest = mLoads[2].mRequest;
|
||||
mLoads[0].mIntrinsicSize = mLoads[2].mIntrinsicSize;
|
||||
// XXX i don't think we always want to set this.
|
||||
mLoads[0].mTransform = mLoads[2].mTransform;
|
||||
struct ImageLoad *load= &mLoads[0];
|
||||
|
||||
mLoads[2].mRequest = nsnull;
|
||||
|
||||
if (!mSizeConstrained && (mLoads[0].mIntrinsicSize != mIntrinsicSize)) {
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
NS_ASSERTION(mParent, "No parent to pass the reflow request up to.");
|
||||
NS_ASSERTION(presShell, "No PresShell.");
|
||||
if (mParent && presShell && mGotInitialReflow) { // don't reflow if we havn't gotten the inital reflow yet
|
||||
mState |= NS_FRAME_IS_DIRTY;
|
||||
mParent->ReflowDirtyChild(presShell, NS_STATIC_CAST(nsIFrame*, this));
|
||||
}
|
||||
} else {
|
||||
nsSize s;
|
||||
GetSize(s);
|
||||
nsRect r(0,0, s.width, s.height);
|
||||
Invalidate(aPresContext, r, PR_FALSE);
|
||||
}
|
||||
|
||||
} else {
|
||||
mLoads[2].mRequest = nsnull;
|
||||
}
|
||||
|
||||
} else if (NS_FAILED(aStatus)) {
|
||||
PRBool lowFailed = PR_FALSE;
|
||||
PRBool imageFailed = PR_FALSE;
|
||||
|
||||
// One of the two images didn't load, which one?
|
||||
if (mLowImageRequest == aRequest || !mLowImageRequest) {
|
||||
lowFailed = PR_TRUE;
|
||||
}
|
||||
if (mImageRequest == aRequest || !mImageRequest) {
|
||||
if (whichLoad == 0 || !mLoads[0].mRequest) {
|
||||
imageFailed = PR_TRUE;
|
||||
}
|
||||
|
||||
if (whichLoad == 1 || !mLoads[1].mRequest) {
|
||||
lowFailed = PR_TRUE;
|
||||
}
|
||||
|
||||
if (imageFailed && lowFailed)
|
||||
imageFailedToLoad = PR_TRUE;
|
||||
}
|
||||
|
@ -568,19 +635,25 @@ NS_IMETHODIMP nsImageFrame::OnStopDecode(imgIRequest *aRequest, nsIPresContext *
|
|||
|
||||
NS_IMETHODIMP nsImageFrame::FrameChanged(imgIContainer *aContainer, nsIPresContext *aPresContext, gfxIImageFrame *aNewFrame, nsRect *aDirtyRect)
|
||||
{
|
||||
nsRect r(*aDirtyRect);
|
||||
if (!mLoads[0].mRequest)
|
||||
return NS_OK; // if mLoads[0].mRequest is null, this isn't for the first one, so we don't care about it.
|
||||
|
||||
float p2t;
|
||||
aPresContext->GetPixelsToTwips(&p2t);
|
||||
r.x = NSIntPixelsToTwips(r.x, p2t);
|
||||
r.y = NSIntPixelsToTwips(r.y, p2t);
|
||||
r.width = NSIntPixelsToTwips(r.width, p2t);
|
||||
r.height = NSIntPixelsToTwips(r.height, p2t);
|
||||
nsCOMPtr<imgIContainer> con;
|
||||
mLoads[0].mRequest->GetImage(getter_AddRefs(con));
|
||||
if (aContainer == con.get()) {
|
||||
nsRect r(*aDirtyRect);
|
||||
|
||||
mTransform.TransformCoord(&r.x, &r.y, &r.width, &r.height);
|
||||
float p2t;
|
||||
aPresContext->GetPixelsToTwips(&p2t);
|
||||
r.x = NSIntPixelsToTwips(r.x, p2t);
|
||||
r.y = NSIntPixelsToTwips(r.y, p2t);
|
||||
r.width = NSIntPixelsToTwips(r.width, p2t);
|
||||
r.height = NSIntPixelsToTwips(r.height, p2t);
|
||||
|
||||
Invalidate(aPresContext, r, PR_FALSE);
|
||||
mLoads[0].mTransform.TransformCoord(&r.x, &r.y, &r.width, &r.height);
|
||||
|
||||
Invalidate(aPresContext, r, PR_FALSE);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -597,7 +670,6 @@ nsImageFrame::GetDesiredSize(nsIPresContext* aPresContext,
|
|||
const nsHTMLReflowState& aReflowState,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
|
||||
nscoord widthConstraint = NS_INTRINSICSIZE;
|
||||
nscoord heightConstraint = NS_INTRINSICSIZE;
|
||||
PRBool fixedContentWidth = PR_FALSE;
|
||||
|
@ -621,6 +693,18 @@ nsImageFrame::GetDesiredSize(nsIPresContext* aPresContext,
|
|||
fixedContentHeight = PR_TRUE;
|
||||
}
|
||||
|
||||
// if mLoads[0].mIntrinsicSize.width and height are 0, then we should check to see
|
||||
// if the size is already known by the image container.
|
||||
if (mLoads[0].mIntrinsicSize.width == 0 && mLoads[0].mIntrinsicSize.height == 0) {
|
||||
nsCOMPtr<imgIContainer> con;
|
||||
mLoads[0].mRequest->GetImage(getter_AddRefs(con));
|
||||
if (con) {
|
||||
con->GetWidth(&mLoads[0].mIntrinsicSize.width);
|
||||
con->GetHeight(&mLoads[0].mIntrinsicSize.height);
|
||||
}
|
||||
}
|
||||
mIntrinsicSize = mLoads[0].mIntrinsicSize;
|
||||
|
||||
PRBool haveComputedSize = PR_FALSE;
|
||||
PRBool needIntrinsicImageSize = PR_FALSE;
|
||||
|
||||
|
@ -675,11 +759,13 @@ nsImageFrame::GetDesiredSize(nsIPresContext* aPresContext,
|
|||
mComputedSize.width = newWidth;
|
||||
mComputedSize.height = newHeight;
|
||||
|
||||
nsTransform2D *transform = &mLoads[0].mTransform;
|
||||
|
||||
if (mComputedSize == mIntrinsicSize) {
|
||||
mTransform.SetToIdentity();
|
||||
transform->SetToIdentity();
|
||||
} else {
|
||||
if (mIntrinsicSize.width != 0 && mIntrinsicSize.height != 0) {
|
||||
mTransform.SetToScale(float(mComputedSize.width) / float(mIntrinsicSize.width),
|
||||
transform->SetToScale(float(mComputedSize.width) / float(mIntrinsicSize.width),
|
||||
float(mComputedSize.height) / float(mIntrinsicSize.height));
|
||||
}
|
||||
}
|
||||
|
@ -977,17 +1063,16 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
|
|||
nsCOMPtr<imgIContainer> imgCon;
|
||||
nsCOMPtr<imgIContainer> lowImgCon;
|
||||
|
||||
if (mImageRequest) {
|
||||
mImageRequest->GetImage(getter_AddRefs(imgCon));
|
||||
PRUint32 loadStatus = imgIRequest::STATUS_ERROR;
|
||||
|
||||
if (mLoads[0].mRequest) {
|
||||
mLoads[0].mRequest->GetImage(getter_AddRefs(imgCon));
|
||||
mLoads[0].mRequest->GetImageStatus(&loadStatus);
|
||||
}
|
||||
if (mLowImageRequest) {
|
||||
mLowImageRequest->GetImage(getter_AddRefs(lowImgCon));
|
||||
if (mLoads[1].mRequest) {
|
||||
mLoads[1].mRequest->GetImage(getter_AddRefs(lowImgCon));
|
||||
}
|
||||
|
||||
PRUint32 loadStatus = imgIRequest::STATUS_ERROR;
|
||||
if (mImageRequest) {
|
||||
mImageRequest->GetImageStatus(&loadStatus);
|
||||
}
|
||||
if (loadStatus & imgIRequest::STATUS_ERROR || !(imgCon || lowImgCon)) {
|
||||
// No image yet, or image load failed. Draw the alt-text and an icon
|
||||
// indicating the status
|
||||
|
@ -1019,7 +1104,7 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
|
|||
|
||||
if (imgCon) {
|
||||
nsPoint p(inner.x, inner.y);
|
||||
if (mIntrinsicSize == mComputedSize) {
|
||||
if (mLoads[0].mIntrinsicSize == mComputedSize) {
|
||||
inner.IntersectRect(inner, aDirtyRect);
|
||||
nsRect r(inner.x, inner.y, inner.width, inner.height);
|
||||
r.x -= mBorderPadding.left;
|
||||
|
@ -1027,8 +1112,8 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
|
|||
aRenderingContext.DrawImage(imgCon, &r, &p);
|
||||
} else {
|
||||
nsTransform2D trans;
|
||||
trans.SetToScale((float(mIntrinsicSize.width) / float(inner.width)),
|
||||
(float(mIntrinsicSize.height) / float(inner.height)));
|
||||
trans.SetToScale((float(mLoads[0].mIntrinsicSize.width) / float(inner.width)),
|
||||
(float(mLoads[0].mIntrinsicSize.height) / float(inner.height)));
|
||||
|
||||
nsRect r(0, 0, inner.width, inner.height);
|
||||
|
||||
|
@ -1409,20 +1494,25 @@ nsImageFrame::AttributeChanged(nsIPresContext* aPresContext,
|
|||
|
||||
PRUint32 loadStatus = imgIRequest::STATUS_ERROR;
|
||||
|
||||
if (mImageRequest)
|
||||
mImageRequest->GetImageStatus(&loadStatus);
|
||||
if (mLoads[0].mRequest)
|
||||
mLoads[0].mRequest->GetImageStatus(&loadStatus);
|
||||
|
||||
if (!(loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE)) {
|
||||
if (mImageRequest) {
|
||||
if (mLoads[0].mRequest) {
|
||||
mFailureReplace = PR_FALSE; // don't cause a CantRenderReplacedElement call
|
||||
mImageRequest->Cancel(NS_ERROR_FAILURE);
|
||||
mImageRequest = nsnull;
|
||||
mLoads[0].mRequest->Cancel(NS_ERROR_FAILURE);
|
||||
mLoads[0].mRequest = nsnull;
|
||||
}
|
||||
|
||||
mCanSendLoadEvent = PR_TRUE;
|
||||
}
|
||||
|
||||
LoadImage(newSRC, aPresContext, getter_AddRefs(mImageRequest));
|
||||
if (mLoads[2].mRequest) {
|
||||
mLoads[2].mRequest->Cancel(NS_ERROR_FAILURE);
|
||||
mLoads[2].mRequest = nsnull;
|
||||
}
|
||||
mLoads[2].mRequest = do_CreateInstance("@mozilla.org/image/request;1");
|
||||
LoadImage(newSRC, aPresContext, mLoads[2].mRequest);
|
||||
}
|
||||
else if (nsHTMLAtoms::width == aAttribute || nsHTMLAtoms::height == aAttribute)
|
||||
{ // XXX: could check for new width == old width, and make that a no-op
|
||||
|
@ -1448,7 +1538,7 @@ nsImageFrame::GetFrameType(nsIAtom** aType) const
|
|||
NS_IMETHODIMP
|
||||
nsImageFrame::GetIntrinsicImageSize(nsSize& aSize)
|
||||
{
|
||||
aSize = mIntrinsicSize;
|
||||
aSize = mLoads[0].mIntrinsicSize;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1459,9 +1549,9 @@ nsImageFrame::GetNaturalImageSize(PRUint32 *naturalWidth,
|
|||
*naturalWidth = 0;
|
||||
*naturalHeight = 0;
|
||||
|
||||
if (mImageRequest) {
|
||||
if (mLoads[0].mRequest) {
|
||||
nsCOMPtr<imgIContainer> container;
|
||||
mImageRequest->GetImage(getter_AddRefs(container));
|
||||
mLoads[0].mRequest->GetImage(getter_AddRefs(container));
|
||||
if (container) {
|
||||
PRInt32 w, h;
|
||||
container->GetWidth(&w);
|
||||
|
@ -1478,7 +1568,7 @@ nsImageFrame::GetNaturalImageSize(PRUint32 *naturalWidth,
|
|||
NS_IMETHODIMP
|
||||
nsImageFrame::GetImageRequest(imgIRequest **aRequest)
|
||||
{
|
||||
*aRequest = mImageRequest;
|
||||
*aRequest = mLoads[0].mRequest;
|
||||
NS_IF_ADDREF(*aRequest);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1487,13 +1577,13 @@ NS_IMETHODIMP
|
|||
nsImageFrame::IsImageComplete(PRBool* aComplete)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aComplete);
|
||||
if (!mImageRequest) {
|
||||
if (!mLoads[0].mRequest) {
|
||||
*aComplete = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint32 status;
|
||||
mImageRequest->GetImageStatus(&status);
|
||||
mLoads[0].mRequest->GetImageStatus(&status);
|
||||
*aComplete = ((status & imgIRequest::STATUS_LOAD_COMPLETE) != 0);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1516,7 +1606,7 @@ void HaveFixedSize(const nsHTMLReflowState& aReflowState, PRPackedBool& aConstra
|
|||
|
||||
|
||||
nsresult
|
||||
nsImageFrame::LoadImage(const nsAReadableString& aSpec, nsIPresContext *aPresContext, imgIRequest **aRequest)
|
||||
nsImageFrame::LoadImage(const nsAReadableString& aSpec, nsIPresContext *aPresContext, imgIRequest *aRequest)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
@ -1561,7 +1651,8 @@ nsImageFrame::LoadImage(const nsAReadableString& aSpec, nsIPresContext *aPresCon
|
|||
/* set this back to FALSE before we do the real load */
|
||||
mInitialLoadCompleted = PR_FALSE;
|
||||
|
||||
return il->LoadImage(uri, loadGroup, mListener, aPresContext, loadFlags, nsnull, aRequest);
|
||||
nsCOMPtr<imgIRequest> tempRequest;
|
||||
return il->LoadImage(uri, loadGroup, mListener, aPresContext, loadFlags, nsnull, aRequest, getter_AddRefs(tempRequest));
|
||||
}
|
||||
|
||||
#define INTERNAL_GOPHER_LENGTH 16 /* "internal-gopher-" length */
|
||||
|
|
|
@ -74,6 +74,15 @@ private:
|
|||
nsImageFrame *mFrame;
|
||||
};
|
||||
|
||||
|
||||
struct ImageLoad {
|
||||
ImageLoad() : mIntrinsicSize(0,0) { }
|
||||
nsCOMPtr<imgIRequest> mRequest;
|
||||
nsSize mIntrinsicSize;
|
||||
|
||||
nsTransform2D mTransform;
|
||||
};
|
||||
|
||||
#define ImageFrameSuper nsLeafFrame
|
||||
|
||||
class nsImageFrame : public ImageFrameSuper, public nsIImageFrame {
|
||||
|
@ -192,7 +201,7 @@ protected:
|
|||
nsRect& aInnerArea) const;
|
||||
|
||||
|
||||
nsresult LoadImage(const nsAReadableString& aSpec, nsIPresContext *aPresContext, imgIRequest **aRequest);
|
||||
nsresult LoadImage(const nsAReadableString& aSpec, nsIPresContext *aPresContext, imgIRequest *aRequest);
|
||||
|
||||
inline PRBool CanLoadImage(nsIURI *aURI);
|
||||
|
||||
|
@ -204,18 +213,26 @@ protected:
|
|||
|
||||
void FireDOMEvent(PRUint32 aMessage);
|
||||
|
||||
nsImageMap* mImageMap;
|
||||
|
||||
nsCOMPtr<imgIRequest> mImageRequest;
|
||||
nsCOMPtr<imgIRequest> mLowImageRequest;
|
||||
private:
|
||||
inline int GetImageLoad(imgIRequest *aRequest);
|
||||
|
||||
|
||||
nsImageMap* mImageMap;
|
||||
|
||||
nsCOMPtr<imgIDecoderObserver> mListener;
|
||||
|
||||
/**
|
||||
* 0 is the current image being displayed on the screen.
|
||||
* 1 is for the lowsrc image if any.
|
||||
* 2 is for attribute changed images.
|
||||
* when the load from 2 completes, it will replace 0.
|
||||
*/
|
||||
struct ImageLoad mLoads[3];
|
||||
|
||||
nsSize mComputedSize;
|
||||
nsSize mIntrinsicSize;
|
||||
|
||||
nsTransform2D mTransform;
|
||||
|
||||
PRPackedBool mSizeConstrained;
|
||||
PRPackedBool mGotInitialReflow;
|
||||
PRPackedBool mInitialLoadCompleted;
|
||||
|
|
|
@ -145,7 +145,7 @@ nsBulletFrame::Init(nsIPresContext* aPresContext,
|
|||
NS_RELEASE(listener);
|
||||
}
|
||||
|
||||
il->LoadImage(imgURI, loadGroup, mListener, aPresContext, nsIRequest::LOAD_NORMAL, nsnull, getter_AddRefs(mImageRequest));
|
||||
il->LoadImage(imgURI, loadGroup, mListener, aPresContext, nsIRequest::LOAD_NORMAL, nsnull, nsnull, getter_AddRefs(mImageRequest));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1383,7 +1383,7 @@ nsBulletFrame::Reflow(nsIPresContext* aPresContext,
|
|||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
GetLoadGroup(aPresContext, getter_AddRefs(loadGroup));
|
||||
|
||||
il->LoadImage(newURI, loadGroup, mListener, aPresContext, nsIRequest::LOAD_NORMAL, nsnull, getter_AddRefs(mImageRequest));
|
||||
il->LoadImage(newURI, loadGroup, mListener, aPresContext, nsIRequest::LOAD_NORMAL, nsnull, nsnull, getter_AddRefs(mImageRequest));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,6 +131,24 @@ NS_NewImageFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nsImageFrame::GetImageLoad(imgIRequest *aRequest)
|
||||
{
|
||||
if (aRequest == mLoads[0].mRequest)
|
||||
return 0;
|
||||
else if (aRequest == mLoads[1].mRequest)
|
||||
return 1;
|
||||
else if (aRequest == mLoads[2].mRequest)
|
||||
return 2;
|
||||
|
||||
NS_ASSERTION((aRequest == mLoads[0].mRequest &&
|
||||
aRequest == mLoads[1].mRequest &&
|
||||
aRequest == mLoads[2].mRequest), "Failure to figure out which imgIRequest this is!");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
nsImageFrame::nsImageFrame() :
|
||||
mIntrinsicSize(0, 0),
|
||||
mGotInitialReflow(PR_FALSE),
|
||||
|
@ -208,17 +226,17 @@ nsImageFrame::Destroy(nsIPresContext* aPresContext)
|
|||
NS_RELEASE(mImageMap);
|
||||
}
|
||||
|
||||
if (mImageRequest)
|
||||
mImageRequest->Cancel(NS_ERROR_FAILURE); // NS_BINDING_ABORT ?
|
||||
if (mLowImageRequest)
|
||||
mLowImageRequest->Cancel(NS_ERROR_FAILURE); // NS_BINDING_ABORT ?
|
||||
for (int i=0; i != 3; ++i) {
|
||||
if (mLoads[i].mRequest) {
|
||||
mLoads[i].mRequest->Cancel(NS_ERROR_FAILURE);
|
||||
mLoads[i].mRequest = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
// set the frame to null so we don't send messages to a dead object.
|
||||
if (mListener)
|
||||
NS_REINTERPRET_CAST(nsImageListener*, mListener.get())->SetFrame(nsnull);
|
||||
|
||||
mImageRequest = nsnull;
|
||||
mLowImageRequest = nsnull;
|
||||
mListener = nsnull;
|
||||
|
||||
return nsLeafFrame::Destroy(aPresContext);
|
||||
|
@ -258,15 +276,17 @@ nsImageFrame::Init(nsIPresContext* aPresContext,
|
|||
|
||||
// Set the image loader's source URL and base URL
|
||||
if (NS_CONTENT_ATTR_HAS_VALUE == lowSrcResult && !lowSrc.IsEmpty()) {
|
||||
LoadImage(lowSrc, aPresContext, getter_AddRefs(mLowImageRequest));
|
||||
mLoads[1].mRequest = do_CreateInstance("@mozilla.org/image/request;1");
|
||||
LoadImage(lowSrc, aPresContext, mLoads[1].mRequest);
|
||||
}
|
||||
|
||||
mInitialLoadCompleted = PR_FALSE;
|
||||
mCanSendLoadEvent = PR_TRUE;
|
||||
|
||||
rv = LoadImage(src, aPresContext, getter_AddRefs(mImageRequest)); // if the image was found in the cache,
|
||||
// it is possible that LoadImage will result in
|
||||
// a call to OnStartContainer()
|
||||
mLoads[0].mRequest = do_CreateInstance("@mozilla.org/image/request;1");
|
||||
rv = LoadImage(src, aPresContext, mLoads[0].mRequest); // if the image was found in the cache,
|
||||
// it is possible that LoadImage will result in
|
||||
// a call to OnStartContainer()
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -279,8 +299,14 @@ NS_IMETHODIMP nsImageFrame::OnStartDecode(imgIRequest *aRequest, nsIPresContext
|
|||
|
||||
NS_IMETHODIMP nsImageFrame::OnStartContainer(imgIRequest *aRequest, nsIPresContext *aPresContext, imgIContainer *aImage)
|
||||
{
|
||||
if (!aImage) return NS_ERROR_INVALID_ARG;
|
||||
|
||||
mInitialLoadCompleted = PR_TRUE;
|
||||
|
||||
int whichLoad = GetImageLoad(aRequest);
|
||||
if (whichLoad == -1) return NS_ERROR_FAILURE;
|
||||
struct ImageLoad *load= &mLoads[whichLoad];
|
||||
|
||||
if (aImage)
|
||||
{
|
||||
/* Get requested animation policy from the pres context:
|
||||
|
@ -295,11 +321,6 @@ NS_IMETHODIMP nsImageFrame::OnStartContainer(imgIRequest *aRequest, nsIPresConte
|
|||
}
|
||||
|
||||
nscoord w, h;
|
||||
#ifdef DEBUG_pavlov
|
||||
NS_ENSURE_ARG_POINTER(aImage);
|
||||
#else
|
||||
if (!aImage) return NS_ERROR_INVALID_ARG;
|
||||
#endif
|
||||
aImage->GetWidth(&w);
|
||||
aImage->GetHeight(&h);
|
||||
|
||||
|
@ -308,19 +329,19 @@ NS_IMETHODIMP nsImageFrame::OnStartContainer(imgIRequest *aRequest, nsIPresConte
|
|||
|
||||
nsSize newsize(NSIntPixelsToTwips(w, p2t), NSIntPixelsToTwips(h, p2t));
|
||||
|
||||
if (mIntrinsicSize != newsize) {
|
||||
mIntrinsicSize = newsize;
|
||||
if (load->mIntrinsicSize != newsize) {
|
||||
load->mIntrinsicSize = newsize;
|
||||
|
||||
if (mIntrinsicSize.width != 0 && mIntrinsicSize.height != 0)
|
||||
mTransform.SetToScale((float(mComputedSize.width) / float(mIntrinsicSize.width)),
|
||||
(float(mComputedSize.height) / float(mIntrinsicSize.height)));
|
||||
if (load->mIntrinsicSize.width != 0 && load->mIntrinsicSize.height != 0)
|
||||
load->mTransform.SetToScale((float(mComputedSize.width) / float(load->mIntrinsicSize.width)),
|
||||
(float(mComputedSize.height) / float(load->mIntrinsicSize.height)));
|
||||
|
||||
if (!mSizeConstrained) {
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
NS_ASSERTION(mParent, "No parent to pass the reflow request up to.");
|
||||
NS_ASSERTION(presShell, "No PresShell.");
|
||||
if (mParent && presShell && mGotInitialReflow) { // don't reflow if we havn't gotten the inital reflow yet
|
||||
if (mParent && presShell && mGotInitialReflow && whichLoad == 0) { // don't reflow if we havn't gotten the inital reflow yet
|
||||
mState |= NS_FRAME_IS_DIRTY;
|
||||
mParent->ReflowDirtyChild(presShell, NS_STATIC_CAST(nsIFrame*, this));
|
||||
}
|
||||
|
@ -343,6 +364,12 @@ NS_IMETHODIMP nsImageFrame::OnDataAvailable(imgIRequest *aRequest, nsIPresContex
|
|||
if (!aRect)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
int whichLoad = GetImageLoad(aRequest);
|
||||
if (whichLoad == -1) return NS_ERROR_FAILURE;
|
||||
if (whichLoad != 0) return NS_OK;
|
||||
struct ImageLoad *load= &mLoads[whichLoad];
|
||||
|
||||
|
||||
nsRect r(aRect->x, aRect->y, aRect->width, aRect->height);
|
||||
|
||||
float p2t;
|
||||
|
@ -352,12 +379,13 @@ NS_IMETHODIMP nsImageFrame::OnDataAvailable(imgIRequest *aRequest, nsIPresContex
|
|||
r.width = NSIntPixelsToTwips(r.width, p2t);
|
||||
r.height = NSIntPixelsToTwips(r.height, p2t);
|
||||
|
||||
mTransform.TransformCoord(&r.x, &r.y, &r.width, &r.height);
|
||||
load->mTransform.TransformCoord(&r.x, &r.y, &r.width, &r.height);
|
||||
|
||||
r.x += mBorderPadding.left;
|
||||
r.y += mBorderPadding.top;
|
||||
|
||||
Invalidate(aPresContext, r, PR_FALSE);
|
||||
if (whichLoad == 0)
|
||||
Invalidate(aPresContext, r, PR_FALSE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -519,18 +547,57 @@ NS_IMETHODIMP nsImageFrame::OnStopDecode(imgIRequest *aRequest, nsIPresContext *
|
|||
// check to see if an image error occurred
|
||||
PRBool imageFailedToLoad = PR_FALSE;
|
||||
|
||||
if (NS_FAILED(aStatus)) { // We failed to load the image. Notify the pres shell
|
||||
int whichLoad = GetImageLoad(aRequest);
|
||||
|
||||
if (whichLoad == -1) return NS_ERROR_FAILURE;
|
||||
|
||||
if (whichLoad == 2) {
|
||||
if (NS_SUCCEEDED(aStatus)) {
|
||||
if (mLoads[0].mRequest) {
|
||||
mLoads[0].mRequest->Cancel(NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
mLoads[0].mRequest = mLoads[2].mRequest;
|
||||
mLoads[0].mIntrinsicSize = mLoads[2].mIntrinsicSize;
|
||||
// XXX i don't think we always want to set this.
|
||||
mLoads[0].mTransform = mLoads[2].mTransform;
|
||||
struct ImageLoad *load= &mLoads[0];
|
||||
|
||||
mLoads[2].mRequest = nsnull;
|
||||
|
||||
if (!mSizeConstrained && (mLoads[0].mIntrinsicSize != mIntrinsicSize)) {
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
aPresContext->GetShell(getter_AddRefs(presShell));
|
||||
NS_ASSERTION(mParent, "No parent to pass the reflow request up to.");
|
||||
NS_ASSERTION(presShell, "No PresShell.");
|
||||
if (mParent && presShell && mGotInitialReflow) { // don't reflow if we havn't gotten the inital reflow yet
|
||||
mState |= NS_FRAME_IS_DIRTY;
|
||||
mParent->ReflowDirtyChild(presShell, NS_STATIC_CAST(nsIFrame*, this));
|
||||
}
|
||||
} else {
|
||||
nsSize s;
|
||||
GetSize(s);
|
||||
nsRect r(0,0, s.width, s.height);
|
||||
Invalidate(aPresContext, r, PR_FALSE);
|
||||
}
|
||||
|
||||
} else {
|
||||
mLoads[2].mRequest = nsnull;
|
||||
}
|
||||
|
||||
} else if (NS_FAILED(aStatus)) {
|
||||
PRBool lowFailed = PR_FALSE;
|
||||
PRBool imageFailed = PR_FALSE;
|
||||
|
||||
// One of the two images didn't load, which one?
|
||||
if (mLowImageRequest == aRequest || !mLowImageRequest) {
|
||||
lowFailed = PR_TRUE;
|
||||
}
|
||||
if (mImageRequest == aRequest || !mImageRequest) {
|
||||
if (whichLoad == 0 || !mLoads[0].mRequest) {
|
||||
imageFailed = PR_TRUE;
|
||||
}
|
||||
|
||||
if (whichLoad == 1 || !mLoads[1].mRequest) {
|
||||
lowFailed = PR_TRUE;
|
||||
}
|
||||
|
||||
if (imageFailed && lowFailed)
|
||||
imageFailedToLoad = PR_TRUE;
|
||||
}
|
||||
|
@ -568,19 +635,25 @@ NS_IMETHODIMP nsImageFrame::OnStopDecode(imgIRequest *aRequest, nsIPresContext *
|
|||
|
||||
NS_IMETHODIMP nsImageFrame::FrameChanged(imgIContainer *aContainer, nsIPresContext *aPresContext, gfxIImageFrame *aNewFrame, nsRect *aDirtyRect)
|
||||
{
|
||||
nsRect r(*aDirtyRect);
|
||||
if (!mLoads[0].mRequest)
|
||||
return NS_OK; // if mLoads[0].mRequest is null, this isn't for the first one, so we don't care about it.
|
||||
|
||||
float p2t;
|
||||
aPresContext->GetPixelsToTwips(&p2t);
|
||||
r.x = NSIntPixelsToTwips(r.x, p2t);
|
||||
r.y = NSIntPixelsToTwips(r.y, p2t);
|
||||
r.width = NSIntPixelsToTwips(r.width, p2t);
|
||||
r.height = NSIntPixelsToTwips(r.height, p2t);
|
||||
nsCOMPtr<imgIContainer> con;
|
||||
mLoads[0].mRequest->GetImage(getter_AddRefs(con));
|
||||
if (aContainer == con.get()) {
|
||||
nsRect r(*aDirtyRect);
|
||||
|
||||
mTransform.TransformCoord(&r.x, &r.y, &r.width, &r.height);
|
||||
float p2t;
|
||||
aPresContext->GetPixelsToTwips(&p2t);
|
||||
r.x = NSIntPixelsToTwips(r.x, p2t);
|
||||
r.y = NSIntPixelsToTwips(r.y, p2t);
|
||||
r.width = NSIntPixelsToTwips(r.width, p2t);
|
||||
r.height = NSIntPixelsToTwips(r.height, p2t);
|
||||
|
||||
Invalidate(aPresContext, r, PR_FALSE);
|
||||
mLoads[0].mTransform.TransformCoord(&r.x, &r.y, &r.width, &r.height);
|
||||
|
||||
Invalidate(aPresContext, r, PR_FALSE);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -597,7 +670,6 @@ nsImageFrame::GetDesiredSize(nsIPresContext* aPresContext,
|
|||
const nsHTMLReflowState& aReflowState,
|
||||
nsHTMLReflowMetrics& aDesiredSize)
|
||||
{
|
||||
|
||||
nscoord widthConstraint = NS_INTRINSICSIZE;
|
||||
nscoord heightConstraint = NS_INTRINSICSIZE;
|
||||
PRBool fixedContentWidth = PR_FALSE;
|
||||
|
@ -621,6 +693,18 @@ nsImageFrame::GetDesiredSize(nsIPresContext* aPresContext,
|
|||
fixedContentHeight = PR_TRUE;
|
||||
}
|
||||
|
||||
// if mLoads[0].mIntrinsicSize.width and height are 0, then we should check to see
|
||||
// if the size is already known by the image container.
|
||||
if (mLoads[0].mIntrinsicSize.width == 0 && mLoads[0].mIntrinsicSize.height == 0) {
|
||||
nsCOMPtr<imgIContainer> con;
|
||||
mLoads[0].mRequest->GetImage(getter_AddRefs(con));
|
||||
if (con) {
|
||||
con->GetWidth(&mLoads[0].mIntrinsicSize.width);
|
||||
con->GetHeight(&mLoads[0].mIntrinsicSize.height);
|
||||
}
|
||||
}
|
||||
mIntrinsicSize = mLoads[0].mIntrinsicSize;
|
||||
|
||||
PRBool haveComputedSize = PR_FALSE;
|
||||
PRBool needIntrinsicImageSize = PR_FALSE;
|
||||
|
||||
|
@ -675,11 +759,13 @@ nsImageFrame::GetDesiredSize(nsIPresContext* aPresContext,
|
|||
mComputedSize.width = newWidth;
|
||||
mComputedSize.height = newHeight;
|
||||
|
||||
nsTransform2D *transform = &mLoads[0].mTransform;
|
||||
|
||||
if (mComputedSize == mIntrinsicSize) {
|
||||
mTransform.SetToIdentity();
|
||||
transform->SetToIdentity();
|
||||
} else {
|
||||
if (mIntrinsicSize.width != 0 && mIntrinsicSize.height != 0) {
|
||||
mTransform.SetToScale(float(mComputedSize.width) / float(mIntrinsicSize.width),
|
||||
transform->SetToScale(float(mComputedSize.width) / float(mIntrinsicSize.width),
|
||||
float(mComputedSize.height) / float(mIntrinsicSize.height));
|
||||
}
|
||||
}
|
||||
|
@ -977,17 +1063,16 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
|
|||
nsCOMPtr<imgIContainer> imgCon;
|
||||
nsCOMPtr<imgIContainer> lowImgCon;
|
||||
|
||||
if (mImageRequest) {
|
||||
mImageRequest->GetImage(getter_AddRefs(imgCon));
|
||||
PRUint32 loadStatus = imgIRequest::STATUS_ERROR;
|
||||
|
||||
if (mLoads[0].mRequest) {
|
||||
mLoads[0].mRequest->GetImage(getter_AddRefs(imgCon));
|
||||
mLoads[0].mRequest->GetImageStatus(&loadStatus);
|
||||
}
|
||||
if (mLowImageRequest) {
|
||||
mLowImageRequest->GetImage(getter_AddRefs(lowImgCon));
|
||||
if (mLoads[1].mRequest) {
|
||||
mLoads[1].mRequest->GetImage(getter_AddRefs(lowImgCon));
|
||||
}
|
||||
|
||||
PRUint32 loadStatus = imgIRequest::STATUS_ERROR;
|
||||
if (mImageRequest) {
|
||||
mImageRequest->GetImageStatus(&loadStatus);
|
||||
}
|
||||
if (loadStatus & imgIRequest::STATUS_ERROR || !(imgCon || lowImgCon)) {
|
||||
// No image yet, or image load failed. Draw the alt-text and an icon
|
||||
// indicating the status
|
||||
|
@ -1019,7 +1104,7 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
|
|||
|
||||
if (imgCon) {
|
||||
nsPoint p(inner.x, inner.y);
|
||||
if (mIntrinsicSize == mComputedSize) {
|
||||
if (mLoads[0].mIntrinsicSize == mComputedSize) {
|
||||
inner.IntersectRect(inner, aDirtyRect);
|
||||
nsRect r(inner.x, inner.y, inner.width, inner.height);
|
||||
r.x -= mBorderPadding.left;
|
||||
|
@ -1027,8 +1112,8 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
|
|||
aRenderingContext.DrawImage(imgCon, &r, &p);
|
||||
} else {
|
||||
nsTransform2D trans;
|
||||
trans.SetToScale((float(mIntrinsicSize.width) / float(inner.width)),
|
||||
(float(mIntrinsicSize.height) / float(inner.height)));
|
||||
trans.SetToScale((float(mLoads[0].mIntrinsicSize.width) / float(inner.width)),
|
||||
(float(mLoads[0].mIntrinsicSize.height) / float(inner.height)));
|
||||
|
||||
nsRect r(0, 0, inner.width, inner.height);
|
||||
|
||||
|
@ -1409,20 +1494,25 @@ nsImageFrame::AttributeChanged(nsIPresContext* aPresContext,
|
|||
|
||||
PRUint32 loadStatus = imgIRequest::STATUS_ERROR;
|
||||
|
||||
if (mImageRequest)
|
||||
mImageRequest->GetImageStatus(&loadStatus);
|
||||
if (mLoads[0].mRequest)
|
||||
mLoads[0].mRequest->GetImageStatus(&loadStatus);
|
||||
|
||||
if (!(loadStatus & imgIRequest::STATUS_SIZE_AVAILABLE)) {
|
||||
if (mImageRequest) {
|
||||
if (mLoads[0].mRequest) {
|
||||
mFailureReplace = PR_FALSE; // don't cause a CantRenderReplacedElement call
|
||||
mImageRequest->Cancel(NS_ERROR_FAILURE);
|
||||
mImageRequest = nsnull;
|
||||
mLoads[0].mRequest->Cancel(NS_ERROR_FAILURE);
|
||||
mLoads[0].mRequest = nsnull;
|
||||
}
|
||||
|
||||
mCanSendLoadEvent = PR_TRUE;
|
||||
}
|
||||
|
||||
LoadImage(newSRC, aPresContext, getter_AddRefs(mImageRequest));
|
||||
if (mLoads[2].mRequest) {
|
||||
mLoads[2].mRequest->Cancel(NS_ERROR_FAILURE);
|
||||
mLoads[2].mRequest = nsnull;
|
||||
}
|
||||
mLoads[2].mRequest = do_CreateInstance("@mozilla.org/image/request;1");
|
||||
LoadImage(newSRC, aPresContext, mLoads[2].mRequest);
|
||||
}
|
||||
else if (nsHTMLAtoms::width == aAttribute || nsHTMLAtoms::height == aAttribute)
|
||||
{ // XXX: could check for new width == old width, and make that a no-op
|
||||
|
@ -1448,7 +1538,7 @@ nsImageFrame::GetFrameType(nsIAtom** aType) const
|
|||
NS_IMETHODIMP
|
||||
nsImageFrame::GetIntrinsicImageSize(nsSize& aSize)
|
||||
{
|
||||
aSize = mIntrinsicSize;
|
||||
aSize = mLoads[0].mIntrinsicSize;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1459,9 +1549,9 @@ nsImageFrame::GetNaturalImageSize(PRUint32 *naturalWidth,
|
|||
*naturalWidth = 0;
|
||||
*naturalHeight = 0;
|
||||
|
||||
if (mImageRequest) {
|
||||
if (mLoads[0].mRequest) {
|
||||
nsCOMPtr<imgIContainer> container;
|
||||
mImageRequest->GetImage(getter_AddRefs(container));
|
||||
mLoads[0].mRequest->GetImage(getter_AddRefs(container));
|
||||
if (container) {
|
||||
PRInt32 w, h;
|
||||
container->GetWidth(&w);
|
||||
|
@ -1478,7 +1568,7 @@ nsImageFrame::GetNaturalImageSize(PRUint32 *naturalWidth,
|
|||
NS_IMETHODIMP
|
||||
nsImageFrame::GetImageRequest(imgIRequest **aRequest)
|
||||
{
|
||||
*aRequest = mImageRequest;
|
||||
*aRequest = mLoads[0].mRequest;
|
||||
NS_IF_ADDREF(*aRequest);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1487,13 +1577,13 @@ NS_IMETHODIMP
|
|||
nsImageFrame::IsImageComplete(PRBool* aComplete)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aComplete);
|
||||
if (!mImageRequest) {
|
||||
if (!mLoads[0].mRequest) {
|
||||
*aComplete = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint32 status;
|
||||
mImageRequest->GetImageStatus(&status);
|
||||
mLoads[0].mRequest->GetImageStatus(&status);
|
||||
*aComplete = ((status & imgIRequest::STATUS_LOAD_COMPLETE) != 0);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1516,7 +1606,7 @@ void HaveFixedSize(const nsHTMLReflowState& aReflowState, PRPackedBool& aConstra
|
|||
|
||||
|
||||
nsresult
|
||||
nsImageFrame::LoadImage(const nsAReadableString& aSpec, nsIPresContext *aPresContext, imgIRequest **aRequest)
|
||||
nsImageFrame::LoadImage(const nsAReadableString& aSpec, nsIPresContext *aPresContext, imgIRequest *aRequest)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
@ -1561,7 +1651,8 @@ nsImageFrame::LoadImage(const nsAReadableString& aSpec, nsIPresContext *aPresCon
|
|||
/* set this back to FALSE before we do the real load */
|
||||
mInitialLoadCompleted = PR_FALSE;
|
||||
|
||||
return il->LoadImage(uri, loadGroup, mListener, aPresContext, loadFlags, nsnull, aRequest);
|
||||
nsCOMPtr<imgIRequest> tempRequest;
|
||||
return il->LoadImage(uri, loadGroup, mListener, aPresContext, loadFlags, nsnull, aRequest, getter_AddRefs(tempRequest));
|
||||
}
|
||||
|
||||
#define INTERNAL_GOPHER_LENGTH 16 /* "internal-gopher-" length */
|
||||
|
|
|
@ -74,6 +74,15 @@ private:
|
|||
nsImageFrame *mFrame;
|
||||
};
|
||||
|
||||
|
||||
struct ImageLoad {
|
||||
ImageLoad() : mIntrinsicSize(0,0) { }
|
||||
nsCOMPtr<imgIRequest> mRequest;
|
||||
nsSize mIntrinsicSize;
|
||||
|
||||
nsTransform2D mTransform;
|
||||
};
|
||||
|
||||
#define ImageFrameSuper nsLeafFrame
|
||||
|
||||
class nsImageFrame : public ImageFrameSuper, public nsIImageFrame {
|
||||
|
@ -192,7 +201,7 @@ protected:
|
|||
nsRect& aInnerArea) const;
|
||||
|
||||
|
||||
nsresult LoadImage(const nsAReadableString& aSpec, nsIPresContext *aPresContext, imgIRequest **aRequest);
|
||||
nsresult LoadImage(const nsAReadableString& aSpec, nsIPresContext *aPresContext, imgIRequest *aRequest);
|
||||
|
||||
inline PRBool CanLoadImage(nsIURI *aURI);
|
||||
|
||||
|
@ -204,18 +213,26 @@ protected:
|
|||
|
||||
void FireDOMEvent(PRUint32 aMessage);
|
||||
|
||||
nsImageMap* mImageMap;
|
||||
|
||||
nsCOMPtr<imgIRequest> mImageRequest;
|
||||
nsCOMPtr<imgIRequest> mLowImageRequest;
|
||||
private:
|
||||
inline int GetImageLoad(imgIRequest *aRequest);
|
||||
|
||||
|
||||
nsImageMap* mImageMap;
|
||||
|
||||
nsCOMPtr<imgIDecoderObserver> mListener;
|
||||
|
||||
/**
|
||||
* 0 is the current image being displayed on the screen.
|
||||
* 1 is for the lowsrc image if any.
|
||||
* 2 is for attribute changed images.
|
||||
* when the load from 2 completes, it will replace 0.
|
||||
*/
|
||||
struct ImageLoad mLoads[3];
|
||||
|
||||
nsSize mComputedSize;
|
||||
nsSize mIntrinsicSize;
|
||||
|
||||
nsTransform2D mTransform;
|
||||
|
||||
PRPackedBool mSizeConstrained;
|
||||
PRPackedBool mGotInitialReflow;
|
||||
PRPackedBool mInitialLoadCompleted;
|
||||
|
|
|
@ -287,7 +287,7 @@ nsImageBoxFrame::UpdateImage(nsIPresContext* aPresContext, PRBool& aResize)
|
|||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
GetLoadGroup(aPresContext, getter_AddRefs(loadGroup));
|
||||
|
||||
il->LoadImage(srcURI, loadGroup, mListener, aPresContext, nsIRequest::LOAD_NORMAL, nsnull, getter_AddRefs(mImageRequest));
|
||||
il->LoadImage(srcURI, loadGroup, mListener, aPresContext, nsIRequest::LOAD_NORMAL, nsnull, nsnull, getter_AddRefs(mImageRequest));
|
||||
|
||||
aResize = PR_TRUE;
|
||||
|
||||
|
|
|
@ -1336,7 +1336,7 @@ nsOutlinerBodyFrame::GetImage(PRInt32 aRowIndex, const PRUnichar* aColID,
|
|||
|
||||
nsresult rv;
|
||||
nsCOMPtr<imgILoader> il(do_GetService("@mozilla.org/image/loader;1", &rv));
|
||||
il->LoadImage(srcURI, nsnull, listener, mPresContext, nsIRequest::LOAD_NORMAL, nsnull, getter_AddRefs(imageRequest));
|
||||
il->LoadImage(srcURI, nsnull, listener, mPresContext, nsIRequest::LOAD_NORMAL, nsnull, nsnull, getter_AddRefs(imageRequest));
|
||||
|
||||
if (!mImageCache) {
|
||||
mImageCache = new nsSupportsHashtable(32);
|
||||
|
|
|
@ -1336,7 +1336,7 @@ nsOutlinerBodyFrame::GetImage(PRInt32 aRowIndex, const PRUnichar* aColID,
|
|||
|
||||
nsresult rv;
|
||||
nsCOMPtr<imgILoader> il(do_GetService("@mozilla.org/image/loader;1", &rv));
|
||||
il->LoadImage(srcURI, nsnull, listener, mPresContext, nsIRequest::LOAD_NORMAL, nsnull, getter_AddRefs(imageRequest));
|
||||
il->LoadImage(srcURI, nsnull, listener, mPresContext, nsIRequest::LOAD_NORMAL, nsnull, nsnull, getter_AddRefs(imageRequest));
|
||||
|
||||
if (!mImageCache) {
|
||||
mImageCache = new nsSupportsHashtable(32);
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
ImageLogging.h
|
|
@ -28,7 +28,7 @@ include $(DEPTH)/config/autoconf.mk
|
|||
|
||||
MODULE = imglib2
|
||||
|
||||
EXPORTS = ImageLogging.h
|
||||
EXPORTS = ImageErrors.h ImageLogging.h
|
||||
|
||||
XPIDLSRCS = imgICache.idl \
|
||||
imgIContainer.idl \
|
||||
|
|
|
@ -55,8 +55,13 @@ interface imgILoader : nsISupports
|
|||
* @param aLoadFlags Load flags for the request
|
||||
* @param aCacheKey cache key to use for a load if the original
|
||||
* image came from a request that had post data
|
||||
* @param aRequest A newly created, unused imgIRequest object or NULL for one to
|
||||
be created for you.
|
||||
*/
|
||||
imgIRequest loadImage(in nsIURI aURI, in nsILoadGroup aLoadGroup, in imgIDecoderObserver aObserver, in nsISupports aCX, in nsLoadFlags aLoadFlags, in nsISupports cacheKey);
|
||||
imgIRequest loadImage(in nsIURI aURI, in nsILoadGroup aLoadGroup,
|
||||
in imgIDecoderObserver aObserver, in nsISupports aCX,
|
||||
in nsLoadFlags aLoadFlags, in nsISupports cacheKey,
|
||||
in imgIRequest aRequest);
|
||||
|
||||
/**
|
||||
* Start the load and decode of an image.
|
||||
|
|
|
@ -68,14 +68,3 @@ interface imgIRequest : nsIRequest
|
|||
readonly attribute imgIDecoderObserver decoderObserver;
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
||||
/**
|
||||
* imagelib specific nsresult success and error codes
|
||||
*/
|
||||
#define NS_IMAGELIB_SUCCESS_LOAD_FINISHED NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_IMGLIB, 0)
|
||||
|
||||
#define NS_IMAGELIB_ERROR_FAILURE NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_IMGLIB, 5)
|
||||
#define NS_IMAGELIB_ERROR_NO_DECODER NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_IMGLIB, 6)
|
||||
|
||||
%}
|
||||
|
|
|
@ -25,7 +25,7 @@ DEPTH = ..\..\..
|
|||
MODULE = imglib2
|
||||
XPIDL_MODULE = imglib2
|
||||
|
||||
EXPORTS = ImageLogging.h
|
||||
EXPORTS = ImageErrors.h ImageLogging.h
|
||||
|
||||
XPIDLSRCS = \
|
||||
.\imgICache.idl \
|
||||
|
|
|
@ -52,13 +52,9 @@ static nsModuleComponentInfo components[] =
|
|||
NS_IMGLOADER_CID,
|
||||
"@mozilla.org/image/loader;1",
|
||||
imgLoaderConstructor, },
|
||||
{ "image request",
|
||||
NS_IMGREQUEST_CID,
|
||||
"@mozilla.org/image/request/real;1",
|
||||
imgRequestConstructor, },
|
||||
{ "image request proxy",
|
||||
NS_IMGREQUESTPROXY_CID,
|
||||
"@mozilla.org/image/request/proxy;1",
|
||||
"@mozilla.org/image/request;1",
|
||||
imgRequestProxyConstructor, },
|
||||
};
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "imgLoader.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
@ -94,8 +93,8 @@ imgLoader::~imgLoader()
|
|||
|
||||
#define SHOULD_RELOAD(flags) (flags & nsIRequest::LOAD_BYPASS_CACHE || flags & nsIRequest::VALIDATE_ALWAYS)
|
||||
|
||||
/* imgIRequest loadImage (in nsIURI aURI, in nsILoadGroup aLoadGroup, in imgIDecoderObserver aObserver, in nsISupports aCX, in nsLoadFlags aLoadFlags, in nsISupports aCacheKey); */
|
||||
NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI, nsILoadGroup *aLoadGroup, imgIDecoderObserver *aObserver, nsISupports *aCX, nsLoadFlags aLoadFlags, nsISupports* aCacheKey, imgIRequest **_retval)
|
||||
/* imgIRequest loadImage (in nsIURI aURI, in nsILoadGroup aLoadGroup, in imgIDecoderObserver aObserver, in nsISupports aCX, in nsLoadFlags aLoadFlags, in nsISupports cacheKey, in imgIRequest aRequest); */
|
||||
NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI, nsILoadGroup *aLoadGroup, imgIDecoderObserver *aObserver, nsISupports *aCX, nsLoadFlags aLoadFlags, nsISupports *cacheKey, imgIRequest *aRequest, imgIRequest **_retval)
|
||||
{
|
||||
NS_ASSERTION(aURI, "imgLoader::LoadImage -- NULL URI pointer");
|
||||
|
||||
|
@ -232,7 +231,7 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI, nsILoadGroup *aLoadGroup, imgID
|
|||
LOG_MSG(gImgLog, "imgLoader::LoadImage", "async open failed.");
|
||||
|
||||
nsresult rv = CreateNewProxyForRequest(request, aLoadGroup, aObserver,
|
||||
aCX, aLoadFlags, _retval);
|
||||
aCX, aLoadFlags, aRequest, _retval);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
request->OnStartRequest(newChannel, nsnull);
|
||||
request->OnStopRequest(newChannel, nsnull, NS_BINDING_ABORTED);
|
||||
|
@ -250,7 +249,7 @@ NS_IMETHODIMP imgLoader::LoadImage(nsIURI *aURI, nsILoadGroup *aLoadGroup, imgID
|
|||
|
||||
LOG_MSG(gImgLog, "imgLoader::LoadImage", "creating proxy request.");
|
||||
|
||||
nsresult rv = CreateNewProxyForRequest(request, aLoadGroup, aObserver, aCX, aLoadFlags, _retval);
|
||||
nsresult rv = CreateNewProxyForRequest(request, aLoadGroup, aObserver, aCX, aLoadFlags, aRequest, _retval);
|
||||
|
||||
NS_RELEASE(request);
|
||||
|
||||
|
@ -308,7 +307,7 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb
|
|||
nsCOMPtr<nsILoadGroup> loadGroup;
|
||||
channel->GetLoadGroup(getter_AddRefs(loadGroup));
|
||||
|
||||
nsresult rv = CreateNewProxyForRequest(request, loadGroup, aObserver, cx, nsIRequest::LOAD_NORMAL, _retval);
|
||||
nsresult rv = CreateNewProxyForRequest(request, loadGroup, aObserver, cx, nsIRequest::LOAD_NORMAL, nsnull, _retval);
|
||||
|
||||
NS_RELEASE(request);
|
||||
|
||||
|
@ -316,11 +315,11 @@ NS_IMETHODIMP imgLoader::LoadImageWithChannel(nsIChannel *channel, imgIDecoderOb
|
|||
}
|
||||
|
||||
|
||||
|
||||
nsresult
|
||||
imgLoader::CreateNewProxyForRequest(imgRequest *aRequest, nsILoadGroup *aLoadGroup,
|
||||
imgIDecoderObserver *aObserver, nsISupports *cx,
|
||||
nsLoadFlags aLoadFlags, imgIRequest **_retval)
|
||||
nsLoadFlags aLoadFlags, imgIRequest *aProxyRequest,
|
||||
imgIRequest **_retval)
|
||||
{
|
||||
LOG_SCOPE_WITH_PARAM(gImgLog, "imgLoader::CreateNewProxyForRequest", "imgRequest", aRequest);
|
||||
|
||||
|
@ -330,9 +329,12 @@ imgLoader::CreateNewProxyForRequest(imgRequest *aRequest, nsILoadGroup *aLoadGro
|
|||
*/
|
||||
|
||||
imgRequestProxy *proxyRequest;
|
||||
NS_NEWXPCOM(proxyRequest, imgRequestProxy);
|
||||
if (!proxyRequest) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (aProxyRequest) {
|
||||
proxyRequest = NS_STATIC_CAST(imgRequestProxy *, aProxyRequest);
|
||||
} else {
|
||||
NS_NEWXPCOM(proxyRequest, imgRequestProxy);
|
||||
if (!proxyRequest) return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
NS_ADDREF(proxyRequest);
|
||||
|
||||
/* It is important to call |SetLoadFlags()| before calling |Init()| because
|
||||
|
|
|
@ -52,7 +52,8 @@ public:
|
|||
private:
|
||||
nsresult CreateNewProxyForRequest(imgRequest *aRequest, nsILoadGroup *aLoadGroup,
|
||||
imgIDecoderObserver *aObserver, nsISupports *cx,
|
||||
nsLoadFlags aLoadFlags, imgIRequest **_retval);
|
||||
nsLoadFlags aLoadFlags, imgIRequest *aRequestProxy,
|
||||
imgIRequest **_retval);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "imgRequestProxy.h"
|
||||
|
||||
#include "imgILoader.h"
|
||||
#include "ImageErrors.h"
|
||||
#include "ImageLogging.h"
|
||||
|
||||
#include "gfxIImageFrame.h"
|
||||
|
|
Загрузка…
Ссылка в новой задаче