forked from mirrors/gecko-dev
Bug 753 - Remove nsIImage, gfxIImageFrame, and their implementations, and expose an equivalent api on imgIContainer. r=roc,josh,bz,longsonr,vlad,karlt,jimm,bsmedberg,mfinkle,peterw,peterv sr=vlad,roc
--HG-- rename : gfx/src/shared/gfxImageFrame.cpp => modules/libpr0n/src/imgFrame.cpp rename : gfx/src/shared/gfxImageFrame.h => modules/libpr0n/src/imgFrame.h
This commit is contained in:
parent
a6e367551a
commit
2aa59235f2
98 changed files with 2290 additions and 3404 deletions
|
|
@ -115,9 +115,9 @@ nsHTMLImageAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
imageRequest->GetImage(getter_AddRefs(imgContainer));
|
||||
|
||||
if (imgContainer) {
|
||||
PRUint32 numFrames;
|
||||
imgContainer->GetNumFrames(&numFrames);
|
||||
if (numFrames > 1)
|
||||
PRBool animated;
|
||||
imgContainer->GetAnimated(&animated);
|
||||
if (animated)
|
||||
*aState |= nsIAccessibleStates::STATE_ANIMATED;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,4 +91,12 @@ EXTRA_DSO_LDOPTS += \
|
|||
$(NULL)
|
||||
endif
|
||||
|
||||
ifndef MOZ_ENABLE_LIBXUL
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
# Doesn't work, couldn't figure out why
|
||||
#EXTRA_DSO_LIBS += thebes
|
||||
EXTRA_DSO_LDOPTS += $(LIBXUL_DIST)/lib/$(LIB_PREFIX)thebes.$(LIB_SUFFIX)
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@
|
|||
#include "nsIGConfService.h"
|
||||
#include "nsIGnomeVFSService.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIProcess.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
|
@ -55,7 +54,6 @@
|
|||
#include "nsIImageLoadingContent.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "nsIImage.h"
|
||||
#include "prprf.h"
|
||||
#ifdef MOZ_WIDGET_GTK2
|
||||
#include "nsIImageToPixbuf.h"
|
||||
|
|
@ -349,12 +347,8 @@ nsGNOMEShellService::SetShouldCheckDefaultBrowser(PRBool aShouldCheck)
|
|||
}
|
||||
|
||||
static nsresult
|
||||
WriteImage(const nsCString& aPath, gfxIImageFrame* aImage)
|
||||
WriteImage(const nsCString& aPath, imgIContainer* aImage)
|
||||
{
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(aImage));
|
||||
if (!img)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
#ifndef MOZ_WIDGET_GTK2
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
#else
|
||||
|
|
@ -363,7 +357,7 @@ WriteImage(const nsCString& aPath, gfxIImageFrame* aImage)
|
|||
if (!imgToPixbuf)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
GdkPixbuf* pixbuf = imgToPixbuf->ConvertImageToPixbuf(img);
|
||||
GdkPixbuf* pixbuf = imgToPixbuf->ConvertImageToPixbuf(aImage);
|
||||
if (!pixbuf)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
|
|
@ -379,8 +373,6 @@ nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement,
|
|||
PRInt32 aPosition)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<gfxIImageFrame> gfxFrame;
|
||||
|
||||
nsCOMPtr<nsIImageLoadingContent> imageContent = do_QueryInterface(aElement, &rv);
|
||||
if (!imageContent) return rv;
|
||||
|
||||
|
|
@ -393,12 +385,6 @@ nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement,
|
|||
rv = request->GetImage(getter_AddRefs(container));
|
||||
if (!container) return rv;
|
||||
|
||||
// get the current frame, which holds the image data
|
||||
container->GetCurrentFrame(getter_AddRefs(gfxFrame));
|
||||
|
||||
if (!gfxFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Write the background file to the home directory.
|
||||
nsCAutoString filePath(PR_GetEnv("HOME"));
|
||||
|
||||
|
|
@ -423,7 +409,7 @@ nsGNOMEShellService::SetDesktopBackground(nsIDOMElement* aElement,
|
|||
filePath.Append("_wallpaper.png");
|
||||
|
||||
// write the image to a file in the home dir
|
||||
rv = WriteImage(filePath, gfxFrame);
|
||||
rv = WriteImage(filePath, container);
|
||||
|
||||
// if the file was written successfully, set it as the system wallpaper
|
||||
nsCOMPtr<nsIGConfService> gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID);
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
|
|
@ -519,23 +518,18 @@ nsWindowsShellService::SetShouldCheckDefaultBrowser(PRBool aShouldCheck)
|
|||
}
|
||||
|
||||
static nsresult
|
||||
WriteBitmap(nsIFile* aFile, gfxIImageFrame* aImage)
|
||||
WriteBitmap(nsIFile* aFile, imgIContainer* aImage)
|
||||
{
|
||||
PRInt32 width, height;
|
||||
aImage->GetWidth(&width);
|
||||
aImage->GetHeight(&height);
|
||||
nsRefPtr<gfxImageSurface> image;
|
||||
nsresult rv = aImage->CopyCurrentFrame(getter_AddRefs(image));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint8* bits;
|
||||
PRUint32 length;
|
||||
aImage->LockImageData();
|
||||
aImage->GetImageData(&bits, &length);
|
||||
if (!bits) {
|
||||
aImage->UnlockImageData();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
PRInt32 width = image->Width();
|
||||
PRInt32 height = image->Height();
|
||||
|
||||
PRUint32 bpr;
|
||||
aImage->GetImageBytesPerRow(&bpr);
|
||||
PRUint8* bits = image->Data();
|
||||
PRUint32 length = image->GetDataSize();
|
||||
PRUint32 bpr = PRUint32(image->Stride());
|
||||
PRInt32 bitCount = bpr/width;
|
||||
|
||||
// initialize these bitmap structs which we will later
|
||||
|
|
@ -562,7 +556,7 @@ WriteBitmap(nsIFile* aFile, gfxIImageFrame* aImage)
|
|||
|
||||
// get a file output stream
|
||||
nsCOMPtr<nsIOutputStream> stream;
|
||||
nsresult rv = NS_NewLocalFileOutputStream(getter_AddRefs(stream), aFile);
|
||||
rv = NS_NewLocalFileOutputStream(getter_AddRefs(stream), aFile);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// write the bitmap headers and rgb pixel data to the file
|
||||
|
|
@ -592,7 +586,6 @@ WriteBitmap(nsIFile* aFile, gfxIImageFrame* aImage)
|
|||
stream->Close();
|
||||
}
|
||||
|
||||
aImage->UnlockImageData();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
@ -602,8 +595,7 @@ nsWindowsShellService::SetDesktopBackground(nsIDOMElement* aElement,
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> gfxFrame;
|
||||
|
||||
nsCOMPtr<imgIContainer> container;
|
||||
nsCOMPtr<nsIDOMHTMLImageElement> imgElement(do_QueryInterface(aElement));
|
||||
if (!imgElement) {
|
||||
// XXX write background loading stuff!
|
||||
|
|
@ -620,18 +612,11 @@ nsWindowsShellService::SetDesktopBackground(nsIDOMElement* aElement,
|
|||
getter_AddRefs(request));
|
||||
if (!request)
|
||||
return rv;
|
||||
nsCOMPtr<imgIContainer> container;
|
||||
rv = request->GetImage(getter_AddRefs(container));
|
||||
if (!container)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// get the current frame, which holds the image data
|
||||
container->GetCurrentFrame(getter_AddRefs(gfxFrame));
|
||||
}
|
||||
|
||||
if (!gfxFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// get the file name from localized strings
|
||||
nsCOMPtr<nsIStringBundleService>
|
||||
bundleService(do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv));
|
||||
|
|
@ -664,7 +649,7 @@ nsWindowsShellService::SetDesktopBackground(nsIDOMElement* aElement,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// write the bitmap to a file in the profile directory
|
||||
rv = WriteBitmap(file, gfxFrame);
|
||||
rv = WriteBitmap(file, container);
|
||||
|
||||
// if the file was written successfully, set it as the system wallpaper
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
|
|
|||
|
|
@ -78,12 +78,12 @@ class nsIThreadJSContextStack;
|
|||
class nsIParserService;
|
||||
class nsIIOService;
|
||||
class nsIURI;
|
||||
class imgIContainer;
|
||||
class imgIDecoderObserver;
|
||||
class imgIRequest;
|
||||
class imgILoader;
|
||||
class imgICache;
|
||||
class nsIPrefBranch;
|
||||
class nsIImage;
|
||||
class nsIImageLoadingContent;
|
||||
class nsIDOMHTMLFormElement;
|
||||
class nsIDOMDocument;
|
||||
|
|
@ -654,13 +654,13 @@ public:
|
|||
static PRBool IsImageInCache(nsIURI* aURI);
|
||||
|
||||
/**
|
||||
* Method to get an nsIImage from an image loading content
|
||||
* Method to get an imgIContainer from an image loading content
|
||||
*
|
||||
* @param aContent The image loading content. Must not be null.
|
||||
* @param aRequest The image request [out]
|
||||
* @return the nsIImage corresponding to the first frame of the image
|
||||
* @return the imgIContainer corresponding to the first frame of the image
|
||||
*/
|
||||
static already_AddRefed<nsIImage> GetImageFromContent(nsIImageLoadingContent* aContent, imgIRequest **aRequest = nsnull);
|
||||
static already_AddRefed<imgIContainer> GetImageFromContent(nsIImageLoadingContent* aContent, imgIRequest **aRequest = nsnull);
|
||||
|
||||
/**
|
||||
* Method that decides whether a content node is draggable
|
||||
|
|
|
|||
|
|
@ -80,7 +80,6 @@
|
|||
#include "nsINameSpaceManager.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIPrincipal.h"
|
||||
|
|
@ -93,6 +92,7 @@
|
|||
#include "nsEscape.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "nsContentCID.h"
|
||||
#include "nsDOMDataTransfer.h"
|
||||
|
|
@ -171,7 +171,7 @@ private:
|
|||
nsString mInfoString;
|
||||
|
||||
PRBool mIsAnchor;
|
||||
nsCOMPtr<nsIImage> mImage;
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -972,7 +972,7 @@ nsTransferableFactory::Produce(nsDOMDataTransfer* aDataTransfer,
|
|||
nsCOMPtr<imgIRequest> imgRequest;
|
||||
|
||||
// grab the image data, and its request.
|
||||
nsCOMPtr<nsIImage> img =
|
||||
nsCOMPtr<imgIContainer> img =
|
||||
nsContentUtils::GetImageFromContent(image,
|
||||
getter_AddRefs(imgRequest));
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ class nsIDOMDocument;
|
|||
class nsIDOMDragEvent;
|
||||
class nsISelection;
|
||||
class nsITransferable;
|
||||
class nsIImage;
|
||||
class nsIPresShell;
|
||||
class nsPresContext;
|
||||
class nsIContent;
|
||||
|
|
|
|||
|
|
@ -98,8 +98,6 @@
|
|||
#include "imgIRequest.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgILoader.h"
|
||||
#include "nsIImage.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIImageLoadingContent.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
|
@ -2446,7 +2444,7 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
|
|||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<nsIImage>
|
||||
already_AddRefed<imgIContainer>
|
||||
nsContentUtils::GetImageFromContent(nsIImageLoadingContent* aContent,
|
||||
imgIRequest **aRequest)
|
||||
{
|
||||
|
|
@ -2470,26 +2468,11 @@ nsContentUtils::GetImageFromContent(nsIImageLoadingContent* aContent,
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> imgFrame;
|
||||
imgContainer->GetFrameAt(0, getter_AddRefs(imgFrame));
|
||||
|
||||
if (!imgFrame) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInterfaceRequestor> ir = do_QueryInterface(imgFrame);
|
||||
|
||||
if (!ir) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (aRequest) {
|
||||
imgRequest.swap(*aRequest);
|
||||
}
|
||||
|
||||
nsIImage* image = nsnull;
|
||||
CallGetInterface(ir.get(), &image);
|
||||
return image;
|
||||
return imgContainer.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "imgIContainer.h"
|
||||
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIContentViewerEdit.h"
|
||||
|
|
@ -65,7 +66,6 @@
|
|||
// image copy stuff
|
||||
#include "nsIImageLoadingContent.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsContentCID.h"
|
||||
|
||||
|
|
@ -463,7 +463,7 @@ nsCopySupport::ImageCopy(nsIImageLoadingContent* aImageElement,
|
|||
|
||||
if (aCopyFlags & nsIContentViewerEdit::COPY_IMAGE_DATA) {
|
||||
// get the image data from the element
|
||||
nsCOMPtr<nsIImage> image =
|
||||
nsCOMPtr<imgIContainer> image =
|
||||
nsContentUtils::GetImageFromContent(aImageElement);
|
||||
NS_ENSURE_TRUE(image, NS_ERROR_FAILURE);
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@
|
|||
#include "nsIURI.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "imgILoader.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
|
@ -158,10 +157,9 @@ nsImageLoadingContent::~nsImageLoadingContent()
|
|||
*/
|
||||
NS_IMETHODIMP
|
||||
nsImageLoadingContent::FrameChanged(imgIContainer* aContainer,
|
||||
gfxIImageFrame* aFrame,
|
||||
nsIntRect* aDirtyRect)
|
||||
{
|
||||
LOOP_OVER_OBSERVERS(FrameChanged(aContainer, aFrame, aDirtyRect));
|
||||
LOOP_OVER_OBSERVERS(FrameChanged(aContainer, aDirtyRect));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -196,7 +194,7 @@ nsImageLoadingContent::OnStartContainer(imgIRequest* aRequest,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsImageLoadingContent::OnStartFrame(imgIRequest* aRequest,
|
||||
gfxIImageFrame* aFrame)
|
||||
PRUint32 aFrame)
|
||||
{
|
||||
LOOP_OVER_OBSERVERS(OnStartFrame(aRequest, aFrame));
|
||||
return NS_OK;
|
||||
|
|
@ -204,16 +202,16 @@ nsImageLoadingContent::OnStartFrame(imgIRequest* aRequest,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsImageLoadingContent::OnDataAvailable(imgIRequest* aRequest,
|
||||
gfxIImageFrame* aFrame,
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect* aRect)
|
||||
{
|
||||
LOOP_OVER_OBSERVERS(OnDataAvailable(aRequest, aFrame, aRect));
|
||||
LOOP_OVER_OBSERVERS(OnDataAvailable(aRequest, aCurrentFrame, aRect));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImageLoadingContent::OnStopFrame(imgIRequest* aRequest,
|
||||
gfxIImageFrame* aFrame)
|
||||
PRUint32 aFrame)
|
||||
{
|
||||
LOOP_OVER_OBSERVERS(OnStopFrame(aRequest, aFrame));
|
||||
return NS_OK;
|
||||
|
|
|
|||
|
|
@ -58,14 +58,14 @@ nsStubImageDecoderObserver::OnStartContainer(imgIRequest *aRequest,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsStubImageDecoderObserver::OnStartFrame(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame)
|
||||
PRUint32 aFrame)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStubImageDecoderObserver::OnDataAvailable(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame,
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect * aRect)
|
||||
{
|
||||
return NS_OK;
|
||||
|
|
@ -73,7 +73,7 @@ nsStubImageDecoderObserver::OnDataAvailable(imgIRequest *aRequest,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsStubImageDecoderObserver::OnStopFrame(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame)
|
||||
PRUint32 aFrame)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -102,7 +102,6 @@ nsStubImageDecoderObserver::OnStopRequest(imgIRequest *aRequest,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsStubImageDecoderObserver::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *aFrame,
|
||||
nsIntRect * aDirtyRect)
|
||||
{
|
||||
return NS_OK;
|
||||
|
|
|
|||
|
|
@ -61,8 +61,6 @@
|
|||
#include "nsIDOMSVGURIReference.h"
|
||||
#include "nsImageLoadingContent.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsSVGPreserveAspectRatio.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
|
@ -5191,8 +5189,7 @@ public:
|
|||
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
|
||||
const PRUnichar *statusArg);
|
||||
// imgIContainerObserver
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect *dirtyRect);
|
||||
// imgIContainerObserver
|
||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest,
|
||||
imgIContainer *aContainer);
|
||||
|
|
@ -5378,31 +5375,27 @@ nsSVGFEImageElement::Filter(nsSVGFilterInstance *instance,
|
|||
if (currentRequest)
|
||||
currentRequest->GetImage(getter_AddRefs(imageContainer));
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> currentFrame;
|
||||
nsRefPtr<gfxASurface> currentFrame;
|
||||
if (imageContainer)
|
||||
imageContainer->GetCurrentFrame(getter_AddRefs(currentFrame));
|
||||
|
||||
nsRefPtr<gfxPattern> thebesPattern = nsnull;
|
||||
if (currentFrame) {
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(currentFrame));
|
||||
|
||||
img->GetPattern(getter_AddRefs(thebesPattern));
|
||||
}
|
||||
// We need to wrap the surface in a pattern to have somewhere to set the
|
||||
// graphics filter.
|
||||
nsRefPtr<gfxPattern> thebesPattern;
|
||||
if (currentFrame)
|
||||
thebesPattern = new gfxPattern(currentFrame);
|
||||
|
||||
if (thebesPattern) {
|
||||
thebesPattern->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(frame));
|
||||
|
||||
PRInt32 x, y, nativeWidth, nativeHeight;
|
||||
currentFrame->GetX(&x);
|
||||
currentFrame->GetY(&y);
|
||||
currentFrame->GetWidth(&nativeWidth);
|
||||
currentFrame->GetHeight(&nativeHeight);
|
||||
PRInt32 nativeWidth, nativeHeight;
|
||||
imageContainer->GetWidth(&nativeWidth);
|
||||
imageContainer->GetHeight(&nativeHeight);
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> trans;
|
||||
const gfxRect& filterSubregion = aTarget->mFilterPrimitiveSubregion;
|
||||
trans = nsSVGUtils::GetViewBoxTransform(filterSubregion.Width(), filterSubregion.Height(),
|
||||
x, y,
|
||||
nativeWidth, nativeHeight,
|
||||
0, 0, nativeWidth, nativeHeight,
|
||||
mPreserveAspectRatio);
|
||||
nsCOMPtr<nsIDOMSVGMatrix> xy, fini;
|
||||
NS_NewSVGMatrix(getter_AddRefs(xy), 1, 0, 0, 1, filterSubregion.X(), filterSubregion.Y());
|
||||
|
|
@ -5457,11 +5450,10 @@ nsSVGFEImageElement::OnStopDecode(imgIRequest *aRequest,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsSVGFEImageElement::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect)
|
||||
{
|
||||
nsresult rv =
|
||||
nsImageLoadingContent::FrameChanged(aContainer, newframe, dirtyRect);
|
||||
nsImageLoadingContent::FrameChanged(aContainer, dirtyRect);
|
||||
Invalidate();
|
||||
return rv;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,6 @@
|
|||
#include "nsPresContext.h"
|
||||
#include "nsIParser.h"
|
||||
#include "nsParserCIID.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsLinebreakConverter.h"
|
||||
|
|
|
|||
|
|
@ -93,7 +93,6 @@
|
|||
#include "nsIDOMDocumentFragment.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "SetDocTitleTxn.h"
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ XPIDLSRCS = \
|
|||
nsIFontEnumerator.idl \
|
||||
nsIScriptableRegion.idl \
|
||||
gfxIFormats.idl \
|
||||
gfxIImageFrame.idl \
|
||||
gfxidltypes.idl \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,168 +0,0 @@
|
|||
/** -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
* Chris Saari <saari@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "gfxidltypes.idl"
|
||||
#include "gfxIFormats.idl"
|
||||
|
||||
%{C++
|
||||
#include "nsRect.h"
|
||||
%}
|
||||
|
||||
native nsRectRef(nsIntRect &);
|
||||
|
||||
/**
|
||||
* gfxIImageFrame interface
|
||||
*
|
||||
* All x, y, width, height values are in pixels.
|
||||
*
|
||||
* @author Tim Rowley <tor@cs.brown.edu>
|
||||
* @author Stuart Parmenter <pavlov@netscape.com>
|
||||
* @version 0.1
|
||||
*/
|
||||
[scriptable, uuid(9c37930b-cadd-453c-89e1-9ed456715b9c)]
|
||||
interface gfxIImageFrame : nsISupports
|
||||
{
|
||||
/**
|
||||
* Create a new \a aWidth x \a aHeight sized image.
|
||||
*
|
||||
* @param aX The x-offset from the origin of the gfxIImageContainer parent.
|
||||
* @param aY The y-offset from the origin of the gfxIImageContainer parent.
|
||||
* @param aWidth The width of the image to create.
|
||||
* @param aHeight The height of the image to create.
|
||||
* @param aFormat the width of the image to create.
|
||||
*
|
||||
* @note The data in a new image is uninitialized.
|
||||
*/
|
||||
void init(in PRInt32 aX,
|
||||
in PRInt32 aY,
|
||||
in PRInt32 aWidth,
|
||||
in PRInt32 aHeight,
|
||||
in gfx_format aFormat,
|
||||
in gfx_depth aDepth);
|
||||
|
||||
/**
|
||||
* TRUE by default. When set to FALSE, you will no longer be able to make any modifications
|
||||
* to the data of the image. Any attempts will fail.
|
||||
*/
|
||||
attribute boolean mutable;
|
||||
|
||||
/**
|
||||
* The x-offset of the image.
|
||||
*/
|
||||
readonly attribute PRInt32 x;
|
||||
|
||||
/**
|
||||
* The y-offset of the image.
|
||||
*/
|
||||
readonly attribute PRInt32 y;
|
||||
|
||||
/**
|
||||
* The width of the image.
|
||||
*/
|
||||
readonly attribute PRInt32 width;
|
||||
|
||||
/**
|
||||
* The height of the image.
|
||||
*/
|
||||
readonly attribute PRInt32 height;
|
||||
|
||||
/**
|
||||
* The rectangle this frame ocupies.
|
||||
* @param rect this is really an out parameter.
|
||||
*/
|
||||
[noscript] void getRect(in nsRectRef rect);
|
||||
|
||||
/**
|
||||
* The image data format the image was created with.
|
||||
* @see gfxIFormats
|
||||
*/
|
||||
readonly attribute gfx_format format;
|
||||
|
||||
/**
|
||||
* returns whether the image requires the background to be painted
|
||||
*/
|
||||
readonly attribute boolean needsBackground;
|
||||
|
||||
/* data accessors */
|
||||
readonly attribute unsigned long imageBytesPerRow;
|
||||
|
||||
/**
|
||||
* returns the number of bytes allocated for the image
|
||||
*/
|
||||
readonly attribute unsigned long imageDataLength;
|
||||
|
||||
// XXX do we copy here? lets not...
|
||||
void getImageData([array, size_is(length)] out PRUint8 bits, out unsigned long length);
|
||||
|
||||
/**
|
||||
* Get Palette data pointer
|
||||
*/
|
||||
void getPaletteData([array, size_is(length)] out gfx_color palette, out unsigned long length);
|
||||
|
||||
/**
|
||||
* Lock image pixels before addressing the data directly
|
||||
*/
|
||||
void lockImageData();
|
||||
|
||||
/**
|
||||
* Unlock image pixels
|
||||
*/
|
||||
void unlockImageData();
|
||||
|
||||
|
||||
/* GIF Specific methods. These should be in a different class or interface. */
|
||||
|
||||
/**
|
||||
* Represents the number of milliseconds until the next frame should be displayed.
|
||||
* @note -1 means that this frame should be displayed forever.
|
||||
*/
|
||||
attribute long timeout;
|
||||
|
||||
/* frame disposal method, used only by GIFs. Should probably subclass image frame
|
||||
* and image container for GIFs special needs, but for simplicity it is here for the
|
||||
* moment
|
||||
*/
|
||||
attribute long frameDisposalMethod;
|
||||
|
||||
/* PNG specific methods */
|
||||
|
||||
attribute long blendMethod;
|
||||
};
|
||||
|
|
@ -60,7 +60,6 @@ EXPORTS = \
|
|||
nsIRenderingContext.h \
|
||||
nsIFontMetrics.h \
|
||||
nsIDeviceContext.h \
|
||||
nsIImage.h \
|
||||
nsGfxCIID.h \
|
||||
nsIRegion.h \
|
||||
nsITheme.h \
|
||||
|
|
|
|||
|
|
@ -1,307 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsIImage_h___
|
||||
#define nsIImage_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsMargin.h"
|
||||
#include "nsRect.h"
|
||||
#include "gfxPattern.h"
|
||||
|
||||
class gfxASurface;
|
||||
struct gfxMatrix;
|
||||
struct gfxRect;
|
||||
class gfxContext;
|
||||
|
||||
class nsIDeviceContext;
|
||||
|
||||
struct nsColorMap
|
||||
{
|
||||
//I lifted this from the image lib. The difference is that
|
||||
//this uses nscolor instead of NI_RGB. Multiple color pollution
|
||||
//is a bad thing. MMP
|
||||
PRInt32 NumColors; // Number of colors in the colormap.
|
||||
// A negative value can be used to denote a
|
||||
// possibly non-unique set.
|
||||
//nscolor *Map; // Colormap colors.
|
||||
PRUint8 *Index; // NULL, if map is in index order, otherwise
|
||||
// specifies the indices of the map entries. */
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
nsMaskRequirements_kNoMask,
|
||||
nsMaskRequirements_kNeeds1Bit,
|
||||
nsMaskRequirements_kNeeds8Bit
|
||||
} nsMaskRequirements;
|
||||
|
||||
|
||||
#define nsImageUpdateFlags_kColorMapChanged 0x1
|
||||
#define nsImageUpdateFlags_kBitsChanged 0x2
|
||||
|
||||
// IID for the nsIImage interface
|
||||
// 0358ce68-b076-43b0-8f5c-36ed4592822c
|
||||
#define NS_IIMAGE_IID \
|
||||
{ 0x358ce68, 0xb076, 0x43b0, \
|
||||
{ 0x8f, 0x5c, 0x36, 0xed, 0x45, 0x92, 0x82, 0x2c } }
|
||||
|
||||
// Interface to Images
|
||||
class nsIImage : public nsISupports
|
||||
{
|
||||
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IIMAGE_IID)
|
||||
|
||||
/**
|
||||
* Build and initialize the nsIImage
|
||||
* @param aWidth The width in pixels of the desired pixelmap
|
||||
* @param aHeight The height in pixels of the desired pixelmap
|
||||
* @param aDepth The number of bits per pixel for the pixelmap
|
||||
* @param aMaskRequirements A flag indicating if a alpha mask should be allocated
|
||||
*/
|
||||
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements) = 0;
|
||||
|
||||
/**
|
||||
* Get the number of bytes per pixel for this image
|
||||
* @update - dwc 2/3/99
|
||||
* @return - the number of bytes per pixel
|
||||
*/
|
||||
virtual PRInt32 GetBytesPix() = 0;
|
||||
|
||||
/**
|
||||
* Get whether rows are organized top to bottom, or bottom to top
|
||||
* @update - syd 3/29/99
|
||||
* @return PR_TRUE if top to bottom, else PR_FALSE
|
||||
*/
|
||||
virtual PRBool GetIsRowOrderTopToBottom() = 0;
|
||||
|
||||
/**
|
||||
* Get the width for the pixelmap
|
||||
* @update - dwc 2/1/99
|
||||
* @return The width in pixels for the pixelmap
|
||||
*/
|
||||
virtual PRInt32 GetWidth() = 0;
|
||||
|
||||
/**
|
||||
* Get the height for the pixelmap
|
||||
* @update - dwc 2/1/99
|
||||
* @return The height in pixels for the pixelmap
|
||||
*/
|
||||
virtual PRInt32 GetHeight() = 0;
|
||||
|
||||
/**
|
||||
* Get a pointer to the bits for the pixelmap, only if it is not optimized
|
||||
* @update - dwc 2/1/99
|
||||
* @return address of the DIB pixel array
|
||||
*/
|
||||
virtual PRUint8 * GetBits() = 0;
|
||||
|
||||
/**
|
||||
* Get the number of bytes needed to get to the next scanline for the pixelmap
|
||||
* @update - dwc 2/1/99
|
||||
* @return The number of bytes in each scanline
|
||||
*/
|
||||
virtual PRInt32 GetLineStride() = 0;
|
||||
|
||||
/**
|
||||
* Get whether this image has an alpha mask. Preferable to testing
|
||||
* if GetAlphaBits() is non-null.
|
||||
* @update - sfraser 10/19/99
|
||||
* @return PR_TRUE if the image has an alpha mask, PR_FALSE otherwise
|
||||
*/
|
||||
virtual PRBool GetHasAlphaMask() = 0;
|
||||
|
||||
/**
|
||||
* Get a pointer to the bits for the alpha mask
|
||||
* @update - dwc 2/1/99
|
||||
* @return address of the alpha mask pixel array
|
||||
*/
|
||||
virtual PRUint8 * GetAlphaBits() = 0;
|
||||
|
||||
/**
|
||||
* Get the number of bytes per scanline for the alpha mask
|
||||
* @update - dwc 2/1/99
|
||||
* @return The number of bytes in each scanline
|
||||
*/
|
||||
virtual PRInt32 GetAlphaLineStride() = 0;
|
||||
|
||||
/**
|
||||
* Update the nsIImage color table
|
||||
* @update - dougt 9/9/08
|
||||
* @param aFlags Used to pass in parameters for the update
|
||||
* @param aUpdateRect The rectangle to update
|
||||
* @return success code. failure means stop decoding
|
||||
*/
|
||||
virtual nsresult ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsIntRect *aUpdateRect) = 0;
|
||||
|
||||
/**
|
||||
* Get whether this image's region is completely filled with data.
|
||||
* @return PR_TRUE if image is complete, PR_FALSE if image is not yet
|
||||
* complete or broken
|
||||
*/
|
||||
virtual PRBool GetIsImageComplete() = 0;
|
||||
|
||||
/**
|
||||
* Converted this pixelmap to an optimized pixelmap for the device
|
||||
* @update - dwc 2/1/99
|
||||
* @param aContext The device to optimize for
|
||||
* @return the result of the operation, if NS_OK, then the pixelmap is optimized
|
||||
*/
|
||||
virtual nsresult Optimize(nsIDeviceContext* aContext) = 0;
|
||||
|
||||
/**
|
||||
* Get the colormap for the nsIImage
|
||||
* @update - dwc 2/1/99
|
||||
* @return if non null, the colormap for the pixelmap,otherwise the image is not color mapped
|
||||
*/
|
||||
virtual nsColorMap * GetColorMap() = 0;
|
||||
|
||||
/**
|
||||
* BitBlit the nsIImage to a device, the source and dest can be scaled.
|
||||
* @param aContext the destination
|
||||
* @param aFilter the filter for the image
|
||||
* @param aUserSpaceToImageSpace the transform that maps user-space
|
||||
* coordinates to coordinates in (tiled, post-padding) image pixels
|
||||
* @param aFill the area to fill with tiled images
|
||||
* @param aPadding the padding to be added to this image before tiling,
|
||||
* in image pixels
|
||||
* @param aSubimage the subimage in padded+tiled image space that we're
|
||||
* extracting the contents from. Pixels outside this rectangle must not
|
||||
* be sampled.
|
||||
*
|
||||
* So this is supposed to
|
||||
* -- add aPadding transparent pixels around the image
|
||||
* -- use that image to tile the plane
|
||||
* -- replace everything outside the aSubimage region with the nearest
|
||||
* border pixel of that region (like EXTEND_PAD)
|
||||
* -- fill aFill with the image, using aImageSpaceToDeviceSpace as the
|
||||
* image-space-to-device-space transform
|
||||
*/
|
||||
virtual void Draw(gfxContext* aContext,
|
||||
gfxPattern::GraphicsFilter aFilter,
|
||||
const gfxMatrix& aUserSpaceToImageSpace,
|
||||
const gfxRect& aFill,
|
||||
const nsIntMargin& aPadding,
|
||||
const nsIntRect& aSubimage) = 0;
|
||||
|
||||
/**
|
||||
* Get the alpha depth for the image mask
|
||||
* @update - lordpixel 2001/05/16
|
||||
* @return the alpha mask depth for the image, ie, 0, 1 or 8
|
||||
*/
|
||||
virtual PRInt8 GetAlphaDepth() = 0;
|
||||
|
||||
/**
|
||||
* Return information about the bits for this structure
|
||||
* @update - dwc 2/1/99
|
||||
* @return a bitmap info structure for the Device Dependent Bits
|
||||
*/
|
||||
virtual void* GetBitInfo() = 0;
|
||||
|
||||
|
||||
/**
|
||||
* LockImagePixels
|
||||
* Lock the image pixels so that we can access them directly,
|
||||
* with safety. May be a noop on some platforms.
|
||||
*
|
||||
* If you want to be able to call GetSurface(), wrap the call in
|
||||
* LockImagePixels()/UnlockImagePixels(). This also allows you to write to
|
||||
* the surface returned by GetSurface().
|
||||
*
|
||||
* aMaskPixels = PR_TRUE for the mask, PR_FALSE for the image
|
||||
*
|
||||
* Must be balanced by a call to UnlockImagePixels().
|
||||
*
|
||||
* @update - sfraser 10/18/99
|
||||
* @return error result
|
||||
*/
|
||||
NS_IMETHOD LockImagePixels(PRBool aMaskPixels) = 0;
|
||||
|
||||
/**
|
||||
* UnlockImagePixels
|
||||
* Unlock the image pixels. May be a noop on some platforms.
|
||||
*
|
||||
* Should balance an earlier call to LockImagePixels().
|
||||
*
|
||||
* aMaskPixels = PR_TRUE for the mask, PR_FALSE for the image
|
||||
*
|
||||
* @update - sfraser 10/18/99
|
||||
* @return error result
|
||||
*/
|
||||
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels) = 0;
|
||||
|
||||
/**
|
||||
* GetSurface
|
||||
* Return the Thebes gfxASurface in aSurface, if there is one. Should be
|
||||
* wrapped by LockImagePixels()/UnlockImagePixels().
|
||||
*
|
||||
* aSurface will be AddRef'd (as with most getters), so
|
||||
* getter_AddRefs should be used.
|
||||
*/
|
||||
NS_IMETHOD GetSurface(gfxASurface **aSurface) = 0;
|
||||
|
||||
/**
|
||||
* GetSurface
|
||||
* Return the Thebes gfxPattern in aPattern. It is always possible to get a
|
||||
* gfxPattern (unlike the gfxASurface from GetSurface()).
|
||||
*
|
||||
* aPattern will be AddRef'd (as with most getters), so
|
||||
* getter_AddRefs should be used.
|
||||
*/
|
||||
NS_IMETHOD GetPattern(gfxPattern **aPattern) = 0;
|
||||
|
||||
/**
|
||||
* SetHasNoAlpha
|
||||
*
|
||||
* Hint to the image that all the pixels are fully opaque, even if
|
||||
* the original format requested a 1-bit or 8-bit alpha mask
|
||||
*/
|
||||
virtual void SetHasNoAlpha() = 0;
|
||||
|
||||
/**
|
||||
* Extract a rectangular region of the nsIImage and return it as a new
|
||||
* nsIImage.
|
||||
* @param aSubimage the region to extract
|
||||
* @param aResult the extracted image
|
||||
*/
|
||||
NS_IMETHOD Extract(const nsIntRect& aSubimage,
|
||||
nsIImage** aResult NS_OUTPARAM) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIImage, NS_IIMAGE_IID)
|
||||
|
||||
#endif
|
||||
|
|
@ -59,7 +59,7 @@ REQUIRES = xpcom \
|
|||
xpconnect \
|
||||
$(NULL)
|
||||
|
||||
DIRS = shared thebes
|
||||
DIRS = thebes
|
||||
|
||||
ifdef MOZ_ENABLE_POSTSCRIPT
|
||||
DIRS += psshared
|
||||
|
|
|
|||
|
|
@ -1,67 +0,0 @@
|
|||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2001
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = gfx
|
||||
LIBRARY_NAME = gfxshared_s
|
||||
FORCE_STATIC_LIB=1
|
||||
EXPORT_LIBRARY=1
|
||||
LIBXUL_LIBRARY = 1
|
||||
|
||||
REQUIRES= \
|
||||
xpcom \
|
||||
string \
|
||||
imglib2 \
|
||||
widget \
|
||||
thebes \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
gfxImageFrame.cpp \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES = -I$(srcdir)/.. \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
|
@ -1,428 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "gfxImageFrame.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include <limits.h>
|
||||
#include "prmem.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS2(gfxImageFrame, gfxIImageFrame, nsIInterfaceRequestor)
|
||||
|
||||
gfxImageFrame::gfxImageFrame() :
|
||||
mImageData(nsnull),
|
||||
mTimeout(100),
|
||||
mDisposalMethod(0), /* imgIContainer::kDisposeNotSpecified */
|
||||
mBlendMethod(1), /* imgIContainer::kBlendOver */
|
||||
mInitialized(PR_FALSE),
|
||||
mMutable(PR_TRUE)
|
||||
{
|
||||
/* member initializers and constructor code */
|
||||
}
|
||||
|
||||
gfxImageFrame::~gfxImageFrame()
|
||||
{
|
||||
/* destructor code */
|
||||
PR_FREEIF(mImageData);
|
||||
mInitialized = PR_FALSE;
|
||||
}
|
||||
|
||||
/* void init (in PRInt32 aX, in PRInt32 aY, in PRInt32 aWidth, in PRInt32 aHeight, in gfx_format aFormat); */
|
||||
NS_IMETHODIMP gfxImageFrame::Init(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, gfx_format aFormat,gfx_depth aDepth)
|
||||
{
|
||||
if (mInitialized)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// assert for properties that should be verified by decoders, warn for properties related to bad content
|
||||
|
||||
if (aWidth <= 0 || aHeight <= 0) {
|
||||
NS_ASSERTION(0, "error - negative image size\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* check to make sure we don't overflow a 32-bit */
|
||||
PRInt32 tmp = aWidth * aHeight;
|
||||
if (tmp / aHeight != aWidth) {
|
||||
NS_WARNING("width or height too large");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
tmp = tmp * 4;
|
||||
if (tmp / 4 != aWidth * aHeight) {
|
||||
NS_WARNING("width or height too large");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* reject over-wide or over-tall images */
|
||||
const PRInt32 k64KLimit = 0x0000FFFF;
|
||||
if ( aWidth > k64KLimit || aHeight > k64KLimit ){
|
||||
NS_WARNING("image too big");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
// CoreGraphics is limited to images < 32K in *height*, so clamp all surfaces on the Mac to that height
|
||||
if (aHeight > SHRT_MAX) {
|
||||
NS_WARNING("image too big");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
mOffset.MoveTo(aX, aY);
|
||||
mSize.SizeTo(aWidth, aHeight);
|
||||
|
||||
mFormat = aFormat;
|
||||
mDepth = aDepth;
|
||||
|
||||
PRBool needImage = PR_TRUE;
|
||||
nsMaskRequirements maskReq;
|
||||
|
||||
switch (aFormat) {
|
||||
case gfxIFormats::BGR:
|
||||
case gfxIFormats::RGB:
|
||||
maskReq = nsMaskRequirements_kNoMask;
|
||||
break;
|
||||
|
||||
case gfxIFormats::BGRA:
|
||||
case gfxIFormats::RGBA:
|
||||
maskReq = nsMaskRequirements_kNeeds8Bit;
|
||||
break;
|
||||
|
||||
case gfxIFormats::BGR_A1:
|
||||
case gfxIFormats::RGB_A1:
|
||||
maskReq = nsMaskRequirements_kNeeds1Bit;
|
||||
break;
|
||||
|
||||
case gfxIFormats::BGR_A8:
|
||||
case gfxIFormats::RGB_A8:
|
||||
maskReq = nsMaskRequirements_kNeeds8Bit;
|
||||
break;
|
||||
|
||||
case gfxIFormats::PAL:
|
||||
case gfxIFormats::PAL_A1:
|
||||
needImage = PR_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_ERROR("unsupported gfx_format\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (needImage) {
|
||||
if (aDepth != 24) {
|
||||
NS_ERROR("This Depth is not supported");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
mImage = do_CreateInstance("@mozilla.org/gfx/image;1", &rv);
|
||||
NS_ASSERTION(mImage, "creation of image failed");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = mImage->Init(aWidth, aHeight, aDepth, maskReq);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
if ((aDepth < 1) || (aDepth > 8)) {
|
||||
NS_ERROR("This Depth is not supported\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mImageData = (PRUint8*)PR_MALLOC(PaletteDataLength() + ImageDataLength());
|
||||
NS_ENSURE_TRUE(mImageData, NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
mInitialized = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/* attribute boolean mutable */
|
||||
NS_IMETHODIMP gfxImageFrame::GetMutable(PRBool *aMutable)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
NS_ASSERTION(mInitialized, "gfxImageFrame::GetMutable called on non-inited gfxImageFrame");
|
||||
*aMutable = mMutable;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP gfxImageFrame::SetMutable(PRBool aMutable)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
mMutable = aMutable;
|
||||
|
||||
if (!aMutable && mImage)
|
||||
mImage->Optimize(nsnull);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute PRInt32 x; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetX(PRInt32 *aX)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aX = mOffset.x;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute PRInt32 y; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetY(PRInt32 *aY)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aY = mOffset.y;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/* readonly attribute PRInt32 width; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetWidth(PRInt32 *aWidth)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aWidth = mSize.width;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute PRInt32 height; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetHeight(PRInt32 *aHeight)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aHeight = mSize.height;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void getRect(in nsRectRef rect); */
|
||||
NS_IMETHODIMP gfxImageFrame::GetRect(nsIntRect &aRect)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
aRect.SetRect(mOffset.x, mOffset.y, mSize.width, mSize.height);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute gfx_format format; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetFormat(gfx_format *aFormat)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aFormat = mFormat;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute boolean needsBackground; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetNeedsBackground(PRBool *aNeedsBackground)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aNeedsBackground = (mFormat != gfxIFormats::RGB &&
|
||||
mFormat != gfxIFormats::PAL &&
|
||||
mFormat != gfxIFormats::BGR) ||
|
||||
!mImage->GetIsImageComplete();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/* readonly attribute unsigned long imageBytesPerRow; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetImageBytesPerRow(PRUint32 *aBytesPerRow)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aBytesPerRow = mImage ? mImage->GetLineStride(): mSize.width;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute unsigned long imageDataLength; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetImageDataLength(PRUint32 *aBitsLength)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aBitsLength = ImageDataLength();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void getImageData([array, size_is(length)] out PRUint8 bits, out unsigned long length); */
|
||||
NS_IMETHODIMP gfxImageFrame::GetImageData(PRUint8 **aData, PRUint32 *length)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
NS_ASSERTION(mMutable, "trying to get data on an immutable frame");
|
||||
|
||||
*aData = mImage ? mImage->GetBits() : (mImageData + PaletteDataLength());
|
||||
*length = ImageDataLength();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void getPaletteData ([array, size_is (length)] out PRUint32 palette, out unsigned long length); */
|
||||
NS_IMETHODIMP gfxImageFrame::GetPaletteData(gfx_color **aPalette, PRUint32 *length)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
if (!mImageData)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*aPalette = (gfx_color*)mImageData;
|
||||
*length = PaletteDataLength();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void lockImageData (); */
|
||||
NS_IMETHODIMP gfxImageFrame::LockImageData()
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
if (!mImage)
|
||||
return NS_OK;
|
||||
return mImage->LockImagePixels(PR_FALSE);
|
||||
}
|
||||
|
||||
/* void unlockImageData (); */
|
||||
NS_IMETHODIMP gfxImageFrame::UnlockImageData()
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
if (!mImage)
|
||||
return NS_OK;
|
||||
return mImage->UnlockImagePixels(PR_FALSE);
|
||||
}
|
||||
|
||||
/* attribute long timeout; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetTimeout(PRInt32 *aTimeout)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
// Ensure a minimal time between updates so we don't throttle the UI thread.
|
||||
// consider 0 == unspecified and make it fast but not too fast. See bug
|
||||
// 125137, bug 139677, and bug 207059. The behavior of recent IE and Opera
|
||||
// versions seems to be:
|
||||
// IE 6/Win:
|
||||
// 10 - 50ms go 100ms
|
||||
// >50ms go correct speed
|
||||
// Opera 7 final/Win:
|
||||
// 10ms goes 100ms
|
||||
// >10ms go correct speed
|
||||
// It seems that there are broken tools out there that set a 0ms or 10ms
|
||||
// timeout when they really want a "default" one. So munge values in that
|
||||
// range.
|
||||
if (mTimeout >= 0 && mTimeout <= 10)
|
||||
*aTimeout = 100;
|
||||
else
|
||||
*aTimeout = mTimeout;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP gfxImageFrame::SetTimeout(PRInt32 aTimeout)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
mTimeout = aTimeout;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* attribute long frameDisposalMethod; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetFrameDisposalMethod(PRInt32 *aFrameDisposalMethod)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aFrameDisposalMethod = mDisposalMethod;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP gfxImageFrame::SetFrameDisposalMethod(PRInt32 aFrameDisposalMethod)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
mDisposalMethod = aFrameDisposalMethod;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* attribute long blendMethod; */
|
||||
NS_IMETHODIMP gfxImageFrame::GetBlendMethod(PRInt32 *aBlendMethod)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aBlendMethod = mBlendMethod;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP gfxImageFrame::SetBlendMethod(PRInt32 aBlendMethod)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
mBlendMethod = (PRInt8)aBlendMethod;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP gfxImageFrame::GetInterface(const nsIID & aIID, void * *result)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
|
||||
if (NS_SUCCEEDED(QueryInterface(aIID, result)))
|
||||
return NS_OK;
|
||||
if (mImage && aIID.Equals(NS_GET_IID(nsIImage)))
|
||||
return mImage->QueryInterface(aIID, result);
|
||||
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2000-2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
||||
#include "nsIImage.h"
|
||||
|
||||
#include "nsPoint.h"
|
||||
#include "nsSize.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#define GFX_IMAGEFRAME_CID \
|
||||
{ /* aa699204-1dd1-11b2-84a9-a280c268e4fb */ \
|
||||
0xaa699204, \
|
||||
0x1dd1, \
|
||||
0x11b2, \
|
||||
{0x84, 0xa9, 0xa2, 0x80, 0xc2, 0x68, 0xe4, 0xfb} \
|
||||
}
|
||||
|
||||
class gfxImageFrame : public gfxIImageFrame,
|
||||
public nsIInterfaceRequestor
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_GFXIIMAGEFRAME
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
||||
gfxImageFrame();
|
||||
virtual ~gfxImageFrame();
|
||||
|
||||
protected:
|
||||
nsIntSize mSize;
|
||||
|
||||
private:
|
||||
PRUint32 PaletteDataLength() const {
|
||||
return ((1 << mDepth) * sizeof(gfx_color));
|
||||
}
|
||||
|
||||
PRUint32 ImageDataLength() const {
|
||||
return (mImage ? mImage->GetLineStride() : mSize.width) * mSize.height;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIImage> mImage;
|
||||
PRUint8* mImageData;
|
||||
|
||||
PRInt32 mTimeout; // -1 means display forever
|
||||
nsIntPoint mOffset;
|
||||
PRInt32 mDisposalMethod;
|
||||
|
||||
gfx_format mFormat;
|
||||
gfx_depth mDepth;
|
||||
PRInt8 mBlendMethod;
|
||||
PRPackedBool mInitialized;
|
||||
PRPackedBool mMutable;
|
||||
};
|
||||
|
|
@ -72,7 +72,6 @@ endif
|
|||
|
||||
CPPSRCS = \
|
||||
nsThebesDeviceContext.cpp \
|
||||
nsThebesImage.cpp \
|
||||
nsThebesRegion.cpp \
|
||||
nsThebesGfxFactory.cpp \
|
||||
nsThebesRenderingContext.cpp \
|
||||
|
|
@ -128,7 +127,6 @@ LOCAL_INCLUDES = \
|
|||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS += \
|
||||
../shared/$(LIB_PREFIX)gfxshared_s.$(LIB_SUFFIX) \
|
||||
$(LIBS_DIR) \
|
||||
$(EXTRA_DSO_LIBS) \
|
||||
$(DEPTH)/modules/libutil/src/$(LIB_PREFIX)mozutil_s.$(LIB_SUFFIX) \
|
||||
|
|
|
|||
|
|
@ -42,21 +42,17 @@
|
|||
#include "nsGfxCIID.h"
|
||||
|
||||
#include "nsScriptableRegion.h"
|
||||
#include "gfxImageFrame.h"
|
||||
|
||||
#include "nsThebesDeviceContext.h"
|
||||
#include "nsThebesRenderingContext.h"
|
||||
#include "nsThebesImage.h"
|
||||
#include "nsThebesRegion.h"
|
||||
#include "nsThebesFontMetrics.h"
|
||||
#include "nsThebesFontEnumerator.h"
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesFontMetrics)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(gfxImageFrame)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesDeviceContext)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesRenderingContext)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesImage)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesRegion)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsThebesFontEnumerator)
|
||||
|
||||
|
|
@ -119,10 +115,6 @@ static const nsModuleComponentInfo components[] =
|
|||
NS_RENDERING_CONTEXT_CID,
|
||||
"@mozilla.org/gfx/renderingcontext;1",
|
||||
nsThebesRenderingContextConstructor },
|
||||
{ "Thebes nsImage",
|
||||
NS_IMAGE_CID,
|
||||
"@mozilla.org/gfx/image;1",
|
||||
nsThebesImageConstructor },
|
||||
{ "Thebes Region",
|
||||
NS_REGION_CID,
|
||||
"@mozilla.org/gfx/region/nsThebes;1",
|
||||
|
|
@ -131,10 +123,6 @@ static const nsModuleComponentInfo components[] =
|
|||
NS_SCRIPTABLE_REGION_CID,
|
||||
"@mozilla.org/gfx/region;1",
|
||||
nsScriptableRegionConstructor },
|
||||
{ "image frame",
|
||||
GFX_IMAGEFRAME_CID,
|
||||
"@mozilla.org/gfx/image/frame;2",
|
||||
gfxImageFrameConstructor },
|
||||
};
|
||||
|
||||
static nsresult
|
||||
|
|
|
|||
|
|
@ -1,857 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is thebes gfx
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* mozilla.org.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsThebesImage.h"
|
||||
#include "nsThebesRenderingContext.h"
|
||||
|
||||
#include "gfxContext.h"
|
||||
#include "gfxPattern.h"
|
||||
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
#include "prenv.h"
|
||||
|
||||
static PRBool gDisableOptimize = PR_FALSE;
|
||||
|
||||
/*XXX get CAIRO_HAS_DDRAW_SURFACE */
|
||||
#include "cairo.h"
|
||||
|
||||
#ifdef CAIRO_HAS_DDRAW_SURFACE
|
||||
#include "gfxDDrawSurface.h"
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN) || defined(WINCE)
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN) && !defined(WINCE)
|
||||
|
||||
/* Whether to use the windows surface; only for desktop win32 */
|
||||
#define USE_WIN_SURFACE 1
|
||||
|
||||
static PRUint32 gTotalDDBs = 0;
|
||||
static PRUint32 gTotalDDBSize = 0;
|
||||
// only use up a maximum of 64MB in DDBs
|
||||
#define kMaxDDBSize (64*1024*1024)
|
||||
// and don't let anything in that's bigger than 4MB
|
||||
#define kMaxSingleDDBSize (4*1024*1024)
|
||||
|
||||
#endif
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsThebesImage, nsIImage)
|
||||
|
||||
nsThebesImage::nsThebesImage()
|
||||
: mFormat(gfxImageSurface::ImageFormatRGB24),
|
||||
mWidth(0),
|
||||
mHeight(0),
|
||||
mDecoded(0,0,0,0),
|
||||
mImageComplete(PR_FALSE),
|
||||
mSinglePixel(PR_FALSE),
|
||||
mFormatChanged(PR_FALSE),
|
||||
mNeverUseDeviceSurface(PR_FALSE),
|
||||
mSinglePixelColor(0),
|
||||
mAlphaDepth(0)
|
||||
{
|
||||
static PRBool hasCheckedOptimize = PR_FALSE;
|
||||
if (!hasCheckedOptimize) {
|
||||
if (PR_GetEnv("MOZ_DISABLE_IMAGE_OPTIMIZE")) {
|
||||
gDisableOptimize = PR_TRUE;
|
||||
}
|
||||
hasCheckedOptimize = PR_TRUE;
|
||||
}
|
||||
|
||||
#ifdef USE_WIN_SURFACE
|
||||
mIsDDBSurface = PR_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsThebesImage::Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements)
|
||||
{
|
||||
mWidth = aWidth;
|
||||
mHeight = aHeight;
|
||||
|
||||
// Reject over-wide or over-tall images.
|
||||
if (!AllowedImageSize(aWidth, aHeight))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Check to see if we are running OOM
|
||||
nsCOMPtr<nsIMemory> mem;
|
||||
NS_GetMemoryManager(getter_AddRefs(mem));
|
||||
if (!mem)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
PRBool lowMemory;
|
||||
mem->IsLowMemory(&lowMemory);
|
||||
if (lowMemory)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
gfxImageSurface::gfxImageFormat format;
|
||||
switch(aMaskRequirements)
|
||||
{
|
||||
case nsMaskRequirements_kNeeds1Bit:
|
||||
format = gfxImageSurface::ImageFormatARGB32;
|
||||
mAlphaDepth = 1;
|
||||
break;
|
||||
case nsMaskRequirements_kNeeds8Bit:
|
||||
format = gfxImageSurface::ImageFormatARGB32;
|
||||
mAlphaDepth = 8;
|
||||
break;
|
||||
default:
|
||||
format = gfxImageSurface::ImageFormatRGB24;
|
||||
mAlphaDepth = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
mFormat = format;
|
||||
|
||||
// For Windows, we must create the device surface first (if we're
|
||||
// going to) so that the image surface can wrap it. Can't be done
|
||||
// the other way around.
|
||||
#ifdef USE_WIN_SURFACE
|
||||
if (!mNeverUseDeviceSurface && !ShouldUseImageSurfaces()) {
|
||||
mWinSurface = new gfxWindowsSurface(gfxIntSize(mWidth, mHeight), format);
|
||||
if (mWinSurface && mWinSurface->CairoStatus() == 0) {
|
||||
// no error
|
||||
mImageSurface = mWinSurface->GetImageSurface();
|
||||
} else {
|
||||
mWinSurface = nsnull;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// For other platforms we create the image surface first and then
|
||||
// possibly wrap it in a device surface. This branch is also used
|
||||
// on Windows if we're not using device surfaces or if we couldn't
|
||||
// create one.
|
||||
if (!mImageSurface)
|
||||
mImageSurface = new gfxImageSurface(gfxIntSize(mWidth, mHeight), format);
|
||||
|
||||
if (!mImageSurface || mImageSurface->CairoStatus()) {
|
||||
mImageSurface = nsnull;
|
||||
// guess
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (!mNeverUseDeviceSurface && !ShouldUseImageSurfaces()) {
|
||||
mQuartzSurface = new gfxQuartzImageSurface(mImageSurface);
|
||||
}
|
||||
#endif
|
||||
|
||||
mStride = mImageSurface->Stride();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsThebesImage::~nsThebesImage()
|
||||
{
|
||||
#ifdef USE_WIN_SURFACE
|
||||
if (mIsDDBSurface) {
|
||||
gTotalDDBs--;
|
||||
gTotalDDBSize -= mWidth*mHeight*4;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsThebesImage::GetBytesPix()
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsThebesImage::GetIsRowOrderTopToBottom()
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsThebesImage::GetWidth()
|
||||
{
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsThebesImage::GetHeight()
|
||||
{
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
PRUint8 *
|
||||
nsThebesImage::GetBits()
|
||||
{
|
||||
if (mImageSurface)
|
||||
return mImageSurface->Data();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsThebesImage::GetLineStride()
|
||||
{
|
||||
return mStride;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsThebesImage::GetHasAlphaMask()
|
||||
{
|
||||
return mAlphaDepth > 0;
|
||||
}
|
||||
|
||||
PRUint8 *
|
||||
nsThebesImage::GetAlphaBits()
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsThebesImage::GetAlphaLineStride()
|
||||
{
|
||||
return (mAlphaDepth > 0) ? mStride : 0;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsThebesImage::ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsIntRect *aUpdateRect)
|
||||
{
|
||||
// Check to see if we are running OOM
|
||||
nsCOMPtr<nsIMemory> mem;
|
||||
NS_GetMemoryManager(getter_AddRefs(mem));
|
||||
if (!mem)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
PRBool lowMemory;
|
||||
mem->IsLowMemory(&lowMemory);
|
||||
if (lowMemory)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mDecoded.UnionRect(mDecoded, *aUpdateRect);
|
||||
|
||||
// clamp to bounds, in case someone sends a bogus
|
||||
// updateRect (I'm looking at you, gif decoder)
|
||||
nsIntRect boundsRect(0, 0, mWidth, mHeight);
|
||||
mDecoded.IntersectRect(mDecoded, boundsRect);
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (mQuartzSurface)
|
||||
mQuartzSurface->Flush();
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsThebesImage::GetIsImageComplete()
|
||||
{
|
||||
if (!mImageComplete)
|
||||
mImageComplete = (mDecoded == nsIntRect(0, 0, mWidth, mHeight));
|
||||
return mImageComplete;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsThebesImage::Optimize(nsIDeviceContext* aContext)
|
||||
{
|
||||
if (gDisableOptimize)
|
||||
return NS_OK;
|
||||
|
||||
if (mOptSurface || mSinglePixel)
|
||||
return NS_OK;
|
||||
|
||||
/* Figure out if the entire image is a constant color */
|
||||
|
||||
// this should always be true
|
||||
if (mStride == mWidth * 4) {
|
||||
PRUint32 *imgData = (PRUint32*) mImageSurface->Data();
|
||||
PRUint32 firstPixel = * (PRUint32*) imgData;
|
||||
PRUint32 pixelCount = mWidth * mHeight + 1;
|
||||
|
||||
while (--pixelCount && *imgData++ == firstPixel)
|
||||
;
|
||||
|
||||
if (pixelCount == 0) {
|
||||
// all pixels were the same
|
||||
if (mFormat == gfxImageSurface::ImageFormatARGB32 ||
|
||||
mFormat == gfxImageSurface::ImageFormatRGB24)
|
||||
{
|
||||
mSinglePixelColor = gfxRGBA
|
||||
(firstPixel,
|
||||
(mFormat == gfxImageSurface::ImageFormatRGB24 ?
|
||||
gfxRGBA::PACKED_XRGB :
|
||||
gfxRGBA::PACKED_ARGB_PREMULTIPLIED));
|
||||
|
||||
mSinglePixel = PR_TRUE;
|
||||
|
||||
// blow away the older surfaces, to release data
|
||||
|
||||
mImageSurface = nsnull;
|
||||
mOptSurface = nsnull;
|
||||
#ifdef USE_WIN_SURFACE
|
||||
mWinSurface = nsnull;
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
mQuartzSurface = nsnull;
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// if it's not RGB24/ARGB32, don't optimize, but we never hit this at the moment
|
||||
}
|
||||
|
||||
// if we're being forced to use image surfaces due to
|
||||
// resource constraints, don't try to optimize beyond same-pixel.
|
||||
if (mNeverUseDeviceSurface || ShouldUseImageSurfaces())
|
||||
return NS_OK;
|
||||
|
||||
mOptSurface = nsnull;
|
||||
|
||||
#ifdef USE_WIN_SURFACE
|
||||
// we need to special-case windows here, because windows has
|
||||
// a distinction between DIB and DDB and we want to use DDBs as much
|
||||
// as we can.
|
||||
if (mWinSurface) {
|
||||
// Don't do DDBs for large images; see bug 359147
|
||||
// Note that we bother with DDBs at all because they are much faster
|
||||
// on some systems; on others there isn't much of a speed difference
|
||||
// between DIBs and DDBs.
|
||||
//
|
||||
// Originally this just limited to 1024x1024; but that still
|
||||
// had us hitting overall total memory usage limits (which was
|
||||
// around 220MB on my intel shared memory system with 2GB RAM
|
||||
// and 16-128mb in use by the video card, so I can't make
|
||||
// heads or tails out of this limit).
|
||||
//
|
||||
// So instead, we clamp the max size to 64MB (this limit shuld
|
||||
// be made dynamic based on.. something.. as soon a we figure
|
||||
// out that something) and also limit each individual image to
|
||||
// be less than 4MB to keep very large images out of DDBs.
|
||||
|
||||
// assume (almost -- we don't quadword-align) worst-case size
|
||||
PRUint32 ddbSize = mWidth * mHeight * 4;
|
||||
if (ddbSize <= kMaxSingleDDBSize &&
|
||||
ddbSize + gTotalDDBSize <= kMaxDDBSize)
|
||||
{
|
||||
nsRefPtr<gfxWindowsSurface> wsurf = mWinSurface->OptimizeToDDB(nsnull, gfxIntSize(mWidth, mHeight), mFormat);
|
||||
if (wsurf) {
|
||||
gTotalDDBs++;
|
||||
gTotalDDBSize += ddbSize;
|
||||
mIsDDBSurface = PR_TRUE;
|
||||
mOptSurface = wsurf;
|
||||
}
|
||||
}
|
||||
if (!mOptSurface && !mFormatChanged) {
|
||||
// just use the DIB if the format has not changed
|
||||
mOptSurface = mWinSurface;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (mQuartzSurface) {
|
||||
mQuartzSurface->Flush();
|
||||
mOptSurface = mQuartzSurface;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mOptSurface == nsnull)
|
||||
mOptSurface = gfxPlatform::GetPlatform()->OptimizeImage(mImageSurface, mFormat);
|
||||
|
||||
if (mOptSurface) {
|
||||
mImageSurface = nsnull;
|
||||
#ifdef USE_WIN_SURFACE
|
||||
mWinSurface = nsnull;
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
mQuartzSurface = nsnull;
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsColorMap *
|
||||
nsThebesImage::GetColorMap()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PRInt8
|
||||
nsThebesImage::GetAlphaDepth()
|
||||
{
|
||||
return mAlphaDepth;
|
||||
}
|
||||
|
||||
void *
|
||||
nsThebesImage::GetBitInfo()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesImage::LockImagePixels(PRBool aMaskPixels)
|
||||
{
|
||||
if (aMaskPixels)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
if ((mOptSurface || mSinglePixel) && !mImageSurface) {
|
||||
// Recover the pixels
|
||||
mImageSurface = new gfxImageSurface(gfxIntSize(mWidth, mHeight),
|
||||
gfxImageSurface::ImageFormatARGB32);
|
||||
if (!mImageSurface || mImageSurface->CairoStatus())
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
gfxContext context(mImageSurface);
|
||||
context.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
if (mSinglePixel)
|
||||
context.SetDeviceColor(mSinglePixelColor);
|
||||
else
|
||||
context.SetSource(mOptSurface);
|
||||
context.Paint();
|
||||
|
||||
#ifdef USE_WIN_SURFACE
|
||||
mWinSurface = nsnull;
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
mQuartzSurface = nsnull;
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsThebesImage::UnlockImagePixels(PRBool aMaskPixels)
|
||||
{
|
||||
if (aMaskPixels)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
mOptSurface = nsnull;
|
||||
#ifdef XP_MACOSX
|
||||
if (mQuartzSurface)
|
||||
mQuartzSurface->Flush();
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
IsSafeImageTransformComponent(gfxFloat aValue)
|
||||
{
|
||||
return aValue >= -32768 && aValue <= 32767;
|
||||
}
|
||||
|
||||
void
|
||||
nsThebesImage::Draw(gfxContext* aContext,
|
||||
gfxPattern::GraphicsFilter aFilter,
|
||||
const gfxMatrix& aUserSpaceToImageSpace,
|
||||
const gfxRect& aFill,
|
||||
const nsIntMargin& aPadding,
|
||||
const nsIntRect& aSubimage)
|
||||
{
|
||||
NS_ASSERTION(!aFill.IsEmpty(), "zero dest size --- fix caller");
|
||||
NS_ASSERTION(!aSubimage.IsEmpty(), "zero source size --- fix caller");
|
||||
|
||||
PRBool doPadding = aPadding != nsIntMargin(0,0,0,0);
|
||||
PRBool doPartialDecode = !GetIsImageComplete();
|
||||
gfxContext::GraphicsOperator op = aContext->CurrentOperator();
|
||||
|
||||
if (mSinglePixel && !doPadding && !doPartialDecode) {
|
||||
// Single-color fast path
|
||||
// if a == 0, it's a noop
|
||||
if (mSinglePixelColor.a == 0.0)
|
||||
return;
|
||||
|
||||
if (op == gfxContext::OPERATOR_OVER && mSinglePixelColor.a == 1.0)
|
||||
aContext->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
|
||||
aContext->SetDeviceColor(mSinglePixelColor);
|
||||
aContext->NewPath();
|
||||
aContext->Rectangle(aFill);
|
||||
aContext->Fill();
|
||||
aContext->SetOperator(op);
|
||||
aContext->SetDeviceColor(gfxRGBA(0,0,0,0));
|
||||
return;
|
||||
}
|
||||
|
||||
gfxMatrix userSpaceToImageSpace = aUserSpaceToImageSpace;
|
||||
gfxRect sourceRect = userSpaceToImageSpace.Transform(aFill);
|
||||
gfxRect imageRect(0, 0, mWidth + aPadding.LeftRight(), mHeight + aPadding.TopBottom());
|
||||
gfxRect subimage(aSubimage.x, aSubimage.y, aSubimage.width, aSubimage.height);
|
||||
gfxRect fill = aFill;
|
||||
nsRefPtr<gfxASurface> surface;
|
||||
gfxImageSurface::gfxImageFormat format;
|
||||
|
||||
NS_ASSERTION(!sourceRect.Intersect(subimage).IsEmpty(),
|
||||
"We must be allowed to sample *some* source pixels!");
|
||||
|
||||
PRBool doTile = !imageRect.Contains(sourceRect);
|
||||
if (doPadding || doPartialDecode) {
|
||||
gfxRect available = gfxRect(mDecoded.x, mDecoded.y, mDecoded.width, mDecoded.height) +
|
||||
gfxPoint(aPadding.left, aPadding.top);
|
||||
|
||||
if (!doTile && !mSinglePixel) {
|
||||
// Not tiling, and we have a surface, so we can account for
|
||||
// padding and/or a partial decode just by twiddling parameters.
|
||||
// First, update our user-space fill rect.
|
||||
sourceRect = sourceRect.Intersect(available);
|
||||
gfxMatrix imageSpaceToUserSpace = userSpaceToImageSpace;
|
||||
imageSpaceToUserSpace.Invert();
|
||||
fill = imageSpaceToUserSpace.Transform(sourceRect);
|
||||
|
||||
surface = ThebesSurface();
|
||||
format = mFormat;
|
||||
subimage = subimage.Intersect(available) - gfxPoint(aPadding.left, aPadding.top);
|
||||
userSpaceToImageSpace.Multiply(
|
||||
gfxMatrix().Translate(-gfxPoint(aPadding.left, aPadding.top)));
|
||||
sourceRect = sourceRect - gfxPoint(aPadding.left, aPadding.top);
|
||||
imageRect = gfxRect(0, 0, mWidth, mHeight);
|
||||
} else {
|
||||
// Create a temporary surface
|
||||
gfxIntSize size(PRInt32(imageRect.Width()),
|
||||
PRInt32(imageRect.Height()));
|
||||
// Give this surface an alpha channel because there are
|
||||
// transparent pixels in the padding or undecoded area
|
||||
format = gfxASurface::ImageFormatARGB32;
|
||||
surface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(size,
|
||||
format);
|
||||
if (!surface || surface->CairoStatus() != 0)
|
||||
return;
|
||||
|
||||
// Fill 'available' with whatever we've got
|
||||
gfxContext tmpCtx(surface);
|
||||
tmpCtx.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
if (mSinglePixel) {
|
||||
tmpCtx.SetDeviceColor(mSinglePixelColor);
|
||||
} else {
|
||||
tmpCtx.SetSource(ThebesSurface(), gfxPoint(aPadding.left, aPadding.top));
|
||||
}
|
||||
tmpCtx.Rectangle(available);
|
||||
tmpCtx.Fill();
|
||||
}
|
||||
} else {
|
||||
NS_ASSERTION(!mSinglePixel, "This should already have been handled");
|
||||
surface = ThebesSurface();
|
||||
format = mFormat;
|
||||
}
|
||||
// At this point, we've taken care of mSinglePixel images, images with
|
||||
// aPadding, and partially-decoded images.
|
||||
|
||||
if (!AllowedImageSize(fill.size.width + 1, fill.size.height + 1)) {
|
||||
NS_WARNING("Destination area too large, bailing out");
|
||||
return;
|
||||
}
|
||||
// Compute device-space-to-image-space transform. We need to sanity-
|
||||
// check it to work around a pixman bug :-(
|
||||
// XXX should we only do this for certain surface types?
|
||||
gfxFloat deviceX, deviceY;
|
||||
nsRefPtr<gfxASurface> currentTarget =
|
||||
aContext->CurrentSurface(&deviceX, &deviceY);
|
||||
gfxMatrix currentMatrix = aContext->CurrentMatrix();
|
||||
gfxMatrix deviceToUser = currentMatrix;
|
||||
deviceToUser.Invert();
|
||||
deviceToUser.Translate(-gfxPoint(-deviceX, -deviceY));
|
||||
gfxMatrix deviceToImage = deviceToUser;
|
||||
deviceToImage.Multiply(userSpaceToImageSpace);
|
||||
|
||||
PRBool pushedGroup = PR_FALSE;
|
||||
if (currentTarget->GetType() != gfxASurface::SurfaceTypeQuartz) {
|
||||
// BEGIN working around cairo/pixman bug (bug 364968)
|
||||
// Quartz's limits for matrix are much larger than pixman
|
||||
|
||||
// Our device-space-to-image-space transform may not be acceptable to pixman.
|
||||
if (!IsSafeImageTransformComponent(deviceToImage.xx) ||
|
||||
!IsSafeImageTransformComponent(deviceToImage.xy) ||
|
||||
!IsSafeImageTransformComponent(deviceToImage.yx) ||
|
||||
!IsSafeImageTransformComponent(deviceToImage.yy)) {
|
||||
NS_WARNING("Scaling up too much, bailing out");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsSafeImageTransformComponent(deviceToImage.x0) ||
|
||||
!IsSafeImageTransformComponent(deviceToImage.y0)) {
|
||||
// We'll push a group, which will hopefully reduce our transform's
|
||||
// translation so it's in bounds
|
||||
aContext->Save();
|
||||
|
||||
// Clip the rounded-out-to-device-pixels bounds of the
|
||||
// transformed fill area. This is the area for the group we
|
||||
// want to push.
|
||||
aContext->IdentityMatrix();
|
||||
gfxRect bounds = currentMatrix.TransformBounds(fill);
|
||||
bounds.RoundOut();
|
||||
aContext->Clip(bounds);
|
||||
aContext->SetMatrix(currentMatrix);
|
||||
|
||||
aContext->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
|
||||
aContext->SetOperator(gfxContext::OPERATOR_OVER);
|
||||
pushedGroup = PR_TRUE;
|
||||
}
|
||||
// END working around cairo/pixman bug (bug 364968)
|
||||
}
|
||||
|
||||
nsRefPtr<gfxPattern> pattern = new gfxPattern(surface);
|
||||
pattern->SetMatrix(userSpaceToImageSpace);
|
||||
|
||||
// OK now, the hard part left is to account for the subimage sampling
|
||||
// restriction. If all the transforms involved are just integer
|
||||
// translations, then we assume no resampling will occur so there's
|
||||
// nothing to do.
|
||||
// XXX if only we had source-clipping in cairo!
|
||||
if (!currentMatrix.HasNonIntegerTranslation() &&
|
||||
!userSpaceToImageSpace.HasNonIntegerTranslation()) {
|
||||
if (doTile) {
|
||||
pattern->SetExtend(gfxPattern::EXTEND_REPEAT);
|
||||
}
|
||||
} else {
|
||||
if (doTile || !subimage.Contains(imageRect)) {
|
||||
// EXTEND_PAD won't help us here; we have to create a temporary
|
||||
// surface to hold the subimage of pixels we're allowed to
|
||||
// sample
|
||||
|
||||
gfxRect userSpaceClipExtents = aContext->GetClipExtents();
|
||||
// This isn't optimal --- if aContext has a rotation then
|
||||
// GetClipExtents will have to do a bounding-box computation,
|
||||
// and TransformBounds might too, so we could get a better
|
||||
// result if we computed image space clip extents in one go
|
||||
// --- but it doesn't really matter and this is easier to
|
||||
// understand.
|
||||
gfxRect imageSpaceClipExtents =
|
||||
userSpaceToImageSpace.TransformBounds(userSpaceClipExtents);
|
||||
// Inflate by one pixel because bilinear filtering will sample
|
||||
// at most one pixel beyond the computed image pixel coordinate.
|
||||
imageSpaceClipExtents.Outset(1.0);
|
||||
|
||||
gfxRect needed =
|
||||
imageSpaceClipExtents.Intersect(sourceRect).Intersect(subimage);
|
||||
needed.RoundOut();
|
||||
// if 'needed' is empty, nothing will be drawn since aFill
|
||||
// must be entirely outside the clip region, so it doesn't
|
||||
// matter what we do here, but we should avoid trying to
|
||||
// create a zero-size surface.
|
||||
if (!needed.IsEmpty()) {
|
||||
gfxIntSize size(PRInt32(needed.Width()), PRInt32(needed.Height()));
|
||||
nsRefPtr<gfxASurface> temp =
|
||||
gfxPlatform::GetPlatform()->CreateOffscreenSurface(size, format);
|
||||
if (temp && temp->CairoStatus() == 0) {
|
||||
gfxContext tmpCtx(temp);
|
||||
tmpCtx.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
nsRefPtr<gfxPattern> tmpPattern = new gfxPattern(surface);
|
||||
if (tmpPattern) {
|
||||
tmpPattern->SetExtend(gfxPattern::EXTEND_REPEAT);
|
||||
tmpPattern->SetMatrix(gfxMatrix().Translate(needed.pos));
|
||||
tmpCtx.SetPattern(tmpPattern);
|
||||
tmpCtx.Paint();
|
||||
tmpPattern = new gfxPattern(temp);
|
||||
if (tmpPattern) {
|
||||
pattern.swap(tmpPattern);
|
||||
pattern->SetMatrix(
|
||||
gfxMatrix(userSpaceToImageSpace).Multiply(gfxMatrix().Translate(-needed.pos)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// In theory we can handle this using cairo's EXTEND_PAD,
|
||||
// but implementation limitations mean we have to consult
|
||||
// the surface type.
|
||||
switch (currentTarget->GetType()) {
|
||||
case gfxASurface::SurfaceTypeXlib:
|
||||
case gfxASurface::SurfaceTypeXcb: {
|
||||
// See bug 324698. This is a workaround for EXTEND_PAD not being
|
||||
// implemented correctly on linux in the X server.
|
||||
//
|
||||
// Set the filter to CAIRO_FILTER_FAST --- otherwise,
|
||||
// pixman's sampling will sample transparency for the outside edges and we'll
|
||||
// get blurry edges. CAIRO_EXTEND_PAD would also work here, if
|
||||
// available
|
||||
//
|
||||
// But don't do this for simple downscales because it's horrible.
|
||||
// Downscaling means that device-space coordinates are
|
||||
// scaled *up* to find the image pixel coordinates.
|
||||
//
|
||||
// deviceToImage is slightly stale because up above we may
|
||||
// have adjusted the pattern's matrix ... but the adjustment
|
||||
// is only a translation so the scale factors in deviceToImage
|
||||
// are still valid.
|
||||
PRBool isDownscale =
|
||||
deviceToImage.xx >= 1.0 && deviceToImage.yy >= 1.0 &&
|
||||
deviceToImage.xy == 0.0 && deviceToImage.yx == 0.0;
|
||||
if (!isDownscale) {
|
||||
pattern->SetFilter(gfxPattern::FILTER_FAST);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case gfxASurface::SurfaceTypeQuartz:
|
||||
case gfxASurface::SurfaceTypeQuartzImage:
|
||||
// Don't set EXTEND_PAD, Mac seems to be OK. Really?
|
||||
pattern->SetFilter(aFilter);
|
||||
break;
|
||||
|
||||
default:
|
||||
// turn on EXTEND_PAD.
|
||||
// This is what we really want for all surface types, if the
|
||||
// implementation was universally good.
|
||||
pattern->SetExtend(gfxPattern::EXTEND_PAD);
|
||||
pattern->SetFilter(aFilter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((op == gfxContext::OPERATOR_OVER || pushedGroup) &&
|
||||
format == gfxASurface::ImageFormatRGB24) {
|
||||
aContext->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
}
|
||||
|
||||
// Phew! Now we can actually draw this image
|
||||
aContext->NewPath();
|
||||
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
pattern->SetFilter(gfxPattern::FILTER_FAST);
|
||||
#endif
|
||||
aContext->SetPattern(pattern);
|
||||
aContext->Rectangle(fill);
|
||||
aContext->Fill();
|
||||
|
||||
aContext->SetOperator(op);
|
||||
if (pushedGroup) {
|
||||
aContext->PopGroupToSource();
|
||||
aContext->Paint();
|
||||
aContext->Restore();
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsThebesImage::Extract(const nsIntRect& aRegion,
|
||||
nsIImage** aResult)
|
||||
{
|
||||
nsRefPtr<nsThebesImage> subImage(new nsThebesImage());
|
||||
if (!subImage)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// The scaling problems described in bug 468496 are especially
|
||||
// likely to be visible for the sub-image, as at present the only
|
||||
// user is the border-image code and border-images tend to get
|
||||
// stretched a lot. At the same time, the performance concerns
|
||||
// that prevent us from just using Cairo's fallback scaler when
|
||||
// accelerated graphics won't cut it are less relevant to such
|
||||
// images, since they also tend to be small. Thus, we forcibly
|
||||
// disable the use of anything other than a client-side image
|
||||
// surface for the sub-image; this ensures that the correct
|
||||
// (albeit slower) Cairo fallback scaler will be used.
|
||||
subImage->mNeverUseDeviceSurface = PR_TRUE;
|
||||
|
||||
// ->Init() is just going to convert this back, bleah.
|
||||
nsMaskRequirements maskReq;
|
||||
switch (mAlphaDepth) {
|
||||
case 0: maskReq = nsMaskRequirements_kNoMask; break;
|
||||
case 1: maskReq = nsMaskRequirements_kNeeds1Bit; break;
|
||||
case 8: maskReq = nsMaskRequirements_kNeeds8Bit; break;
|
||||
default:
|
||||
NS_NOTREACHED("impossible alpha depth");
|
||||
maskReq = nsMaskRequirements_kNeeds8Bit; // safe
|
||||
}
|
||||
|
||||
nsresult rv = subImage->Init(aRegion.width, aRegion.height,
|
||||
8 /* ignored */, maskReq);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
{ // scope to destroy ctx
|
||||
gfxContext ctx(subImage->ThebesSurface());
|
||||
ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
if (mSinglePixel) {
|
||||
ctx.SetDeviceColor(mSinglePixelColor);
|
||||
} else {
|
||||
// SetSource() places point (0,0) of its first argument at
|
||||
// the coordinages given by its second argument. We want
|
||||
// (x,y) of the image to be (0,0) of source space, so we
|
||||
// put (0,0) of the image at (-x,-y).
|
||||
ctx.SetSource(this->ThebesSurface(),
|
||||
gfxPoint(-aRegion.x, -aRegion.y));
|
||||
}
|
||||
ctx.Rectangle(gfxRect(0, 0, aRegion.width, aRegion.height));
|
||||
ctx.Fill();
|
||||
}
|
||||
|
||||
nsIntRect filled(0, 0, aRegion.width, aRegion.height);
|
||||
subImage->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &filled);
|
||||
subImage->Optimize(nsnull);
|
||||
|
||||
NS_ADDREF(*aResult = subImage);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsThebesImage::ShouldUseImageSurfaces()
|
||||
{
|
||||
#if defined(WINCE)
|
||||
// There is no test on windows mobile to check for Gui resources.
|
||||
// Allocate, until we run out of memory.
|
||||
gfxWindowsPlatform::RenderMode rmode = gfxWindowsPlatform::GetPlatform()->GetRenderMode();
|
||||
return rmode != gfxWindowsPlatform::RENDER_DDRAW &&
|
||||
rmode != gfxWindowsPlatform::RENDER_DDRAW_GL;
|
||||
|
||||
#elif defined(USE_WIN_SURFACE)
|
||||
static const DWORD kGDIObjectsHighWaterMark = 7000;
|
||||
|
||||
// at 7000 GDI objects, stop allocating normal images to make sure
|
||||
// we never hit the 10k hard limit.
|
||||
// GetCurrentProcess() just returns (HANDLE)-1, it's inlined afaik
|
||||
DWORD count = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS);
|
||||
if (count == 0 ||
|
||||
count > kGDIObjectsHighWaterMark)
|
||||
{
|
||||
// either something's broken (count == 0),
|
||||
// or we hit our high water mark; disable
|
||||
// image allocations for a bit.
|
||||
return PR_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// A hint from the image decoders that this image has no alpha, even
|
||||
// though we created is ARGB32. This changes our format to RGB24,
|
||||
// which in turn will cause us to Optimize() to RGB24. Has no effect
|
||||
// after Optimize() is called, though in all cases it will be just a
|
||||
// performance win -- the pixels are still correct and have the A byte
|
||||
// set to 0xff.
|
||||
void
|
||||
nsThebesImage::SetHasNoAlpha()
|
||||
{
|
||||
if (mFormat == gfxASurface::ImageFormatARGB32) {
|
||||
mFormat = gfxASurface::ImageFormatRGB24;
|
||||
mFormatChanged = PR_TRUE;
|
||||
mAlphaDepth = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,187 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is thebes gfx
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* mozilla.org.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef _NSTHEBESIMAGE_H_
|
||||
#define _NSTHEBESIMAGE_H_
|
||||
|
||||
#include "nsIImage.h"
|
||||
|
||||
#include "gfxColor.h"
|
||||
#include "gfxASurface.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxPattern.h"
|
||||
#if defined(XP_WIN)
|
||||
#include "gfxWindowsSurface.h"
|
||||
#elif defined(XP_MACOSX)
|
||||
#include "gfxQuartzImageSurface.h"
|
||||
#endif
|
||||
|
||||
class nsThebesImage : public nsIImage
|
||||
{
|
||||
public:
|
||||
nsThebesImage();
|
||||
~nsThebesImage();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight,
|
||||
PRInt32 aDepth, nsMaskRequirements aMaskRequirements);
|
||||
virtual PRInt32 GetBytesPix();
|
||||
virtual PRBool GetIsRowOrderTopToBottom();
|
||||
virtual PRInt32 GetWidth();
|
||||
virtual PRInt32 GetHeight();
|
||||
virtual PRUint8 *GetBits();
|
||||
virtual PRInt32 GetLineStride();
|
||||
virtual PRBool GetHasAlphaMask();
|
||||
virtual PRUint8 *GetAlphaBits();
|
||||
virtual PRInt32 GetAlphaLineStride();
|
||||
virtual PRBool GetIsImageComplete();
|
||||
virtual nsresult ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsIntRect *aUpdateRect);
|
||||
virtual nsresult Optimize(nsIDeviceContext* aContext);
|
||||
virtual nsColorMap *GetColorMap();
|
||||
|
||||
virtual void Draw(gfxContext* aContext,
|
||||
gfxPattern::GraphicsFilter aFilter,
|
||||
const gfxMatrix& aUserSpaceToImageSpace,
|
||||
const gfxRect& aFill,
|
||||
const nsIntMargin& aPadding,
|
||||
const nsIntRect& aSubimage);
|
||||
|
||||
virtual PRInt8 GetAlphaDepth();
|
||||
virtual void* GetBitInfo();
|
||||
NS_IMETHOD LockImagePixels(PRBool aMaskPixels);
|
||||
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
|
||||
|
||||
NS_IMETHOD GetSurface(gfxASurface **aSurface) {
|
||||
*aSurface = ThebesSurface();
|
||||
NS_ADDREF(*aSurface);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetPattern(gfxPattern **aPattern) {
|
||||
if (mSinglePixel)
|
||||
*aPattern = new gfxPattern(mSinglePixelColor);
|
||||
else
|
||||
*aPattern = new gfxPattern(ThebesSurface());
|
||||
NS_ADDREF(*aPattern);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
gfxASurface* ThebesSurface() {
|
||||
if (mOptSurface)
|
||||
return mOptSurface;
|
||||
#if defined(XP_WIN) && !defined(WINCE)
|
||||
if (mWinSurface)
|
||||
return mWinSurface;
|
||||
#elif defined(XP_MACOSX)
|
||||
if (mQuartzSurface)
|
||||
return mQuartzSurface;
|
||||
#endif
|
||||
return mImageSurface;
|
||||
}
|
||||
|
||||
void SetHasNoAlpha();
|
||||
|
||||
NS_IMETHOD Extract(const nsIntRect& aSubimage,
|
||||
nsIImage** aResult NS_OUTPARAM);
|
||||
|
||||
protected:
|
||||
static PRBool AllowedImageSize(PRInt32 aWidth, PRInt32 aHeight) {
|
||||
NS_ASSERTION(aWidth > 0, "invalid image width");
|
||||
NS_ASSERTION(aHeight > 0, "invalid image height");
|
||||
|
||||
// reject over-wide or over-tall images
|
||||
const PRInt32 k64KLimit = 0x0000FFFF;
|
||||
if (NS_UNLIKELY(aWidth > k64KLimit || aHeight > k64KLimit )) {
|
||||
NS_WARNING("image too big");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// protect against division by zero - this really shouldn't happen
|
||||
// if our consumers were well behaved, but they aren't (bug 368427)
|
||||
if (NS_UNLIKELY(aHeight == 0)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// check to make sure we don't overflow a 32-bit
|
||||
PRInt32 tmp = aWidth * aHeight;
|
||||
if (NS_UNLIKELY(tmp / aHeight != aWidth)) {
|
||||
NS_WARNING("width or height too large");
|
||||
return PR_FALSE;
|
||||
}
|
||||
tmp = tmp * 4;
|
||||
if (NS_UNLIKELY(tmp / 4 != aWidth * aHeight)) {
|
||||
NS_WARNING("width or height too large");
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
gfxImageSurface::gfxImageFormat mFormat;
|
||||
PRInt32 mWidth;
|
||||
PRInt32 mHeight;
|
||||
PRInt32 mStride;
|
||||
nsIntRect mDecoded;
|
||||
PRPackedBool mImageComplete;
|
||||
PRPackedBool mSinglePixel;
|
||||
PRPackedBool mFormatChanged;
|
||||
PRPackedBool mNeverUseDeviceSurface;
|
||||
#if defined(XP_WIN) && !defined(WINCE)
|
||||
PRPackedBool mIsDDBSurface;
|
||||
#endif
|
||||
|
||||
gfxRGBA mSinglePixelColor;
|
||||
|
||||
nsRefPtr<gfxImageSurface> mImageSurface;
|
||||
nsRefPtr<gfxASurface> mOptSurface;
|
||||
#if defined(XP_WIN) && !defined(WINCE)
|
||||
nsRefPtr<gfxWindowsSurface> mWinSurface;
|
||||
#elif defined(XP_MACOSX)
|
||||
nsRefPtr<gfxQuartzImageSurface> mQuartzSurface;
|
||||
#endif
|
||||
|
||||
PRUint8 mAlphaDepth;
|
||||
|
||||
// this function should return true if
|
||||
// we should (temporarily) not allocate any
|
||||
// platform native surfaces and instead use
|
||||
// image surfaces for everything.
|
||||
static PRBool ShouldUseImageSurfaces();
|
||||
};
|
||||
|
||||
#endif /* _NSTHEBESIMAGE_H_ */
|
||||
|
|
@ -46,12 +46,7 @@
|
|||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsGfxCIID.h"
|
||||
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIImage.h"
|
||||
|
||||
#include "nsThebesRegion.h"
|
||||
#include "nsThebesImage.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
|
|
|||
|
|
@ -54,8 +54,6 @@
|
|||
#include "nsIThebesFontMetrics.h"
|
||||
#include "gfxContext.h"
|
||||
|
||||
class nsIImage;
|
||||
|
||||
class nsThebesRenderingContext : public nsIRenderingContext
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@
|
|||
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsPoint.h"
|
||||
#include "nsRect.h"
|
||||
|
|
@ -63,7 +62,6 @@
|
|||
#include "nsIScrollableFrame.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsCSSColorUtils.h"
|
||||
#include "nsITheme.h"
|
||||
|
|
@ -321,7 +319,7 @@ static void DrawBorderImage(nsPresContext* aPresContext,
|
|||
|
||||
static void DrawBorderImageComponent(nsIRenderingContext& aRenderingContext,
|
||||
nsIFrame* aForFrame,
|
||||
nsIImage* aImage,
|
||||
imgIContainer* aImage,
|
||||
const nsRect& aDirtyRect,
|
||||
const nsRect& aFill,
|
||||
const nsIntRect& aSrc,
|
||||
|
|
@ -1687,27 +1685,9 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
|||
drawBackgroundColor) {
|
||||
nsCOMPtr<imgIContainer> image;
|
||||
bottomImage->GetImage(getter_AddRefs(image));
|
||||
// If the image is completely opaque, we may not need to paint
|
||||
// the background color.
|
||||
nsCOMPtr<gfxIImageFrame> gfxImgFrame;
|
||||
image->GetCurrentFrame(getter_AddRefs(gfxImgFrame));
|
||||
if (gfxImgFrame) {
|
||||
gfxImgFrame->GetNeedsBackground(&drawBackgroundColor);
|
||||
if (!drawBackgroundColor) {
|
||||
// If the current frame is smaller than its container, we
|
||||
// need to paint the background color even if the frame
|
||||
// itself is opaque.
|
||||
nsIntSize iSize;
|
||||
image->GetWidth(&iSize.width);
|
||||
image->GetHeight(&iSize.height);
|
||||
nsIntRect iframeRect;
|
||||
gfxImgFrame->GetRect(iframeRect);
|
||||
if (iSize.width != iframeRect.width ||
|
||||
iSize.height != iframeRect.height) {
|
||||
drawBackgroundColor = PR_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
PRBool isOpaque;
|
||||
if (NS_SUCCEEDED(image->GetCurrentFrameIsOpaque(&isOpaque)) && isOpaque)
|
||||
drawBackgroundColor = PR_FALSE;
|
||||
}
|
||||
|
||||
// The background color is rendered over the entire dirty area,
|
||||
|
|
@ -1938,18 +1918,6 @@ DrawBorderImage(nsPresContext* aPresContext,
|
|||
imgContainer->GetWidth(&imageSize.width);
|
||||
imgContainer->GetHeight(&imageSize.height);
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> imgFrame;
|
||||
imgContainer->GetCurrentFrame(getter_AddRefs(imgFrame));
|
||||
|
||||
nsIntRect innerRect;
|
||||
imgFrame->GetRect(innerRect);
|
||||
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(imgFrame));
|
||||
// The inner rectangle should precisely enclose the image pixels for
|
||||
// this frame.
|
||||
NS_ASSERTION(innerRect.width == img->GetWidth(), "img inner width off");
|
||||
NS_ASSERTION(innerRect.height == img->GetHeight(), "img inner height off");
|
||||
|
||||
// Convert percentages and clamp values to the image size.
|
||||
nsIntMargin split;
|
||||
NS_FOR_CSS_SIDES(s) {
|
||||
|
|
@ -1983,7 +1951,7 @@ DrawBorderImage(nsPresContext* aPresContext,
|
|||
// These helper tables recharacterize the 'split' and 'border' margins
|
||||
// in a more convenient form: they are the x/y/width/height coords
|
||||
// required for various bands of the border, and they have been transformed
|
||||
// to be relative to the innerRect (for 'split') or the page (for 'border').
|
||||
// to be relative to the image (for 'split') or the page (for 'border').
|
||||
enum {
|
||||
LEFT, MIDDLE, RIGHT,
|
||||
TOP = LEFT, BOTTOM = RIGHT
|
||||
|
|
@ -2010,14 +1978,14 @@ DrawBorderImage(nsPresContext* aPresContext,
|
|||
};
|
||||
|
||||
const PRInt32 splitX[3] = {
|
||||
-innerRect.x + 0,
|
||||
-innerRect.x + split.left,
|
||||
-innerRect.x + imageSize.width - split.right,
|
||||
0,
|
||||
split.left,
|
||||
imageSize.width - split.right,
|
||||
};
|
||||
const PRInt32 splitY[3] = {
|
||||
-innerRect.y + 0,
|
||||
-innerRect.y + split.top,
|
||||
-innerRect.y + imageSize.height - split.bottom,
|
||||
0,
|
||||
split.top,
|
||||
imageSize.height - split.bottom,
|
||||
};
|
||||
const PRInt32 splitWidth[3] = {
|
||||
split.left,
|
||||
|
|
@ -2108,7 +2076,7 @@ DrawBorderImage(nsPresContext* aPresContext,
|
|||
}
|
||||
|
||||
DrawBorderImageComponent(aRenderingContext, aForFrame,
|
||||
img, aDirtyRect,
|
||||
imgContainer, aDirtyRect,
|
||||
destArea, subArea,
|
||||
fillStyleH, fillStyleV, unitSize);
|
||||
}
|
||||
|
|
@ -2118,7 +2086,7 @@ DrawBorderImage(nsPresContext* aPresContext,
|
|||
static void
|
||||
DrawBorderImageComponent(nsIRenderingContext& aRenderingContext,
|
||||
nsIFrame* aForFrame,
|
||||
nsIImage* aImage,
|
||||
imgIContainer* aImage,
|
||||
const nsRect& aDirtyRect,
|
||||
const nsRect& aFill,
|
||||
const nsIntRect& aSrc,
|
||||
|
|
@ -2129,8 +2097,8 @@ DrawBorderImageComponent(nsIRenderingContext& aRenderingContext,
|
|||
if (aFill.IsEmpty() || aSrc.IsEmpty())
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIImage> subImage;
|
||||
if (NS_FAILED(aImage->Extract(aSrc, getter_AddRefs(subImage))))
|
||||
nsCOMPtr<imgIContainer> subImage;
|
||||
if (NS_FAILED(aImage->ExtractCurrentFrame(aSrc, getter_AddRefs(subImage))))
|
||||
return;
|
||||
|
||||
gfxPattern::GraphicsFilter graphicsFilter =
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@
|
|||
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsPoint.h"
|
||||
#include "nsRect.h"
|
||||
|
|
@ -56,7 +55,6 @@
|
|||
#include "nsIScrollableFrame.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsCSSColorUtils.h"
|
||||
#include "nsITheme.h"
|
||||
|
|
|
|||
|
|
@ -58,9 +58,7 @@
|
|||
#endif
|
||||
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIImage.h"
|
||||
|
||||
nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
|
||||
PRBool aIsForEvents, PRBool aBuildCaret)
|
||||
|
|
@ -555,18 +553,12 @@ nsDisplayBackground::IsOpaque(nsDisplayListBuilder* aBuilder) {
|
|||
nsCOMPtr<imgIContainer> container;
|
||||
bottomLayer.mImage->GetImage(getter_AddRefs(container));
|
||||
if (container) {
|
||||
PRUint32 nframes;
|
||||
container->GetNumFrames(&nframes);
|
||||
if (nframes == 1) {
|
||||
nsCOMPtr<gfxIImageFrame> imgFrame;
|
||||
container->GetCurrentFrame(getter_AddRefs(imgFrame));
|
||||
if (imgFrame) {
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(imgFrame));
|
||||
|
||||
PRBool hasMask = img->GetHasAlphaMask();
|
||||
|
||||
return !hasMask;
|
||||
}
|
||||
PRBool animated;
|
||||
container->GetAnimated(&animated);
|
||||
if (!animated) {
|
||||
PRBool isOpaque;
|
||||
if (NS_SUCCEEDED(container->GetCurrentFrameIsOpaque(&isOpaque)))
|
||||
return isOpaque;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ NS_IMETHODIMP nsImageLoader::OnStartContainer(imgIRequest *aRequest,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP nsImageLoader::OnStopFrame(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame)
|
||||
PRUint32 aFrame)
|
||||
{
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
|
@ -182,7 +182,6 @@ NS_IMETHODIMP nsImageLoader::OnStopFrame(imgIRequest *aRequest,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP nsImageLoader::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect)
|
||||
{
|
||||
if (!mFrame)
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ public:
|
|||
|
||||
// imgIDecoderObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
||||
NS_IMETHOD OnStopFrame(imgIRequest *aRequest, gfxIImageFrame *aFrame);
|
||||
NS_IMETHOD OnStopFrame(imgIRequest *aRequest, PRUint32 aFrame);
|
||||
// Do not override OnDataAvailable since background images are not
|
||||
// displayed incrementally; they are displayed after the entire image
|
||||
// has been loaded.
|
||||
|
|
@ -78,8 +78,7 @@ public:
|
|||
// incrementally in nsImageFrame.cpp.
|
||||
|
||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect *dirtyRect);
|
||||
|
||||
void Destroy();
|
||||
|
||||
|
|
|
|||
|
|
@ -61,12 +61,10 @@
|
|||
#include "nsFrameManager.h"
|
||||
#include "nsBlockFrame.h"
|
||||
#include "nsBidiPresUtils.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxRect.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxFont.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsCSSRendering.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
|
@ -2732,14 +2730,13 @@ MapToFloatUserPixels(const gfxSize& aSize,
|
|||
|
||||
static nsresult
|
||||
DrawImageInternal(nsIRenderingContext* aRenderingContext,
|
||||
nsIImage* aImage,
|
||||
imgIContainer* aImage,
|
||||
gfxPattern::GraphicsFilter aGraphicsFilter,
|
||||
const nsRect& aDest,
|
||||
const nsRect& aFill,
|
||||
const nsPoint& aAnchor,
|
||||
const nsRect& aDirty,
|
||||
const nsIntSize& aImageSize,
|
||||
const nsIntRect& aInnerRect)
|
||||
const nsIntSize& aImageSize)
|
||||
{
|
||||
if (aDest.IsEmpty() || aFill.IsEmpty())
|
||||
return NS_OK;
|
||||
|
|
@ -2839,22 +2836,18 @@ DrawImageInternal(nsIRenderingContext* aRenderingContext,
|
|||
if (finalFillRect.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
nsIntMargin padding(aInnerRect.x, aInnerRect.y,
|
||||
imageSize.width - aInnerRect.XMost(),
|
||||
imageSize.height - aInnerRect.YMost());
|
||||
aImage->Draw(ctx, aGraphicsFilter, transform, finalFillRect, padding, intSubimage);
|
||||
aImage->Draw(ctx, aGraphicsFilter, transform, finalFillRect, intSubimage);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* Workhorse for DrawSingleUnscaledImage. */
|
||||
static nsresult
|
||||
DrawSingleUnscaledImageInternal(nsIRenderingContext* aRenderingContext,
|
||||
nsIImage* aImage,
|
||||
imgIContainer* aImage,
|
||||
const nsPoint& aDest,
|
||||
const nsRect& aDirty,
|
||||
const nsRect* aSourceArea,
|
||||
const nsIntSize& aImageSize,
|
||||
const nsIntRect& aInnerRect)
|
||||
const nsIntSize& aImageSize)
|
||||
{
|
||||
if (aImageSize.width == 0 || aImageSize.height == 0)
|
||||
return NS_OK;
|
||||
|
|
@ -2877,19 +2870,18 @@ DrawSingleUnscaledImageInternal(nsIRenderingContext* aRenderingContext,
|
|||
// translation but we don't want to actually tile the image.
|
||||
fill.IntersectRect(fill, dest);
|
||||
return DrawImageInternal(aRenderingContext, aImage, gfxPattern::FILTER_NEAREST,
|
||||
dest, fill, aDest, aDirty, aImageSize, aInnerRect);
|
||||
dest, fill, aDest, aDirty, aImageSize);
|
||||
}
|
||||
|
||||
/* Workhorse for DrawSingleImage. */
|
||||
static nsresult
|
||||
DrawSingleImageInternal(nsIRenderingContext* aRenderingContext,
|
||||
nsIImage* aImage,
|
||||
imgIContainer* aImage,
|
||||
gfxPattern::GraphicsFilter aGraphicsFilter,
|
||||
const nsRect& aDest,
|
||||
const nsRect& aDirty,
|
||||
const nsRect* aSourceArea,
|
||||
const nsIntSize& aImageSize,
|
||||
const nsIntRect& aInnerRect)
|
||||
const nsIntSize& aImageSize)
|
||||
{
|
||||
if (aImageSize.width == 0 || aImageSize.height == 0)
|
||||
return NS_OK;
|
||||
|
|
@ -2911,7 +2903,7 @@ DrawSingleImageInternal(nsIRenderingContext* aRenderingContext,
|
|||
nsRect fill;
|
||||
fill.IntersectRect(aDest, dest);
|
||||
return DrawImageInternal(aRenderingContext, aImage, aGraphicsFilter, dest, fill,
|
||||
fill.TopLeft(), aDirty, aImageSize, aInnerRect);
|
||||
fill.TopLeft(), aDirty, aImageSize);
|
||||
}
|
||||
|
||||
/* The exposed Draw*Image functions just do interface conversion and call the
|
||||
|
|
@ -2926,38 +2918,13 @@ nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext,
|
|||
const nsPoint& aAnchor,
|
||||
const nsRect& aDirty)
|
||||
{
|
||||
nsCOMPtr<gfxIImageFrame> imgFrame;
|
||||
aImage->GetCurrentFrame(getter_AddRefs(imgFrame));
|
||||
if (!imgFrame) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(imgFrame));
|
||||
if (!img) return NS_ERROR_FAILURE;
|
||||
|
||||
nsIntRect innerRect;
|
||||
imgFrame->GetRect(innerRect);
|
||||
|
||||
nsIntSize imageSize;
|
||||
aImage->GetWidth(&imageSize.width);
|
||||
aImage->GetHeight(&imageSize.height);
|
||||
|
||||
return DrawImageInternal(aRenderingContext, img, aGraphicsFilter,
|
||||
aDest, aFill, aAnchor, aDirty,
|
||||
imageSize, innerRect);
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext,
|
||||
nsIImage* aImage,
|
||||
gfxPattern::GraphicsFilter aGraphicsFilter,
|
||||
const nsRect& aDest,
|
||||
const nsRect& aFill,
|
||||
const nsPoint& aAnchor,
|
||||
const nsRect& aDirty)
|
||||
{
|
||||
nsIntSize imageSize(aImage->GetWidth(), aImage->GetHeight());
|
||||
return DrawImageInternal(aRenderingContext, aImage, aGraphicsFilter,
|
||||
aDest, aFill, aAnchor, aDirty,
|
||||
imageSize, nsIntRect(nsIntPoint(0,0), imageSize));
|
||||
imageSize);
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
|
|
@ -2967,23 +2934,13 @@ nsLayoutUtils::DrawSingleUnscaledImage(nsIRenderingContext* aRenderingContext,
|
|||
const nsRect& aDirty,
|
||||
const nsRect* aSourceArea)
|
||||
{
|
||||
nsCOMPtr<gfxIImageFrame> imgFrame;
|
||||
aImage->GetCurrentFrame(getter_AddRefs(imgFrame));
|
||||
if (!imgFrame) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(imgFrame));
|
||||
if (!img) return NS_ERROR_FAILURE;
|
||||
|
||||
nsIntRect innerRect;
|
||||
imgFrame->GetRect(innerRect);
|
||||
|
||||
nsIntSize imageSize;
|
||||
aImage->GetWidth(&imageSize.width);
|
||||
aImage->GetHeight(&imageSize.height);
|
||||
|
||||
return DrawSingleUnscaledImageInternal(aRenderingContext, img,
|
||||
return DrawSingleUnscaledImageInternal(aRenderingContext, aImage,
|
||||
aDest, aDirty, aSourceArea,
|
||||
imageSize, innerRect);
|
||||
imageSize);
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
|
|
@ -2994,41 +2951,15 @@ nsLayoutUtils::DrawSingleImage(nsIRenderingContext* aRenderingContext,
|
|||
const nsRect& aDirty,
|
||||
const nsRect* aSourceArea)
|
||||
{
|
||||
nsCOMPtr<gfxIImageFrame> imgFrame;
|
||||
aImage->GetCurrentFrame(getter_AddRefs(imgFrame));
|
||||
if (!imgFrame) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(imgFrame));
|
||||
if (!img) return NS_ERROR_FAILURE;
|
||||
|
||||
nsIntRect innerRect;
|
||||
imgFrame->GetRect(innerRect);
|
||||
|
||||
nsIntSize imageSize;
|
||||
aImage->GetWidth(&imageSize.width);
|
||||
aImage->GetHeight(&imageSize.height);
|
||||
|
||||
return DrawSingleImageInternal(aRenderingContext, img, aGraphicsFilter,
|
||||
aDest, aDirty, aSourceArea,
|
||||
imageSize, innerRect);
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
nsLayoutUtils::DrawSingleImage(nsIRenderingContext* aRenderingContext,
|
||||
nsIImage* aImage,
|
||||
gfxPattern::GraphicsFilter aGraphicsFilter,
|
||||
const nsRect& aDest,
|
||||
const nsRect& aDirty,
|
||||
const nsRect* aSourceArea)
|
||||
{
|
||||
nsIntSize imageSize(aImage->GetWidth(), aImage->GetHeight());
|
||||
return DrawSingleImageInternal(aRenderingContext, aImage, aGraphicsFilter,
|
||||
aDest, aDirty, aSourceArea,
|
||||
imageSize,
|
||||
nsIntRect(nsIntPoint(0, 0), imageSize));
|
||||
imageSize);
|
||||
}
|
||||
|
||||
|
||||
/* static */ nsRect
|
||||
nsLayoutUtils::GetWholeImageDestination(const nsIntSize& aWholeImageSize,
|
||||
const nsRect& aImageSourceArea,
|
||||
|
|
@ -3386,7 +3317,6 @@ nsLayoutUtils::SurfaceFromElement(nsIDOMElement *aElement,
|
|||
#endif
|
||||
|
||||
// Finally, check if it's a normal image
|
||||
nsCOMPtr<imgIContainer> imgContainer;
|
||||
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(aElement);
|
||||
|
||||
if (!imageLoader)
|
||||
|
|
@ -3425,34 +3355,28 @@ nsLayoutUtils::SurfaceFromElement(nsIDOMElement *aElement,
|
|||
return result;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIContainer> imgContainer;
|
||||
rv = imgRequest->GetImage(getter_AddRefs(imgContainer));
|
||||
if (NS_FAILED(rv) || !imgContainer)
|
||||
return result;
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> frame;
|
||||
rv = imgContainer->GetCurrentFrame(getter_AddRefs(frame));
|
||||
nsRefPtr<gfxASurface> framesurf;
|
||||
rv = imgContainer->GetCurrentFrame(getter_AddRefs(framesurf));
|
||||
if (NS_FAILED(rv))
|
||||
return result;
|
||||
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(frame));
|
||||
if (!img)
|
||||
return result;
|
||||
|
||||
PRInt32 imgWidth, imgHeight;
|
||||
rv = frame->GetWidth(&imgWidth);
|
||||
rv |= frame->GetHeight(&imgHeight);
|
||||
rv = imgContainer->GetWidth(&imgWidth);
|
||||
rv |= imgContainer->GetHeight(&imgHeight);
|
||||
if (NS_FAILED(rv))
|
||||
return result;
|
||||
|
||||
nsRefPtr<gfxPattern> gfxpattern;
|
||||
img->GetPattern(getter_AddRefs(gfxpattern));
|
||||
nsRefPtr<gfxASurface> gfxsurf = gfxpattern->GetSurface();
|
||||
|
||||
if (wantImageSurface && gfxsurf->GetType() != gfxASurface::SurfaceTypeImage) {
|
||||
if (wantImageSurface && framesurf->GetType() != gfxASurface::SurfaceTypeImage) {
|
||||
forceCopy = PR_TRUE;
|
||||
}
|
||||
|
||||
if (forceCopy || !gfxsurf) {
|
||||
nsRefPtr<gfxASurface> gfxsurf = framesurf;
|
||||
if (forceCopy) {
|
||||
if (wantImageSurface) {
|
||||
gfxsurf = new gfxImageSurface (gfxIntSize(imgWidth, imgHeight), gfxASurface::ImageFormatARGB32);
|
||||
} else {
|
||||
|
|
@ -3463,7 +3387,7 @@ nsLayoutUtils::SurfaceFromElement(nsIDOMElement *aElement,
|
|||
nsRefPtr<gfxContext> ctx = new gfxContext(gfxsurf);
|
||||
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->SetPattern(gfxpattern);
|
||||
ctx->SetSource(framesurf);
|
||||
ctx->Paint();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -862,14 +862,6 @@ public:
|
|||
const nsPoint& aAnchor,
|
||||
const nsRect& aDirty);
|
||||
|
||||
static nsresult DrawImage(nsIRenderingContext* aRenderingContext,
|
||||
nsIImage* aImage,
|
||||
gfxPattern::GraphicsFilter aGraphicsFilter,
|
||||
const nsRect& aDest,
|
||||
const nsRect& aFill,
|
||||
const nsPoint& aAnchor,
|
||||
const nsRect& aDirty);
|
||||
|
||||
/**
|
||||
* Draw a whole image without scaling or tiling.
|
||||
*
|
||||
|
|
@ -911,13 +903,6 @@ public:
|
|||
const nsRect& aDirty,
|
||||
const nsRect* aSourceArea = nsnull);
|
||||
|
||||
static nsresult DrawSingleImage(nsIRenderingContext* aRenderingContext,
|
||||
nsIImage* aImage,
|
||||
gfxPattern::GraphicsFilter aGraphicsFilter,
|
||||
const nsRect& aDest,
|
||||
const nsRect& aDirty,
|
||||
const nsRect* aSourceArea = nsnull);
|
||||
|
||||
/**
|
||||
* Given a source area of an image (in appunits) and a destination area
|
||||
* that we want to map that source area too, computes the area that
|
||||
|
|
|
|||
|
|
@ -84,7 +84,6 @@ class nsIContent;
|
|||
class nsIFontMetrics;
|
||||
class nsIFrame;
|
||||
class nsFrameManager;
|
||||
class nsIImage;
|
||||
class nsILinkHandler;
|
||||
class nsStyleContext;
|
||||
class nsIAtom;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@
|
|||
#include "nsISupports.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsCSSAnonBoxes.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIDocument.h"
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@
|
|||
#include "nsGkAtoms.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsIFontMetrics.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsFormControlFrame.h"
|
||||
#include "nsGUIEvent.h"
|
||||
|
|
|
|||
|
|
@ -71,13 +71,12 @@ public:
|
|||
NS_DECL_ISUPPORTS
|
||||
// imgIDecoderObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
||||
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, gfxIImageFrame *aFrame,
|
||||
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, PRBool aCurrentFrame,
|
||||
const nsIntRect *aRect);
|
||||
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
|
||||
const PRUnichar *statusArg);
|
||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect *dirtyRect);
|
||||
|
||||
void SetFrame(nsBulletFrame *frame) { mFrame = frame; }
|
||||
|
||||
|
|
@ -1458,7 +1457,7 @@ NS_IMETHODIMP nsBulletFrame::OnStartContainer(imgIRequest *aRequest,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP nsBulletFrame::OnDataAvailable(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame,
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect *aRect)
|
||||
{
|
||||
// The image has changed.
|
||||
|
|
@ -1489,7 +1488,6 @@ NS_IMETHODIMP nsBulletFrame::OnStopDecode(imgIRequest *aRequest,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP nsBulletFrame::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *aNewFrame,
|
||||
nsIntRect *aDirtyRect)
|
||||
{
|
||||
// Invalidate the entire content area. Maybe it's not optimal but it's simple and
|
||||
|
|
@ -1547,13 +1545,13 @@ NS_IMETHODIMP nsBulletListener::OnStartContainer(imgIRequest *aRequest,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP nsBulletListener::OnDataAvailable(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame,
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect *aRect)
|
||||
{
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mFrame->OnDataAvailable(aRequest, aFrame, aRect);
|
||||
return mFrame->OnDataAvailable(aRequest, aCurrentFrame, aRect);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsBulletListener::OnStopDecode(imgIRequest *aRequest,
|
||||
|
|
@ -1567,11 +1565,10 @@ NS_IMETHODIMP nsBulletListener::OnStopDecode(imgIRequest *aRequest,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP nsBulletListener::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect)
|
||||
{
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mFrame->FrameChanged(aContainer, newframe, dirtyRect);
|
||||
return mFrame->FrameChanged(aContainer, dirtyRect);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@
|
|||
|
||||
#include "imgIRequest.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
class gfxIImageFrame;
|
||||
|
||||
/**
|
||||
* A simple class that manages the layout and rendering of html bullets.
|
||||
|
|
@ -81,13 +80,12 @@ public:
|
|||
|
||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
||||
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame,
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect *aRect);
|
||||
NS_IMETHOD OnStopDecode(imgIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aStatusArg);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *aNewframe,
|
||||
nsIntRect *aDirtyRect);
|
||||
|
||||
/* get list item text, without '.' */
|
||||
|
|
|
|||
|
|
@ -109,7 +109,6 @@
|
|||
#include "nsIServiceManager.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsILookAndFeel.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsWidgetsCID.h" // for NS_LOOKANDFEEL_CID
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@
|
|||
#include "nsPresContext.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsINodeInfo.h"
|
||||
|
|
@ -93,7 +92,6 @@
|
|||
#include "nsCSSFrameConstructor.h"
|
||||
#include "nsIPrefBranch2.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIDOMRange.h"
|
||||
|
||||
#include "nsIContentPolicy.h"
|
||||
|
|
@ -523,7 +521,7 @@ nsImageFrame::OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage)
|
|||
|
||||
nsresult
|
||||
nsImageFrame::OnDataAvailable(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame,
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect *aRect)
|
||||
{
|
||||
// XXX do we need to make sure that the reflow from the
|
||||
|
|
@ -555,16 +553,8 @@ nsImageFrame::OnDataAvailable(imgIRequest *aRequest,
|
|||
|
||||
// Don't invalidate if the current visible frame isn't the one the data is
|
||||
// from
|
||||
nsCOMPtr<imgIContainer> container;
|
||||
aRequest->GetImage(getter_AddRefs(container));
|
||||
if (container) {
|
||||
nsCOMPtr<gfxIImageFrame> currentFrame;
|
||||
container->GetCurrentFrame(getter_AddRefs(currentFrame));
|
||||
if (aFrame != currentFrame) {
|
||||
// just bail
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
if (!aCurrentFrame)
|
||||
return NS_OK;
|
||||
|
||||
#ifdef DEBUG_decode
|
||||
printf("Source rect (%d,%d,%d,%d) -> invalidate dest rect (%d,%d,%d,%d)\n",
|
||||
|
|
@ -634,9 +624,7 @@ nsImageFrame::OnStopDecode(imgIRequest *aRequest,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsImageFrame::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *aNewFrame,
|
||||
nsIntRect *aDirtyRect)
|
||||
nsImageFrame::FrameChanged(imgIContainer *aContainer, nsIntRect *aDirtyRect)
|
||||
{
|
||||
if (!GetStyleVisibility()->IsVisible()) {
|
||||
return NS_OK;
|
||||
|
|
@ -1833,13 +1821,13 @@ NS_IMETHODIMP nsImageListener::OnStartContainer(imgIRequest *aRequest,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP nsImageListener::OnDataAvailable(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame,
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect *aRect)
|
||||
{
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mFrame->OnDataAvailable(aRequest, aFrame, aRect);
|
||||
return mFrame->OnDataAvailable(aRequest, aCurrentFrame, aRect);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImageListener::OnStopDecode(imgIRequest *aRequest,
|
||||
|
|
@ -1853,13 +1841,12 @@ NS_IMETHODIMP nsImageListener::OnStopDecode(imgIRequest *aRequest,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP nsImageListener::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *newframe,
|
||||
nsIntRect * dirtyRect)
|
||||
{
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mFrame->FrameChanged(aContainer, newframe, dirtyRect);
|
||||
return mFrame->FrameChanged(aContainer, dirtyRect);
|
||||
}
|
||||
|
||||
static PRBool
|
||||
|
|
|
|||
|
|
@ -73,13 +73,12 @@ public:
|
|||
NS_DECL_ISUPPORTS
|
||||
// imgIDecoderObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
||||
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, gfxIImageFrame *aFrame,
|
||||
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, PRBool aCurrentFrame,
|
||||
const nsIntRect *aRect);
|
||||
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
|
||||
const PRUnichar *statusArg);
|
||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, gfxIImageFrame *newframe,
|
||||
nsIntRect * dirtyRect);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect * dirtyRect);
|
||||
|
||||
void SetFrame(nsImageFrame *frame) { mFrame = frame; }
|
||||
|
||||
|
|
@ -218,15 +217,12 @@ protected:
|
|||
protected:
|
||||
friend class nsImageListener;
|
||||
nsresult OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
||||
nsresult OnDataAvailable(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame,
|
||||
nsresult OnDataAvailable(imgIRequest *aRequest, PRBool aCurrentFrame,
|
||||
const nsIntRect *rect);
|
||||
nsresult OnStopDecode(imgIRequest *aRequest,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aStatusArg);
|
||||
nsresult FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *aNewframe,
|
||||
nsIntRect *aDirtyRect);
|
||||
nsresult FrameChanged(imgIContainer *aContainer, nsIntRect *aDirtyRect);
|
||||
|
||||
private:
|
||||
// random helpers
|
||||
|
|
|
|||
|
|
@ -21,6 +21,6 @@
|
|||
|
||||
<rect width="100%" height="100%" fill="lime"/>
|
||||
<rect width="183" height="183" fill="red"/>
|
||||
<image width="183" height="183" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAABGdBTUEAALGPC%2FxhBQAAAAxJREFUGFdjYPjPAAACAgEA0dNGRAAAAABJRU5ErkJggg%3D%3D"/>
|
||||
<image style="image-rendering: -moz-crisp-edges" width="183" height="183" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAABGdBTUEAALGPC%2FxhBQAAAAxJREFUGFdjYPjPAAACAgEA0dNGRAAAAABJRU5ErkJggg%3D%3D"/>
|
||||
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1.1 KiB |
|
|
@ -37,7 +37,6 @@
|
|||
#include "nsSVGPathGeometryFrame.h"
|
||||
#include "nsIDOMSVGMatrix.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsStubImageDecoderObserver.h"
|
||||
#include "nsImageLoadingContent.h"
|
||||
#include "nsIDOMSVGImageElement.h"
|
||||
|
|
@ -47,7 +46,6 @@
|
|||
#include "nsSVGMatrix.h"
|
||||
#include "gfxContext.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIImage.h"
|
||||
|
||||
class nsSVGImageFrame;
|
||||
|
||||
|
|
@ -61,8 +59,7 @@ public:
|
|||
NS_IMETHOD OnStopDecode(imgIRequest *aRequest, nsresult status,
|
||||
const PRUnichar *statusArg);
|
||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, gfxIImageFrame *newframe,
|
||||
nsRect * dirtyRect);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect * dirtyRect);
|
||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest,
|
||||
imgIContainer *aContainer);
|
||||
|
|
@ -243,16 +240,15 @@ nsSVGImageFrame::PaintSVG(nsSVGRenderState *aContext,
|
|||
currentRequest->GetImage(getter_AddRefs(mImageContainer));
|
||||
}
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> currentFrame;
|
||||
nsRefPtr<gfxASurface> currentFrame;
|
||||
if (mImageContainer)
|
||||
mImageContainer->GetCurrentFrame(getter_AddRefs(currentFrame));
|
||||
|
||||
nsRefPtr<gfxPattern> thebesPattern = nsnull;
|
||||
if (currentFrame) {
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(currentFrame));
|
||||
|
||||
img->GetPattern(getter_AddRefs(thebesPattern));
|
||||
}
|
||||
// We need to wrap the surface in a pattern to have somewhere to set the
|
||||
// graphics filter.
|
||||
nsRefPtr<gfxPattern> thebesPattern;
|
||||
if (currentFrame)
|
||||
thebesPattern = new gfxPattern(currentFrame);
|
||||
|
||||
if (thebesPattern) {
|
||||
|
||||
|
|
@ -279,8 +275,8 @@ nsSVGImageFrame::PaintSVG(nsSVGRenderState *aContext,
|
|||
}
|
||||
|
||||
PRInt32 nativeWidth, nativeHeight;
|
||||
currentFrame->GetWidth(&nativeWidth);
|
||||
currentFrame->GetHeight(&nativeHeight);
|
||||
mImageContainer->GetWidth(&nativeWidth);
|
||||
mImageContainer->GetHeight(&nativeHeight);
|
||||
|
||||
nsSVGUtils::CompositePatternMatrix(gfx, thebesPattern, fini, nativeWidth, nativeHeight, opacity);
|
||||
|
||||
|
|
@ -384,8 +380,7 @@ NS_IMETHODIMP nsSVGImageListener::OnStopDecode(imgIRequest *aRequest,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP nsSVGImageListener::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *newframe,
|
||||
nsRect * dirtyRect)
|
||||
nsIntRect * dirtyRect)
|
||||
{
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@
|
|||
#include "nsPresContext.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIHTMLDocument.h"
|
||||
#include "nsStyleConsts.h"
|
||||
|
|
@ -543,7 +542,6 @@ NS_IMETHODIMP nsImageBoxFrame::OnStopDecode(imgIRequest *request,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP nsImageBoxFrame::FrameChanged(imgIContainer *container,
|
||||
gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect)
|
||||
{
|
||||
nsBoxLayoutState state(PresContext());
|
||||
|
|
@ -591,12 +589,11 @@ NS_IMETHODIMP nsImageBoxListener::OnStopDecode(imgIRequest *request,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP nsImageBoxListener::FrameChanged(imgIContainer *container,
|
||||
gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect)
|
||||
{
|
||||
if (!mFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mFrame->FrameChanged(container, newframe, dirtyRect);
|
||||
return mFrame->FrameChanged(container, dirtyRect);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,8 +59,7 @@ public:
|
|||
NS_IMETHOD OnStopDecode(imgIRequest *request, nsresult status,
|
||||
const PRUnichar *statusArg);
|
||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD FrameChanged(imgIContainer *container, gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *container, nsIntRect *dirtyRect);
|
||||
|
||||
void SetFrame(nsImageBoxFrame *frame) { mFrame = frame; }
|
||||
|
||||
|
|
@ -121,9 +120,7 @@ public:
|
|||
NS_IMETHOD OnStopDecode(imgIRequest *request,
|
||||
nsresult status,
|
||||
const PRUnichar *statusArg);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *container,
|
||||
gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *container, nsIntRect *dirtyRect);
|
||||
|
||||
virtual ~nsImageBoxFrame();
|
||||
|
||||
|
|
|
|||
|
|
@ -2173,11 +2173,11 @@ nsTreeBodyFrame::GetImage(PRInt32 aRowIndex, nsTreeColumn* aCol, PRBool aUseCont
|
|||
imgIRequest *imgReq = entry.request;
|
||||
imgReq->GetImageStatus(&status);
|
||||
imgReq->GetImage(aResult); // We hand back the image here. The GetImage call addrefs *aResult.
|
||||
PRUint32 numFrames = 1;
|
||||
PRBool animated = PR_FALSE;
|
||||
if (*aResult)
|
||||
(*aResult)->GetNumFrames(&numFrames);
|
||||
(*aResult)->GetAnimated(&animated);
|
||||
|
||||
if ((!(status & imgIRequest::STATUS_LOAD_COMPLETE)) || numFrames > 1) {
|
||||
if ((!(status & imgIRequest::STATUS_LOAD_COMPLETE)) || animated) {
|
||||
// We either aren't done loading, or we're animating. Add our row as a listener for invalidations.
|
||||
nsCOMPtr<imgIDecoderObserver> obs;
|
||||
imgReq->GetDecoderObserver(getter_AddRefs(obs));
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ NS_IMETHODIMP nsTreeImageListener::OnStartContainer(imgIRequest *aRequest,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP nsTreeImageListener::OnDataAvailable(imgIRequest *aRequest,
|
||||
gfxIImageFrame *aFrame,
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect *aRect)
|
||||
{
|
||||
Invalidate();
|
||||
|
|
@ -72,7 +72,6 @@ NS_IMETHODIMP nsTreeImageListener::OnDataAvailable(imgIRequest *aRequest,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP nsTreeImageListener::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect)
|
||||
{
|
||||
Invalidate();
|
||||
|
|
|
|||
|
|
@ -72,11 +72,10 @@ public:
|
|||
NS_DECL_ISUPPORTS
|
||||
// imgIDecoderObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD OnStartContainer(imgIRequest *aRequest, imgIContainer *aImage);
|
||||
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, gfxIImageFrame *aFrame,
|
||||
NS_IMETHOD OnDataAvailable(imgIRequest *aRequest, PRBool aCurrentFrame,
|
||||
const nsIntRect *aRect);
|
||||
// imgIContainerObserver (override nsStubImageDecoderObserver)
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, gfxIImageFrame *newframe,
|
||||
nsIntRect *dirtyRect);
|
||||
NS_IMETHOD FrameChanged(imgIContainer *aContainer, nsIntRect *dirtyRect);
|
||||
|
||||
NS_IMETHOD AddCell(PRInt32 aIndex, nsITreeColumn* aCol);
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#define IMG_BUILD_xbm 1
|
||||
#endif
|
||||
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIModule.h"
|
||||
#include "nsICategoryManager.h"
|
||||
|
|
@ -206,7 +207,7 @@ static const nsModuleComponentInfo components[] =
|
|||
imgLoaderConstructor, },
|
||||
{ "image container",
|
||||
NS_IMGCONTAINER_CID,
|
||||
"@mozilla.org/image/container;1",
|
||||
"@mozilla.org/image/container;2",
|
||||
imgContainerConstructor, },
|
||||
{ "image loader",
|
||||
NS_IMGLOADER_CID,
|
||||
|
|
@ -313,6 +314,12 @@ static const nsModuleComponentInfo components[] =
|
|||
static nsresult
|
||||
imglib_Initialize(nsIModule* aSelf)
|
||||
{
|
||||
// Hack: We need the gfx module to be initialized because we use gfxPlatform
|
||||
// in imgFrame. Request something from the gfx module to ensure that
|
||||
// everything's set up for us.
|
||||
nsCOMPtr<nsIDeviceContext> devctx =
|
||||
do_CreateInstance("@mozilla.org/gfx/devicecontext;1");
|
||||
|
||||
imgLoader::InitCache();
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@
|
|||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
||||
#include "imgILoad.h"
|
||||
#include "nsIImage.h"
|
||||
|
||||
#include "prlog.h"
|
||||
|
||||
|
|
@ -89,11 +88,7 @@ NS_IMETHODIMP nsBMPDecoder::Init(imgILoad *aLoad)
|
|||
mObserver = do_QueryInterface(aLoad);
|
||||
|
||||
nsresult rv;
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;1", &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2", &rv);
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;2", &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
|
@ -106,13 +101,12 @@ NS_IMETHODIMP nsBMPDecoder::Close()
|
|||
|
||||
mImage->DecodingComplete();
|
||||
if (mObserver) {
|
||||
mObserver->OnStopFrame(nsnull, mFrame);
|
||||
mObserver->OnStopFrame(nsnull, 0);
|
||||
mObserver->OnStopContainer(nsnull, mImage);
|
||||
mObserver->OnStopDecode(nsnull, NS_OK, nsnull);
|
||||
mObserver = nsnull;
|
||||
}
|
||||
mImage = nsnull;
|
||||
mFrame = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -266,8 +260,10 @@ NS_METHOD nsBMPDecoder::ProcessData(const char* aBuffer, PRUint32 aCount)
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mOldLine = mCurLine = real_height;
|
||||
|
||||
PRUint32 imageLength;
|
||||
if ((mBIH.compression == BI_RLE8) || (mBIH.compression == BI_RLE4)) {
|
||||
rv = mFrame->Init(0, 0, mBIH.width, real_height, RLE_GFXFORMAT_ALPHA, 24);
|
||||
rv = mImage->AppendFrame(0, 0, mBIH.width, real_height, gfxASurface::ImageFormatARGB32,
|
||||
(PRUint8**)&mImageData, &imageLength);
|
||||
} else {
|
||||
// mRow is not used for RLE encoded images
|
||||
mRow = (PRUint8*)malloc((mBIH.width * mBIH.bpp)/8 + 4);
|
||||
|
|
@ -277,12 +273,10 @@ NS_METHOD nsBMPDecoder::ProcessData(const char* aBuffer, PRUint32 aCount)
|
|||
if (!mRow) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
rv = mFrame->Init(0, 0, mBIH.width, real_height, BMP_GFXFORMAT, 24);
|
||||
rv = mImage->AppendFrame(0, 0, mBIH.width, real_height, gfxASurface::ImageFormatRGB24,
|
||||
(PRUint8**)&mImageData, &imageLength);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 imageLength;
|
||||
mFrame->GetImageData((PRUint8**)&mImageData, &imageLength);
|
||||
if (!mImageData)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
|
@ -297,9 +291,7 @@ NS_METHOD nsBMPDecoder::ProcessData(const char* aBuffer, PRUint32 aCount)
|
|||
memset(mImageData, 0, imageLength);
|
||||
}
|
||||
|
||||
rv = mImage->AppendFrame(mFrame);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mObserver->OnStartFrame(nsnull, mFrame);
|
||||
mObserver->OnStartFrame(nsnull, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
PRUint8 bpc; // bytes per color
|
||||
|
|
@ -603,14 +595,11 @@ NS_METHOD nsBMPDecoder::ProcessData(const char* aBuffer, PRUint32 aCount)
|
|||
nsIntRect r(0, mBIH.height < 0 ? -mBIH.height - mOldLine : mCurLine,
|
||||
mBIH.width, rows);
|
||||
|
||||
// Tell the image that it's data has been updated
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(mFrame, &rv));
|
||||
// Tell the image that its data has been updated
|
||||
rv = mImage->FrameUpdated(0, r);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
mObserver->OnDataAvailable(nsnull, mFrame, &r);
|
||||
mObserver->OnDataAvailable(nsnull, PR_TRUE, &r);
|
||||
mOldLine = mCurLine;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@
|
|||
#include "imgIDecoder.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "gfxColor.h"
|
||||
|
||||
#define NS_BMPDECODER_CID \
|
||||
|
|
@ -118,9 +117,6 @@ struct bitFields {
|
|||
#endif
|
||||
|
||||
#define USE_RGB
|
||||
#define BMP_GFXFORMAT gfxIFormats::RGB
|
||||
#define RLE_GFXFORMAT_ALPHA gfxIFormats::RGB_A1
|
||||
#define GFXBYTESPERPIXEL 4
|
||||
|
||||
// BMPINFOHEADER.compression defines
|
||||
#define BI_RLE8 1
|
||||
|
|
@ -173,7 +169,6 @@ private:
|
|||
nsCOMPtr<imgIDecoderObserver> mObserver;
|
||||
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<gfxIImageFrame> mFrame;
|
||||
|
||||
PRUint32 mPos;
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@
|
|||
#include "imgILoad.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIImage.h"
|
||||
|
||||
#include "nsIProperties.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
|
@ -93,39 +92,30 @@ NS_IMETHODIMP nsICODecoder::Init(imgILoad *aLoad)
|
|||
{
|
||||
mObserver = do_QueryInterface(aLoad);
|
||||
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;1");
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;2");
|
||||
if (!mImage)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
|
||||
if (!mFrame)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return aLoad->SetImage(mImage);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsICODecoder::Close()
|
||||
{
|
||||
// Tell the image that it's data has been updated
|
||||
// This should be a mFrame function, so that we don't have to query for interface...
|
||||
nsIntRect r(0, 0, mDirEntry.mWidth, mDirEntry.mHeight);
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(mFrame));
|
||||
nsresult rv = NS_OK;
|
||||
if (img)
|
||||
rv = img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);
|
||||
nsresult rv = mImage->FrameUpdated(0, r);
|
||||
|
||||
mImage->DecodingComplete();
|
||||
|
||||
if (mObserver) {
|
||||
mObserver->OnDataAvailable(nsnull, mFrame, &r);
|
||||
mObserver->OnStopFrame(nsnull, mFrame);
|
||||
mObserver->OnStopContainer(nsnull, mImage);
|
||||
mObserver->OnDataAvailable(nsnull, PR_TRUE, &r);
|
||||
mObserver->OnStopFrame(nsnull, 0);
|
||||
mObserver->OnStopContainer(nsnull, 0);
|
||||
mObserver->OnStopDecode(nsnull, NS_OK, nsnull);
|
||||
mObserver = nsnull;
|
||||
}
|
||||
|
||||
mImage = nsnull;
|
||||
mFrame = nsnull;
|
||||
|
||||
mPos = 0;
|
||||
|
||||
|
|
@ -304,15 +294,13 @@ nsresult nsICODecoder::ProcessData(const char* aBuffer, PRUint32 aCount) {
|
|||
if (!mRow)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = mFrame->Init(0, 0, mDirEntry.mWidth, mDirEntry.mHeight, GFXFORMATALPHA8, 24);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mImage->AppendFrame(mFrame);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mObserver->OnStartFrame(nsnull, mFrame);
|
||||
PRUint32 imageLength;
|
||||
rv = mImage->AppendFrame(0, 0, mDirEntry.mWidth, mDirEntry.mHeight,
|
||||
gfxASurface::ImageFormatARGB32, (PRUint8**)&mImageData, &imageLength);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 imageLength;
|
||||
mFrame->GetImageData((PRUint8**)&mImageData, &imageLength);
|
||||
mObserver->OnStartFrame(nsnull, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (mColors && (mPos >= mImageOffset + BITMAPINFOSIZE) &&
|
||||
|
|
|
|||
|
|
@ -44,20 +44,12 @@
|
|||
#include "imgIDecoder.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsBMPDecoder.h"
|
||||
|
||||
// {CB3EDE1A-0FA5-4e27-AAFE-0F7801E5A1F1}
|
||||
#define NS_ICODECODER_CID \
|
||||
{ 0xcb3ede1a, 0xfa5, 0x4e27, { 0xaa, 0xfe, 0xf, 0x78, 0x1, 0xe5, 0xa1, 0xf1 } }
|
||||
|
||||
#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) || defined(MOZ_WIDGET_PHOTON)
|
||||
#define GFXFORMATALPHA8 gfxIFormats::BGR_A8
|
||||
#else
|
||||
#define USE_RGBA1
|
||||
#define GFXFORMATALPHA8 gfxIFormats::RGB_A8
|
||||
#endif
|
||||
|
||||
struct IconDirEntry
|
||||
{
|
||||
PRUint8 mWidth;
|
||||
|
|
@ -103,7 +95,6 @@ private:
|
|||
private:
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver;
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<gfxIImageFrame> mFrame;
|
||||
|
||||
PRUint32 mPos;
|
||||
PRUint16 mNumIcons;
|
||||
|
|
|
|||
|
|
@ -74,7 +74,6 @@ mailing address.
|
|||
#include <stddef.h>
|
||||
#include "prmem.h"
|
||||
|
||||
#include "nsIImage.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
||||
#include "nsGIFDecoder2.h"
|
||||
|
|
@ -142,7 +141,7 @@ NS_IMETHODIMP nsGIFDecoder2::Init(imgILoad *aLoad)
|
|||
{
|
||||
mObserver = do_QueryInterface(aLoad);
|
||||
|
||||
mImageContainer = do_CreateInstance("@mozilla.org/image/container;1");
|
||||
mImageContainer = do_CreateInstance("@mozilla.org/image/container;2");
|
||||
aLoad->SetImage(mImageContainer);
|
||||
|
||||
// Start with the version (GIF89a|GIF87a)
|
||||
|
|
@ -161,8 +160,7 @@ NS_IMETHODIMP nsGIFDecoder2::Init(imgILoad *aLoad)
|
|||
/* void close (); */
|
||||
NS_IMETHODIMP nsGIFDecoder2::Close()
|
||||
{
|
||||
if (mImageFrame)
|
||||
EndImageFrame();
|
||||
EndImageFrame();
|
||||
EndGIF();
|
||||
|
||||
PR_FREEIF(mGIFStruct.local_colormap);
|
||||
|
|
@ -205,8 +203,7 @@ nsGIFDecoder2::FlushImageData(PRUint32 fromRow, PRUint32 rows)
|
|||
nsIntRect r(0, fromRow, mGIFStruct.width, rows);
|
||||
|
||||
// Update image
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(mImageFrame));
|
||||
nsresult rv = img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);
|
||||
nsresult rv = mImageContainer->FrameUpdated(mGIFStruct.images_decoded, r);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -214,8 +211,10 @@ nsGIFDecoder2::FlushImageData(PRUint32 fromRow, PRUint32 rows)
|
|||
// Offset to the frame position
|
||||
// Only notify observer(s) for first frame
|
||||
if (!mGIFStruct.images_decoded && mObserver) {
|
||||
PRUint32 imgCurFrame;
|
||||
mImageContainer->GetCurrentFrameIndex(&imgCurFrame);
|
||||
r.y += mGIFStruct.y_offset;
|
||||
mObserver->OnDataAvailable(nsnull, mImageFrame, &r);
|
||||
mObserver->OnDataAvailable(nsnull, imgCurFrame == PRUint32(mGIFStruct.images_decoded), &r);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -251,7 +250,7 @@ nsresult nsGIFDecoder2::ProcessData(unsigned char *data, PRUint32 count, PRUint3
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Flushing is only needed for first frame
|
||||
if (!mGIFStruct.images_decoded && mImageFrame) {
|
||||
if (!mGIFStruct.images_decoded) {
|
||||
rv = FlushImageData();
|
||||
mLastFlushedRow = mCurrentRow;
|
||||
mLastFlushedPass = mCurrentPass;
|
||||
|
|
@ -324,8 +323,6 @@ void nsGIFDecoder2::EndGIF()
|
|||
//******************************************************************************
|
||||
void nsGIFDecoder2::BeginImageFrame(gfx_depth aDepth)
|
||||
{
|
||||
mImageFrame = nsnull; // clear out our current frame reference
|
||||
|
||||
if (!mGIFStruct.images_decoded) {
|
||||
// Send a onetime OnDataAvailable (Display Refresh) for the first frame
|
||||
// if it has a y-axis offset. Otherwise, the area may never be refreshed
|
||||
|
|
@ -333,41 +330,46 @@ void nsGIFDecoder2::BeginImageFrame(gfx_depth aDepth)
|
|||
if (mGIFStruct.y_offset > 0) {
|
||||
PRInt32 imgWidth;
|
||||
mImageContainer->GetWidth(&imgWidth);
|
||||
PRUint32 imgCurFrame;
|
||||
mImageContainer->GetCurrentFrameIndex(&imgCurFrame);
|
||||
nsIntRect r(0, 0, imgWidth, mGIFStruct.y_offset);
|
||||
mObserver->OnDataAvailable(nsnull, mImageFrame, &r);
|
||||
mObserver->OnDataAvailable(nsnull, imgCurFrame == PRUint32(mGIFStruct.images_decoded), &r);
|
||||
}
|
||||
}
|
||||
|
||||
PRUint32 imageDataLength;
|
||||
nsresult rv;
|
||||
gfxASurface::gfxImageFormat format;
|
||||
if (mGIFStruct.is_transparent)
|
||||
format = gfxASurface::ImageFormatARGB32;
|
||||
else
|
||||
format = gfxASurface::ImageFormatRGB24;
|
||||
|
||||
// Use correct format, RGB for first frame, PAL for following frames
|
||||
// and include transparency to allow for optimization of opaque images
|
||||
gfx_format format;
|
||||
if (mGIFStruct.images_decoded) {
|
||||
// Image data is stored with original depth and palette
|
||||
format = mGIFStruct.is_transparent ? gfxIFormats::PAL_A1 : gfxIFormats::PAL;
|
||||
rv = mImageContainer->AppendPalettedFrame(mGIFStruct.x_offset, mGIFStruct.y_offset,
|
||||
mGIFStruct.width, mGIFStruct.height,
|
||||
format, aDepth, &mImageData, &imageDataLength,
|
||||
&mColormap, &mColormapSize);
|
||||
|
||||
|
||||
} else {
|
||||
// Regardless of depth of input, image is decoded into 24bit RGB
|
||||
format = mGIFStruct.is_transparent ? gfxIFormats::RGB_A1 : gfxIFormats::RGB;
|
||||
aDepth = 24;
|
||||
rv = mImageContainer->AppendFrame(mGIFStruct.x_offset, mGIFStruct.y_offset,
|
||||
mGIFStruct.width, mGIFStruct.height,
|
||||
format, &mImageData, &imageDataLength);
|
||||
}
|
||||
|
||||
// initialize the frame and append it to the container
|
||||
mImageFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
|
||||
if (!mImageFrame || NS_FAILED(mImageFrame->Init(
|
||||
mGIFStruct.x_offset, mGIFStruct.y_offset,
|
||||
mGIFStruct.width, mGIFStruct.height, format, aDepth))) {
|
||||
mImageFrame = 0;
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
}
|
||||
|
||||
mImageFrame->SetFrameDisposalMethod(mGIFStruct.disposal_method);
|
||||
if (!mGIFStruct.images_decoded)
|
||||
mImageContainer->AppendFrame(mImageFrame);
|
||||
mImageContainer->SetFrameDisposalMethod(mGIFStruct.images_decoded,
|
||||
mGIFStruct.disposal_method);
|
||||
|
||||
if (mObserver)
|
||||
mObserver->OnStartFrame(nsnull, mImageFrame);
|
||||
|
||||
PRUint32 imageDataLength;
|
||||
mImageFrame->GetImageData(&mImageData, &imageDataLength);
|
||||
mObserver->OnStartFrame(nsnull, mGIFStruct.images_decoded);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -384,20 +386,23 @@ void nsGIFDecoder2::EndImageFrame()
|
|||
// This will clear the remaining bits of the placeholder. (Bug 37589)
|
||||
const PRUint32 realFrameHeight = mGIFStruct.height + mGIFStruct.y_offset;
|
||||
if (realFrameHeight < mGIFStruct.screen_height) {
|
||||
PRUint32 imgCurFrame;
|
||||
mImageContainer->GetCurrentFrameIndex(&imgCurFrame);
|
||||
nsIntRect r(0, realFrameHeight,
|
||||
mGIFStruct.screen_width,
|
||||
mGIFStruct.screen_height - realFrameHeight);
|
||||
mObserver->OnDataAvailable(nsnull, mImageFrame, &r);
|
||||
mObserver->OnDataAvailable(nsnull, imgCurFrame == PRUint32(mGIFStruct.images_decoded), &r);
|
||||
}
|
||||
// This transparency check is only valid for first frame
|
||||
if (mGIFStruct.is_transparent && !mSawTransparency) {
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(mImageFrame));
|
||||
img->SetHasNoAlpha();
|
||||
mImageContainer->SetFrameHasNoAlpha(mGIFStruct.images_decoded);
|
||||
}
|
||||
}
|
||||
mCurrentRow = mLastFlushedRow = -1;
|
||||
mCurrentPass = mLastFlushedPass = 0;
|
||||
|
||||
PRUint32 curframe = mGIFStruct.images_decoded;
|
||||
|
||||
// Only add frame if we have any rows at all
|
||||
if (mGIFStruct.rows_remaining != mGIFStruct.height) {
|
||||
if (mGIFStruct.rows_remaining && mGIFStruct.images_decoded) {
|
||||
|
|
@ -410,18 +415,14 @@ void nsGIFDecoder2::EndImageFrame()
|
|||
// image data, at least according to the spec, but we delay in setting the
|
||||
// timeout for the image until here to help ensure that we have the whole
|
||||
// image frame decoded before we go off and try to display another frame.
|
||||
mImageFrame->SetTimeout(mGIFStruct.delay_time);
|
||||
if (mGIFStruct.images_decoded)
|
||||
mImageContainer->AppendFrame(mImageFrame);
|
||||
mImageContainer->SetFrameTimeout(mGIFStruct.images_decoded, mGIFStruct.delay_time);
|
||||
mImageContainer->EndFrameDecode(mGIFStruct.images_decoded);
|
||||
mGIFStruct.images_decoded++;
|
||||
|
||||
mGIFStruct.images_decoded++;
|
||||
}
|
||||
|
||||
if (mObserver)
|
||||
mObserver->OnStopFrame(nsnull, mImageFrame);
|
||||
|
||||
// Release reference to this frame
|
||||
mImageFrame = nsnull;
|
||||
mObserver->OnStopFrame(nsnull, curframe);
|
||||
|
||||
// Reset the transparent pixel
|
||||
if (mOldColor) {
|
||||
|
|
@ -497,7 +498,7 @@ PRUint32 nsGIFDecoder2::OutputRow()
|
|||
if (drow_end > drow_start) {
|
||||
// irow is the current row filled
|
||||
for (int r = drow_start; r <= drow_end; r++) {
|
||||
if (r != mGIFStruct.irow) {
|
||||
if (r != int(mGIFStruct.irow)) {
|
||||
memcpy(mImageData + (r * bpr), rowp, bpr);
|
||||
}
|
||||
}
|
||||
|
|
@ -1060,7 +1061,7 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len)
|
|||
BeginImageFrame(realDepth);
|
||||
|
||||
// handle allocation error
|
||||
if (!mImageFrame) {
|
||||
if (!mImageData) {
|
||||
mGIFStruct.state = gif_error;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1086,17 +1087,12 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len)
|
|||
if (q[8] & 0x80) /* has a local colormap? */
|
||||
{
|
||||
mGIFStruct.local_colormap_size = 1 << depth;
|
||||
PRUint32 paletteSize;
|
||||
if (mGIFStruct.images_decoded) {
|
||||
// Copy directly into the palette of current frame,
|
||||
// by pointing mColormap to that palette.
|
||||
mImageFrame->GetPaletteData(&mColormap, &paletteSize);
|
||||
} else {
|
||||
if (!mGIFStruct.images_decoded) {
|
||||
// First frame has local colormap, allocate space for it
|
||||
// as the image frame doesn't have its own palette
|
||||
paletteSize = sizeof(PRUint32) << realDepth;
|
||||
mColormapSize = sizeof(PRUint32) << realDepth;
|
||||
if (!mGIFStruct.local_colormap) {
|
||||
mGIFStruct.local_colormap = (PRUint32*)PR_MALLOC(paletteSize);
|
||||
mGIFStruct.local_colormap = (PRUint32*)PR_MALLOC(mColormapSize);
|
||||
if (!mGIFStruct.local_colormap) {
|
||||
mGIFStruct.state = gif_oom;
|
||||
break;
|
||||
|
|
@ -1105,9 +1101,9 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len)
|
|||
mColormap = mGIFStruct.local_colormap;
|
||||
}
|
||||
const PRUint32 size = 3 << depth;
|
||||
if (paletteSize > size) {
|
||||
if (mColormapSize > size) {
|
||||
// Clear the notfilled part of the colormap
|
||||
memset(((PRUint8*)mColormap) + size, 0, paletteSize - size);
|
||||
memset(((PRUint8*)mColormap) + size, 0, mColormapSize - size);
|
||||
}
|
||||
if (len < size) {
|
||||
// Use 'hold' pattern to get the image colormap
|
||||
|
|
@ -1122,12 +1118,11 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len)
|
|||
break;
|
||||
} else {
|
||||
/* Switch back to the global palette */
|
||||
mColormap = mGIFStruct.global_colormap;
|
||||
if (mGIFStruct.images_decoded) {
|
||||
// Copy global colormap into the palette of current frame
|
||||
PRUint32 size;
|
||||
mImageFrame->GetPaletteData(&mColormap, &size);
|
||||
memcpy(mColormap, mGIFStruct.global_colormap, size);
|
||||
memcpy(mColormap, mGIFStruct.global_colormap, mColormapSize);
|
||||
} else {
|
||||
mColormap = mGIFStruct.global_colormap;
|
||||
}
|
||||
}
|
||||
GETN(1, gif_lzw_start);
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@
|
|||
#include "imgIDecoder.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
|
||||
#include "GIF2.h"
|
||||
|
||||
|
|
@ -88,13 +87,13 @@ private:
|
|||
inline int ClearCode() const { return 1 << mGIFStruct.datasize; }
|
||||
|
||||
nsCOMPtr<imgIContainer> mImageContainer;
|
||||
nsCOMPtr<gfxIImageFrame> mImageFrame;
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
|
||||
PRInt32 mCurrentRow;
|
||||
PRInt32 mLastFlushedRow;
|
||||
|
||||
PRUint8 *mImageData; // Pointer to image data in either Cairo or 8bit format
|
||||
PRUint32 *mColormap; // Current colormap to be used in Cairo format
|
||||
PRUint32 mColormapSize;
|
||||
PRUint32 mOldColor; // The old value of the transparent pixel
|
||||
PRUint8 mCurrentPass;
|
||||
PRUint8 mLastFlushedPass;
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@
|
|||
#include "nsRect.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
||||
#include "nsIImage.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
||||
NS_IMPL_THREADSAFE_ADDREF(nsIconDecoder)
|
||||
|
|
@ -71,14 +70,11 @@ NS_IMETHODIMP nsIconDecoder::Init(imgILoad *aLoad)
|
|||
{
|
||||
mObserver = do_QueryInterface(aLoad); // we're holding 2 strong refs to the request.
|
||||
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;1");
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;2");
|
||||
if (!mImage) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
aLoad->SetImage(mImage);
|
||||
|
||||
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
|
||||
if (!mFrame) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -88,7 +84,7 @@ NS_IMETHODIMP nsIconDecoder::Close()
|
|||
|
||||
if (mObserver)
|
||||
{
|
||||
mObserver->OnStopFrame(nsnull, mFrame);
|
||||
mObserver->OnStopFrame(nsnull, 0);
|
||||
mObserver->OnStopContainer(nsnull, mImage);
|
||||
mObserver->OnStopDecode(nsnull, NS_OK, nsnull);
|
||||
}
|
||||
|
|
@ -120,17 +116,15 @@ NS_IMETHODIMP nsIconDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR
|
|||
if (mObserver)
|
||||
mObserver->OnStartContainer(nsnull, mImage);
|
||||
|
||||
rv = mFrame->Init(0, 0, w, h, gfxIFormats::BGRA, 24);
|
||||
PRUint32 imageLen;
|
||||
PRUint8 *imageData;
|
||||
|
||||
rv = mImage->AppendFrame(0, 0, w, h, gfxASurface::ImageFormatARGB32, &imageData, &imageLen);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
mImage->AppendFrame(mFrame);
|
||||
if (mObserver)
|
||||
mObserver->OnStartFrame(nsnull, mFrame);
|
||||
|
||||
PRUint32 imageLen;
|
||||
PRUint8 *imageData;
|
||||
mFrame->GetImageData(&imageData, &imageLen);
|
||||
mObserver->OnStartFrame(nsnull, 0);
|
||||
|
||||
// Ensure that there enough in the inputStream
|
||||
NS_ENSURE_TRUE(count >= imageLen, NS_ERROR_UNEXPECTED);
|
||||
|
|
@ -142,12 +136,11 @@ NS_IMETHODIMP nsIconDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR
|
|||
|
||||
// Notify the image...
|
||||
nsIntRect r(0, 0, w, h);
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(mFrame));
|
||||
rv = img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);
|
||||
rv = mImage->FrameUpdated(0, r);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
mObserver->OnDataAvailable(nsnull, mFrame, &r);
|
||||
mObserver->OnDataAvailable(nsnull, PR_TRUE, &r);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@
|
|||
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
|
||||
#define NS_ICONDECODER_CID \
|
||||
{ /* FFC08380-256C-11d5-9905-001083010E9B */ \
|
||||
|
|
@ -87,7 +86,6 @@ public:
|
|||
|
||||
private:
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<gfxIImageFrame> mFrame;
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@
|
|||
#include "nspr.h"
|
||||
#include "nsCRT.h"
|
||||
#include "ImageLogging.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "gfxColor.h"
|
||||
|
||||
|
|
@ -101,6 +100,7 @@ nsJPEGDecoder::nsJPEGDecoder()
|
|||
mState = JPEG_HEADER;
|
||||
mReading = PR_TRUE;
|
||||
mError = NS_OK;
|
||||
mImageData = nsnull;
|
||||
|
||||
mBytesToSkip = 0;
|
||||
memset(&mInfo, 0, sizeof(jpeg_decompress_struct));
|
||||
|
|
@ -187,7 +187,7 @@ NS_IMETHODIMP nsJPEGDecoder::Init(imgILoad *aLoad)
|
|||
mImageLoad->GetImage(getter_AddRefs(mImage));
|
||||
|
||||
if (!mImage) {
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;1");
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;2");
|
||||
if (!mImage)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
|
@ -473,49 +473,23 @@ nsresult nsJPEGDecoder::ProcessData(const char *data, PRUint32 count, PRUint32 *
|
|||
|
||||
mObserver->OnStartContainer(nsnull, mImage);
|
||||
|
||||
mImage->GetFrameAt(0, getter_AddRefs(mFrame));
|
||||
|
||||
if (mFrame) {
|
||||
PRInt32 width, height;
|
||||
mFrame->GetWidth(&width);
|
||||
mFrame->GetHeight(&height);
|
||||
|
||||
if ((width != (PRInt32)mInfo.image_width) ||
|
||||
(height != (PRInt32)mInfo.image_height)) {
|
||||
// Can't reuse frame, create a new one with correct size
|
||||
mFrame = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mFrame) {
|
||||
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
|
||||
if (!mFrame) {
|
||||
mState = JPEG_ERROR;
|
||||
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
|
||||
("} (could not create image frame)"));
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
gfx_format format = gfxIFormats::RGB;
|
||||
#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS)
|
||||
format = gfxIFormats::BGR;
|
||||
#endif
|
||||
|
||||
if (NS_FAILED(mFrame->Init(0, 0, mInfo.image_width, mInfo.image_height, format, 24))) {
|
||||
mState = JPEG_ERROR;
|
||||
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
|
||||
("} (could not initialize image frame)"));
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
mImage->AppendFrame(mFrame);
|
||||
|
||||
// Use EnsureCleanFrame so we don't create a new frame if we're being
|
||||
// reused for e.g. multipart/x-replace
|
||||
PRUint32 imagelength;
|
||||
if (NS_FAILED(mImage->EnsureCleanFrame(0, 0, 0, mInfo.image_width, mInfo.image_height,
|
||||
gfxASurface::ImageFormatRGB24,
|
||||
&mImageData, &imagelength))) {
|
||||
mState = JPEG_ERROR;
|
||||
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
|
||||
(" JPEGDecoderAccounting: nsJPEGDecoder::ProcessData -- created image frame with %ux%u pixels",
|
||||
mInfo.image_width, mInfo.image_height));
|
||||
("} (could not initialize image frame)"));
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
mObserver->OnStartFrame(nsnull, mFrame);
|
||||
PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG,
|
||||
(" JPEGDecoderAccounting: nsJPEGDecoder::ProcessData -- created image frame with %ux%u pixels",
|
||||
mInfo.image_width, mInfo.image_height));
|
||||
|
||||
mObserver->OnStartFrame(nsnull, 0);
|
||||
mState = JPEG_START_DECOMPRESS;
|
||||
}
|
||||
|
||||
|
|
@ -699,16 +673,9 @@ nsJPEGDecoder::OutputScanlines(PRBool* suspend)
|
|||
const PRUint32 top = mInfo.output_scanline;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
mFrame->LockImageData();
|
||||
|
||||
// we're thebes. we can write stuff directly to the data
|
||||
PRUint8 *imageData;
|
||||
PRUint32 imageDataLength;
|
||||
mFrame->GetImageData(&imageData, &imageDataLength);
|
||||
|
||||
while ((mInfo.output_scanline < mInfo.output_height)) {
|
||||
/* Use the Cairo image buffer as scanline buffer */
|
||||
PRUint32 *imageRow = ((PRUint32*)imageData) +
|
||||
PRUint32 *imageRow = ((PRUint32*)mImageData) +
|
||||
(mInfo.output_scanline * mInfo.output_width);
|
||||
|
||||
if (mInfo.cconvert->color_convert == ycc_rgb_convert_argb) {
|
||||
|
|
@ -791,13 +758,10 @@ nsJPEGDecoder::OutputScanlines(PRBool* suspend)
|
|||
|
||||
if (top != mInfo.output_scanline) {
|
||||
nsIntRect r(0, top, mInfo.output_width, mInfo.output_scanline-top);
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(mFrame));
|
||||
rv = img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);
|
||||
mObserver->OnDataAvailable(nsnull, mFrame, &r);
|
||||
rv = mImage->FrameUpdated(0, r);
|
||||
mObserver->OnDataAvailable(nsnull, PR_TRUE, &r);
|
||||
}
|
||||
|
||||
mFrame->UnlockImageData();
|
||||
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
@ -1013,15 +977,16 @@ term_source (j_decompress_ptr jd)
|
|||
nsJPEGDecoder *decoder = (nsJPEGDecoder *)(jd->client_data);
|
||||
|
||||
if (decoder->mObserver) {
|
||||
decoder->mObserver->OnStopFrame(nsnull, decoder->mFrame);
|
||||
decoder->mObserver->OnStopFrame(nsnull, 0);
|
||||
decoder->mObserver->OnStopContainer(nsnull, decoder->mImage);
|
||||
decoder->mObserver->OnStopDecode(nsnull, NS_OK, nsnull);
|
||||
}
|
||||
|
||||
PRBool isMutable = PR_FALSE;
|
||||
PRBool multipart = PR_FALSE;
|
||||
if (decoder->mImageLoad)
|
||||
decoder->mImageLoad->GetIsMultiPartChannel(&isMutable);
|
||||
decoder->mFrame->SetMutable(isMutable);
|
||||
decoder->mImageLoad->GetIsMultiPartChannel(&multipart);
|
||||
if (!multipart)
|
||||
decoder->mImage->DecodingComplete();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@
|
|||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "imgILoad.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
|
@ -99,9 +98,9 @@ protected:
|
|||
public:
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<imgILoad> mImageLoad;
|
||||
nsCOMPtr<gfxIImageFrame> mFrame;
|
||||
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver;
|
||||
PRUint8 *mImageData;
|
||||
|
||||
struct jpeg_decompress_struct mInfo;
|
||||
struct jpeg_source_mgr mSourceMgr;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@
|
|||
#include "nsIInputStream.h"
|
||||
|
||||
#include "imgIContainerObserver.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
||||
#include "gfxColor.h"
|
||||
|
|
@ -99,25 +98,29 @@ nsPNGDecoder::~nsPNGDecoder()
|
|||
|
||||
// CreateFrame() is used for both simple and animated images
|
||||
void nsPNGDecoder::CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,
|
||||
PRInt32 width, PRInt32 height, gfx_format format)
|
||||
PRInt32 width, PRInt32 height,
|
||||
gfxASurface::gfxImageFormat format)
|
||||
{
|
||||
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2");
|
||||
if (!mFrame)
|
||||
longjmp(mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY
|
||||
|
||||
nsresult rv = mFrame->Init(x_offset, y_offset, width, height, format, 24);
|
||||
PRUint32 imageDataLength;
|
||||
nsresult rv = mImage->AppendFrame(x_offset, y_offset, width, height, format,
|
||||
&mImageData, &imageDataLength);
|
||||
if (NS_FAILED(rv))
|
||||
longjmp(mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY
|
||||
|
||||
mFrameRect.x = x_offset;
|
||||
mFrameRect.y = y_offset;
|
||||
mFrameRect.width = width;
|
||||
mFrameRect.height = height;
|
||||
|
||||
if (png_get_valid(mPNG, mInfo, PNG_INFO_acTL))
|
||||
SetAnimFrameInfo();
|
||||
|
||||
mImage->AppendFrame(mFrame);
|
||||
|
||||
if (mObserver)
|
||||
mObserver->OnStartFrame(nsnull, mFrame);
|
||||
|
||||
|
||||
PRUint32 numFrames = 0;
|
||||
mImage->GetNumFrames(&numFrames);
|
||||
|
||||
if (mObserver)
|
||||
mObserver->OnStartFrame(nsnull, numFrames - 1);
|
||||
|
||||
PR_LOG(gPNGDecoderAccountingLog, PR_LOG_DEBUG,
|
||||
("PNGDecoderAccounting: nsPNGDecoder::CreateFrame -- created image frame with %dx%d pixels in container %p",
|
||||
width, height,
|
||||
|
|
@ -141,7 +144,7 @@ void nsPNGDecoder::SetAnimFrameInfo()
|
|||
blend_op = png_get_next_frame_blend_op(mPNG, mInfo);
|
||||
|
||||
if (delay_num == 0) {
|
||||
timeout = 0; // gfxImageFrame::SetTimeout() will set to a minimum
|
||||
timeout = 0; // SetFrameTimeout() will set to a minimum
|
||||
} else {
|
||||
if (delay_den == 0)
|
||||
delay_den = 100; // so says the APNG spec
|
||||
|
|
@ -151,54 +154,49 @@ void nsPNGDecoder::SetAnimFrameInfo()
|
|||
timeout = static_cast<PRInt32>
|
||||
(static_cast<PRFloat64>(delay_num) * 1000 / delay_den);
|
||||
}
|
||||
mFrame->SetTimeout(timeout);
|
||||
|
||||
PRUint32 numFrames = 0;
|
||||
mImage->GetNumFrames(&numFrames);
|
||||
|
||||
mImage->SetFrameTimeout(numFrames - 1, timeout);
|
||||
|
||||
if (dispose_op == PNG_DISPOSE_OP_PREVIOUS)
|
||||
mFrame->SetFrameDisposalMethod(imgIContainer::kDisposeRestorePrevious);
|
||||
mImage->SetFrameDisposalMethod(numFrames - 1, imgIContainer::kDisposeRestorePrevious);
|
||||
else if (dispose_op == PNG_DISPOSE_OP_BACKGROUND)
|
||||
mFrame->SetFrameDisposalMethod(imgIContainer::kDisposeClear);
|
||||
mImage->SetFrameDisposalMethod(numFrames - 1, imgIContainer::kDisposeClear);
|
||||
else
|
||||
mFrame->SetFrameDisposalMethod(imgIContainer::kDisposeKeep);
|
||||
mImage->SetFrameDisposalMethod(numFrames - 1, imgIContainer::kDisposeKeep);
|
||||
|
||||
if (blend_op == PNG_BLEND_OP_SOURCE)
|
||||
mFrame->SetBlendMethod(imgIContainer::kBlendSource);
|
||||
/*else // 'over' is the default for a gfxImageFrame
|
||||
mFrame->SetBlendMethod(imgIContainer::kBlendOver); */
|
||||
mImage->SetFrameBlendMethod(numFrames - 1, imgIContainer::kBlendSource);
|
||||
/*else // 'over' is the default
|
||||
mImage->SetFrameBlendMethod(numFrames - 1, imgIContainer::kBlendOver); */
|
||||
}
|
||||
|
||||
// set timeout and frame disposal method for the current frame
|
||||
void nsPNGDecoder::EndImageFrame()
|
||||
{
|
||||
if (mFrameHasNoAlpha) {
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(mFrame));
|
||||
img->SetHasNoAlpha();
|
||||
}
|
||||
|
||||
// First tell the container that this frame is complete
|
||||
PRInt32 timeout = 100;
|
||||
PRUint32 numFrames = 0;
|
||||
mFrame->GetTimeout(&timeout);
|
||||
mImage->GetNumFrames(&numFrames);
|
||||
|
||||
// We can't use mPNG->num_frames_read as it may be one ahead.
|
||||
if (numFrames > 1) {
|
||||
// Tell the image renderer that the frame is complete
|
||||
PRInt32 width, height;
|
||||
mFrame->GetWidth(&width);
|
||||
mFrame->GetHeight(&height);
|
||||
if (mFrameHasNoAlpha)
|
||||
mImage->SetFrameHasNoAlpha(numFrames - 1);
|
||||
|
||||
nsIntRect r(0, 0, width, height);
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(mFrame));
|
||||
if (NS_FAILED(img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r))) {
|
||||
if (NS_FAILED(mImage->FrameUpdated(numFrames - 1, mFrameRect))) {
|
||||
mError = PR_TRUE;
|
||||
// allow the call out to the observers.
|
||||
}
|
||||
mObserver->OnDataAvailable(nsnull, mFrame, &r);
|
||||
PRUint32 curFrame;
|
||||
mImage->GetCurrentFrameIndex(&curFrame);
|
||||
mObserver->OnDataAvailable(nsnull, curFrame == numFrames - 1, &mFrameRect);
|
||||
}
|
||||
|
||||
mImage->EndFrameDecode(numFrames);
|
||||
mImage->EndFrameDecode(numFrames - 1);
|
||||
if (mObserver)
|
||||
mObserver->OnStopFrame(nsnull, mFrame);
|
||||
mObserver->OnStopFrame(nsnull, numFrames - 1);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -265,7 +263,7 @@ NS_IMETHODIMP nsPNGDecoder::Init(imgILoad *aLoad)
|
|||
*/
|
||||
mImageLoad->GetImage(getter_AddRefs(mImage));
|
||||
if (!mImage) {
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;1");
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;2");
|
||||
if (!mImage)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
|
@ -556,12 +554,11 @@ info_callback(png_structp png_ptr, png_infop info_ptr)
|
|||
decoder->mInProfile = PNGGetColorProfile(png_ptr, info_ptr,
|
||||
color_type, &inType, &pIntent);
|
||||
/* If we're not mandating an intent, use the one from the image. */
|
||||
if (intent == -1)
|
||||
if (intent == PRUint32(-1))
|
||||
intent = pIntent;
|
||||
}
|
||||
if (decoder->mInProfile && gfxPlatform::GetCMSOutputProfile()) {
|
||||
qcms_data_type outType;
|
||||
PRUint32 dwFlags = 0;
|
||||
|
||||
if (color_type & PNG_COLOR_MASK_ALPHA || num_trans)
|
||||
outType = QCMS_DATA_RGBA_8;
|
||||
|
|
@ -631,22 +628,17 @@ info_callback(png_structp png_ptr, png_infop info_ptr)
|
|||
if (containerWidth == 0 && containerHeight == 0) {
|
||||
// the image hasn't been inited yet
|
||||
decoder->mImage->Init(width, height, decoder->mObserver);
|
||||
} else if (containerWidth != width || containerHeight != height) {
|
||||
} else if (containerWidth != PRInt32(width) || containerHeight != PRInt32(height)) {
|
||||
longjmp(decoder->mPNG->jmpbuf, 5); // NS_ERROR_UNEXPECTED
|
||||
}
|
||||
|
||||
if (decoder->mObserver)
|
||||
decoder->mObserver->OnStartContainer(nsnull, decoder->mImage);
|
||||
|
||||
if (channels == 1 || channels == 3) {
|
||||
decoder->format = gfxIFormats::RGB;
|
||||
} else if (channels == 2 || channels == 4) {
|
||||
if (alpha_bits == 8) {
|
||||
decoder->format = gfxIFormats::RGB_A8;
|
||||
} else if (alpha_bits == 1) {
|
||||
decoder->format = gfxIFormats::RGB_A1;
|
||||
}
|
||||
}
|
||||
if (channels == 1 || channels == 3)
|
||||
decoder->format = gfxASurface::ImageFormatRGB24;
|
||||
else if (channels == 2 || channels == 4)
|
||||
decoder->format = gfxASurface::ImageFormatARGB32;
|
||||
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL))
|
||||
png_set_progressive_frame_fn(png_ptr, frame_info_callback, NULL);
|
||||
|
|
@ -674,9 +666,6 @@ info_callback(png_structp png_ptr, png_infop info_ptr)
|
|||
}
|
||||
}
|
||||
|
||||
if (png_get_first_frame_is_hidden(png_ptr, info_ptr))
|
||||
decoder->mFrame = nsnull;
|
||||
|
||||
/* Reject any ancillary chunk after IDAT with a bad CRC (bug #397593).
|
||||
* It would be better to show the default frame (if one has already been
|
||||
* successfully decoded) before bailing, but it's simpler to just bail
|
||||
|
|
@ -725,9 +714,8 @@ row_callback(png_structp png_ptr, png_bytep new_row,
|
|||
return;
|
||||
|
||||
if (new_row) {
|
||||
PRInt32 width;
|
||||
decoder->mFrame->GetWidth(&width);
|
||||
PRUint32 iwidth = width;
|
||||
PRInt32 width = decoder->mFrameRect.width;
|
||||
PRUint32 iwidth = decoder->mFrameRect.width;
|
||||
|
||||
png_bytep line = new_row;
|
||||
if (decoder->interlacebuf) {
|
||||
|
|
@ -735,11 +723,8 @@ row_callback(png_structp png_ptr, png_bytep new_row,
|
|||
png_progressive_combine_row(png_ptr, line, new_row);
|
||||
}
|
||||
|
||||
// we're thebes. we can write stuff directly to the data
|
||||
PRUint8 *imageData;
|
||||
PRUint32 imageDataLength, bpr = width * sizeof(PRUint32);
|
||||
decoder->mFrame->GetImageData(&imageData, &imageDataLength);
|
||||
PRUint32 *cptr32 = (PRUint32*)(imageData + (row_num*bpr));
|
||||
PRUint32 bpr = width * sizeof(PRUint32);
|
||||
PRUint32 *cptr32 = (PRUint32*)(decoder->mImageData + (row_num*bpr));
|
||||
PRBool rowHasNoAlpha = PR_TRUE;
|
||||
|
||||
if (decoder->mTransform) {
|
||||
|
|
@ -758,7 +743,7 @@ row_callback(png_structp png_ptr, png_bytep new_row,
|
|||
}
|
||||
|
||||
switch (decoder->format) {
|
||||
case gfxIFormats::RGB:
|
||||
case gfxASurface::ImageFormatRGB24:
|
||||
{
|
||||
// counter for while() loops below
|
||||
PRUint32 idx = iwidth;
|
||||
|
|
@ -785,17 +770,7 @@ row_callback(png_structp png_ptr, png_bytep new_row,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case gfxIFormats::RGB_A1:
|
||||
{
|
||||
for (PRUint32 x=iwidth; x>0; --x) {
|
||||
*cptr32++ = GFX_PACKED_PIXEL(line[3]?0xFF:0x00, line[0], line[1], line[2]);
|
||||
if (line[3] == 0)
|
||||
rowHasNoAlpha = PR_FALSE;
|
||||
line += 4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case gfxIFormats::RGB_A8:
|
||||
case gfxASurface::ImageFormatARGB32:
|
||||
{
|
||||
for (PRUint32 x=width; x>0; --x) {
|
||||
*cptr32++ = GFX_PACKED_PIXEL(line[3], line[0], line[1], line[2]);
|
||||
|
|
@ -805,6 +780,10 @@ row_callback(png_structp png_ptr, png_bytep new_row,
|
|||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("Unknown PNG format!");
|
||||
NS_ABORT();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rowHasNoAlpha)
|
||||
|
|
@ -815,12 +794,13 @@ row_callback(png_structp png_ptr, png_bytep new_row,
|
|||
if (numFrames <= 1) {
|
||||
// Only do incremental image display for the first frame
|
||||
nsIntRect r(0, row_num, width, 1);
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(decoder->mFrame));
|
||||
if (NS_FAILED(img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r))) {
|
||||
if (NS_FAILED(decoder->mImage->FrameUpdated(numFrames - 1, r))) {
|
||||
decoder->mError = PR_TRUE; /* bail */
|
||||
return;
|
||||
}
|
||||
decoder->mObserver->OnDataAvailable(nsnull, decoder->mFrame, &r);
|
||||
PRUint32 curFrame;
|
||||
decoder->mImage->GetCurrentFrameIndex(&curFrame);
|
||||
decoder->mObserver->OnDataAvailable(nsnull, curFrame == numFrames - 1, &r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,9 +44,8 @@
|
|||
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "imgILoad.h"
|
||||
|
||||
#include "gfxASurface.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
|
|
@ -72,25 +71,27 @@ public:
|
|||
virtual ~nsPNGDecoder();
|
||||
|
||||
void CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,
|
||||
PRInt32 width, PRInt32 height, gfx_format format);
|
||||
PRInt32 width, PRInt32 height,
|
||||
gfxASurface::gfxImageFormat format);
|
||||
void SetAnimFrameInfo();
|
||||
|
||||
void EndImageFrame();
|
||||
|
||||
public:
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<gfxIImageFrame> mFrame;
|
||||
nsCOMPtr<imgILoad> mImageLoad;
|
||||
nsCOMPtr<imgIDecoderObserver> mObserver; // this is just qi'd from mRequest for speed
|
||||
|
||||
png_structp mPNG;
|
||||
png_infop mInfo;
|
||||
nsIntRect mFrameRect;
|
||||
PRUint8 *mCMSLine;
|
||||
PRUint8 *interlacebuf;
|
||||
PRUint8 *mImageData;
|
||||
qcms_profile *mInProfile;
|
||||
qcms_transform *mTransform;
|
||||
|
||||
gfx_format format;
|
||||
gfxASurface::gfxImageFormat format;
|
||||
PRUint8 mChannels;
|
||||
PRPackedBool mError;
|
||||
PRPackedBool mFrameHasNoAlpha;
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@
|
|||
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
||||
#include "imgILoad.h"
|
||||
|
|
@ -56,7 +55,6 @@
|
|||
#include "nsISupportsPrimitives.h"
|
||||
|
||||
#include "gfxColor.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
||||
// Static colormap
|
||||
|
|
@ -82,11 +80,7 @@ NS_IMETHODIMP nsXBMDecoder::Init(imgILoad *aLoad)
|
|||
nsresult rv;
|
||||
mObserver = do_QueryInterface(aLoad);
|
||||
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;1", &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2", &rv);
|
||||
mImage = do_CreateInstance("@mozilla.org/image/container;2", &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
|
@ -106,7 +100,6 @@ NS_IMETHODIMP nsXBMDecoder::Close()
|
|||
mObserver->OnStopDecode(nsnull, NS_OK, nsnull);
|
||||
mObserver = nsnull;
|
||||
mImage = nsnull;
|
||||
mFrame = nsnull;
|
||||
mImageData = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
|
|
@ -198,7 +191,9 @@ nsresult nsXBMDecoder::ProcessData(const char* aData, PRUint32 aCount) {
|
|||
mImage->Init(mWidth, mHeight, mObserver);
|
||||
mObserver->OnStartContainer(nsnull, mImage);
|
||||
|
||||
nsresult rv = mFrame->Init(0, 0, mWidth, mHeight, gfxIFormats::RGB_A1, 24);
|
||||
PRUint32 imageLen;
|
||||
nsresult rv = mImage->AppendFrame(0, 0, mWidth, mHeight, gfxASurface::ImageFormatARGB32,
|
||||
(PRUint8**)&mImageData, &imageLen);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
|
@ -218,11 +213,7 @@ nsresult nsXBMDecoder::ProcessData(const char* aData, PRUint32 aCount) {
|
|||
}
|
||||
}
|
||||
|
||||
mImage->AppendFrame(mFrame);
|
||||
mObserver->OnStartFrame(nsnull, mFrame);
|
||||
|
||||
PRUint32 imageLen;
|
||||
mFrame->GetImageData((PRUint8**)&mImageData, &imageLen);
|
||||
mObserver->OnStartFrame(nsnull, 0);
|
||||
|
||||
mState = RECV_SEEK;
|
||||
|
||||
|
|
@ -240,7 +231,6 @@ nsresult nsXBMDecoder::ProcessData(const char* aData, PRUint32 aCount) {
|
|||
}
|
||||
}
|
||||
if (mState == RECV_DATA) {
|
||||
nsCOMPtr<nsIImage> img = do_GetInterface(mFrame);
|
||||
PRUint32 *ar = mImageData + mCurRow * mWidth + mCurCol;
|
||||
|
||||
do {
|
||||
|
|
@ -279,17 +269,17 @@ nsresult nsXBMDecoder::ProcessData(const char* aData, PRUint32 aCount) {
|
|||
mCurCol += numPixels;
|
||||
if (mCurCol == mWidth || mState == RECV_DONE) {
|
||||
nsIntRect r(0, mCurRow, mWidth, 1);
|
||||
nsresult rv = img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);
|
||||
nsresult rv = mImage->FrameUpdated(0, r);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mObserver->OnDataAvailable(nsnull, mFrame, &r);
|
||||
mObserver->OnDataAvailable(nsnull, PR_TRUE, &r);
|
||||
|
||||
mCurRow++;
|
||||
if (mCurRow == mHeight) {
|
||||
mState = RECV_DONE;
|
||||
return mObserver->OnStopFrame(nsnull, mFrame);
|
||||
return mObserver->OnStopFrame(nsnull, 0);
|
||||
}
|
||||
mCurCol = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@
|
|||
#include "imgIDecoder.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
|
||||
#define NS_XBMDECODER_CID \
|
||||
{ /* {dbfd145d-3298-4f3c-902f-2c5e1a1494ce} */ \
|
||||
|
|
@ -72,7 +71,6 @@ private:
|
|||
nsCOMPtr<imgIDecoderObserver> mObserver;
|
||||
|
||||
nsCOMPtr<imgIContainer> mImage;
|
||||
nsCOMPtr<gfxIImageFrame> mFrame;
|
||||
|
||||
PRUint32 mCurRow;
|
||||
PRUint32 mCurCol;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
* Federico Mena-Quintero <federico@novell.com>
|
||||
* Joe Drew <joe@drew.ca>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
|
@ -39,22 +40,113 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "gfxidltypes.idl"
|
||||
#include "gfxIFormats.idl"
|
||||
|
||||
interface gfxIImageFrame;
|
||||
interface imgIContainerObserver;
|
||||
|
||||
%{C++
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxMatrix.h"
|
||||
#include "gfxRect.h"
|
||||
#include "gfxPattern.h"
|
||||
#include "gfxASurface.h"
|
||||
#include "nsRect.h"
|
||||
%}
|
||||
|
||||
[ptr] native gfxImageSurface(gfxImageSurface);
|
||||
[ptr] native gfxASurface(gfxASurface);
|
||||
native gfxImageFormat(gfxASurface::gfxImageFormat);
|
||||
[ptr] native gfxContext(gfxContext);
|
||||
[ref] native gfxMatrix(gfxMatrix);
|
||||
[ref] native gfxRect(gfxRect);
|
||||
native gfxGraphicsFilter(gfxPattern::GraphicsFilter);
|
||||
[ref] native nsIntRect(nsIntRect);
|
||||
|
||||
/**
|
||||
* gfxIImageContainer interface
|
||||
* imgIContainer is the interface that represents an image. It allows
|
||||
* access to frames as Thebes surfaces, and permits users to extract subregions
|
||||
* as other imgIContainers. It also allows drawing of images on to Thebes
|
||||
* contexts.
|
||||
*
|
||||
* @author Stuart Parmenter <pavlov@netscape.com>
|
||||
* @version 0.2
|
||||
* @see "gfx2"
|
||||
* Internally, imgIContainer also manages animation of images.
|
||||
*/
|
||||
[scriptable, uuid(a4e9df32-f5d7-479f-9082-70e1fead23d5)]
|
||||
[scriptable, uuid(1bcf7a25-1356-47a8-bf80-e284989ea38f)]
|
||||
interface imgIContainer : nsISupports
|
||||
{
|
||||
/**
|
||||
* The width of the container rectangle.
|
||||
*/
|
||||
readonly attribute PRInt32 width;
|
||||
|
||||
/**
|
||||
* The height of the container rectangle.
|
||||
*/
|
||||
readonly attribute PRInt32 height;
|
||||
|
||||
/**
|
||||
* Whether this image is animated.
|
||||
*/
|
||||
readonly attribute boolean animated;
|
||||
|
||||
/**
|
||||
* Whether the current frame is opaque; that is, needs the background painted
|
||||
* behind it.
|
||||
*/
|
||||
readonly attribute boolean currentFrameIsOpaque;
|
||||
|
||||
/**
|
||||
* Get a surface for the current frame. This may be a platform-native,
|
||||
* optimized frame, so you cannot inspect its pixel data.
|
||||
*/
|
||||
[noscript] readonly attribute gfxASurface currentFrame;
|
||||
|
||||
/**
|
||||
* Create and return a new copy of the current frame that you can write to
|
||||
* and otherwise inspect the pixels of.
|
||||
*/
|
||||
[noscript] gfxImageSurface copyCurrentFrame();
|
||||
|
||||
/**
|
||||
* Create a new imgContainer that contains only a single frame, which itself
|
||||
* contains a subregion of the current frame.
|
||||
*
|
||||
* @param aRect the area of the current frame to be duplicated in the
|
||||
* returned imgContainer's frame.
|
||||
*/
|
||||
[noscript] imgIContainer extractCurrentFrame([const] in nsIntRect aRect);
|
||||
|
||||
/**
|
||||
* Draw the current frame on to the context specified.
|
||||
*
|
||||
* @param aContext The Thebex context to draw the image to.
|
||||
* @param aFilter The filter to be used if we're scaling the image.
|
||||
* @param aUserSpaceToImageSpace The transformation from user space (e.g.,
|
||||
* appunits) to image space.
|
||||
* @param aFill The area in the context to draw pixels to. Image will be
|
||||
* automatically tiled as necessary.
|
||||
* @param @aSubimage The area of the image, in pixels, that we are allowed to
|
||||
* sample from.
|
||||
*/
|
||||
[noscript] void draw(in gfxContext aContext, in gfxGraphicsFilter aFilter,
|
||||
in gfxMatrix aUserSpaceToImageSpace, in gfxRect aFill,
|
||||
in nsIntRect aSubimage);
|
||||
|
||||
|
||||
/************ Internal libpr0n use only below here. *****************/
|
||||
|
||||
/**
|
||||
* Create a new \a aWidth x \a aHeight sized image container.
|
||||
*
|
||||
* @param aWidth The width of the container in which all the
|
||||
* frames will fit.
|
||||
* @param aHeight The height of the container in which all the
|
||||
* frames will fit.
|
||||
* @param aObserver Observer to send animation notifications to.
|
||||
*/
|
||||
void init(in PRInt32 aWidth,
|
||||
in PRInt32 aHeight,
|
||||
in imgIContainerObserver aObserver);
|
||||
|
||||
/**
|
||||
* "Disposal" method indicates how the image should be handled before the
|
||||
* subsequent image is displayed.
|
||||
|
|
@ -78,42 +170,6 @@ interface imgIContainer : nsISupports
|
|||
const long kBlendOver = 1; // The frame should be composited onto the output buffer
|
||||
// based on its alpha, using a simple OVER operation
|
||||
|
||||
/**
|
||||
* Create a new \a aWidth x \a aHeight sized image container.
|
||||
*
|
||||
* @param aWidth The width of the container in which all the
|
||||
* gfxIImageFrame children will fit.
|
||||
* @param aHeight The height of the container in which all the
|
||||
* gfxIImageFrame children will fit.
|
||||
* @param aObserver Observer to send animation notifications to.
|
||||
*/
|
||||
void init(in PRInt32 aWidth,
|
||||
in PRInt32 aHeight,
|
||||
in imgIContainerObserver aObserver);
|
||||
|
||||
|
||||
/* this should probably be on the device context (or equiv) */
|
||||
readonly attribute gfx_format preferredAlphaChannelFormat;
|
||||
|
||||
/**
|
||||
* The width of the container rectangle.
|
||||
*/
|
||||
readonly attribute PRInt32 width;
|
||||
|
||||
/**
|
||||
* The height of the container rectangle.
|
||||
*/
|
||||
readonly attribute PRInt32 height;
|
||||
|
||||
|
||||
/**
|
||||
* Get the current frame that would be drawn if the image was to be drawn now
|
||||
*/
|
||||
readonly attribute gfxIImageFrame currentFrame;
|
||||
|
||||
|
||||
readonly attribute unsigned long numFrames;
|
||||
|
||||
/**
|
||||
* Animation mode Constants
|
||||
* 0 = normal
|
||||
|
|
@ -126,13 +182,54 @@ interface imgIContainer : nsISupports
|
|||
|
||||
attribute unsigned short animationMode;
|
||||
|
||||
gfxIImageFrame getFrameAt(in unsigned long index);
|
||||
/**
|
||||
* The rectangle defining the location and size of the currently displayed frame.
|
||||
* Should be an attribute, but can't be because of reference/pointer
|
||||
* conflicts with native types in xpidl.
|
||||
*/
|
||||
[noscript] void getCurrentFrameRect(in nsIntRect aFrameRect);
|
||||
|
||||
/**
|
||||
* Adds \a item to the end of the list of frames.
|
||||
* @param item frame to add.
|
||||
* The index of the current frame that would be drawn if the image was to be
|
||||
* drawn now.
|
||||
*/
|
||||
void appendFrame(in gfxIImageFrame item);
|
||||
readonly attribute unsigned long currentFrameIndex;
|
||||
|
||||
/**
|
||||
* The total number of frames in this image.
|
||||
*/
|
||||
readonly attribute unsigned long numFrames;
|
||||
|
||||
/**
|
||||
* Get the size, in bytes, of a particular frame's image data.
|
||||
*/
|
||||
unsigned long getFrameImageDataLength(in unsigned long framenumber);
|
||||
|
||||
void getFrameColormap(in unsigned long framenumber,
|
||||
[array, size_is(paletteLength)] out PRUint32 paletteData,
|
||||
out unsigned long paletteLength);
|
||||
|
||||
void setFrameDisposalMethod(in unsigned long framenumber, in PRInt32 aDisposalMethod);
|
||||
void setFrameBlendMethod(in unsigned long framenumber, in PRInt32 aBlendMethod);
|
||||
void setFrameTimeout(in unsigned long framenumber, in PRInt32 aTimeout);
|
||||
void setFrameHasNoAlpha(in unsigned long framenumber);
|
||||
|
||||
/**
|
||||
* Create or re-use a frame at index aFrameNum. It is an error to call this with aFrameNum not in the range [0, numFrames].
|
||||
*/
|
||||
[noscript] void ensureCleanFrame(in unsigned long aFramenum, in PRInt32 aX, in PRInt32 aY, in PRInt32 aWidth, in PRInt32 aHeight, in gfxImageFormat aFormat,
|
||||
[array, size_is(imageLength)] out PRUint8 imageData, out unsigned long imageLength);
|
||||
|
||||
/**
|
||||
* Adds to the end of the list of frames.
|
||||
*/
|
||||
[noscript] void appendFrame(in PRInt32 aX, in PRInt32 aY, in PRInt32 aWidth, in PRInt32 aHeight, in gfxImageFormat aFormat,
|
||||
[array, size_is(imageLength)] out PRUint8 imageData, out unsigned long imageLength);
|
||||
[noscript] void appendPalettedFrame(in PRInt32 aX, in PRInt32 aY, in PRInt32 aWidth, in PRInt32 aHeight, in gfxImageFormat aFormat, in PRUint8 aPaletteDepth,
|
||||
[array, size_is(imageLength)] out PRUint8 imageData, out unsigned long imageLength,
|
||||
[array, size_is(paletteLength)] out PRUint32 paletteData, out unsigned long paletteLength);
|
||||
|
||||
[noscript] void frameUpdated(in unsigned long framenum, in nsIntRect aNewRect);
|
||||
|
||||
/* notification when the current frame is done decoding */
|
||||
void endFrameDecode(in unsigned long framenumber);
|
||||
|
|
|
|||
|
|
@ -46,18 +46,14 @@
|
|||
|
||||
interface imgIContainer;
|
||||
|
||||
interface gfxIImageFrame;
|
||||
|
||||
/**
|
||||
* imgIContainerObserver interface
|
||||
*
|
||||
* @author Stuart Parmenter <pavlov@netscape.com>
|
||||
* @version 0.1
|
||||
*/
|
||||
[scriptable, uuid(53102f15-0f53-4939-957e-aea353ad2700)]
|
||||
[scriptable, uuid(e214c295-4b8e-4aa9-9907-45289e57295b)]
|
||||
interface imgIContainerObserver : nsISupports
|
||||
{
|
||||
[noscript] void frameChanged(in imgIContainer aContainer,
|
||||
in gfxIImageFrame aFrame,
|
||||
in nsIntRect aDirtyRect);
|
||||
[noscript] void frameChanged(in imgIContainer aContainer, in nsIntRect aDirtyRect);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@
|
|||
|
||||
interface imgIRequest;
|
||||
interface imgIContainer;
|
||||
interface gfxIImageFrame;
|
||||
|
||||
%{C++
|
||||
#include "nsRect.h"
|
||||
|
|
@ -59,7 +58,7 @@ interface gfxIImageFrame;
|
|||
* @version 0.1
|
||||
* @see imagelib2
|
||||
*/
|
||||
[scriptable, uuid(876f14ee-f27c-41cd-b6fb-9efda3ebc7b5)]
|
||||
[scriptable, uuid(1dfc9189-6421-4281-83b2-d9c1c9ba4d1b)]
|
||||
interface imgIDecoderObserver : imgIContainerObserver
|
||||
{
|
||||
/**
|
||||
|
|
@ -85,17 +84,17 @@ interface imgIDecoderObserver : imgIContainerObserver
|
|||
/**
|
||||
* called when each frame is created
|
||||
*/
|
||||
void onStartFrame(in imgIRequest aRequest, in gfxIImageFrame aFrame);
|
||||
void onStartFrame(in imgIRequest aRequest, in unsigned long aFrame);
|
||||
|
||||
/**
|
||||
* called when some part of the frame has new data in it
|
||||
*/
|
||||
[noscript] void onDataAvailable(in imgIRequest aRequest, in gfxIImageFrame aFrame, [const] in nsIntRect aRect);
|
||||
[noscript] void onDataAvailable(in imgIRequest aRequest, in boolean aCurrentFrame, [const] in nsIntRect aRect);
|
||||
|
||||
/**
|
||||
* called when a frame is finished decoding
|
||||
*/
|
||||
void onStopFrame(in imgIRequest aRequest, in gfxIImageFrame aFrame);
|
||||
void onStopFrame(in imgIRequest aRequest, in unsigned long aFrame);
|
||||
|
||||
/**
|
||||
* probably not needed. called right before onStopDecode
|
||||
|
|
|
|||
|
|
@ -59,10 +59,12 @@ REQUIRES = xpcom \
|
|||
xpconnect \
|
||||
js \
|
||||
uriloader \
|
||||
qcms \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
imgContainer.cpp \
|
||||
imgFrame.cpp \
|
||||
imgLoader.cpp \
|
||||
imgRequest.cpp \
|
||||
imgRequestProxy.cpp \
|
||||
|
|
@ -70,3 +72,7 @@ CPPSRCS = \
|
|||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
# Because imgFrame.cpp includes "cairo.h"
|
||||
CXXFLAGS += $(MOZ_CAIRO_CFLAGS)
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -55,18 +55,18 @@
|
|||
#include "nsCOMArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIProperties.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsTArray.h"
|
||||
#include "imgFrame.h"
|
||||
|
||||
#define NS_IMGCONTAINER_CID \
|
||||
{ /* 27f0682c-ff64-4dd2-ae7a-668e59f2fd38 */ \
|
||||
0x27f0682c, \
|
||||
0xff64, \
|
||||
0x4dd2, \
|
||||
{0xae, 0x7a, 0x66, 0x8e, 0x59, 0xf2, 0xfd, 0x38} \
|
||||
{ /* c76ff2c1-9bf6-418a-b143-3340c00112f7 */ \
|
||||
0x376ff2c1, \
|
||||
0x9bf6, \
|
||||
0x418a, \
|
||||
{0xb1, 0x43, 0x33, 0x40, 0xc0, 0x01, 0x12, 0xf7} \
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -167,14 +167,14 @@ private:
|
|||
* lastCompositedFrameIndex to -1. Code assume that if
|
||||
* lastCompositedFrameIndex >= 0 then compositingFrame exists.
|
||||
*/
|
||||
nsCOMPtr<gfxIImageFrame> compositingFrame;
|
||||
nsAutoPtr<imgFrame> compositingFrame;
|
||||
/** the previous composited frame, for DISPOSE_RESTORE_PREVIOUS
|
||||
*
|
||||
* The Previous Frame (all frames composited up to the current) needs to be
|
||||
* stored in cases where the image specifies it wants the last frame back
|
||||
* when it's done with the current frame.
|
||||
*/
|
||||
nsCOMPtr<gfxIImageFrame> compositingPrevFrame;
|
||||
nsAutoPtr<imgFrame> compositingPrevFrame;
|
||||
//! Timer to animate multiframed images
|
||||
nsCOMPtr<nsITimer> timer;
|
||||
|
||||
|
|
@ -195,7 +195,9 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
gfxIImageFrame* GetCurrentFrameNoRef();
|
||||
imgFrame* GetImgFrame(PRUint32 framenum);
|
||||
imgFrame* GetCurrentImgFrame();
|
||||
PRInt32 GetCurrentImgFrameIndex() const;
|
||||
|
||||
inline Anim* ensureAnimExists() {
|
||||
if (!mAnim)
|
||||
|
|
@ -212,76 +214,53 @@ private:
|
|||
* @param aNextFrame Frame we need to incorperate/display
|
||||
* @param aNextFrameIndex Position of aNextFrame in mFrames list
|
||||
*/
|
||||
nsresult DoComposite(gfxIImageFrame** aFrameToUse, nsIntRect* aDirtyRect,
|
||||
gfxIImageFrame* aPrevFrame,
|
||||
gfxIImageFrame* aNextFrame,
|
||||
nsresult DoComposite(imgFrame** aFrameToUse, nsIntRect* aDirtyRect,
|
||||
imgFrame* aPrevFrame,
|
||||
imgFrame* aNextFrame,
|
||||
PRInt32 aNextFrameIndex);
|
||||
|
||||
/**
|
||||
* Combine aOverlayFrame's mask into aCompositingFrame's mask.
|
||||
*
|
||||
* This takes the mask information from the passed in aOverlayFrame and
|
||||
* inserts that information into the aCompositingFrame's mask at the proper
|
||||
* offsets. It does *not* rebuild the entire mask.
|
||||
*
|
||||
* @param aCompositingFrame Target frame
|
||||
* @param aOverlayFrame This frame's mask is being copied
|
||||
*/
|
||||
void BuildCompositeMask(gfxIImageFrame* aCompositingFrame,
|
||||
gfxIImageFrame* aOverlayFrame);
|
||||
|
||||
/** Sets an area of the frame's mask.
|
||||
*
|
||||
* @param aFrame Target Frame
|
||||
* @param aVisible Turn on (PR_TRUE) or off (PR_FALSE) visibility
|
||||
*
|
||||
* @note Invisible area of frame's image will need to be set to 0
|
||||
*/
|
||||
void SetMaskVisibility(gfxIImageFrame *aFrame, PRBool aVisible);
|
||||
//! @overload
|
||||
void SetMaskVisibility(gfxIImageFrame *aFrame,
|
||||
PRInt32 aX, PRInt32 aY,
|
||||
PRInt32 aWidth, PRInt32 aHeight,
|
||||
PRBool aVisible);
|
||||
//! @overload
|
||||
void SetMaskVisibility(gfxIImageFrame *aFrame,
|
||||
nsIntRect &aRect, PRBool aVisible) {
|
||||
SetMaskVisibility(aFrame, aRect.x, aRect.y,
|
||||
aRect.width, aRect.height, aVisible);
|
||||
}
|
||||
|
||||
/** Clears an area of <aFrame> with transparent black.
|
||||
*
|
||||
* @param aFrame Target Frame
|
||||
*
|
||||
* @note Does also clears the transparancy mask
|
||||
*/
|
||||
static void ClearFrame(gfxIImageFrame* aFrame);
|
||||
static void ClearFrame(imgFrame* aFrame);
|
||||
|
||||
//! @overload
|
||||
static void ClearFrame(gfxIImageFrame* aFrame, nsIntRect &aRect);
|
||||
static void ClearFrame(imgFrame* aFrame, nsIntRect &aRect);
|
||||
|
||||
//! Copy one gfxIImageFrame's image and mask into another
|
||||
static PRBool CopyFrameImage(gfxIImageFrame *aSrcFrame,
|
||||
gfxIImageFrame *aDstFrame);
|
||||
//! Copy one frames's image and mask into another
|
||||
static PRBool CopyFrameImage(imgFrame *aSrcFrame,
|
||||
imgFrame *aDstFrame);
|
||||
|
||||
/** Draws one gfxIImageFrame's image to into another,
|
||||
/** Draws one frames's image to into another,
|
||||
* at the position specified by aRect
|
||||
*
|
||||
* @param aSrcFrame Frame providing the source image
|
||||
* @param aDstFrame Frame where the image is drawn into
|
||||
* @param aRect The position and size to draw the image
|
||||
*/
|
||||
static nsresult DrawFrameTo(gfxIImageFrame *aSrcFrame,
|
||||
gfxIImageFrame *aDstFrame,
|
||||
static nsresult DrawFrameTo(imgFrame *aSrcFrame,
|
||||
imgFrame *aDstFrame,
|
||||
nsIntRect& aRect);
|
||||
|
||||
nsresult InternalAddFrameHelper(PRUint32 framenum, imgFrame *frame,
|
||||
PRUint8 **imageData, PRUint32 *imageLength,
|
||||
PRUint32 **paletteData, PRUint32 *paletteLength);
|
||||
nsresult InternalAddFrame(PRUint32 framenum, PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight,
|
||||
gfxASurface::gfxImageFormat aFormat, PRUint8 aPaletteDepth,
|
||||
PRUint8 **imageData, PRUint32 *imageLength,
|
||||
PRUint32 **paletteData, PRUint32 *paletteLength);
|
||||
|
||||
private: // data
|
||||
|
||||
nsIntSize mSize;
|
||||
|
||||
//! All the <gfxIImageFrame>s of the PNG
|
||||
//! All the frames of the image
|
||||
// *** IMPORTANT: if you use mFrames in a method, call RestoreDiscardedData() first to ensure
|
||||
// that the frames actually exist (they may have been discarded to save memory).
|
||||
nsCOMArray<gfxIImageFrame> mFrames;
|
||||
nsTArray<imgFrame *> mFrames;
|
||||
int mNumFrames; /* stored separately from mFrames.Count() to support discarded images */
|
||||
|
||||
nsCOMPtr<nsIProperties> mProperties;
|
||||
|
|
|
|||
922
modules/libpr0n/src/imgFrame.cpp
Normal file
922
modules/libpr0n/src/imgFrame.cpp
Normal file
|
|
@ -0,0 +1,922 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Joe Drew <joe@drew.ca> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "imgFrame.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "prmem.h"
|
||||
#include "prenv.h"
|
||||
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
static PRBool gDisableOptimize = PR_FALSE;
|
||||
|
||||
/*XXX get CAIRO_HAS_DDRAW_SURFACE */
|
||||
#include "cairo.h"
|
||||
|
||||
#ifdef CAIRO_HAS_DDRAW_SURFACE
|
||||
#include "gfxDDrawSurface.h"
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN) || defined(WINCE)
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN) && !defined(WINCE)
|
||||
|
||||
/* Whether to use the windows surface; only for desktop win32 */
|
||||
#define USE_WIN_SURFACE 1
|
||||
|
||||
static PRUint32 gTotalDDBs = 0;
|
||||
static PRUint32 gTotalDDBSize = 0;
|
||||
// only use up a maximum of 64MB in DDBs
|
||||
#define kMaxDDBSize (64*1024*1024)
|
||||
// and don't let anything in that's bigger than 4MB
|
||||
#define kMaxSingleDDBSize (4*1024*1024)
|
||||
|
||||
#endif
|
||||
|
||||
// Returns true if an image of aWidth x aHeight is allowed and legal.
|
||||
static PRBool AllowedImageSize(PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
NS_ASSERTION(aWidth > 0, "invalid image width");
|
||||
NS_ASSERTION(aHeight > 0, "invalid image height");
|
||||
|
||||
// reject over-wide or over-tall images
|
||||
const PRInt32 k64KLimit = 0x0000FFFF;
|
||||
if (NS_UNLIKELY(aWidth > k64KLimit || aHeight > k64KLimit )) {
|
||||
NS_WARNING("image too big");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// protect against division by zero - this really shouldn't happen
|
||||
// if our consumers were well behaved, but they aren't (bug 368427)
|
||||
if (NS_UNLIKELY(aHeight == 0)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// check to make sure we don't overflow a 32-bit
|
||||
PRInt32 tmp = aWidth * aHeight;
|
||||
if (NS_UNLIKELY(tmp / aHeight != aWidth)) {
|
||||
NS_WARNING("width or height too large");
|
||||
return PR_FALSE;
|
||||
}
|
||||
tmp = tmp * 4;
|
||||
if (NS_UNLIKELY(tmp / 4 != aWidth * aHeight)) {
|
||||
NS_WARNING("width or height too large");
|
||||
return PR_FALSE;
|
||||
}
|
||||
#if defined(XP_MACOSX)
|
||||
// CoreGraphics is limited to images < 32K in *height*, so clamp all surfaces on the Mac to that height
|
||||
if (NS_UNLIKELY(aHeight > SHRT_MAX)) {
|
||||
NS_WARNING("image too big");
|
||||
return PR_FALSE;
|
||||
}
|
||||
#endif
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// Returns whether we should, at this time, use image surfaces instead of
|
||||
// optimized platform-specific surfaces.
|
||||
static PRBool ShouldUseImageSurfaces()
|
||||
{
|
||||
#if defined(WINCE)
|
||||
// There is no test on windows mobile to check for Gui resources.
|
||||
// Allocate, until we run out of memory.
|
||||
gfxWindowsPlatform::RenderMode rmode = gfxWindowsPlatform::GetPlatform()->GetRenderMode();
|
||||
return rmode != gfxWindowsPlatform::RENDER_DDRAW &&
|
||||
rmode != gfxWindowsPlatform::RENDER_DDRAW_GL;
|
||||
|
||||
#elif defined(USE_WIN_SURFACE)
|
||||
static const DWORD kGDIObjectsHighWaterMark = 7000;
|
||||
|
||||
// at 7000 GDI objects, stop allocating normal images to make sure
|
||||
// we never hit the 10k hard limit.
|
||||
// GetCurrentProcess() just returns (HANDLE)-1, it's inlined afaik
|
||||
DWORD count = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS);
|
||||
if (count == 0 ||
|
||||
count > kGDIObjectsHighWaterMark)
|
||||
{
|
||||
// either something's broken (count == 0),
|
||||
// or we hit our high water mark; disable
|
||||
// image allocations for a bit.
|
||||
return PR_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
imgFrame::imgFrame() :
|
||||
mDecoded(0, 0, 0, 0),
|
||||
mPalettedImageData(nsnull),
|
||||
mSinglePixelColor(0),
|
||||
mTimeout(100),
|
||||
mDisposalMethod(0), /* imgIContainer::kDisposeNotSpecified */
|
||||
mBlendMethod(1), /* imgIContainer::kBlendOver */
|
||||
mSinglePixel(PR_FALSE),
|
||||
mNeverUseDeviceSurface(PR_FALSE),
|
||||
mFormatChanged(PR_FALSE)
|
||||
#ifdef USE_WIN_SURFACE
|
||||
, mIsDDBSurface(PR_FALSE)
|
||||
#endif
|
||||
{
|
||||
static PRBool hasCheckedOptimize = PR_FALSE;
|
||||
if (!hasCheckedOptimize) {
|
||||
if (PR_GetEnv("MOZ_DISABLE_IMAGE_OPTIMIZE")) {
|
||||
gDisableOptimize = PR_TRUE;
|
||||
}
|
||||
hasCheckedOptimize = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
imgFrame::~imgFrame()
|
||||
{
|
||||
PR_FREEIF(mPalettedImageData);
|
||||
#ifdef USE_WIN_SURFACE
|
||||
if (mIsDDBSurface) {
|
||||
gTotalDDBs--;
|
||||
gTotalDDBSize -= mSize.width * mSize.height * 4;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult imgFrame::Init(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight,
|
||||
gfxASurface::gfxImageFormat aFormat, PRInt8 aPaletteDepth /* = 0 */)
|
||||
{
|
||||
// assert for properties that should be verified by decoders, warn for properties related to bad content
|
||||
if (!AllowedImageSize(aWidth, aHeight))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Check to see if we are running OOM
|
||||
nsCOMPtr<nsIMemory> mem;
|
||||
NS_GetMemoryManager(getter_AddRefs(mem));
|
||||
if (!mem)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
PRBool lowMemory;
|
||||
mem->IsLowMemory(&lowMemory);
|
||||
if (lowMemory)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mOffset.MoveTo(aX, aY);
|
||||
mSize.SizeTo(aWidth, aHeight);
|
||||
|
||||
mFormat = aFormat;
|
||||
mPaletteDepth = aPaletteDepth;
|
||||
|
||||
if (aPaletteDepth != 0) {
|
||||
// We're creating for a paletted image.
|
||||
if (aPaletteDepth > 8) {
|
||||
NS_ERROR("This Depth is not supported\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPalettedImageData = (PRUint8*)PR_MALLOC(PaletteDataLength() + GetImageDataLength());
|
||||
NS_ENSURE_TRUE(mPalettedImageData, NS_ERROR_OUT_OF_MEMORY);
|
||||
} else {
|
||||
// For Windows, we must create the device surface first (if we're
|
||||
// going to) so that the image surface can wrap it. Can't be done
|
||||
// the other way around.
|
||||
#ifdef USE_WIN_SURFACE
|
||||
if (!mNeverUseDeviceSurface && !ShouldUseImageSurfaces()) {
|
||||
mWinSurface = new gfxWindowsSurface(gfxIntSize(mSize.width, mSize.height), mFormat);
|
||||
if (mWinSurface && mWinSurface->CairoStatus() == 0) {
|
||||
// no error
|
||||
mImageSurface = mWinSurface->GetImageSurface();
|
||||
} else {
|
||||
mWinSurface = nsnull;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// For other platforms we create the image surface first and then
|
||||
// possibly wrap it in a device surface. This branch is also used
|
||||
// on Windows if we're not using device surfaces or if we couldn't
|
||||
// create one.
|
||||
if (!mImageSurface)
|
||||
mImageSurface = new gfxImageSurface(gfxIntSize(mSize.width, mSize.height), mFormat);
|
||||
|
||||
if (!mImageSurface || mImageSurface->CairoStatus()) {
|
||||
mImageSurface = nsnull;
|
||||
// guess
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (!mNeverUseDeviceSurface && !ShouldUseImageSurfaces()) {
|
||||
mQuartzSurface = new gfxQuartzImageSurface(mImageSurface);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult imgFrame::Optimize()
|
||||
{
|
||||
if (gDisableOptimize)
|
||||
return NS_OK;
|
||||
|
||||
if (mPalettedImageData || mOptSurface || mSinglePixel)
|
||||
return NS_OK;
|
||||
|
||||
/* Figure out if the entire image is a constant color */
|
||||
|
||||
// this should always be true
|
||||
if (mImageSurface->Stride() == mSize.width * 4) {
|
||||
PRUint32 *imgData = (PRUint32*) mImageSurface->Data();
|
||||
PRUint32 firstPixel = * (PRUint32*) imgData;
|
||||
PRUint32 pixelCount = mSize.width * mSize.height + 1;
|
||||
|
||||
while (--pixelCount && *imgData++ == firstPixel)
|
||||
;
|
||||
|
||||
if (pixelCount == 0) {
|
||||
// all pixels were the same
|
||||
if (mFormat == gfxASurface::ImageFormatARGB32 ||
|
||||
mFormat == gfxASurface::ImageFormatRGB24)
|
||||
{
|
||||
mSinglePixelColor = gfxRGBA
|
||||
(firstPixel,
|
||||
(mFormat == gfxImageSurface::ImageFormatRGB24 ?
|
||||
gfxRGBA::PACKED_XRGB :
|
||||
gfxRGBA::PACKED_ARGB_PREMULTIPLIED));
|
||||
|
||||
mSinglePixel = PR_TRUE;
|
||||
|
||||
// blow away the older surfaces (if they exist), to release their memory
|
||||
mImageSurface = nsnull;
|
||||
mOptSurface = nsnull;
|
||||
#ifdef USE_WIN_SURFACE
|
||||
mWinSurface = nsnull;
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
mQuartzSurface = nsnull;
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// if it's not RGB24/ARGB32, don't optimize, but we never hit this at the moment
|
||||
}
|
||||
|
||||
// if we're being forced to use image surfaces due to
|
||||
// resource constraints, don't try to optimize beyond same-pixel.
|
||||
if (mNeverUseDeviceSurface || ShouldUseImageSurfaces())
|
||||
return NS_OK;
|
||||
|
||||
mOptSurface = nsnull;
|
||||
|
||||
#ifdef USE_WIN_SURFACE
|
||||
// we need to special-case windows here, because windows has
|
||||
// a distinction between DIB and DDB and we want to use DDBs as much
|
||||
// as we can.
|
||||
if (mWinSurface) {
|
||||
// Don't do DDBs for large images; see bug 359147
|
||||
// Note that we bother with DDBs at all because they are much faster
|
||||
// on some systems; on others there isn't much of a speed difference
|
||||
// between DIBs and DDBs.
|
||||
//
|
||||
// Originally this just limited to 1024x1024; but that still
|
||||
// had us hitting overall total memory usage limits (which was
|
||||
// around 220MB on my intel shared memory system with 2GB RAM
|
||||
// and 16-128mb in use by the video card, so I can't make
|
||||
// heads or tails out of this limit).
|
||||
//
|
||||
// So instead, we clamp the max size to 64MB (this limit shuld
|
||||
// be made dynamic based on.. something.. as soon a we figure
|
||||
// out that something) and also limit each individual image to
|
||||
// be less than 4MB to keep very large images out of DDBs.
|
||||
|
||||
// assume (almost -- we don't quadword-align) worst-case size
|
||||
PRUint32 ddbSize = mSize.width * mSize.height * 4;
|
||||
if (ddbSize <= kMaxSingleDDBSize &&
|
||||
ddbSize + gTotalDDBSize <= kMaxDDBSize)
|
||||
{
|
||||
nsRefPtr<gfxWindowsSurface> wsurf = mWinSurface->OptimizeToDDB(nsnull, gfxIntSize(mSize.width, mSize.height), mFormat);
|
||||
if (wsurf) {
|
||||
gTotalDDBs++;
|
||||
gTotalDDBSize += ddbSize;
|
||||
mIsDDBSurface = PR_TRUE;
|
||||
mOptSurface = wsurf;
|
||||
}
|
||||
}
|
||||
if (!mOptSurface && !mFormatChanged) {
|
||||
// just use the DIB if the format has not changed
|
||||
mOptSurface = mWinSurface;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (mQuartzSurface) {
|
||||
mQuartzSurface->Flush();
|
||||
mOptSurface = mQuartzSurface;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mOptSurface == nsnull)
|
||||
mOptSurface = gfxPlatform::GetPlatform()->OptimizeImage(mImageSurface, mFormat);
|
||||
|
||||
if (mOptSurface) {
|
||||
mImageSurface = nsnull;
|
||||
#ifdef USE_WIN_SURFACE
|
||||
mWinSurface = nsnull;
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
mQuartzSurface = nsnull;
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
IsSafeImageTransformComponent(gfxFloat aValue)
|
||||
{
|
||||
return aValue >= -32768 && aValue <= 32767;
|
||||
}
|
||||
|
||||
void imgFrame::Draw(gfxContext *aContext, gfxPattern::GraphicsFilter aFilter,
|
||||
const gfxMatrix &aUserSpaceToImageSpace, const gfxRect& aFill,
|
||||
const nsIntMargin &aPadding, const nsIntRect &aSubimage)
|
||||
{
|
||||
NS_ASSERTION(!aFill.IsEmpty(), "zero dest size --- fix caller");
|
||||
NS_ASSERTION(!aSubimage.IsEmpty(), "zero source size --- fix caller");
|
||||
NS_ASSERTION(!mPalettedImageData, "Directly drawing a paletted image!");
|
||||
|
||||
PRBool doPadding = aPadding != nsIntMargin(0,0,0,0);
|
||||
PRBool doPartialDecode = !ImageComplete();
|
||||
gfxContext::GraphicsOperator op = aContext->CurrentOperator();
|
||||
|
||||
if (mSinglePixel && !doPadding && ImageComplete()) {
|
||||
// Single-color fast path
|
||||
// if a == 0, it's a noop
|
||||
if (mSinglePixelColor.a == 0.0)
|
||||
return;
|
||||
|
||||
if (op == gfxContext::OPERATOR_OVER && mSinglePixelColor.a == 1.0)
|
||||
aContext->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
|
||||
aContext->SetDeviceColor(mSinglePixelColor);
|
||||
aContext->NewPath();
|
||||
aContext->Rectangle(aFill);
|
||||
aContext->Fill();
|
||||
aContext->SetOperator(op);
|
||||
aContext->SetDeviceColor(gfxRGBA(0,0,0,0));
|
||||
return;
|
||||
}
|
||||
|
||||
gfxMatrix userSpaceToImageSpace = aUserSpaceToImageSpace;
|
||||
gfxRect sourceRect = userSpaceToImageSpace.Transform(aFill);
|
||||
gfxRect imageRect(0, 0, mSize.width + aPadding.LeftRight(), mSize.height + aPadding.TopBottom());
|
||||
gfxRect subimage(aSubimage.x, aSubimage.y, aSubimage.width, aSubimage.height);
|
||||
gfxRect fill = aFill;
|
||||
nsRefPtr<gfxASurface> surface;
|
||||
gfxImageSurface::gfxImageFormat format;
|
||||
|
||||
NS_ASSERTION(!sourceRect.Intersect(subimage).IsEmpty(),
|
||||
"We must be allowed to sample *some* source pixels!");
|
||||
|
||||
PRBool doTile = !imageRect.Contains(sourceRect);
|
||||
if (doPadding || doPartialDecode) {
|
||||
gfxRect available = gfxRect(mDecoded.x, mDecoded.y, mDecoded.width, mDecoded.height) +
|
||||
gfxPoint(aPadding.left, aPadding.top);
|
||||
|
||||
if (!doTile && !mSinglePixel) {
|
||||
// Not tiling, and we have a surface, so we can account for
|
||||
// padding and/or a partial decode just by twiddling parameters.
|
||||
// First, update our user-space fill rect.
|
||||
sourceRect = sourceRect.Intersect(available);
|
||||
gfxMatrix imageSpaceToUserSpace = userSpaceToImageSpace;
|
||||
imageSpaceToUserSpace.Invert();
|
||||
fill = imageSpaceToUserSpace.Transform(sourceRect);
|
||||
|
||||
surface = ThebesSurface();
|
||||
format = mFormat;
|
||||
subimage = subimage.Intersect(available) - gfxPoint(aPadding.left, aPadding.top);
|
||||
userSpaceToImageSpace.Multiply(gfxMatrix().Translate(-gfxPoint(aPadding.left, aPadding.top)));
|
||||
sourceRect = sourceRect - gfxPoint(aPadding.left, aPadding.top);
|
||||
imageRect = gfxRect(0, 0, mSize.width, mSize.height);
|
||||
} else {
|
||||
// Create a temporary surface
|
||||
gfxIntSize size(PRInt32(imageRect.Width()), PRInt32(imageRect.Height()));
|
||||
// Give this surface an alpha channel because there are
|
||||
// transparent pixels in the padding or undecoded area
|
||||
format = gfxASurface::ImageFormatARGB32;
|
||||
surface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(size, format);
|
||||
if (!surface || surface->CairoStatus() != 0)
|
||||
return;
|
||||
|
||||
// Fill 'available' with whatever we've got
|
||||
gfxContext tmpCtx(surface);
|
||||
tmpCtx.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
if (mSinglePixel) {
|
||||
tmpCtx.SetDeviceColor(mSinglePixelColor);
|
||||
} else {
|
||||
tmpCtx.SetSource(ThebesSurface(), gfxPoint(aPadding.left, aPadding.top));
|
||||
}
|
||||
tmpCtx.Rectangle(available);
|
||||
tmpCtx.Fill();
|
||||
}
|
||||
} else {
|
||||
NS_ASSERTION(!mSinglePixel, "This should already have been handled");
|
||||
surface = ThebesSurface();
|
||||
format = mFormat;
|
||||
}
|
||||
// At this point, we've taken care of mSinglePixel images, images with
|
||||
// aPadding, and partially-decoded images.
|
||||
|
||||
if (!AllowedImageSize(fill.size.width + 1, fill.size.height + 1)) {
|
||||
NS_WARNING("Destination area too large, bailing out");
|
||||
return;
|
||||
}
|
||||
|
||||
// Compute device-space-to-image-space transform. We need to sanity-
|
||||
// check it to work around a pixman bug :-(
|
||||
// XXX should we only do this for certain surface types?
|
||||
gfxFloat deviceX, deviceY;
|
||||
nsRefPtr<gfxASurface> currentTarget =
|
||||
aContext->CurrentSurface(&deviceX, &deviceY);
|
||||
gfxMatrix currentMatrix = aContext->CurrentMatrix();
|
||||
gfxMatrix deviceToUser = currentMatrix;
|
||||
deviceToUser.Invert();
|
||||
deviceToUser.Translate(-gfxPoint(-deviceX, -deviceY));
|
||||
gfxMatrix deviceToImage = deviceToUser;
|
||||
deviceToImage.Multiply(userSpaceToImageSpace);
|
||||
|
||||
PRBool pushedGroup = PR_FALSE;
|
||||
if (currentTarget->GetType() != gfxASurface::SurfaceTypeQuartz) {
|
||||
// BEGIN working around cairo/pixman bug (bug 364968)
|
||||
// Quartz's limits for matrix are much larger than pixman
|
||||
|
||||
// Our device-space-to-image-space transform may not be acceptable to pixman.
|
||||
if (!IsSafeImageTransformComponent(deviceToImage.xx) ||
|
||||
!IsSafeImageTransformComponent(deviceToImage.xy) ||
|
||||
!IsSafeImageTransformComponent(deviceToImage.yx) ||
|
||||
!IsSafeImageTransformComponent(deviceToImage.yy)) {
|
||||
NS_WARNING("Scaling up too much, bailing out");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsSafeImageTransformComponent(deviceToImage.x0) ||
|
||||
!IsSafeImageTransformComponent(deviceToImage.y0)) {
|
||||
// We'll push a group, which will hopefully reduce our transform's
|
||||
// translation so it's in bounds
|
||||
aContext->Save();
|
||||
|
||||
// Clip the rounded-out-to-device-pixels bounds of the
|
||||
// transformed fill area. This is the area for the group we
|
||||
// want to push.
|
||||
aContext->IdentityMatrix();
|
||||
gfxRect bounds = currentMatrix.TransformBounds(fill);
|
||||
bounds.RoundOut();
|
||||
aContext->Clip(bounds);
|
||||
aContext->SetMatrix(currentMatrix);
|
||||
|
||||
aContext->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
|
||||
aContext->SetOperator(gfxContext::OPERATOR_OVER);
|
||||
pushedGroup = PR_TRUE;
|
||||
}
|
||||
// END working around cairo/pixman bug (bug 364968)
|
||||
}
|
||||
|
||||
nsRefPtr<gfxPattern> pattern = new gfxPattern(surface);
|
||||
pattern->SetMatrix(userSpaceToImageSpace);
|
||||
|
||||
// OK now, the hard part left is to account for the subimage sampling
|
||||
// restriction. If all the transforms involved are just integer
|
||||
// translations, then we assume no resampling will occur so there's
|
||||
// nothing to do.
|
||||
// XXX if only we had source-clipping in cairo!
|
||||
if (!currentMatrix.HasNonIntegerTranslation() &&
|
||||
!userSpaceToImageSpace.HasNonIntegerTranslation()) {
|
||||
if (doTile) {
|
||||
pattern->SetExtend(gfxPattern::EXTEND_REPEAT);
|
||||
}
|
||||
} else {
|
||||
if (doTile || !subimage.Contains(imageRect)) {
|
||||
// EXTEND_PAD won't help us here; we have to create a temporary
|
||||
// surface to hold the subimage of pixels we're allowed to
|
||||
// sample
|
||||
|
||||
gfxRect userSpaceClipExtents = aContext->GetClipExtents();
|
||||
// This isn't optimal --- if aContext has a rotation then GetClipExtents
|
||||
// will have to do a bounding-box computation, and TransformBounds might
|
||||
// too, so we could get a better result if we computed image space clip
|
||||
// extents in one go --- but it doesn't really matter and this is easier
|
||||
// to understand.
|
||||
gfxRect imageSpaceClipExtents = userSpaceToImageSpace.TransformBounds(userSpaceClipExtents);
|
||||
// Inflate by one pixel because bilinear filtering will sample at most
|
||||
// one pixel beyond the computed image pixel coordinate.
|
||||
imageSpaceClipExtents.Outset(1.0);
|
||||
|
||||
gfxRect needed = imageSpaceClipExtents.Intersect(sourceRect).Intersect(subimage);
|
||||
needed.RoundOut();
|
||||
|
||||
// if 'needed' is empty, nothing will be drawn since aFill
|
||||
// must be entirely outside the clip region, so it doesn't
|
||||
// matter what we do here, but we should avoid trying to
|
||||
// create a zero-size surface.
|
||||
if (!needed.IsEmpty()) {
|
||||
gfxIntSize size(PRInt32(needed.Width()), PRInt32(needed.Height()));
|
||||
nsRefPtr<gfxASurface> temp =
|
||||
gfxPlatform::GetPlatform()->CreateOffscreenSurface(size, format);
|
||||
if (temp && temp->CairoStatus() == 0) {
|
||||
gfxContext tmpCtx(temp);
|
||||
tmpCtx.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
nsRefPtr<gfxPattern> tmpPattern = new gfxPattern(surface);
|
||||
if (tmpPattern) {
|
||||
tmpPattern->SetExtend(gfxPattern::EXTEND_REPEAT);
|
||||
tmpPattern->SetMatrix(gfxMatrix().Translate(needed.pos));
|
||||
tmpCtx.SetPattern(tmpPattern);
|
||||
tmpCtx.Paint();
|
||||
tmpPattern = new gfxPattern(temp);
|
||||
if (tmpPattern) {
|
||||
pattern.swap(tmpPattern);
|
||||
pattern->SetMatrix(
|
||||
gfxMatrix(userSpaceToImageSpace).Multiply(gfxMatrix().Translate(-needed.pos)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// In theory we can handle this using cairo's EXTEND_PAD,
|
||||
// but implementation limitations mean we have to consult
|
||||
// the surface type.
|
||||
switch (currentTarget->GetType()) {
|
||||
case gfxASurface::SurfaceTypeXlib:
|
||||
case gfxASurface::SurfaceTypeXcb:
|
||||
{
|
||||
// See bug 324698. This is a workaround for EXTEND_PAD not being
|
||||
// implemented correctly on linux in the X server.
|
||||
//
|
||||
// Set the filter to CAIRO_FILTER_FAST --- otherwise,
|
||||
// pixman's sampling will sample transparency for the outside edges and we'll
|
||||
// get blurry edges. CAIRO_EXTEND_PAD would also work here, if
|
||||
// available
|
||||
//
|
||||
// But don't do this for simple downscales because it's horrible.
|
||||
// Downscaling means that device-space coordinates are
|
||||
// scaled *up* to find the image pixel coordinates.
|
||||
//
|
||||
// deviceToImage is slightly stale because up above we may
|
||||
// have adjusted the pattern's matrix ... but the adjustment
|
||||
// is only a translation so the scale factors in deviceToImage
|
||||
// are still valid.
|
||||
PRBool isDownscale =
|
||||
deviceToImage.xx >= 1.0 && deviceToImage.yy >= 1.0 &&
|
||||
deviceToImage.xy == 0.0 && deviceToImage.yx == 0.0;
|
||||
if (!isDownscale) {
|
||||
pattern->SetFilter(gfxPattern::FILTER_FAST);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case gfxASurface::SurfaceTypeQuartz:
|
||||
case gfxASurface::SurfaceTypeQuartzImage:
|
||||
// Don't set EXTEND_PAD, Mac seems to be OK. Really?
|
||||
pattern->SetFilter(aFilter);
|
||||
break;
|
||||
|
||||
default:
|
||||
// turn on EXTEND_PAD.
|
||||
// This is what we really want for all surface types, if the
|
||||
// implementation was universally good.
|
||||
pattern->SetExtend(gfxPattern::EXTEND_PAD);
|
||||
pattern->SetFilter(aFilter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((op == gfxContext::OPERATOR_OVER || pushedGroup) &&
|
||||
format == gfxASurface::ImageFormatRGB24) {
|
||||
aContext->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
}
|
||||
|
||||
// Phew! Now we can actually draw this image
|
||||
aContext->NewPath();
|
||||
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
pattern->SetFilter(gfxPattern::FILTER_FAST);
|
||||
#endif
|
||||
aContext->SetPattern(pattern);
|
||||
aContext->Rectangle(fill);
|
||||
aContext->Fill();
|
||||
|
||||
aContext->SetOperator(op);
|
||||
if (pushedGroup) {
|
||||
aContext->PopGroupToSource();
|
||||
aContext->Paint();
|
||||
aContext->Restore();
|
||||
}
|
||||
}
|
||||
|
||||
nsresult imgFrame::Extract(const nsIntRect& aRegion, imgFrame** aResult)
|
||||
{
|
||||
nsAutoPtr<imgFrame> subImage(new imgFrame());
|
||||
if (!subImage)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// The scaling problems described in bug 468496 are especially
|
||||
// likely to be visible for the sub-image, as at present the only
|
||||
// user is the border-image code and border-images tend to get
|
||||
// stretched a lot. At the same time, the performance concerns
|
||||
// that prevent us from just using Cairo's fallback scaler when
|
||||
// accelerated graphics won't cut it are less relevant to such
|
||||
// images, since they also tend to be small. Thus, we forcibly
|
||||
// disable the use of anything other than a client-side image
|
||||
// surface for the sub-image; this ensures that the correct
|
||||
// (albeit slower) Cairo fallback scaler will be used.
|
||||
subImage->mNeverUseDeviceSurface = PR_TRUE;
|
||||
|
||||
nsresult rv = subImage->Init(0, 0, aRegion.width, aRegion.height,
|
||||
mFormat, mPaletteDepth);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// scope to destroy ctx
|
||||
{
|
||||
gfxContext ctx(subImage->ThebesSurface());
|
||||
ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
if (mSinglePixel) {
|
||||
ctx.SetDeviceColor(mSinglePixelColor);
|
||||
} else {
|
||||
// SetSource() places point (0,0) of its first argument at
|
||||
// the coordinages given by its second argument. We want
|
||||
// (x,y) of the image to be (0,0) of source space, so we
|
||||
// put (0,0) of the image at (-x,-y).
|
||||
ctx.SetSource(this->ThebesSurface(), gfxPoint(-aRegion.x, -aRegion.y));
|
||||
}
|
||||
ctx.Rectangle(gfxRect(0, 0, aRegion.width, aRegion.height));
|
||||
ctx.Fill();
|
||||
}
|
||||
|
||||
nsIntRect filled(0, 0, aRegion.width, aRegion.height);
|
||||
|
||||
rv = subImage->ImageUpdated(filled);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
subImage->Optimize();
|
||||
|
||||
*aResult = subImage.forget();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult imgFrame::ImageUpdated(const nsIntRect &aUpdateRect)
|
||||
{
|
||||
// Check to see if we are running OOM
|
||||
nsCOMPtr<nsIMemory> mem;
|
||||
NS_GetMemoryManager(getter_AddRefs(mem));
|
||||
if (!mem)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
PRBool lowMemory;
|
||||
mem->IsLowMemory(&lowMemory);
|
||||
if (lowMemory)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mDecoded.UnionRect(mDecoded, aUpdateRect);
|
||||
|
||||
// clamp to bounds, in case someone sends a bogus updateRect (I'm looking at
|
||||
// you, gif decoder)
|
||||
nsIntRect boundsRect(0, 0, mSize.width, mSize.height);
|
||||
mDecoded.IntersectRect(mDecoded, boundsRect);
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (mQuartzSurface)
|
||||
mQuartzSurface->Flush();
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32 imgFrame::GetX() const
|
||||
{
|
||||
return mOffset.x;
|
||||
}
|
||||
|
||||
PRInt32 imgFrame::GetY() const
|
||||
{
|
||||
return mOffset.y;
|
||||
}
|
||||
|
||||
PRInt32 imgFrame::GetWidth() const
|
||||
{
|
||||
return mSize.width;
|
||||
}
|
||||
|
||||
PRInt32 imgFrame::GetHeight() const
|
||||
{
|
||||
return mSize.height;
|
||||
}
|
||||
|
||||
nsIntRect imgFrame::GetRect() const
|
||||
{
|
||||
return nsIntRect(mOffset, mSize);
|
||||
}
|
||||
|
||||
gfxASurface::gfxImageFormat imgFrame::GetFormat() const
|
||||
{
|
||||
return mFormat;
|
||||
}
|
||||
|
||||
PRBool imgFrame::GetNeedsBackground() const
|
||||
{
|
||||
// We need a background painted if we have alpha or we're incomplete.
|
||||
return (mFormat == gfxASurface::ImageFormatARGB32 || !ImageComplete());
|
||||
}
|
||||
|
||||
PRUint32 imgFrame::GetImageBytesPerRow() const
|
||||
{
|
||||
if (mImageSurface)
|
||||
return mImageSurface->Stride();
|
||||
else
|
||||
return mSize.width;
|
||||
}
|
||||
|
||||
PRUint32 imgFrame::GetImageDataLength() const
|
||||
{
|
||||
if (mImageSurface)
|
||||
return mImageSurface->Stride() * mSize.height;
|
||||
else
|
||||
return mSize.width * mSize.height;
|
||||
}
|
||||
|
||||
void imgFrame::GetImageData(PRUint8 **aData, PRUint32 *length) const
|
||||
{
|
||||
if (mImageSurface)
|
||||
*aData = mImageSurface->Data();
|
||||
else if (mPalettedImageData)
|
||||
*aData = mPalettedImageData + PaletteDataLength();
|
||||
else
|
||||
*aData = nsnull;
|
||||
|
||||
*length = GetImageDataLength();
|
||||
}
|
||||
|
||||
PRBool imgFrame::GetIsPaletted() const
|
||||
{
|
||||
return mPalettedImageData != nsnull;
|
||||
}
|
||||
|
||||
PRBool imgFrame::GetHasAlpha() const
|
||||
{
|
||||
return mFormat != gfxASurface::ImageFormatARGB32;
|
||||
}
|
||||
|
||||
void imgFrame::GetPaletteData(PRUint32 **aPalette, PRUint32 *length) const
|
||||
{
|
||||
if (!mPalettedImageData) {
|
||||
*aPalette = nsnull;
|
||||
*length = 0;
|
||||
} else {
|
||||
*aPalette = (PRUint32 *) mPalettedImageData;
|
||||
*length = PaletteDataLength();
|
||||
}
|
||||
}
|
||||
|
||||
nsresult imgFrame::LockImageData()
|
||||
{
|
||||
if (mPalettedImageData)
|
||||
return NS_OK;
|
||||
|
||||
if ((mOptSurface || mSinglePixel) && !mImageSurface) {
|
||||
// Recover the pixels
|
||||
mImageSurface = new gfxImageSurface(gfxIntSize(mSize.width, mSize.height),
|
||||
gfxImageSurface::ImageFormatARGB32);
|
||||
if (!mImageSurface || mImageSurface->CairoStatus())
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
gfxContext context(mImageSurface);
|
||||
context.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
if (mSinglePixel)
|
||||
context.SetDeviceColor(mSinglePixelColor);
|
||||
else
|
||||
context.SetSource(mOptSurface);
|
||||
context.Paint();
|
||||
|
||||
mOptSurface = nsnull;
|
||||
#ifdef USE_WIN_SURFACE
|
||||
mWinSurface = nsnull;
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
mQuartzSurface = nsnull;
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult imgFrame::UnlockImageData()
|
||||
{
|
||||
if (mPalettedImageData)
|
||||
return NS_OK;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (mQuartzSurface)
|
||||
mQuartzSurface->Flush();
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32 imgFrame::GetTimeout() const
|
||||
{
|
||||
// Ensure a minimal time between updates so we don't throttle the UI thread.
|
||||
// consider 0 == unspecified and make it fast but not too fast. See bug
|
||||
// 125137, bug 139677, and bug 207059. The behavior of recent IE and Opera
|
||||
// versions seems to be:
|
||||
// IE 6/Win:
|
||||
// 10 - 50ms go 100ms
|
||||
// >50ms go correct speed
|
||||
// Opera 7 final/Win:
|
||||
// 10ms goes 100ms
|
||||
// >10ms go correct speed
|
||||
// It seems that there are broken tools out there that set a 0ms or 10ms
|
||||
// timeout when they really want a "default" one. So munge values in that
|
||||
// range.
|
||||
if (mTimeout >= 0 && mTimeout <= 10)
|
||||
return 100;
|
||||
else
|
||||
return mTimeout;
|
||||
}
|
||||
|
||||
void imgFrame::SetTimeout(PRInt32 aTimeout)
|
||||
{
|
||||
mTimeout = aTimeout;
|
||||
}
|
||||
|
||||
PRInt32 imgFrame::GetFrameDisposalMethod() const
|
||||
{
|
||||
return mDisposalMethod;
|
||||
}
|
||||
|
||||
void imgFrame::SetFrameDisposalMethod(PRInt32 aFrameDisposalMethod)
|
||||
{
|
||||
mDisposalMethod = aFrameDisposalMethod;
|
||||
}
|
||||
|
||||
PRInt32 imgFrame::GetBlendMethod() const
|
||||
{
|
||||
return mBlendMethod;
|
||||
}
|
||||
|
||||
void imgFrame::SetBlendMethod(PRInt32 aBlendMethod)
|
||||
{
|
||||
mBlendMethod = (PRInt8)aBlendMethod;
|
||||
}
|
||||
|
||||
PRBool imgFrame::ImageComplete() const
|
||||
{
|
||||
return mDecoded == nsIntRect(0, 0, mSize.width, mSize.height);
|
||||
}
|
||||
|
||||
// A hint from the image decoders that this image has no alpha, even
|
||||
// though we created is ARGB32. This changes our format to RGB24,
|
||||
// which in turn will cause us to Optimize() to RGB24. Has no effect
|
||||
// after Optimize() is called, though in all cases it will be just a
|
||||
// performance win -- the pixels are still correct and have the A byte
|
||||
// set to 0xff.
|
||||
void imgFrame::SetHasNoAlpha()
|
||||
{
|
||||
if (mFormat == gfxASurface::ImageFormatARGB32) {
|
||||
mFormat = gfxASurface::ImageFormatRGB24;
|
||||
mFormatChanged = PR_TRUE;
|
||||
}
|
||||
}
|
||||
178
modules/libpr0n/src/imgFrame.h
Normal file
178
modules/libpr0n/src/imgFrame.h
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Joe Drew <joe@drew.ca> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef imgFrame_h
|
||||
#define imgFrame_h
|
||||
|
||||
#include "nsRect.h"
|
||||
#include "nsPoint.h"
|
||||
#include "nsSize.h"
|
||||
#include "gfxTypes.h"
|
||||
#include "nsID.h"
|
||||
#include "gfxIFormats.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxPattern.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#if defined(XP_WIN)
|
||||
#include "gfxWindowsSurface.h"
|
||||
#elif defined(XP_MACOSX)
|
||||
#include "gfxQuartzImageSurface.h"
|
||||
#endif
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
class imgFrame
|
||||
{
|
||||
public:
|
||||
imgFrame();
|
||||
~imgFrame();
|
||||
|
||||
nsresult Init(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, gfxASurface::gfxImageFormat aFormat, PRInt8 aPaletteDepth = 0);
|
||||
nsresult Optimize();
|
||||
|
||||
void Draw(gfxContext *aContext, gfxPattern::GraphicsFilter aFilter,
|
||||
const gfxMatrix &aUserSpaceToImageSpace, const gfxRect& aFill,
|
||||
const nsIntMargin &aPadding, const nsIntRect &aSubimage);
|
||||
|
||||
nsresult Extract(const nsIntRect& aRegion, imgFrame** aResult);
|
||||
|
||||
nsresult ImageUpdated(const nsIntRect &aUpdateRect);
|
||||
|
||||
PRInt32 GetX() const;
|
||||
PRInt32 GetY() const;
|
||||
PRInt32 GetWidth() const;
|
||||
PRInt32 GetHeight() const;
|
||||
nsIntRect GetRect() const;
|
||||
gfxASurface::gfxImageFormat GetFormat() const;
|
||||
PRBool GetNeedsBackground() const;
|
||||
PRUint32 GetImageBytesPerRow() const;
|
||||
PRUint32 GetImageDataLength() const;
|
||||
PRBool GetIsPaletted() const;
|
||||
PRBool GetHasAlpha() const;
|
||||
void GetImageData(PRUint8 **aData, PRUint32 *length) const;
|
||||
void GetPaletteData(PRUint32 **aPalette, PRUint32 *length) const;
|
||||
|
||||
PRInt32 GetTimeout() const;
|
||||
void SetTimeout(PRInt32 aTimeout);
|
||||
|
||||
PRInt32 GetFrameDisposalMethod() const;
|
||||
void SetFrameDisposalMethod(PRInt32 aFrameDisposalMethod);
|
||||
PRInt32 GetBlendMethod() const;
|
||||
void SetBlendMethod(PRInt32 aBlendMethod);
|
||||
PRBool ImageComplete() const;
|
||||
|
||||
void SetHasNoAlpha();
|
||||
|
||||
nsresult LockImageData();
|
||||
nsresult UnlockImageData();
|
||||
|
||||
nsresult GetSurface(gfxASurface **aSurface) const
|
||||
{
|
||||
*aSurface = ThebesSurface();
|
||||
NS_IF_ADDREF(*aSurface);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult GetPattern(gfxPattern **aPattern) const
|
||||
{
|
||||
if (mSinglePixel)
|
||||
*aPattern = new gfxPattern(mSinglePixelColor);
|
||||
else
|
||||
*aPattern = new gfxPattern(ThebesSurface());
|
||||
NS_ADDREF(*aPattern);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
gfxASurface* ThebesSurface() const
|
||||
{
|
||||
if (mOptSurface)
|
||||
return mOptSurface;
|
||||
#if defined(XP_WIN) && !defined(WINCE)
|
||||
if (mWinSurface)
|
||||
return mWinSurface;
|
||||
#elif defined(XP_MACOSX)
|
||||
if (mQuartzSurface)
|
||||
return mQuartzSurface;
|
||||
#endif
|
||||
return mImageSurface;
|
||||
}
|
||||
|
||||
|
||||
private: // methods
|
||||
PRUint32 PaletteDataLength() const {
|
||||
return ((1 << mPaletteDepth) * sizeof(PRUint32));
|
||||
}
|
||||
|
||||
private: // data
|
||||
nsRefPtr<gfxImageSurface> mImageSurface;
|
||||
nsRefPtr<gfxASurface> mOptSurface;
|
||||
#if defined(XP_WIN) && !defined(WINCE)
|
||||
nsRefPtr<gfxWindowsSurface> mWinSurface;
|
||||
#elif defined(XP_MACOSX)
|
||||
nsRefPtr<gfxQuartzImageSurface> mQuartzSurface;
|
||||
#endif
|
||||
|
||||
nsIntSize mSize;
|
||||
nsIntPoint mOffset;
|
||||
|
||||
nsIntRect mDecoded;
|
||||
|
||||
// The palette and image data for images that are paletted, since Cairo
|
||||
// doesn't support these images.
|
||||
// The paletted data comes first, then the image data itself.
|
||||
// Total length is PaletteDataLength() + GetImageDataLength().
|
||||
PRUint8* mPalettedImageData;
|
||||
|
||||
gfxRGBA mSinglePixelColor;
|
||||
|
||||
PRInt32 mTimeout; // -1 means display forever
|
||||
PRInt32 mDisposalMethod;
|
||||
|
||||
gfxASurface::gfxImageFormat mFormat;
|
||||
PRInt8 mPaletteDepth;
|
||||
PRInt8 mBlendMethod;
|
||||
PRPackedBool mSinglePixel;
|
||||
PRPackedBool mNeverUseDeviceSurface;
|
||||
PRPackedBool mFormatChanged;
|
||||
|
||||
#ifdef XP_WIN
|
||||
PRPackedBool mIsDDBSurface;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif /* imgFrame_h */
|
||||
|
|
@ -46,8 +46,6 @@
|
|||
#include "ImageErrors.h"
|
||||
#include "ImageLogging.h"
|
||||
|
||||
#include "gfxIImageFrame.h"
|
||||
|
||||
#include "netCore.h"
|
||||
|
||||
#include "nsIChannel.h"
|
||||
|
|
@ -269,24 +267,19 @@ nsresult imgRequest::NotifyProxyListener(imgRequestProxy *proxy)
|
|||
mImage->GetNumFrames(&nframes);
|
||||
|
||||
if (nframes > 0) {
|
||||
nsCOMPtr<gfxIImageFrame> frame;
|
||||
|
||||
// get the current frame or only frame
|
||||
mImage->GetCurrentFrame(getter_AddRefs(frame));
|
||||
NS_ENSURE_TRUE(frame, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// OnStartFrame
|
||||
PRUint32 frame;
|
||||
mImage->GetCurrentFrameIndex(&frame);
|
||||
proxy->OnStartFrame(frame);
|
||||
|
||||
if (!(mState & onStopContainer)) {
|
||||
// OnDataAvailable
|
||||
nsIntRect r;
|
||||
frame->GetRect(r); // XXX we should only send the currently decoded rectangle here.
|
||||
mImage->GetCurrentFrameRect(r); // XXX we should only send the currently decoded rectangle here.
|
||||
proxy->OnDataAvailable(frame, &r);
|
||||
} else {
|
||||
// OnDataAvailable
|
||||
nsIntRect r;
|
||||
frame->GetRect(r); // We're done loading this image, send the the whole rect
|
||||
mImage->GetCurrentFrameRect(r); // We're done loading this image, send the the whole rect
|
||||
proxy->OnDataAvailable(frame, &r);
|
||||
|
||||
// OnStopFrame
|
||||
|
|
@ -511,16 +504,15 @@ NS_IMETHODIMP imgRequest::GetIsMultiPartChannel(PRBool *aIsMultiPartChannel)
|
|||
|
||||
/** imgIContainerObserver methods **/
|
||||
|
||||
/* [noscript] void frameChanged (in imgIContainer container, in gfxIImageFrame newframe, in nsIntRect dirtyRect); */
|
||||
/* [noscript] void frameChanged (in imgIContainer container, in nsIntRect dirtyRect); */
|
||||
NS_IMETHODIMP imgRequest::FrameChanged(imgIContainer *container,
|
||||
gfxIImageFrame *newframe,
|
||||
nsIntRect * dirtyRect)
|
||||
{
|
||||
LOG_SCOPE(gImgLog, "imgRequest::FrameChanged");
|
||||
|
||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
||||
while (iter.HasMore()) {
|
||||
iter.GetNext()->FrameChanged(container, newframe, dirtyRect);
|
||||
iter.GetNext()->FrameChanged(container, dirtyRect);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
@ -577,9 +569,9 @@ NS_IMETHODIMP imgRequest::OnStartContainer(imgIRequest *request, imgIContainer *
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStartFrame (in imgIRequest request, in gfxIImageFrame frame); */
|
||||
/* void onStartFrame (in imgIRequest request, in unsigned long frame); */
|
||||
NS_IMETHODIMP imgRequest::OnStartFrame(imgIRequest *request,
|
||||
gfxIImageFrame *frame)
|
||||
PRUint32 frame)
|
||||
{
|
||||
LOG_SCOPE(gImgLog, "imgRequest::OnStartFrame");
|
||||
|
||||
|
|
@ -591,28 +583,25 @@ NS_IMETHODIMP imgRequest::OnStartFrame(imgIRequest *request,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/* [noscript] void onDataAvailable (in imgIRequest request, in gfxIImageFrame frame, [const] in nsIntRect rect); */
|
||||
/* [noscript] void onDataAvailable (in imgIRequest request, in boolean aCurrentFrame, [const] in nsIntRect rect); */
|
||||
NS_IMETHODIMP imgRequest::OnDataAvailable(imgIRequest *request,
|
||||
gfxIImageFrame *frame,
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect * rect)
|
||||
{
|
||||
LOG_SCOPE(gImgLog, "imgRequest::OnDataAvailable");
|
||||
|
||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
|
||||
while (iter.HasMore()) {
|
||||
iter.GetNext()->OnDataAvailable(frame, rect);
|
||||
iter.GetNext()->OnDataAvailable(aCurrentFrame, rect);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStopFrame (in imgIRequest request, in gfxIImageFrame frame); */
|
||||
/* void onStopFrame (in imgIRequest request, in unsigned long frame); */
|
||||
NS_IMETHODIMP imgRequest::OnStopFrame(imgIRequest *request,
|
||||
gfxIImageFrame *frame)
|
||||
PRUint32 frame)
|
||||
{
|
||||
NS_ASSERTION(frame, "imgRequest::OnStopFrame called with NULL frame");
|
||||
if (!frame) return NS_ERROR_UNEXPECTED;
|
||||
|
||||
LOG_SCOPE(gImgLog, "imgRequest::OnStopFrame");
|
||||
|
||||
mImageStatus |= imgIRequest::STATUS_FRAME_COMPLETE;
|
||||
|
|
@ -621,7 +610,8 @@ NS_IMETHODIMP imgRequest::OnStopFrame(imgIRequest *request,
|
|||
PRUint32 cacheSize = mCacheEntry->GetDataSize();
|
||||
|
||||
PRUint32 imageSize = 0;
|
||||
frame->GetImageDataLength(&imageSize);
|
||||
if (mImage)
|
||||
mImage->GetFrameImageDataLength(frame, &imageSize);
|
||||
|
||||
mCacheEntry->SetDataSize(cacheSize + imageSize);
|
||||
|
||||
|
|
|
|||
|
|
@ -425,14 +425,14 @@ NS_IMETHODIMP imgRequestProxy::GetHasTransferredData(PRBool* hasData)
|
|||
|
||||
/** imgIContainerObserver methods **/
|
||||
|
||||
void imgRequestProxy::FrameChanged(imgIContainer *container, gfxIImageFrame *newframe, nsIntRect * dirtyRect)
|
||||
void imgRequestProxy::FrameChanged(imgIContainer *container, nsIntRect * dirtyRect)
|
||||
{
|
||||
LOG_FUNC(gImgLog, "imgRequestProxy::FrameChanged");
|
||||
|
||||
if (mListener && !mCanceled) {
|
||||
// Hold a ref to the listener while we call it, just in case.
|
||||
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
||||
mListener->FrameChanged(container, newframe, dirtyRect);
|
||||
mListener->FrameChanged(container, dirtyRect);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -460,7 +460,7 @@ void imgRequestProxy::OnStartContainer(imgIContainer *image)
|
|||
}
|
||||
}
|
||||
|
||||
void imgRequestProxy::OnStartFrame(gfxIImageFrame *frame)
|
||||
void imgRequestProxy::OnStartFrame(PRUint32 frame)
|
||||
{
|
||||
LOG_FUNC(gImgLog, "imgRequestProxy::OnStartFrame");
|
||||
|
||||
|
|
@ -471,18 +471,18 @@ void imgRequestProxy::OnStartFrame(gfxIImageFrame *frame)
|
|||
}
|
||||
}
|
||||
|
||||
void imgRequestProxy::OnDataAvailable(gfxIImageFrame *frame, const nsIntRect * rect)
|
||||
void imgRequestProxy::OnDataAvailable(PRBool aCurrentFrame, const nsIntRect * rect)
|
||||
{
|
||||
LOG_FUNC(gImgLog, "imgRequestProxy::OnDataAvailable");
|
||||
|
||||
if (mListener && !mCanceled) {
|
||||
// Hold a ref to the listener while we call it, just in case.
|
||||
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
||||
mListener->OnDataAvailable(this, frame, rect);
|
||||
mListener->OnDataAvailable(this, aCurrentFrame, rect);
|
||||
}
|
||||
}
|
||||
|
||||
void imgRequestProxy::OnStopFrame(gfxIImageFrame *frame)
|
||||
void imgRequestProxy::OnStopFrame(PRUint32 frame)
|
||||
{
|
||||
LOG_FUNC(gImgLog, "imgRequestProxy::OnStopFrame");
|
||||
|
||||
|
|
|
|||
|
|
@ -111,14 +111,14 @@ protected:
|
|||
/* non-virtual imgIDecoderObserver methods */
|
||||
void OnStartDecode ();
|
||||
void OnStartContainer(imgIContainer *aContainer);
|
||||
void OnStartFrame (gfxIImageFrame *aFrame);
|
||||
void OnDataAvailable (gfxIImageFrame *aFrame, const nsIntRect * aRect);
|
||||
void OnStopFrame (gfxIImageFrame *aFrame);
|
||||
void OnStartFrame (PRUint32 aFrame);
|
||||
void OnDataAvailable (PRBool aCurrentFrame, const nsIntRect * aRect);
|
||||
void OnStopFrame (PRUint32 aFrame);
|
||||
void OnStopContainer (imgIContainer *aContainer);
|
||||
void OnStopDecode (nsresult status, const PRUnichar *statusArg);
|
||||
|
||||
/* non-virtual imgIContainerObserver methods */
|
||||
void FrameChanged(imgIContainer *aContainer, gfxIImageFrame *aFrame, nsIntRect * aDirtyRect);
|
||||
void FrameChanged(imgIContainer *aContainer, nsIntRect * aDirtyRect);
|
||||
|
||||
/* non-virtual nsIRequestObserver (plus some) methods */
|
||||
void OnStartRequest(nsIRequest *request, nsISupports *ctxt);
|
||||
|
|
|
|||
|
|
@ -46,9 +46,6 @@
|
|||
#include "imgIEncoder.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "imgIContainerObserver.h"
|
||||
#include "nsIImage.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxContext.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
|
@ -129,22 +126,21 @@ HelperLoader::OnStartContainer(imgIRequest *aRequest, imgIContainer
|
|||
|
||||
/* Implement imgIDecoderObserver::onStartFrame() */
|
||||
NS_IMETHODIMP
|
||||
HelperLoader::OnStartFrame(imgIRequest *aRequest, gfxIImageFrame *aFrame)
|
||||
HelperLoader::OnStartFrame(imgIRequest *aRequest, PRUint32 aFrame)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* Implement imgIDecoderObserver::onDataAvailable() */
|
||||
NS_IMETHODIMP
|
||||
HelperLoader::OnDataAvailable(imgIRequest *aRequest, gfxIImageFrame
|
||||
*aFrame, const nsIntRect * aRect)
|
||||
HelperLoader::OnDataAvailable(imgIRequest *aRequest, PRBool aCurrentFrame, const nsIntRect * aRect)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* Implement imgIDecoderObserver::onStopFrame() */
|
||||
NS_IMETHODIMP
|
||||
HelperLoader::OnStopFrame(imgIRequest *aRequest, gfxIImageFrame *aFrame)
|
||||
HelperLoader::OnStopFrame(imgIRequest *aRequest, PRUint32 aFrame)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -174,8 +170,7 @@ HelperLoader::OnStopRequest(imgIRequest *aRequest, PRBool aIsLastPart)
|
|||
|
||||
/* implement imgIContainerObserver::frameChanged() */
|
||||
NS_IMETHODIMP
|
||||
HelperLoader::FrameChanged(imgIContainer *aContainer,
|
||||
gfxIImageFrame *aFrame, nsIntRect * aDirtyRect)
|
||||
HelperLoader::FrameChanged(imgIContainer *aContainer, nsIntRect * aDirtyRect)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -230,7 +225,6 @@ NS_IMETHODIMP imgTools::DecodeImageData(nsIInputStream* aInStr,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 written;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = decoder->WriteFrom(aInStr, length, &written);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (written != length)
|
||||
|
|
@ -285,19 +279,16 @@ NS_IMETHODIMP imgTools::EncodeScaledImage(imgIContainer *aContainer,
|
|||
return NS_IMAGELIB_ERROR_NO_ENCODER;
|
||||
|
||||
// Use frame 0 from the image container.
|
||||
nsCOMPtr<gfxIImageFrame> frame;
|
||||
rv = aContainer->GetFrameAt(0, getter_AddRefs(frame));
|
||||
nsRefPtr<gfxImageSurface> frame;
|
||||
rv = aContainer->CopyCurrentFrame(getter_AddRefs(frame));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!frame)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
PRInt32 w,h;
|
||||
frame->GetWidth(&w);
|
||||
frame->GetHeight(&h);
|
||||
PRInt32 w = frame->Width(), h = frame->Height();
|
||||
if (!w || !h)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(frame));
|
||||
nsRefPtr<gfxImageSurface> dest;
|
||||
|
||||
if (!doScaling) {
|
||||
|
|
@ -305,23 +296,16 @@ NS_IMETHODIMP imgTools::EncodeScaledImage(imgIContainer *aContainer,
|
|||
aScaledWidth = w;
|
||||
aScaledHeight = h;
|
||||
|
||||
img->LockImagePixels(PR_FALSE);
|
||||
bitmapData = img->GetBits();
|
||||
if (!bitmapData) {
|
||||
img->UnlockImagePixels(PR_FALSE);
|
||||
bitmapData = frame->Data();
|
||||
if (!bitmapData)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
frame->GetImageBytesPerRow(&strideSize);
|
||||
strideSize = frame->Stride();
|
||||
bitmapDataLength = aScaledHeight * strideSize;
|
||||
|
||||
} else {
|
||||
// Prepare to draw a scaled version of the image to a temporary surface...
|
||||
|
||||
// Get the source image surface
|
||||
nsRefPtr<gfxPattern> gfxpat;
|
||||
img->GetPattern(getter_AddRefs(gfxpat));
|
||||
|
||||
// Create a temporary image surface
|
||||
dest = new gfxImageSurface(gfxIntSize(aScaledWidth, aScaledHeight),
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
|
|
@ -337,7 +321,7 @@ NS_IMETHODIMP imgTools::EncodeScaledImage(imgIContainer *aContainer,
|
|||
|
||||
// Paint a scaled image
|
||||
ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx.SetPattern(gfxpat);
|
||||
ctx.SetSource(frame);
|
||||
ctx.Paint();
|
||||
|
||||
bitmapData = dest->Data();
|
||||
|
|
@ -349,8 +333,6 @@ NS_IMETHODIMP imgTools::EncodeScaledImage(imgIContainer *aContainer,
|
|||
rv = encoder->InitFromData(bitmapData, bitmapDataLength,
|
||||
aScaledWidth, aScaledHeight, strideSize,
|
||||
imgIEncoder::INPUT_FORMAT_HOSTARGB, EmptyString());
|
||||
if (!doScaling)
|
||||
img->UnlockImagePixels(PR_FALSE);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
|
|||
|
|
@ -383,19 +383,23 @@ imgFile = do_get_file(imgName);
|
|||
istream = getFileInputStream(imgFile);
|
||||
do_check_eq(istream.available(), 17759);
|
||||
|
||||
// You'd think the decoder would fail, but it doesn't. The decoders use
|
||||
// stream->ReadSegments with a callback, and buffered streams ignore errors
|
||||
// from the callback. :-( See bug 413595.
|
||||
outParam = { value: null };
|
||||
imgTools.decodeImageData(istream, inMimeType, outParam);
|
||||
container = outParam.value;
|
||||
|
||||
try {
|
||||
istream = imgTools.encodeImage(container, "image/png");
|
||||
outParam = { value: null };
|
||||
imgTools.decodeImageData(istream, inMimeType, outParam);
|
||||
container = outParam.value;
|
||||
|
||||
// We should never hit this - decodeImageData throws an assertion because the
|
||||
// image decoded doesn't have enough frames.
|
||||
try {
|
||||
istream = imgTools.encodeImage(container, "image/png");
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
} catch (e) {
|
||||
err = e;
|
||||
err = e;
|
||||
}
|
||||
checkExpectedError(/NS_ERROR_NOT_AVAILABLE/, err);
|
||||
|
||||
checkExpectedError(/NS_ERROR_ILLEGAL_VALUE/, err);
|
||||
|
||||
|
||||
/* ========== end ========== */
|
||||
|
|
|
|||
|
|
@ -95,7 +95,6 @@ STATIC_LIBS += \
|
|||
xpcom_core \
|
||||
ucvutil_s \
|
||||
gkgfx \
|
||||
gfxshared_s \
|
||||
$(NULL)
|
||||
|
||||
#ifndef MOZ_EMBEDDING_LEVEL_DEFAULT
|
||||
|
|
|
|||
|
|
@ -36,10 +36,9 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsAlertsIconListener.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgILoader.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIImageToPixbuf.h"
|
||||
#include "nsIStringBundle.h"
|
||||
|
|
@ -106,7 +105,7 @@ nsAlertsIconListener::OnStartContainer(imgIRequest* aRequest,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsAlertsIconListener::OnStartFrame(imgIRequest* aRequest,
|
||||
gfxIImageFrame* aFrame)
|
||||
PRUint32 aFrame)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -114,7 +113,7 @@ nsAlertsIconListener::OnStartFrame(imgIRequest* aRequest,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsAlertsIconListener::OnDataAvailable(imgIRequest* aRequest,
|
||||
gfxIImageFrame* aFrame,
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect* aRect)
|
||||
{
|
||||
return NS_OK;
|
||||
|
|
@ -138,7 +137,6 @@ nsAlertsIconListener::OnStopDecode(imgIRequest* aRequest,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsAlertsIconListener::FrameChanged(imgIContainer* aContainer,
|
||||
gfxIImageFrame* aFrame,
|
||||
nsIntRect* aDirtyRect)
|
||||
{
|
||||
return NS_OK;
|
||||
|
|
@ -165,7 +163,7 @@ nsAlertsIconListener::OnStopRequest(imgIRequest* aRequest,
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsAlertsIconListener::OnStopFrame(imgIRequest* aRequest,
|
||||
gfxIImageFrame* aFrame)
|
||||
PRUint32 aFrame)
|
||||
{
|
||||
if (aRequest != mIconRequest)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
|
@ -173,12 +171,8 @@ nsAlertsIconListener::OnStopFrame(imgIRequest* aRequest,
|
|||
if (mLoadedFrame)
|
||||
return NS_OK; // only use one frame
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> frame = aFrame;
|
||||
nsCOMPtr<nsIImage> image = do_GetInterface(frame);
|
||||
if (!image)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv = image->LockImagePixels(PR_FALSE);
|
||||
nsCOMPtr<imgIContainer> image;
|
||||
nsresult rv = aRequest->GetImage(getter_AddRefs(image));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
|
@ -189,10 +183,6 @@ nsAlertsIconListener::OnStopFrame(imgIRequest* aRequest,
|
|||
if (!imagePixbuf)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
rv = image->UnlockImagePixels(PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
ShowAlert(imagePixbuf);
|
||||
|
||||
g_object_unref(imagePixbuf);
|
||||
|
|
|
|||
|
|
@ -94,9 +94,6 @@ JS_Init
|
|||
<atoms>
|
||||
NS_NewPermanentAtom
|
||||
|
||||
<images>
|
||||
gfxImageFrame::Init
|
||||
|
||||
<images>
|
||||
gif_write
|
||||
|
||||
|
|
|
|||
|
|
@ -43,13 +43,13 @@
|
|||
#include "nsXPIDLString.h"
|
||||
#include "nsPrimitiveHelpers.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "nsDragService.h"
|
||||
#include "nsEscape.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "imgIContainer.h"
|
||||
|
||||
// Screenshots use the (undocumented) png pasteboard type.
|
||||
#define IMAGE_PASTEBOARD_TYPES NSTIFFPboardType, @"Apple PNG pasteboard type", nil
|
||||
|
|
@ -425,18 +425,19 @@ nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTransferable)
|
|||
nsCOMPtr<nsISupports> primitiveData;
|
||||
ptrPrimitive->GetData(getter_AddRefs(primitiveData));
|
||||
|
||||
nsCOMPtr<nsIImage> image(do_QueryInterface(primitiveData));
|
||||
nsCOMPtr<imgIContainer> image(do_QueryInterface(primitiveData));
|
||||
if (!image) {
|
||||
NS_WARNING("Image isn't an nsIImage in transferable");
|
||||
NS_WARNING("Image isn't an imgIContainer in transferable");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (NS_FAILED(image->LockImagePixels(PR_FALSE)))
|
||||
nsRefPtr<gfxImageSurface> currentFrame;
|
||||
if (NS_FAILED(image->CopyCurrentFrame(getter_AddRefs(currentFrame))))
|
||||
continue;
|
||||
|
||||
PRInt32 height = image->GetHeight();
|
||||
PRInt32 stride = image->GetLineStride();
|
||||
PRInt32 width = image->GetWidth();
|
||||
PRInt32 height = currentFrame->Height();
|
||||
PRInt32 stride = currentFrame->Stride();
|
||||
PRInt32 width = currentFrame->Width();
|
||||
if ((stride % 4 != 0) || (height < 1) || (width < 1))
|
||||
continue;
|
||||
|
||||
|
|
@ -444,7 +445,7 @@ nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTransferable)
|
|||
// the alpha ordering and endianness of the machine so we don't have to
|
||||
// touch the bits ourselves.
|
||||
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL,
|
||||
image->GetBits(),
|
||||
currentFrame->Data(),
|
||||
stride * height,
|
||||
NULL);
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
|
||||
|
|
@ -475,7 +476,7 @@ nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTransferable)
|
|||
if (destRef)
|
||||
CFRelease(destRef);
|
||||
|
||||
if (NS_FAILED(image->UnlockImagePixels(PR_FALSE)) || !successfullyConverted) {
|
||||
if (!successfullyConverted) {
|
||||
if (tiffData)
|
||||
CFRelease(tiffData);
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@
|
|||
#include "nsIDOMNode.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsPoint.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsICharsetConverterManager.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
|
|
|||
|
|
@ -59,9 +59,9 @@
|
|||
#include "nsNetUtil.h"
|
||||
#include "imgILoader.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsMenuItemX.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "imgIContainer.h"
|
||||
|
||||
static const PRUint32 kIconWidth = 16;
|
||||
static const PRUint32 kIconHeight = 16;
|
||||
|
|
@ -280,9 +280,8 @@ nsMenuItemIconX::LoadIcon(nsIURI* aIconURI)
|
|||
//
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMenuItemIconX::FrameChanged(imgIContainer* aContainer,
|
||||
gfxIImageFrame* aFrame,
|
||||
nsIntRect* aDirtyRect)
|
||||
nsMenuItemIconX::FrameChanged(imgIContainer* aContainer,
|
||||
nsIntRect* aDirtyRect)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -305,32 +304,33 @@ nsMenuItemIconX::OnStartDecode(imgIRequest* aRequest)
|
|||
|
||||
NS_IMETHODIMP
|
||||
nsMenuItemIconX::OnStartContainer(imgIRequest* aRequest,
|
||||
imgIContainer* aContainer)
|
||||
imgIContainer* aContainer)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMenuItemIconX::OnStartFrame(imgIRequest* aRequest, gfxIImageFrame* aFrame)
|
||||
nsMenuItemIconX::OnStartFrame(imgIRequest* aRequest, PRUint32 aFrame)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMenuItemIconX::OnDataAvailable(imgIRequest* aRequest,
|
||||
gfxIImageFrame* aFrame,
|
||||
const nsIntRect* aRect)
|
||||
PRBool aCurrentFrame,
|
||||
const nsIntRect* aRect)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMenuItemIconX::OnStopFrame(imgIRequest* aRequest,
|
||||
gfxIImageFrame* aFrame)
|
||||
PRUint32 aFrame)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
if (aRequest != mIconRequest) return NS_ERROR_FAILURE;
|
||||
if (aRequest != mIconRequest)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Only support one frame.
|
||||
if (mLoadedIcon)
|
||||
|
|
@ -338,22 +338,22 @@ nsMenuItemIconX::OnStopFrame(imgIRequest* aRequest,
|
|||
|
||||
if (!mNativeMenuItem) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> frame = aFrame;
|
||||
nsCOMPtr<nsIImage> image = do_GetInterface(frame);
|
||||
if (!image) return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<imgIContainer> imageContainer;
|
||||
aRequest->GetImage(getter_AddRefs(imageContainer));
|
||||
if (!imageContainer)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv = image->LockImagePixels(PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
nsRefPtr<gfxImageSurface> image;
|
||||
imageContainer->CopyCurrentFrame(getter_AddRefs(image));
|
||||
|
||||
PRInt32 height = image->GetHeight();
|
||||
PRInt32 stride = image->GetLineStride();
|
||||
PRInt32 width = image->GetWidth();
|
||||
PRInt32 height = image->Height();
|
||||
PRInt32 stride = image->Stride();
|
||||
PRInt32 width = image->Width();
|
||||
PRUint32 imageLength = ((stride * height) / 4);
|
||||
if ((stride % 4 != 0) || (height < 1) || (width < 1))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRUint32* imageData = (PRUint32*)image->GetBits();
|
||||
PRUint32* imageData = (PRUint32*)image->Data();
|
||||
|
||||
PRUint32* reorderedData = (PRUint32*)malloc(height * stride);
|
||||
if (!reorderedData)
|
||||
|
|
@ -378,12 +378,6 @@ nsMenuItemIconX::OnStopFrame(imgIRequest* aRequest,
|
|||
NULL, true, kCGRenderingIntentDefault);
|
||||
::CGDataProviderRelease(provider);
|
||||
|
||||
rv = image->UnlockImagePixels(PR_FALSE);
|
||||
if (NS_FAILED(rv)) {
|
||||
::CGColorSpaceRelease(colorSpace);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// The image may not be the right size for a menu icon (16x16).
|
||||
// Create a new CGImage for the menu item.
|
||||
PRUint8* bitmap = (PRUint8*)malloc(kIconBytes);
|
||||
|
|
|
|||
|
|
@ -44,10 +44,11 @@
|
|||
#include "nsPrimitiveHelpers.h"
|
||||
#include "nsICharsetConverterManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsImageToPixbuf.h"
|
||||
#include "nsStringStream.h"
|
||||
|
||||
#include "imgIContainer.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
// For manipulation of the X event queue
|
||||
|
|
@ -239,22 +240,17 @@ nsClipboard::SetData(nsITransferable *aTransferable,
|
|||
|
||||
nsCOMPtr<nsISupports> primitiveData;
|
||||
ptrPrimitive->GetData(getter_AddRefs(primitiveData));
|
||||
nsCOMPtr<nsIImage> image(do_QueryInterface(primitiveData));
|
||||
nsCOMPtr<imgIContainer> image(do_QueryInterface(primitiveData));
|
||||
if (!image) // Not getting an image for an image mime type!?
|
||||
continue;
|
||||
|
||||
if (NS_FAILED(image->LockImagePixels(PR_FALSE)))
|
||||
continue;
|
||||
GdkPixbuf* pixbuf = nsImageToPixbuf::ImageToPixbuf(image);
|
||||
if (!pixbuf) {
|
||||
image->UnlockImagePixels(PR_FALSE);
|
||||
if (!pixbuf)
|
||||
continue;
|
||||
}
|
||||
|
||||
GtkClipboard *aClipboard = gtk_clipboard_get(GetSelectionAtom(aWhichClipboard));
|
||||
gtk_clipboard_set_image(aClipboard, pixbuf);
|
||||
g_object_unref(pixbuf);
|
||||
image->UnlockImagePixels(PR_FALSE);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,17 +44,17 @@
|
|||
{ 0xdfa4ac93, 0x83f2, 0x4ab8, \
|
||||
{ 0x9b, 0x2a, 0x0f, 0xf7, 0x02, 0x2a, 0xeb, 0xe2 } }
|
||||
|
||||
class nsIImage;
|
||||
class imgIContainer;
|
||||
typedef struct _GdkPixbuf GdkPixbuf;
|
||||
|
||||
/**
|
||||
* An interface that allows converting an nsIImage to a GdkPixbuf*.
|
||||
* An interface that allows converting the current frame of an imgIContainer to a GdkPixbuf*.
|
||||
*/
|
||||
class nsIImageToPixbuf : public nsISupports {
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NSIIMAGETOPIXBUF_IID)
|
||||
|
||||
NS_IMETHOD_(GdkPixbuf*) ConvertImageToPixbuf(nsIImage* aImage) = 0;
|
||||
NS_IMETHOD_(GdkPixbuf*) ConvertImageToPixbuf(imgIContainer* aImage) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIImageToPixbuf, NSIIMAGETOPIXBUF_IID)
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
#include "gfxImageSurface.h"
|
||||
#include "gfxContext.h"
|
||||
|
||||
#include "nsIImage.h"
|
||||
#include "imgIContainer.h"
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
|
|
@ -60,21 +60,18 @@ unpremultiply (unsigned char color,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP_(GdkPixbuf*)
|
||||
nsImageToPixbuf::ConvertImageToPixbuf(nsIImage* aImage)
|
||||
nsImageToPixbuf::ConvertImageToPixbuf(imgIContainer* aImage)
|
||||
{
|
||||
return ImageToPixbuf(aImage);
|
||||
}
|
||||
|
||||
GdkPixbuf*
|
||||
nsImageToPixbuf::ImageToPixbuf(nsIImage* aImage)
|
||||
nsImageToPixbuf::ImageToPixbuf(imgIContainer* aImage)
|
||||
{
|
||||
PRInt32 width = aImage->GetWidth(),
|
||||
height = aImage->GetHeight();
|
||||
nsRefPtr<gfxImageSurface> frame;
|
||||
aImage->CopyCurrentFrame(getter_AddRefs(frame));
|
||||
|
||||
nsRefPtr<gfxPattern> pattern;
|
||||
aImage->GetPattern(getter_AddRefs(pattern));
|
||||
|
||||
return PatternToPixbuf(pattern, width, height);
|
||||
return ImgSurfaceToPixbuf(frame, frame->Width(), frame->Height());
|
||||
}
|
||||
|
||||
GdkPixbuf*
|
||||
|
|
@ -158,39 +155,3 @@ nsImageToPixbuf::SurfaceToPixbuf(gfxASurface* aSurface, PRInt32 aWidth, PRInt32
|
|||
|
||||
return ImgSurfaceToPixbuf(imgSurface, aWidth, aHeight);
|
||||
}
|
||||
|
||||
GdkPixbuf*
|
||||
nsImageToPixbuf::PatternToPixbuf(gfxPattern* aPattern, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
if (aPattern->CairoStatus()) {
|
||||
NS_ERROR("invalid pattern");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxImageSurface> imgSurface;
|
||||
if (aPattern->GetType() == gfxPattern::PATTERN_SURFACE) {
|
||||
nsRefPtr<gfxASurface> surface = aPattern->GetSurface();
|
||||
if (surface->GetType() == gfxASurface::SurfaceTypeImage) {
|
||||
imgSurface = static_cast<gfxImageSurface*>
|
||||
(static_cast<gfxASurface*>(surface.get()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!imgSurface) {
|
||||
imgSurface = new gfxImageSurface(gfxIntSize(aWidth, aHeight),
|
||||
gfxImageSurface::ImageFormatARGB32);
|
||||
|
||||
if (!imgSurface)
|
||||
return nsnull;
|
||||
|
||||
nsRefPtr<gfxContext> context = new gfxContext(imgSurface);
|
||||
if (!context)
|
||||
return nsnull;
|
||||
|
||||
context->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
context->SetPattern(aPattern);
|
||||
context->Paint();
|
||||
}
|
||||
|
||||
return ImgSurfaceToPixbuf(imgSurface, aWidth, aHeight);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,15 +47,13 @@ class gfxImageSurface;
|
|||
class nsImageToPixbuf : public nsIImageToPixbuf {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_IMETHOD_(GdkPixbuf*) ConvertImageToPixbuf(nsIImage* aImage);
|
||||
NS_IMETHOD_(GdkPixbuf*) ConvertImageToPixbuf(imgIContainer* aImage);
|
||||
|
||||
// Friendlier version of ConvertImageToPixbuf for callers inside of
|
||||
// widget
|
||||
static GdkPixbuf* ImageToPixbuf(nsIImage* aImage);
|
||||
static GdkPixbuf* ImageToPixbuf(imgIContainer * aImage);
|
||||
static GdkPixbuf* SurfaceToPixbuf(gfxASurface* aSurface,
|
||||
PRInt32 aWidth, PRInt32 aHeight);
|
||||
static GdkPixbuf* PatternToPixbuf(gfxPattern* aPattern,
|
||||
PRInt32 aWidth, PRInt32 aHeight);
|
||||
private:
|
||||
static GdkPixbuf* ImgSurfaceToPixbuf(gfxImageSurface* aImgSurface,
|
||||
PRInt32 aWidth, PRInt32 aHeight);
|
||||
|
|
|
|||
|
|
@ -104,9 +104,7 @@ static const char sAccessibilityKey [] = "config.use_system_prefs.accessibility"
|
|||
/* SetCursor(imgIContainer*) */
|
||||
#include <gdk/gdk.h>
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsGfxCIID.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsImageToPixbuf.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
|
@ -1572,17 +1570,8 @@ nsWindow::SetCursor(imgIContainer* aCursor,
|
|||
}
|
||||
mCursor = nsCursor(-1);
|
||||
|
||||
// Get first image frame
|
||||
nsCOMPtr<gfxIImageFrame> frame;
|
||||
aCursor->GetFrameAt(0, getter_AddRefs(frame));
|
||||
if (!frame)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(frame));
|
||||
if (!img)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
GdkPixbuf* pixbuf = nsImageToPixbuf::ImageToPixbuf(img);
|
||||
// Get the image's current frame
|
||||
GdkPixbuf* pixbuf = nsImageToPixbuf::ImageToPixbuf(aCursor);
|
||||
if (!pixbuf)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,6 @@
|
|||
#include "nsOS2Uni.h"
|
||||
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
|
@ -1711,39 +1710,19 @@ NS_IMETHODIMP nsWindow::SetCursor(imgIContainer* aCursor,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> frame;
|
||||
aCursor->GetFrameAt(0, getter_AddRefs(frame));
|
||||
nsRefPtr<gfxImageFrame> frame;
|
||||
aCursor->CopyCurrentFrame(getter_AddRefs(frame));
|
||||
if (!frame)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
// if the image is ridiculously large, exit because
|
||||
// it will be unrecognizable when shrunk to 32x32
|
||||
PRInt32 width, height;
|
||||
frame->GetWidth(&width);
|
||||
frame->GetHeight(&height);
|
||||
PRInt32 width = frame->Width();
|
||||
PRInt32 height = frame->Height();
|
||||
if (width > 128 || height > 128)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
gfx_format format;
|
||||
nsresult rv = frame->GetFormat(&format);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// only 24-bit images with 0, 1, or 8-bit alpha data are supported.
|
||||
// These are all the formats used in Cairo, and all map to the RGB24 resp. ARGB32 Cairo formats.
|
||||
if (format != gfxIFormats::BGR_A1 && format != gfxIFormats::RGB_A1 &&
|
||||
format != gfxIFormats::BGR_A8 && format != gfxIFormats::RGB_A8 &&
|
||||
format != gfxIFormats::BGR && format != gfxIFormats::RGB)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
frame->LockImageData();
|
||||
PRUint32 dataLen;
|
||||
PRUint8* data;
|
||||
rv = frame->GetImageData(&data, &dataLen);
|
||||
if (NS_FAILED(rv)) {
|
||||
frame->UnlockImageData();
|
||||
return rv;
|
||||
}
|
||||
PRUint8* data = frame->Data();
|
||||
|
||||
// create the color bitmap
|
||||
HBITMAP hBmp = CreateBitmapRGB(data, width, height);
|
||||
|
|
@ -1751,15 +1730,12 @@ NS_IMETHODIMP nsWindow::SetCursor(imgIContainer* aCursor,
|
|||
return NS_ERROR_FAILURE;
|
||||
|
||||
// create a transparency mask from the alpha bytes
|
||||
HBITMAP hAlpha = CreateTransparencyMask(format, data, width, height);
|
||||
HBITMAP hAlpha = CreateTransparencyMask(frame->Format(), data, width, height);
|
||||
if (!hAlpha) {
|
||||
GpiDeleteBitmap(hBmp);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Unlock image data after both processing colors and alpha data
|
||||
frame->UnlockImageData();
|
||||
|
||||
POINTERINFO info = {0};
|
||||
info.fPointer = TRUE;
|
||||
info.xHotspot = aHotspotX;
|
||||
|
|
@ -1875,7 +1851,7 @@ HBITMAP nsWindow::CreateBitmapRGB(PRUint8* aImageData,
|
|||
|
||||
// create a monochrome AND/XOR bitmap from 0, 1, or 8-bit alpha data
|
||||
|
||||
HBITMAP nsWindow::CreateTransparencyMask(gfx_format format,
|
||||
HBITMAP nsWindow::CreateTransparencyMask(gfxASurface::gfxImageFormat format,
|
||||
PRUint8* aImageData,
|
||||
PRUint32 aWidth,
|
||||
PRUint32 aHeight)
|
||||
|
|
@ -1889,36 +1865,29 @@ HBITMAP nsWindow::CreateTransparencyMask(gfx_format format,
|
|||
if (!mono)
|
||||
return NULL;
|
||||
|
||||
switch (format) {
|
||||
// gfxIFormats::BGR and case gfxIFormats::RGB are already
|
||||
// taken care of by initializing XOR and AND masks to zero
|
||||
if (format == gfxASurface::ImageFormatARGB32) {
|
||||
// Non-alpha formats are already taken care of by initializing the XOR and
|
||||
// AND masks to zero
|
||||
|
||||
// make the AND mask the inverse of the 8-bit alpha data
|
||||
case gfxIFormats::BGR_A1:
|
||||
case gfxIFormats::RGB_A1:
|
||||
case gfxIFormats::RGB_A8:
|
||||
case gfxIFormats::BGR_A8: {
|
||||
PRInt32* pSrc = (PRInt32*)aImageData;
|
||||
for (PRUint32 row = aHeight; row > 0; --row) {
|
||||
// Point to the right row in the AND mask
|
||||
PRUint8* pDst = mono + cbData + abpr * (row - 1);
|
||||
PRUint8 mask = 0x80;
|
||||
for (PRUint32 col = aWidth; col > 0; --col) {
|
||||
// Use sign bit to test for transparency, as alpha byte is highest byte
|
||||
// Positive means, alpha < 128, so consider as transparent and set the AND mask
|
||||
if (*pSrc++ >= 0) {
|
||||
*pDst |= mask;
|
||||
}
|
||||
PRInt32* pSrc = (PRInt32*)aImageData;
|
||||
for (PRUint32 row = aHeight; row > 0; --row) {
|
||||
// Point to the right row in the AND mask
|
||||
PRUint8* pDst = mono + cbData + abpr * (row - 1);
|
||||
PRUint8 mask = 0x80;
|
||||
for (PRUint32 col = aWidth; col > 0; --col) {
|
||||
// Use sign bit to test for transparency, as alpha byte is highest byte
|
||||
// Positive means, alpha < 128, so consider as transparent and set the AND mask
|
||||
if (*pSrc++ >= 0) {
|
||||
*pDst |= mask;
|
||||
}
|
||||
|
||||
mask >>= 1;
|
||||
if (!mask) {
|
||||
pDst++;
|
||||
mask = 0x80;
|
||||
}
|
||||
mask >>= 1;
|
||||
if (!mask) {
|
||||
pDst++;
|
||||
mask = 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -313,9 +313,8 @@ protected:
|
|||
HBITMAP DataToBitmap(PRUint8* aImageData, PRUint32 aWidth,
|
||||
PRUint32 aHeight, PRUint32 aDepth);
|
||||
HBITMAP CreateBitmapRGB(PRUint8* aImageData, PRUint32 aWidth, PRUint32 aHeight);
|
||||
// 'format' should be 'gfx_format' which is a PRInt32
|
||||
HBITMAP CreateTransparencyMask(PRInt32 format, PRUint8* aImageData,
|
||||
PRUint32 aWidth, PRUint32 aHeight);
|
||||
HBITMAP CreateTransparencyMask(gfxASurface::gfxImageFormat format,
|
||||
PRUint8* aImageData, PRUint32 aWidth, PRUint32 aHeight);
|
||||
|
||||
BOOL NotifyForeignChildWindows(HWND aWnd);
|
||||
void ScrollChildWindows(PRInt32 aX, PRInt32 aY);
|
||||
|
|
|
|||
|
|
@ -76,9 +76,7 @@
|
|||
|
||||
/* SetCursor(imgIContainer*) */
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsGfxCIID.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -70,8 +70,6 @@
|
|||
#include "nsNetUtil.h"
|
||||
#include "nsEscape.h"
|
||||
|
||||
#include "nsIImage.h"
|
||||
|
||||
|
||||
// oddly, this isn't in the MSVC headers anywhere.
|
||||
UINT nsClipboard::CF_HTML = ::RegisterClipboardFormatW(L"HTML Format");
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@
|
|||
#include "IEnumFE.h"
|
||||
#include "nsPrimitiveHelpers.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsImageClipboard.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
|
@ -859,7 +858,7 @@ nsDataObj::GetBitmap ( const nsACString& , FORMATETC&, STGMEDIUM& )
|
|||
// GetDIB
|
||||
//
|
||||
// Someone is asking for a bitmap. The data in the transferable will be a straight
|
||||
// nsIImage, so just QI it.
|
||||
// imgIContainer, so just QI it.
|
||||
//
|
||||
HRESULT
|
||||
nsDataObj :: GetDib ( const nsACString& inFlavor, FORMATETC &, STGMEDIUM & aSTG )
|
||||
|
|
@ -869,12 +868,11 @@ nsDataObj :: GetDib ( const nsACString& inFlavor, FORMATETC &, STGMEDIUM & aSTG
|
|||
PRUint32 len = 0;
|
||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||
mTransferable->GetTransferData(PromiseFlatCString(inFlavor).get(), getter_AddRefs(genericDataWrapper), &len);
|
||||
nsCOMPtr<nsIImage> image ( do_QueryInterface(genericDataWrapper) );
|
||||
nsCOMPtr<imgIContainer> image ( do_QueryInterface(genericDataWrapper) );
|
||||
if ( !image ) {
|
||||
// In the 0.9.4 timeframe, I had some embedding clients put the nsIImage directly into the
|
||||
// transferable. Newer code, however, wraps the nsIImage in a nsISupportsInterfacePointer.
|
||||
// We should be backwards compatibile with code already out in the field. If we can't find
|
||||
// the image directly out of the transferable, unwrap the image from its wrapper.
|
||||
// Check if the image was put in an nsISupportsInterfacePointer wrapper.
|
||||
// This might not be necessary any more, but could be useful for backwards
|
||||
// compatibility.
|
||||
nsCOMPtr<nsISupportsInterfacePointer> ptr(do_QueryInterface(genericDataWrapper));
|
||||
if ( ptr )
|
||||
ptr->GetData(getter_AddRefs(image));
|
||||
|
|
@ -1384,13 +1382,12 @@ HRESULT nsDataObj::GetFile(FORMATETC& aFE, STGMEDIUM& aSTG)
|
|||
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||
|
||||
mTransferable->GetTransferData(kNativeImageMime, getter_AddRefs(genericDataWrapper), &len);
|
||||
nsCOMPtr<nsIImage> image ( do_QueryInterface(genericDataWrapper) );
|
||||
nsCOMPtr<imgIContainer> image ( do_QueryInterface(genericDataWrapper) );
|
||||
|
||||
if (!image) {
|
||||
// In the 0.9.4 timeframe, I had some embedding clients put the nsIImage directly into the
|
||||
// transferable. Newer code, however, wraps the nsIImage in a nsISupportsInterfacePointer.
|
||||
// We should be backwards compatibile with code already out in the field. If we can't find
|
||||
// the image directly out of the transferable, unwrap the image from its wrapper.
|
||||
// Check if the image was put in an nsISupportsInterfacePointer wrapper.
|
||||
// This might not be necessary any more, but could be useful for backwards
|
||||
// compatibility.
|
||||
nsCOMPtr<nsISupportsInterfacePointer> ptr(do_QueryInterface(genericDataWrapper));
|
||||
if (ptr)
|
||||
ptr->GetData(getter_AddRefs(image));
|
||||
|
|
|
|||
|
|
@ -59,9 +59,9 @@ Any other render format? HTML?
|
|||
//
|
||||
// nsImageToClipboard ctor
|
||||
//
|
||||
// Given an nsIImage, convert it to a DIB that is ready to go on the win32 clipboard
|
||||
// Given an imgIContainer, convert it to a DIB that is ready to go on the win32 clipboard
|
||||
//
|
||||
nsImageToClipboard :: nsImageToClipboard ( nsIImage* inImage )
|
||||
nsImageToClipboard :: nsImageToClipboard ( imgIContainer* inImage )
|
||||
: mImage(inImage)
|
||||
{
|
||||
// nothing to do here
|
||||
|
|
@ -143,19 +143,21 @@ nsImageToClipboard::CalcSpanLength(PRUint32 aWidth, PRUint32 aBitCount)
|
|||
// image.
|
||||
//
|
||||
nsresult
|
||||
nsImageToClipboard::CreateFromImage ( nsIImage* inImage, HANDLE* outBitmap )
|
||||
nsImageToClipboard::CreateFromImage ( imgIContainer* inImage, HANDLE* outBitmap )
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
*outBitmap = nsnull;
|
||||
|
||||
inImage->LockImagePixels(PR_FALSE);
|
||||
nsRefPtr<gfxImageSurface> frame;
|
||||
nsresult rv = inImage->CopyCurrentFrame(getter_AddRefs(frame));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
const PRUint32 imageSize = inImage->GetLineStride() * inImage->GetHeight();
|
||||
const PRUint32 imageSize = frame->GetDataSize();
|
||||
const PRInt32 bitmapSize = sizeof(BITMAPINFOHEADER) + imageSize;
|
||||
|
||||
HGLOBAL glob = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE | GMEM_ZEROINIT, bitmapSize);
|
||||
if (!glob) {
|
||||
inImage->UnlockImagePixels(PR_FALSE);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
|
@ -164,18 +166,21 @@ nsImageToClipboard::CreateFromImage ( nsIImage* inImage, HANDLE* outBitmap )
|
|||
|
||||
BITMAPINFOHEADER *header = (BITMAPINFOHEADER*)data;
|
||||
header->biSize = sizeof(BITMAPINFOHEADER);
|
||||
header->biWidth = inImage->GetWidth();
|
||||
header->biHeight = inImage->GetHeight();
|
||||
header->biWidth = frame->Width();
|
||||
header->biHeight = frame->Height();
|
||||
|
||||
header->biPlanes = 1;
|
||||
header->biBitCount = inImage->GetBytesPix() * 8;
|
||||
if (frame->Format() == gfxASurface::ImageFormatARGB32)
|
||||
header->biBitCount = 32;
|
||||
else if (frame->Format() == gfxASurface::ImageFormatRGB24)
|
||||
header->biBitCount = 24;
|
||||
header->biCompression = BI_RGB;
|
||||
header->biSizeImage = imageSize;
|
||||
|
||||
const PRUint32 bpr = inImage->GetLineStride();
|
||||
const PRUint32 bpr = frame->Stride();
|
||||
|
||||
BYTE *dstBits = (BYTE*)data + sizeof(BITMAPINFOHEADER);
|
||||
BYTE *srcBits = inImage->GetBits();
|
||||
BYTE *srcBits = frame->Data();
|
||||
for (PRInt32 i = 0; i < header->biHeight; ++i) {
|
||||
PRUint32 srcOffset = imageSize - (bpr * (i + 1));
|
||||
PRUint32 dstOffset = i * bpr;
|
||||
|
|
@ -186,11 +191,7 @@ nsImageToClipboard::CreateFromImage ( nsIImage* inImage, HANDLE* outBitmap )
|
|||
|
||||
*outBitmap = (HANDLE)glob;
|
||||
|
||||
inImage->UnlockImagePixels(PR_FALSE);
|
||||
return NS_OK;
|
||||
|
||||
// Wow the old code is broken. I'm not touching it.
|
||||
// It should probably lock/unlock the same object....
|
||||
}
|
||||
|
||||
nsImageFromClipboard :: nsImageFromClipboard ()
|
||||
|
|
|
|||
|
|
@ -50,20 +50,20 @@ Any other render format? HTML?
|
|||
#include <windows.h>
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIImage.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
|
||||
//
|
||||
// nsImageToClipboard
|
||||
//
|
||||
// A utility class that takes an nsIImage and does all the bitmap magic
|
||||
// A utility class that takes an imgIContainer and does all the bitmap magic
|
||||
// to allow us to put it on the clipboard
|
||||
//
|
||||
class nsImageToClipboard
|
||||
{
|
||||
public:
|
||||
nsImageToClipboard ( nsIImage* inImage );
|
||||
nsImageToClipboard ( imgIContainer* inImage );
|
||||
~nsImageToClipboard();
|
||||
|
||||
// Call to get the actual bits that go on the clipboard. If |nsnull|, the
|
||||
|
|
@ -79,9 +79,9 @@ private:
|
|||
PRInt32 CalcSpanLength(PRUint32 aWidth, PRUint32 aBitCount);
|
||||
|
||||
// Do the work
|
||||
nsresult CreateFromImage ( nsIImage* inImage, HANDLE* outBitmap );
|
||||
nsresult CreateFromImage ( imgIContainer* inImage, HANDLE* outBitmap );
|
||||
|
||||
nsCOMPtr<nsIImage> mImage; // the image we're working with
|
||||
nsCOMPtr<imgIContainer> mImage; // the image we're working with
|
||||
|
||||
}; // class nsImageToClipboard
|
||||
|
||||
|
|
|
|||
|
|
@ -119,13 +119,11 @@
|
|||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIDOMNSUIEvent.h"
|
||||
#include "nsITheme.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIScreenManager.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIRollupListener.h"
|
||||
#include "nsIMenuRollup.h"
|
||||
|
|
@ -2058,14 +2056,13 @@ NS_IMETHODIMP nsWindow::SetCursor(imgIContainer* aCursor,
|
|||
}
|
||||
|
||||
// Get the image data
|
||||
nsCOMPtr<gfxIImageFrame> frame;
|
||||
aCursor->GetFrameAt(0, getter_AddRefs(frame));
|
||||
nsRefPtr<gfxImageSurface> frame;
|
||||
aCursor->CopyCurrentFrame(getter_AddRefs(frame));
|
||||
if (!frame)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
PRInt32 width, height;
|
||||
frame->GetWidth(&width);
|
||||
frame->GetHeight(&height);
|
||||
PRInt32 width = frame->Width();
|
||||
PRInt32 height = frame->Height();
|
||||
|
||||
// Reject cursors greater than 128 pixels in either direction, to prevent
|
||||
// spoofing.
|
||||
|
|
@ -2074,19 +2071,10 @@ NS_IMETHODIMP nsWindow::SetCursor(imgIContainer* aCursor,
|
|||
if (width > 128 || height > 128)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
frame->LockImageData();
|
||||
|
||||
PRUint32 dataLen;
|
||||
PRUint8 *data;
|
||||
nsresult rv = frame->GetImageData(&data, &dataLen);
|
||||
if (NS_FAILED(rv)) {
|
||||
frame->UnlockImageData();
|
||||
return rv;
|
||||
}
|
||||
PRUint8 *data = frame->Data();
|
||||
|
||||
HBITMAP bmp = DataToBitmap(data, width, -height, 32);
|
||||
PRUint8* a1data = Data32BitTo1Bit(data, width, height);
|
||||
frame->UnlockImageData();
|
||||
if (!a1data) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,9 +62,7 @@
|
|||
#include "nsIDOMDataTransfer.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsICanvasElement.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIImageLoadingContent.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "nsIViewObserver.h"
|
||||
|
|
@ -530,7 +528,7 @@ nsBaseDragService::DrawDragForImage(nsPresContext* aPresContext,
|
|||
nsIntRect* aScreenDragRect,
|
||||
gfxASurface** aSurface)
|
||||
{
|
||||
nsCOMPtr<nsIImage> img;
|
||||
nsCOMPtr<imgIContainer> imgContainer;
|
||||
if (aImageLoader) {
|
||||
nsCOMPtr<imgIRequest> imgRequest;
|
||||
nsresult rv = aImageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
|
||||
|
|
@ -539,21 +537,11 @@ nsBaseDragService::DrawDragForImage(nsPresContext* aPresContext,
|
|||
if (!imgRequest)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
nsCOMPtr<imgIContainer> imgContainer;
|
||||
rv = imgRequest->GetImage(getter_AddRefs(imgContainer));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!imgContainer)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> iframe;
|
||||
imgContainer->GetCurrentFrame(getter_AddRefs(iframe));
|
||||
if (!iframe)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
img = do_GetInterface(iframe);
|
||||
if (!img)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// use the size of the image as the size of the drag image
|
||||
imgContainer->GetWidth(&aScreenDragRect->width);
|
||||
imgContainer->GetHeight(&aScreenDragRect->height);
|
||||
|
|
@ -612,8 +600,8 @@ nsBaseDragService::DrawDragForImage(nsPresContext* aPresContext,
|
|||
gfxRect outRect(0, 0, destSize.width, destSize.height);
|
||||
gfxMatrix scale =
|
||||
gfxMatrix().Scale(srcSize.width/outRect.Width(), srcSize.height/outRect.Height());
|
||||
img->Draw(ctx, gfxPattern::FILTER_GOOD, scale, outRect, nsIntMargin(0,0,0,0),
|
||||
nsIntRect(0, 0, srcSize.width, srcSize.height));
|
||||
nsIntRect imgSize(0, 0, srcSize.width, srcSize.height);
|
||||
imgContainer->Draw(ctx, gfxPattern::FILTER_GOOD, scale, outRect, imgSize);
|
||||
return NS_OK;
|
||||
} else {
|
||||
return aCanvas->RenderContexts(ctx, gfxPattern::FILTER_GOOD);
|
||||
|
|
|
|||
Loading…
Reference in a new issue