From 29014e986a88379ad1e96bdb3cd82db2bcbce631 Mon Sep 17 00:00:00 2001 From: kipp Date: Mon, 11 May 1998 22:58:20 +0000 Subject: [PATCH] Use new image loading API's git-svn-id: svn://10.0.0.236/trunk@1418 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/base/nsCSSRendering.cpp | 15 +-- mozilla/layout/html/base/src/nsHTMLImage.cpp | 102 ++++++++++++------ .../layout/html/forms/src/nsInputButton.cpp | 26 +++-- .../layout/html/style/src/nsCSSRendering.cpp | 15 +-- 4 files changed, 105 insertions(+), 53 deletions(-) diff --git a/mozilla/layout/base/nsCSSRendering.cpp b/mozilla/layout/base/nsCSSRendering.cpp index 785a1062129..8c0568d2591 100644 --- a/mozilla/layout/base/nsCSSRendering.cpp +++ b/mozilla/layout/base/nsCSSRendering.cpp @@ -24,6 +24,7 @@ #include "nsRect.h" #include "nsIViewManager.h" #include "nsIPresShell.h" +#include "nsIFrameImageLoader.h" #define BORDER_FULL 0 //entire side #define BORDER_INSIDE 1 //inside half @@ -708,14 +709,14 @@ void nsCSSRendering::PaintBackground(nsIPresContext& aPresContext, { if (0 < aColor.mBackgroundImage.Length()) { // Lookup the image - PRInt32 loadStatus; - nsImageError loadError; - nsIImage* image = nsnull; nsSize imageSize; + nsIImage* image = nsnull; + nsIFrameImageLoader* loader = nsnull; nsresult rv = aPresContext.LoadImage(aColor.mBackgroundImage, - aForFrame, loadStatus, loadError, - imageSize, image); - if (nsnull == image) { + aForFrame, PR_FALSE, loader); + if ((NS_OK != rv) || (nsnull == loader) || + (loader->GetImage(image), (nsnull == image))) { + NS_IF_RELEASE(loader); // Redraw will happen later if (0 == (aColor.mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT)) { aRenderingContext.SetColor(aColor.mBackgroundColor); @@ -723,6 +724,8 @@ void nsCSSRendering::PaintBackground(nsIPresContext& aPresContext, } return; } + loader->GetSize(imageSize); + NS_RELEASE(loader); #if XXX // XXX enable this code as soon as nsIImage can support it diff --git a/mozilla/layout/html/base/src/nsHTMLImage.cpp b/mozilla/layout/html/base/src/nsHTMLImage.cpp index 303ee0d76fd..01a8668b4f9 100644 --- a/mozilla/layout/html/base/src/nsHTMLImage.cpp +++ b/mozilla/layout/html/base/src/nsHTMLImage.cpp @@ -21,6 +21,8 @@ #include "nsLeafFrame.h" #include "nsIPresContext.h" #include "nsIRenderingContext.h" +#include "nsIFrameImageLoader.h" +#include "nsIPresShell.h" #include "nsHTMLIIDs.h" #include "nsIImage.h" #include "nsIWidget.h" @@ -66,15 +68,14 @@ protected: nsReflowMetrics& aDesiredSize, const nsSize& aMaxSize); - nsresult LoadImage(nsIPresContext& aPresContext); + void LoadImage(nsIPresContext& aPresContext, PRBool aNeedSizeUpdate, + PRIntn& aLoadStatus); nsIImageMap* GetImageMap(); - nsIImage* mImage; - nsSize mImageSize; + nsIFrameImageLoader* mImageLoader; PRPackedBool mLoadImageFailed; PRPackedBool mLoadBrokenImageFailed; - PRUint8 mImageStatus; void TriggerLink(nsIPresContext& aPresContext, const nsString& aURLSpec, @@ -132,31 +133,60 @@ ImageFrame::ImageFrame(nsIContent* aContent, nsIFrame* aParentFrame) ImageFrame::~ImageFrame() { + NS_IF_RELEASE(mImageLoader); } -nsresult -ImageFrame::LoadImage(nsIPresContext& aPresContext) +void +ImageFrame::LoadImage(nsIPresContext& aPresContext, PRBool aNeedSizeUpdate, + PRIntn& aLoadStatus) { + aLoadStatus = NS_IMAGE_LOAD_STATUS_NONE; + + // Get absolute url nsresult rv; nsAutoString src; if (mLoadImageFailed) { src.Append(BROKEN_IMAGE_URL); } else { - if (eContentAttr_HasValue != mContent->GetAttribute("SRC", src)) { + nsAutoString srcParam; + if (eContentAttr_HasValue != mContent->GetAttribute("SRC", srcParam)) { src.Append(BROKEN_IMAGE_URL); mLoadImageFailed = PR_TRUE; } + else { + nsAutoString baseURL; + + // Get documentURL + nsIPresShell* shell; + shell = aPresContext.GetShell(); + nsIDocument* doc = shell->GetDocument(); + nsIURL* docURL = doc->GetDocumentURL(); + + // Create an absolute URL + nsresult rv = NS_MakeAbsoluteURL(docURL, baseURL, srcParam, src); + + // Release references + NS_RELEASE(shell); + NS_RELEASE(docURL); + NS_RELEASE(doc); + if (NS_OK != rv) { + return; + } + } } - // Try to load the image - PRInt32 loadStatus; - nsImageError loadError; - rv = aPresContext.LoadImage(src, this, loadStatus, loadError, - mImageSize, mImage); - if (NS_OK == rv) { - mImageStatus |= loadStatus; + if (nsnull == mImageLoader) { + // Start image loading + rv = aPresContext.LoadImage(src, this, aNeedSizeUpdate, mImageLoader); + if (NS_OK != rv) { + return; + } } - else { + + // Examine current image load status + mImageLoader->GetImageLoadStatus(aLoadStatus); + if (0 != (aLoadStatus & NS_IMAGE_LOAD_STATUS_ERROR)) { + NS_RELEASE(mImageLoader); if (mLoadImageFailed) { // We are doomed. Loading the broken image has just failed. mLoadBrokenImageFailed = PR_TRUE; @@ -164,10 +194,9 @@ ImageFrame::LoadImage(nsIPresContext& aPresContext) else { // Try again, this time using the broke-image url mLoadImageFailed = PR_TRUE; - return LoadImage(aPresContext); + LoadImage(aPresContext, aNeedSizeUpdate, aLoadStatus); } } - return rv; } NS_METHOD @@ -182,23 +211,28 @@ ImageFrame::Paint(nsIPresContext& aPresContext, return NS_OK; } - nsresult rv = LoadImage(aPresContext); - if (NS_OK != rv) { - // Don't bother informing the outside world that we can't render + if (nsnull == mImageLoader) { + // No image at all (not even the broken-image image) return NS_OK; } - if (nsnull == mImage) { + nsIImage* image; + mImageLoader->GetImage(image); + if (nsnull == image) { + // No image yet return NS_OK; } // First paint background and borders nsLeafFrame::Paint(aPresContext, aRenderingContext, aDirtyRect); + // XXX when rendering the broken image, do not scale! + // XXX when we don't have the image, draw the we-don't-have-an-image look + // Now render the image into our inner area (the area without the // borders and padding) nsRect inner; GetInnerArea(&aPresContext, inner); - aRenderingContext.DrawImage(mImage, inner); + aRenderingContext.DrawImage(image, inner); if (GetShowFrameBorders()) { nsIImageMap* map = GetImageMap(); @@ -344,15 +378,18 @@ ImageFrame::GetDesiredSize(nsIPresContext* aPresContext, { nsSize styleSize; PRIntn ss = nsCSSLayout::GetStyleSize(aPresContext, this, styleSize); + PRIntn loadStatus; if (0 != ss) { if (NS_SIZE_HAS_BOTH == ss) { + LoadImage(*aPresContext, PR_FALSE, loadStatus); aDesiredSize.width = styleSize.width; aDesiredSize.height = styleSize.height; } else { // Preserve aspect ratio of image with unbound dimension. - nsresult rv = LoadImage(*aPresContext); - if (0 == (mImageStatus & NS_LOAD_IMAGE_STATUS_SIZE)) { + LoadImage(*aPresContext, PR_TRUE, loadStatus); + if ((0 == (loadStatus & NS_IMAGE_LOAD_STATUS_SIZE_AVAILABLE)) || + (nsnull == mImageLoader)) { // Provide a dummy size for now; later on when the image size // shows up we will reflow to the new size. aDesiredSize.width = 0; @@ -360,8 +397,10 @@ ImageFrame::GetDesiredSize(nsIPresContext* aPresContext, } else { float p2t = aPresContext->GetPixelsToTwips(); - float imageWidth = mImageSize.width * p2t; - float imageHeight = mImageSize.height * p2t; + nsSize imageSize; + mImageLoader->GetSize(imageSize); + float imageWidth = imageSize.width * p2t; + float imageHeight = imageSize.height * p2t; if (0.0f != imageHeight) { if (0 != (ss & NS_SIZE_HAS_WIDTH)) { // We have a width, and an auto height. Compute height @@ -387,16 +426,19 @@ ImageFrame::GetDesiredSize(nsIPresContext* aPresContext, } } else { - nsresult rv = LoadImage(*aPresContext); - if (0 == (mImageStatus & NS_LOAD_IMAGE_STATUS_SIZE)) { + LoadImage(*aPresContext, PR_TRUE, loadStatus); + if ((0 == (loadStatus & NS_IMAGE_LOAD_STATUS_SIZE_AVAILABLE)) || + (nsnull == mImageLoader)) { // Provide a dummy size for now; later on when the image size // shows up we will reflow to the new size. aDesiredSize.width = 0; aDesiredSize.height = 0; } else { float p2t = aPresContext->GetPixelsToTwips(); - aDesiredSize.width = nscoord(mImageSize.width * p2t); - aDesiredSize.height = nscoord(mImageSize.height * p2t); + nsSize imageSize; + mImageLoader->GetSize(imageSize); + aDesiredSize.width = nscoord(imageSize.width * p2t); + aDesiredSize.height = nscoord(imageSize.height * p2t); } } } diff --git a/mozilla/layout/html/forms/src/nsInputButton.cpp b/mozilla/layout/html/forms/src/nsInputButton.cpp index 3bb3c49d65b..7f803609f8d 100644 --- a/mozilla/layout/html/forms/src/nsInputButton.cpp +++ b/mozilla/layout/html/forms/src/nsInputButton.cpp @@ -41,6 +41,7 @@ #include "nsIFormManager.h" #include "nsIImage.h" #include "nsHTMLForms.h" +#include "nsIFrameImageLoader.h" // XXX rewrite this to embed an html image frame in the form element // frame so that the html image code can be 100% reused to deal with @@ -121,7 +122,7 @@ public: nsButtonType GetButtonType() const; nsButtonTagType GetButtonTagType() const; - nsIImage* GetImage(nsIPresContext& aPresContext, PRBool aNeedBits); + nsIImage* GetImage(nsIPresContext& aPresContext, PRBool aNeedSize); protected: @@ -316,7 +317,7 @@ nsInputButtonFrame::GetButtonTagType() const } nsIImage* nsInputButtonFrame::GetImage(nsIPresContext& aPresContext, - PRBool aNeedBits) + PRBool aNeedSize) { if (kButton_Image != GetButtonType()) { return nsnull; @@ -324,13 +325,14 @@ nsIImage* nsInputButtonFrame::GetImage(nsIPresContext& aPresContext, nsAutoString src; if (eContentAttr_HasValue == mContent->GetAttribute("SRC", src)) { - PRInt32 loadStatus; - nsImageError loadError; - nsIImage* image = nsnull; - nsSize imageSize; - nsresult rv = aPresContext.LoadImage(src, this, loadStatus, loadError, - imageSize, image); - return image; + nsIFrameImageLoader* loader = nsnull; + nsresult rv = aPresContext.LoadImage(src, this, aNeedSize, loader); + if ((NS_OK == rv) && (nsnull != loader)) { + nsIImage* image = nsnull; + loader->GetImage(image); + NS_RELEASE(loader); + return image; + } } return nsnull; } @@ -344,7 +346,7 @@ NS_METHOD nsInputButtonFrame::Paint(nsIPresContext& aPresContext, return nsInputButtonFrameSuper::Paint(aPresContext, aRenderingContext, aDirtyRect); } - nsIImage* image = GetImage(aPresContext, PR_TRUE); + nsIImage* image = GetImage(aPresContext, PR_FALSE); if (nsnull == image) { return NS_OK; } @@ -427,11 +429,13 @@ nsInputButtonFrame::GetDesiredSize(nsIPresContext* aPresContext, if (kButton_Image == GetButtonType()) { // there is an image float p2t = aPresContext->GetPixelsToTwips(); if ((0 < styleSize.width) && (0 < styleSize.height)) { + GetImage(*aPresContext, PR_FALSE); + // Use dimensions from style attributes aDesiredLayoutSize.width = nscoord(styleSize.width * p2t); aDesiredLayoutSize.height = nscoord(styleSize.height * p2t); } else { - nsIImage* image = GetImage(*aPresContext, PR_FALSE); + nsIImage* image = GetImage(*aPresContext, PR_TRUE); if (nsnull == image) { // XXX Here is where we trigger a resize-reflow later on; or block // layout or whatever our policy wants to be diff --git a/mozilla/layout/html/style/src/nsCSSRendering.cpp b/mozilla/layout/html/style/src/nsCSSRendering.cpp index 785a1062129..8c0568d2591 100644 --- a/mozilla/layout/html/style/src/nsCSSRendering.cpp +++ b/mozilla/layout/html/style/src/nsCSSRendering.cpp @@ -24,6 +24,7 @@ #include "nsRect.h" #include "nsIViewManager.h" #include "nsIPresShell.h" +#include "nsIFrameImageLoader.h" #define BORDER_FULL 0 //entire side #define BORDER_INSIDE 1 //inside half @@ -708,14 +709,14 @@ void nsCSSRendering::PaintBackground(nsIPresContext& aPresContext, { if (0 < aColor.mBackgroundImage.Length()) { // Lookup the image - PRInt32 loadStatus; - nsImageError loadError; - nsIImage* image = nsnull; nsSize imageSize; + nsIImage* image = nsnull; + nsIFrameImageLoader* loader = nsnull; nsresult rv = aPresContext.LoadImage(aColor.mBackgroundImage, - aForFrame, loadStatus, loadError, - imageSize, image); - if (nsnull == image) { + aForFrame, PR_FALSE, loader); + if ((NS_OK != rv) || (nsnull == loader) || + (loader->GetImage(image), (nsnull == image))) { + NS_IF_RELEASE(loader); // Redraw will happen later if (0 == (aColor.mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT)) { aRenderingContext.SetColor(aColor.mBackgroundColor); @@ -723,6 +724,8 @@ void nsCSSRendering::PaintBackground(nsIPresContext& aPresContext, } return; } + loader->GetSize(imageSize); + NS_RELEASE(loader); #if XXX // XXX enable this code as soon as nsIImage can support it