Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Protected Attributes
nsCairoImage Class Reference

#include <nsCairoImage.h>

Inheritance diagram for nsCairoImage:
Inheritance graph
[legend]
Collaboration diagram for nsCairoImage:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsCairoImage ()
 ~nsCairoImage ()
virtual NS_DECL_ISUPPORTS nsresult Init (PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements)
 Build and initialize the nsIImage.
virtual PRInt32 GetBytesPix ()
 Get the number of bytes per pixel for this image - dwc 2/3/99.
virtual PRBool GetIsRowOrderTopToBottom ()
 Get whether rows are organized top to bottom, or bottom to top - syd 3/29/99.
virtual PRInt32 GetWidth ()
 Get the width for the pixelmap - dwc 2/1/99.
virtual PRInt32 GetHeight ()
 Get the height for the pixelmap - dwc 2/1/99.
virtual PRUint8GetBits ()
 Get a pointer to the bits for the pixelmap, only if it is not optimized - dwc 2/1/99.
virtual PRInt32 GetLineStride ()
 Get the number of bytes needed to get to the next scanline for the pixelmap - dwc 2/1/99.
virtual PRBool GetHasAlphaMask ()
 Get whether this image has an alpha mask.
virtual PRUint8GetAlphaBits ()
 Get a pointer to the bits for the alpha mask - dwc 2/1/99.
virtual PRInt32 GetAlphaLineStride ()
 Get the number of bytes per scanline for the alpha mask - dwc 2/1/99.
virtual PRBool GetIsImageComplete ()
 Get whether this image's region is completely filled with data.
virtual void ImageUpdated (nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect)
 Update the nsIImage color table - dwc 2/1/99.
virtual nsresult Optimize (nsIDeviceContext *aContext)
 Converted this pixelmap to an optimized pixelmap for the device - dwc 2/1/99.
virtual nsColorMapGetColorMap ()
 Get the colormap for the nsIImage - dwc 2/1/99.
