mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-13 19:41:49 +00:00
b=415854, make single-pixel optimized images release memory; patch from joe@drew.ca; r+sr=vlad
This commit is contained in:
parent
a2838e38fa
commit
c325e922a7
@ -2220,9 +2220,18 @@ nsCanvasRenderingContext2D::CairoSurfaceFromElement(nsIDOMElement *imgElt,
|
||||
if (heightOut)
|
||||
*heightOut = imgHeight;
|
||||
|
||||
nsRefPtr<gfxASurface> gfxsurf;
|
||||
rv = img->GetSurface(getter_AddRefs(gfxsurf));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsRefPtr<gfxPattern> gfxpattern;
|
||||
img->GetPattern(getter_AddRefs(gfxpattern));
|
||||
nsRefPtr<gfxASurface> gfxsurf = gfxpattern->GetSurface();
|
||||
|
||||
if (!gfxsurf) {
|
||||
gfxsurf = new gfxImageSurface (gfxIntSize(imgWidth, imgHeight), gfxASurface::ImageFormatARGB32);
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(gfxsurf);
|
||||
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->SetPattern(gfxpattern);
|
||||
ctx->Paint();
|
||||
}
|
||||
|
||||
*aCairoSurface = gfxsurf->CairoSurface();
|
||||
cairo_surface_reference (*aCairoSurface);
|
||||
|
@ -174,7 +174,6 @@ INCLUDES += \
|
||||
-I$(srcdir)/../../../events/src \
|
||||
-I$(srcdir)/../../../html/content/src \
|
||||
-I$(topsrcdir)/content/xbl/src \
|
||||
-I$(topsrcdir)/gfx/src/thebes \
|
||||
$(NULL)
|
||||
|
||||
DEFINES += -D_IMPL_NS_LAYOUT
|
||||
|
@ -63,7 +63,7 @@
|
||||
#include "nsImageLoadingContent.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsThebesImage.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsSVGAnimatedPreserveAspectRatio.h"
|
||||
#include "nsSVGPreserveAspectRatio.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
@ -5582,19 +5582,14 @@ nsSVGFEImageElement::Filter(nsSVGFilterInstance *instance)
|
||||
if (imageContainer)
|
||||
imageContainer->GetCurrentFrame(getter_AddRefs(currentFrame));
|
||||
|
||||
gfxASurface *thebesSurface = nsnull;
|
||||
nsRefPtr<gfxPattern> thebesPattern = nsnull;
|
||||
if (currentFrame) {
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(currentFrame));
|
||||
|
||||
nsThebesImage *thebesImage = nsnull;
|
||||
if (img)
|
||||
thebesImage = static_cast<nsThebesImage*>(img.get());
|
||||
|
||||
if (thebesImage)
|
||||
thebesSurface = thebesImage->ThebesSurface();
|
||||
img->GetPattern(getter_AddRefs(thebesPattern));
|
||||
}
|
||||
|
||||
if (thebesSurface) {
|
||||
if (thebesPattern) {
|
||||
PRInt32 x, y, nativeWidth, nativeHeight;
|
||||
currentFrame->GetX(&x);
|
||||
currentFrame->GetY(&y);
|
||||
@ -5611,7 +5606,7 @@ nsSVGFEImageElement::Filter(nsSVGFilterInstance *instance)
|
||||
xy->Multiply(trans, getter_AddRefs(fini));
|
||||
|
||||
gfxContext ctx(targetSurface);
|
||||
nsSVGUtils::CompositeSurfaceMatrix(&ctx, thebesSurface, fini, 1.0);
|
||||
nsSVGUtils::CompositePatternMatrix(&ctx, thebesPattern, fini, nativeWidth, nativeHeight, 1.0);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "gfxRect.h"
|
||||
|
||||
class gfxASurface;
|
||||
class gfxPattern;
|
||||
|
||||
class nsIDeviceContext;
|
||||
|
||||
@ -213,7 +214,11 @@ public:
|
||||
/**
|
||||
* LockImagePixels
|
||||
* Lock the image pixels so that we can access them directly,
|
||||
* with safely. May be a noop on some platforms.
|
||||
* 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
|
||||
*
|
||||
@ -239,13 +244,24 @@ public:
|
||||
|
||||
/**
|
||||
* GetSurface
|
||||
* Return the Thebes gfxASurface in aSurface.
|
||||
* 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
|
||||
*
|
||||
|
@ -259,13 +259,6 @@ nsThebesImage::Optimize(nsIDeviceContext* aContext)
|
||||
|
||||
mSinglePixel = PR_TRUE;
|
||||
|
||||
// XXX we can't do this until we either teach anyone
|
||||
// who calls GetSurface() about single-color stuff,
|
||||
// or until we make GetSurface() create a new temporary
|
||||
// surface to return (and that callers understand that
|
||||
// modifying that surface won't modify the image).
|
||||
// Current users are drag & drop and clipboard.
|
||||
#if 0
|
||||
// blow away the older surfaces, to release data
|
||||
|
||||
mImageSurface = nsnull;
|
||||
@ -275,7 +268,6 @@ nsThebesImage::Optimize(nsIDeviceContext* aContext)
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
mQuartzSurface = nsnull;
|
||||
#endif
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
@ -391,7 +383,15 @@ nsThebesImage::LockImagePixels(PRBool aMaskPixels)
|
||||
else
|
||||
context.SetSource(mOptSurface);
|
||||
context.Paint();
|
||||
|
||||
#ifdef XP_WIN
|
||||
mWinSurface = nsnull;
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
mQuartzSurface = nsnull;
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "gfxColor.h"
|
||||
#include "gfxASurface.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxPattern.h"
|
||||
#if defined(XP_WIN)
|
||||
#include "gfxWindowsSurface.h"
|
||||
#elif defined(XP_MACOSX)
|
||||
@ -96,6 +97,22 @@ public:
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD GetPattern(gfxPattern **aPattern) {
|
||||
*aPattern = ThebesPattern();
|
||||
NS_ADDREF(*aPattern);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
gfxPattern* ThebesPattern() {
|
||||
gfxPattern *pattern;
|
||||
if (mSinglePixel)
|
||||
pattern = new gfxPattern(mSinglePixelColor);
|
||||
else
|
||||
pattern = new gfxPattern(ThebesSurface());
|
||||
|
||||
return pattern;
|
||||
}
|
||||
|
||||
gfxASurface* ThebesSurface() {
|
||||
if (mOptSurface)
|
||||
return mOptSurface;
|
||||
|
@ -78,6 +78,17 @@ public:
|
||||
void SetExtend(GraphicsExtend extend);
|
||||
GraphicsExtend Extend() const;
|
||||
|
||||
enum GraphicsPatternType {
|
||||
PATTERN_SOLID,
|
||||
PATTERN_SURFACE,
|
||||
PATTERN_LINEAR,
|
||||
PATTERN_RADIAL
|
||||
};
|
||||
|
||||
GraphicsPatternType GetType() const;
|
||||
|
||||
int CairoStatus();
|
||||
|
||||
void SetFilter(int filter);
|
||||
int Filter() const;
|
||||
|
||||
|
@ -168,6 +168,17 @@ gfxPattern::GetSurface()
|
||||
if (cairo_pattern_get_surface (mPattern, &surf) != CAIRO_STATUS_SUCCESS)
|
||||
return nsnull;
|
||||
|
||||
|
||||
return gfxASurface::Wrap(surf);
|
||||
}
|
||||
|
||||
gfxPattern::GraphicsPatternType
|
||||
gfxPattern::GetType() const
|
||||
{
|
||||
return (GraphicsPatternType) cairo_pattern_get_type(mPattern);
|
||||
}
|
||||
|
||||
int
|
||||
gfxPattern::CairoStatus()
|
||||
{
|
||||
return cairo_pattern_status(mPattern);
|
||||
}
|
||||
|
@ -117,7 +117,6 @@ LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../../../xul/base/src \
|
||||
-I$(srcdir)/../../../../content/svg/content/src \
|
||||
-I$(srcdir)/../../../../content/base/src \
|
||||
-I$(topsrcdir)/gfx/src/thebes \
|
||||
$(NULL)
|
||||
|
||||
libs::
|
||||
|
@ -47,7 +47,7 @@
|
||||
#include "nsSVGMatrix.h"
|
||||
#include "gfxContext.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsThebesImage.h"
|
||||
#include "nsIImage.h"
|
||||
|
||||
class nsSVGImageFrame;
|
||||
|
||||
@ -257,19 +257,14 @@ nsSVGImageFrame::PaintSVG(nsSVGRenderState *aContext, nsRect *aDirtyRect)
|
||||
if (mImageContainer)
|
||||
mImageContainer->GetCurrentFrame(getter_AddRefs(currentFrame));
|
||||
|
||||
gfxASurface *thebesSurface = nsnull;
|
||||
nsRefPtr<gfxPattern> thebesPattern = nsnull;
|
||||
if (currentFrame) {
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(currentFrame));
|
||||
|
||||
nsThebesImage *thebesImage = nsnull;
|
||||
if (img)
|
||||
thebesImage = static_cast<nsThebesImage*>(img.get());
|
||||
|
||||
if (thebesImage)
|
||||
thebesSurface = thebesImage->ThebesSurface();
|
||||
img->GetPattern(getter_AddRefs(thebesPattern));
|
||||
}
|
||||
|
||||
if (thebesSurface) {
|
||||
if (thebesPattern) {
|
||||
gfxContext *gfx = aContext->GetGfxContext();
|
||||
|
||||
if (GetStyleDisplay()->IsScrollableOverflow()) {
|
||||
@ -293,7 +288,7 @@ nsSVGImageFrame::PaintSVG(nsSVGRenderState *aContext, nsRect *aDirtyRect)
|
||||
opacity = GetStyleDisplay()->mOpacity;
|
||||
}
|
||||
|
||||
nsSVGUtils::CompositeSurfaceMatrix(gfx, thebesSurface, fini, opacity);
|
||||
nsSVGUtils::CompositePatternMatrix(gfx, thebesPattern, fini, width, height, opacity);
|
||||
|
||||
if (GetStyleDisplay()->IsScrollableOverflow())
|
||||
gfx->Restore();
|
||||
|
@ -1599,6 +1599,27 @@ nsSVGUtils::CompositeSurfaceMatrix(gfxContext *aContext,
|
||||
aContext->Restore();
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGUtils::CompositePatternMatrix(gfxContext *aContext,
|
||||
gfxPattern *aPattern,
|
||||
nsIDOMSVGMatrix *aCTM, float aWidth, float aHeight, float aOpacity)
|
||||
{
|
||||
gfxMatrix matrix = ConvertSVGMatrixToThebes(aCTM);
|
||||
if (matrix.IsSingular())
|
||||
return;
|
||||
|
||||
aContext->Save();
|
||||
|
||||
SetClipRect(aContext, aCTM, 0, 0, aWidth, aHeight);
|
||||
|
||||
aContext->Multiply(matrix);
|
||||
|
||||
aContext->SetPattern(aPattern);
|
||||
aContext->Paint(aOpacity);
|
||||
|
||||
aContext->Restore();
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGUtils::SetClipRect(gfxContext *aContext,
|
||||
nsIDOMSVGMatrix *aCTM, float aX, float aY,
|
||||
|
@ -69,6 +69,7 @@ class nsSVGSVGElement;
|
||||
class nsAttrValue;
|
||||
class gfxContext;
|
||||
class gfxASurface;
|
||||
class gfxPattern;
|
||||
class nsIRenderingContext;
|
||||
class gfxImageSurface;
|
||||
struct gfxRect;
|
||||
@ -410,6 +411,10 @@ public:
|
||||
gfxASurface *aSurface,
|
||||
nsIDOMSVGMatrix *aCTM, float aOpacity);
|
||||
|
||||
static void CompositePatternMatrix(gfxContext *aContext,
|
||||
gfxPattern *aPattern,
|
||||
nsIDOMSVGMatrix *aCTM, float aWidth, float aHeight, float aOpacity);
|
||||
|
||||
static void SetClipRect(gfxContext *aContext,
|
||||
nsIDOMSVGMatrix *aCTM, float aX, float aY,
|
||||
float aWidth, float aHeight);
|
||||
|
@ -1039,12 +1039,15 @@ void imgContainer::ClearFrame(gfxIImageFrame *aFrame)
|
||||
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(aFrame));
|
||||
nsRefPtr<gfxASurface> surf;
|
||||
|
||||
img->LockImagePixels(0);
|
||||
img->GetSurface(getter_AddRefs(surf));
|
||||
|
||||
// Erase the surface to transparent
|
||||
gfxContext ctx(surf);
|
||||
ctx.SetOperator(gfxContext::OPERATOR_CLEAR);
|
||||
ctx.Paint();
|
||||
img->UnlockImagePixels(0);
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
@ -1056,6 +1059,8 @@ void imgContainer::ClearFrame(gfxIImageFrame *aFrame, nsIntRect &aRect)
|
||||
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(aFrame));
|
||||
nsRefPtr<gfxASurface> surf;
|
||||
|
||||
img->LockImagePixels(0);
|
||||
img->GetSurface(getter_AddRefs(surf));
|
||||
|
||||
// Erase the destination rectangle to transparent
|
||||
@ -1063,6 +1068,7 @@ void imgContainer::ClearFrame(gfxIImageFrame *aFrame, nsIntRect &aRect)
|
||||
ctx.SetOperator(gfxContext::OPERATOR_CLEAR);
|
||||
ctx.Rectangle(gfxRect(aRect.x, aRect.y, aRect.width, aRect.height));
|
||||
ctx.Fill();
|
||||
img->UnlockImagePixels(0);
|
||||
}
|
||||
|
||||
|
||||
@ -1184,11 +1190,13 @@ nsresult imgContainer::DrawFrameTo(gfxIImageFrame *aSrc,
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIImage> srcImg(do_GetInterface(aSrc));
|
||||
nsRefPtr<gfxASurface> srcSurf;
|
||||
srcImg->GetSurface(getter_AddRefs(srcSurf));
|
||||
nsRefPtr<gfxPattern> srcPatt;
|
||||
srcImg->GetPattern(getter_AddRefs(srcPatt));
|
||||
|
||||
nsCOMPtr<nsIImage> dstImg(do_GetInterface(aDst));
|
||||
nsRefPtr<gfxASurface> dstSurf;
|
||||
// Note: dstImage has LockImageData() called on it above, so it's safe to get
|
||||
// the surface.
|
||||
dstImg->GetSurface(getter_AddRefs(dstSurf));
|
||||
|
||||
gfxContext dst(dstSurf);
|
||||
@ -1204,7 +1212,7 @@ nsresult imgContainer::DrawFrameTo(gfxIImageFrame *aSrc,
|
||||
dst.Fill();
|
||||
dst.SetOperator(defaultOperator);
|
||||
}
|
||||
dst.SetSource(srcSurf);
|
||||
dst.SetPattern(srcPatt);
|
||||
dst.Paint();
|
||||
|
||||
return NS_OK;
|
||||
|
@ -319,9 +319,8 @@ NS_IMETHODIMP imgTools::EncodeScaledImage(imgIContainer *aContainer,
|
||||
// Prepare to draw a scaled version of the image to a temporary surface...
|
||||
|
||||
// Get the source image surface
|
||||
nsRefPtr<gfxASurface> gfxsurf;
|
||||
rv = img->GetSurface(getter_AddRefs(gfxsurf));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsRefPtr<gfxPattern> gfxpat;
|
||||
img->GetPattern(getter_AddRefs(gfxpat));
|
||||
|
||||
// Create a temporary image surface
|
||||
dest = new gfxImageSurface(gfxIntSize(aScaledWidth, aScaledHeight),
|
||||
@ -338,7 +337,7 @@ NS_IMETHODIMP imgTools::EncodeScaledImage(imgIContainer *aContainer,
|
||||
|
||||
// Paint a scaled image
|
||||
ctx.SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx.SetSource(gfxsurf);
|
||||
ctx.SetPattern(gfxpat);
|
||||
ctx.Paint();
|
||||
|
||||
bitmapData = dest->Data();
|
||||
|
@ -71,40 +71,15 @@ nsImageToPixbuf::ImageToPixbuf(nsIImage* aImage)
|
||||
PRInt32 width = aImage->GetWidth(),
|
||||
height = aImage->GetHeight();
|
||||
|
||||
nsRefPtr<gfxASurface> surface;
|
||||
aImage->GetSurface(getter_AddRefs(surface));
|
||||
nsRefPtr<gfxPattern> pattern;
|
||||
aImage->GetPattern(getter_AddRefs(pattern));
|
||||
|
||||
return SurfaceToPixbuf(surface, width, height);
|
||||
return PatternToPixbuf(pattern, width, height);
|
||||
}
|
||||
|
||||
GdkPixbuf*
|
||||
nsImageToPixbuf::SurfaceToPixbuf(gfxASurface* aSurface, PRInt32 aWidth, PRInt32 aHeight)
|
||||
nsImageToPixbuf::ImgSurfaceToPixbuf(gfxImageSurface* aImgSurface, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
if (aSurface->CairoStatus()) {
|
||||
NS_ERROR("invalid surface");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxImageSurface> imgSurface;
|
||||
if (aSurface->GetType() == gfxASurface::SurfaceTypeImage) {
|
||||
imgSurface = static_cast<gfxImageSurface*>
|
||||
(static_cast<gfxASurface*>(aSurface));
|
||||
} else {
|
||||
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->SetSource(aSurface);
|
||||
context->Paint();
|
||||
}
|
||||
|
||||
GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, PR_TRUE, 8,
|
||||
aWidth, aHeight);
|
||||
if (!pixbuf)
|
||||
@ -113,10 +88,10 @@ nsImageToPixbuf::SurfaceToPixbuf(gfxASurface* aSurface, PRInt32 aWidth, PRInt32
|
||||
PRUint32 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
guchar* pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
|
||||
long cairoStride = imgSurface->Stride();
|
||||
unsigned char* cairoData = imgSurface->Data();
|
||||
long cairoStride = aImgSurface->Stride();
|
||||
unsigned char* cairoData = aImgSurface->Data();
|
||||
|
||||
gfxASurface::gfxImageFormat format = imgSurface->Format();
|
||||
gfxASurface::gfxImageFormat format = aImgSurface->Format();
|
||||
|
||||
for (PRInt32 row = 0; row < aHeight; ++row) {
|
||||
for (PRInt32 col = 0; col < aWidth; ++col) {
|
||||
@ -152,3 +127,70 @@ nsImageToPixbuf::SurfaceToPixbuf(gfxASurface* aSurface, PRInt32 aWidth, PRInt32
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
GdkPixbuf*
|
||||
nsImageToPixbuf::SurfaceToPixbuf(gfxASurface* aSurface, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
if (aSurface->CairoStatus()) {
|
||||
NS_ERROR("invalid surface");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxImageSurface> imgSurface;
|
||||
if (aSurface->GetType() == gfxASurface::SurfaceTypeImage) {
|
||||
imgSurface = static_cast<gfxImageSurface*>
|
||||
(static_cast<gfxASurface*>(aSurface));
|
||||
} else {
|
||||
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->SetSource(aSurface);
|
||||
context->Paint();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -41,6 +41,8 @@
|
||||
#include "nsIImageToPixbuf.h"
|
||||
|
||||
class gfxASurface;
|
||||
class gfxPattern;
|
||||
class gfxImageSurface;
|
||||
|
||||
class nsImageToPixbuf : public nsIImageToPixbuf {
|
||||
public:
|
||||
@ -52,7 +54,11 @@ class nsImageToPixbuf : public nsIImageToPixbuf {
|
||||
static GdkPixbuf* ImageToPixbuf(nsIImage* 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);
|
||||
~nsImageToPixbuf() {}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user