NS_IMETHOD Draw (nsIRenderingContext &aContext, nsIDrawingSurface *aSurface, PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
 BitBlit the nsIImage to a device, the source can be scaled to the dest - dwc 2/1/99.
NS_IMETHOD Draw (nsIRenderingContext &aContext, nsIDrawingSurface *aSurface, PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight, PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
 BitBlit the nsIImage to a device, the source and dest can be scaled - dwc 2/1/99.
NS_IMETHOD DrawTile (nsIRenderingContext &aContext, nsIDrawingSurface *aSurface, PRInt32 aSXOffset, PRInt32 aSYOffset, PRInt32 aPadX, PRInt32 aPadY, const nsRect &aTileRect)
NS_IMETHOD DrawToImage (nsIImage *aDstImage, PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
 BitBlit the entire (no cropping) nsIImage to another nsImage, the source and dest can be scaled - saari 03/08/01.
virtual PRInt8 GetAlphaDepth ()
 Get the alpha depth for the image mask - lordpixel 2001/05/16.
virtual voidGetBitInfo ()
 Return information about the bits for this structure - dwc 2/1/99.
NS_IMETHOD LockImagePixels (PRBool aMaskPixels)
 LockImagePixels Lock the image pixels so that we can access them directly, with safely.
NS_IMETHOD UnlockImagePixels (PRBool aMaskPixels)
 UnlockImagePixels Unlock the image pixels.
void UpdateFromImageData ()

Protected Attributes

PRInt32 mWidth
PRInt32 mHeight
nsRect mDecoded
cairo_surface_t * mImageSurface
cairo_format_t mCairoFormat
PRUint32mImageSurfaceBuf
PRUint8mImageSurfaceData
PRUint8mImageSurfaceAlpha
PRUint8 mAlphaDepth
PRPackedBool mHadAnyData

Detailed Description

Definition at line 47 of file nsCairoImage.h.


Constructor & Destructor Documentation

Definition at line 94 of file nsCairoImage.cpp.

{
    if (mImageSurface)
        cairo_surface_destroy(mImageSurface);
    // XXXX - totally not safe. mImageSurface should own data,
    // but it doesn't.
    if (mImageSurfaceBuf)
        nsMemory::Free(mImageSurfaceBuf);
    if (mImageSurfaceData)
        nsMemory::Free(mImageSurfaceData);
    if (mImageSurfaceAlpha)
        nsMemory::Free(mImageSurfaceAlpha);
}

Member Function Documentation

NS_IMETHODIMP nsCairoImage::Draw ( nsIRenderingContext aContext,
nsIDrawingSurface aSurface,
PRInt32  aX,
PRInt32  aY,
PRInt32  aWidth,
PRInt32  aHeight 
) [virtual]

BitBlit the nsIImage to a device, the source can be scaled to the dest - dwc 2/1/99.

Parameters:
aSurfacethe surface to blit to
aXThe destination horizontal location
aYThe destination vertical location
aWidthThe destination width of the pixelmap
aHeightThe destination height of the pixelmap
Returns:
if TRUE, no errors

Implements nsIImage.

Definition at line 229 of file nsCairoImage.cpp.

{
    return Draw(aContext, aSurface, 0, 0, mWidth, mHeight, aX, aY, aWidth, aHeight);
}
NS_IMETHODIMP nsCairoImage::Draw ( nsIRenderingContext aContext,
nsIDrawingSurface aSurface,
PRInt32  aSX,
PRInt32  aSY,
PRInt32  aSWidth,
PRInt32  aSHeight,
PRInt32  aDX,
PRInt32  aDY,
PRInt32  aDWidth,
PRInt32  aDHeight 
) [virtual]

BitBlit the nsIImage to a device, the source and dest can be scaled - dwc 2/1/99.

Parameters:
aSurfacethe surface to blit to
aSXThe source width of the pixelmap
aSYThe source vertical location
aSWidthThe source width of the pixelmap
aSHeightThe source height of the pixelmap
aDXThe destination horizontal location
aDYThe destination vertical location
aDWidthThe destination width of the pixelmap
aDHeightThe destination height of the pixelmap
Returns:
if TRUE, no errors

Implements nsIImage.

Definition at line 284 of file nsCairoImage.cpp.

{
#if 1
    fprintf (stderr, "****** nsCairoImage::Draw: (%d,%d,%d,%d) -> (%d,%d,%d,%d)\n",
             aSX, aSY, aSWidth, aSHeight,
             aDX, aDY, aDWidth, aDHeight);
#endif
    UpdateFromImageData();

    nsCairoDrawingSurface *dstSurf = NS_STATIC_CAST(nsCairoDrawingSurface*, aSurface);
    nsCairoRenderingContext *cairoContext = NS_STATIC_CAST(nsCairoRenderingContext*, &aContext);

    cairo_t *dstCairo = cairoContext->GetCairo();

    cairo_translate(dstCairo, aDX, aDY);

    cairo_pattern_t *pat = cairo_pattern_create_for_surface (mImageSurface);
    cairo_matrix_t* matrix = cairo_matrix_create();
    if (matrix) {
        cairo_matrix_set_affine(matrix, double(aSWidth)/aDWidth, 0,
                                0, double(aSHeight)/aDHeight, aSX, aSY);
        cairo_pattern_set_matrix(pat, matrix);
        cairo_matrix_destroy(matrix);
    }
    cairo_set_pattern (dstCairo, pat);
    cairo_pattern_destroy (pat);

    cairo_new_path(dstCairo);
    cairo_rectangle (dstCairo, 0, 0, aDWidth, aDHeight);
    cairo_fill (dstCairo);
    cairo_translate(dstCairo, -aDX, -aDY);
    
    return NS_OK;
}

Here is the call graph for this function:

NS_IMETHODIMP nsCairoImage::DrawTile ( nsIRenderingContext aContext,
nsIDrawingSurface aSurface,
PRInt32  aSXOffset,
PRInt32  aSYOffset,
PRInt32  aPadX,
PRInt32  aPadY,
const nsRect aTileRect 
) [virtual]

Implements nsIImage.

Definition at line 322 of file nsCairoImage.cpp.

{
    UpdateFromImageData();

    if (aPadX || aPadY)
        fprintf (stderr, "Warning: nsCairoImage::DrawTile given padX(%d)/padY(%d), ignoring\n", aPadX, aPadY);

    nsCairoDrawingSurface *dstSurf = NS_STATIC_CAST(nsCairoDrawingSurface*, aSurface);
    nsCairoRenderingContext *cairoContext = NS_STATIC_CAST(nsCairoRenderingContext*, &aContext);

    cairo_t *dstCairo = cairoContext->GetCairo();

    cairo_translate(dstCairo, aTileRect.x, aTileRect.y);

    cairo_pattern_t *pat = cairo_pattern_create_for_surface (mImageSurface);
    cairo_matrix_t* matrix = cairo_matrix_create();
    if (matrix) {
        nsCOMPtr<nsIDeviceContext> dc;
        aContext.GetDeviceContext(*getter_AddRefs(dc));
        float app2dev = dc->AppUnitsToDevUnits();
        cairo_matrix_set_affine(matrix, app2dev, 0, 0, app2dev, aSXOffset, aSYOffset);
        cairo_pattern_set_matrix(pat, matrix);
        cairo_matrix_destroy(matrix);
    }
    cairo_pattern_set_extend(pat, CAIRO_EXTEND_REPEAT);
    cairo_set_pattern (dstCairo, pat);
    cairo_pattern_destroy (pat);

    cairo_new_path(dstCairo);
    cairo_rectangle (dstCairo, 0, 0, aTileRect.width, aTileRect.height);
    cairo_fill (dstCairo);
    cairo_translate(dstCairo, -aTileRect.x, -aTileRect.y);

    return NS_OK;
}

Here is the call graph for this function:

NS_IMETHODIMP nsCairoImage::DrawToImage ( nsIImage aDstImage,
PRInt32  aDX,
PRInt32  aDY,
PRInt32  aDWidth,
PRInt32  aDHeight 
) [virtual]

BitBlit the entire (no cropping) nsIImage to another nsImage, the source and dest can be scaled - saari 03/08/01.

Parameters:
aDstImagethe nsImage to blit to
aDXThe destination horizontal location
aDYThe destination vertical location
aDWidthThe destination width of the pixelmap
aDHeightThe destination height of the pixelmap
Returns:
if TRUE, no errors

Implements nsIImage.

Definition at line 363 of file nsCairoImage.cpp.

{
    UpdateFromImageData();

    nsCairoImage *dstCairoImage = NS_STATIC_CAST(nsCairoImage*, aDstImage);

    cairo_t *dstCairo = cairo_create ();

    cairo_set_target_surface(dstCairo, dstCairoImage->mImageSurface);

    // clip to target
    cairo_rectangle(dstCairo, double(aDX), double(aDY), double(aDWidth), double(aDHeight));
    cairo_clip(dstCairo);

    // scale up to the size difference
    cairo_scale(dstCairo, double(aDWidth)/double(mWidth), double(aDHeight)/double(mHeight));

    // move to where we need to start the image rectangle, so that
    // it gets clipped to the right place
    cairo_translate(dstCairo, double(aDX), double(aDY));

    // show it
    cairo_show_surface (dstCairo, mImageSurface, mWidth, mHeight);

    cairo_destroy (dstCairo);

    return NS_OK;
}

Here is the call graph for this function:

Get a pointer to the bits for the alpha mask - dwc 2/1/99.

Returns:
address of the alpha mask pixel array

Implements nsIImage.

Definition at line 191 of file nsCairoImage.cpp.

{
    return (PRUint8 *) mImageSurfaceAlpha;
}
PRInt8 nsCairoImage::GetAlphaDepth ( ) [virtual]

Get the alpha depth for the image mask - lordpixel 2001/05/16.

Returns:
the alpha mask depth for the image, ie, 0, 1 or 8

Implements nsIImage.

Definition at line 393 of file nsCairoImage.cpp.

{
    return mAlphaDepth;
}

Get the number of bytes per scanline for the alpha mask - dwc 2/1/99.

Returns:
The number of bytes in each scanline

Implements nsIImage.

Definition at line 197 of file nsCairoImage.cpp.

{
    return mAlphaDepth == 1 ? (mWidth+7)/8 : mWidth;
}
void * nsCairoImage::GetBitInfo ( ) [virtual]

Return information about the bits for this structure - dwc 2/1/99.

Returns:
a bitmap info structure for the Device Dependent Bits

Implements nsIImage.

Definition at line 399 of file nsCairoImage.cpp.

{
    return NULL;
}
PRUint8 * nsCairoImage::GetBits ( ) [virtual]

Get a pointer to the bits for the pixelmap, only if it is not optimized - dwc 2/1/99.

Returns:
address of the DIB pixel array

Implements nsIImage.

Definition at line 173 of file nsCairoImage.cpp.

{
    return (PRUint8 *) mImageSurfaceData;
}

Get the number of bytes per pixel for this image - dwc 2/3/99.

Returns:
- the number of bytes per pixel

Implements nsIImage.

Definition at line 148 of file nsCairoImage.cpp.

{
    // not including alpha, I guess
    return 3;
}

Get the colormap for the nsIImage - dwc 2/1/99.

Returns:
if non null, the colormap for the pixelmap,otherwise the image is not color mapped

Implements nsIImage.

Definition at line 221 of file nsCairoImage.cpp.

{
    return NULL;
}

Get whether this image has an alpha mask.

Preferable to testing if GetAlphaBits() is non-null. - sfraser 10/19/99

Returns:
PR_TRUE if the image has an alpha mask, PR_FALSE otherwise

Implements nsIImage.

Definition at line 185 of file nsCairoImage.cpp.

{
    return mAlphaDepth > 0;
}

Get the height for the pixelmap - dwc 2/1/99.

Returns:
The height in pixels for the pixelmap

Implements nsIImage.

Definition at line 167 of file nsCairoImage.cpp.

{
    return mHeight;
}

Get whether this image's region is completely filled with data.

Returns:
PR_TRUE if image is complete, PR_FALSE if image is not yet complete or broken

Implements nsIImage.

Definition at line 209 of file nsCairoImage.cpp.

{
    return mDecoded == nsRect(0, 0, mWidth, mHeight);
}

Here is the call graph for this function:

Get whether rows are organized top to bottom, or bottom to top - syd 3/29/99.

Returns:
PR_TRUE if top to bottom, else PR_FALSE

Implements nsIImage.

Definition at line 155 of file nsCairoImage.cpp.

{
    return PR_FALSE;
}

Get the number of bytes needed to get to the next scanline for the pixelmap - dwc 2/1/99.

Returns:
The number of bytes in each scanline

Implements nsIImage.

Definition at line 179 of file nsCairoImage.cpp.

{
    return mWidth*3;
}

Get the width for the pixelmap - dwc 2/1/99.

Returns:
The width in pixels for the pixelmap

Implements nsIImage.

Definition at line 161 of file nsCairoImage.cpp.

{
    return mWidth;
}
void nsCairoImage::ImageUpdated ( nsIDeviceContext aContext,
PRUint8  aFlags,
nsRect aUpdateRect 
) [virtual]

Update the nsIImage color table - dwc 2/1/99.

Parameters:
aFlagsUsed to pass in parameters for the update
aUpdateRectThe rectangle to update

Implements nsIImage.

Definition at line 203 of file nsCairoImage.cpp.

{
    mDecoded.UnionRect(mDecoded, *aUpdateRect);
}
nsresult nsCairoImage::Init ( PRInt32  aWidth,
PRInt32  aHeight,
PRInt32  aDepth,
nsMaskRequirements  aMaskRequirements 
) [virtual]

Build and initialize the nsIImage.

Parameters:
aWidthThe width in pixels of the desired pixelmap
aHeightThe height in pixels of the desired pixelmap
aDepthThe number of bits per pixel for the pixelmap
aMaskRequirementsA flag indicating if a alpha mask should be allocated

Implements nsIImage.

Definition at line 113 of file nsCairoImage.cpp.

{
    mWidth = aWidth;
    mHeight = aHeight;

    switch(aMaskRequirements)
    {
    case nsMaskRequirements_kNeeds1Bit:
        mAlphaDepth = 1;
        mCairoFormat = CAIRO_FORMAT_ARGB32;
        break;
    case nsMaskRequirements_kNeeds8Bit:
        mAlphaDepth = 8;
        mCairoFormat = CAIRO_FORMAT_ARGB32;
        break;
    default:
        mAlphaDepth = 0;
        // this should be able to be RGB24, but that doesn't seem to work
        mCairoFormat = CAIRO_FORMAT_ARGB32;
        break;
    }

    PRInt32 size = aWidth*aHeight*4;
    mImageSurfaceBuf = (PRUint32*)nsMemory::Alloc(size);
    NS_ENSURE_TRUE(mImageSurfaceBuf, NS_ERROR_OUT_OF_MEMORY);
    // Fill it in. Setting alpha to FF is important for images with no
    // alpha of their own
    memset(mImageSurfaceBuf, 0xFF, size);

    mImageSurface = cairo_image_surface_create_for_data
        ((char*)mImageSurfaceBuf, mCairoFormat, mWidth, mHeight, aWidth * 4);
    return NS_OK;
}

Here is the call graph for this function:

LockImagePixels Lock the image pixels so that we can access them directly, with safely.

May be a noop on some platforms.

aMaskPixels = PR_TRUE for the mask, PR_FALSE for the image

Must be balanced by a call to UnlockImagePixels().

- sfraser 10/18/99

Returns:
error result

Implements nsIImage.

Definition at line 405 of file nsCairoImage.cpp.

{
    if (mImageSurfaceData) {
        return NS_OK;
    }

    if (mAlphaDepth > 0) {
        NS_ASSERTION(mAlphaDepth == 1 || mAlphaDepth == 8,
                     "Bad alpha depth");
        PRUint32 size = mHeight*(mAlphaDepth == 1 ? ((mWidth+7)/8) : mWidth);
        mImageSurfaceAlpha = (PRUint8*)nsMemory::Alloc(size);
        if (!mImageSurfaceAlpha)
            return NS_ERROR_OUT_OF_MEMORY;
    }

    PRUint32 size = mWidth * mHeight * 3;
    mImageSurfaceData = (PRUint8*)nsMemory::Alloc(size);
    if (!mImageSurfaceData)
        return NS_ERROR_OUT_OF_MEMORY;

    PRInt32 count = mWidth*mHeight;
    if (mAlphaDepth > 0 && mHadAnyData) {
        PRInt32 size = mHeight*(mAlphaDepth == 1 ? ((mWidth+7)/8) : mWidth);
        mImageSurfaceAlpha = (PRUint8*)nsMemory::Alloc(size);

        // fill from existing ARGB buffer
        if (mAlphaDepth == 8) {
            for (PRInt32 i = 0; i < count; ++i) {
                mImageSurfaceAlpha[i] = (PRUint8)(mImageSurfaceBuf[i] >> 24);
            }
        } else {
            PRInt32 i = 0;
            for (PRInt32 row = 0; row < mHeight; ++row) {
                PRUint8 alphaBits = 0;
                for (PRInt32 col = 0; col < mWidth; ++col) {
                    PRUint8 mask = 1 << (7 - (col&7));
                    if (mImageSurfaceBuf[row*mWidth + col] & 0xFF000000) {
                        alphaBits |= mask;
                    }
                    if (mask == 0x01) {
                        // This mask byte is complete, write it back
                        mImageSurfaceAlpha[i] = alphaBits;
                        alphaBits = 0;
                        ++i;
                    }
                }
                if (mWidth & 7) {
                    // write back the incomplete alpha mask
                    mImageSurfaceAlpha[i] = alphaBits;
                    ++i;
                }
            }
        }
    }
    
    if (mHadAnyData) {
        // fill from existing ARGB buffer
        for (PRInt32 i = 0; i < count; ++i) {
            ARGBToThreeChannel(&mImageSurfaceBuf[i], &mImageSurfaceData[i*3]);
        }
    }

    return NS_OK;
}

Here is the call graph for this function:

Converted this pixelmap to an optimized pixelmap for the device - dwc 2/1/99.

Parameters:
aContextThe device to optimize for
Returns:
the result of the operation, if NS_OK, then the pixelmap is optimized

Implements nsIImage.

Definition at line 215 of file nsCairoImage.cpp.

{
    return NS_OK;
}

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

- sfraser 10/18/99

Returns:
error result

Implements nsIImage.

Definition at line 471 of file nsCairoImage.cpp.

{
    return NS_OK;
}

Definition at line 236 of file nsCairoImage.cpp.

{
    if (!mImageSurfaceData)
        return;
    
    NS_ASSERTION(mAlphaDepth == 0 || mAlphaDepth == 1 || mAlphaDepth == 8,
                 "Bad alpha depth");

    PRInt32 alphaIndex = 0;
    PRInt32 bufIndex = 0;
    for (PRInt32 row = 0; row < mHeight; ++row) {
        for (PRInt32 col = 0; col < mWidth; ++col) {
            PRUint8 alpha = 0xFF;
            if (mAlphaDepth == 1) {
                PRUint8 mask = 1 << (7 - (col&7));
                if (!(mImageSurfaceAlpha[alphaIndex] & mask)) {
                    alpha = 0;
                }
                if (mask == 0x01) {
                    ++alphaIndex;
                }
            } else if (mAlphaDepth == 8) {
                alpha = mImageSurfaceAlpha[bufIndex];
            }
            mImageSurfaceBuf[bufIndex] = ThreeChannelToARGB(&mImageSurfaceData[bufIndex*3], alpha);
            ++bufIndex;
        }
        if (mAlphaDepth == 1) {
            if (mWidth & 7) {
                ++alphaIndex;
            }
        }
    }

    if (PR_FALSE) { // Enabling this saves memory but can lead to pathological
        // behaviour
        nsMemory::Free(mImageSurfaceData);
        mImageSurfaceData = nsnull;
        if (mImageSurfaceAlpha) {
            nsMemory::Free(mImageSurfaceAlpha);
            mImageSurfaceAlpha = nsnull;
        }

        mHadAnyData = PR_TRUE;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 107 of file nsCairoImage.h.

Definition at line 99 of file nsCairoImage.h.

Definition at line 96 of file nsCairoImage.h.

Definition at line 108 of file nsCairoImage.h.

Definition at line 95 of file nsCairoImage.h.

cairo_surface_t* nsCairoImage::mImageSurface [protected]

Definition at line 98 of file nsCairoImage.h.

Definition at line 105 of file nsCairoImage.h.

Definition at line 101 of file nsCairoImage.h.

Definition at line 104 of file nsCairoImage.h.

Definition at line 94 of file nsCairoImage.h.


The documentation for this class was generated from the following files: