Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes
nsImageGTK Class Reference

#include <nsImageGTK.h>

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

List of all members.

Public Member Functions

 nsImageGTK ()
virtual ~nsImageGTK ()
virtual NS_DECL_ISUPPORTS PRInt32 GetBytesPix ()
virtual PRInt32 GetHeight ()
 Get the height for the pixelmap - dwc 2/1/99.
virtual PRInt32 GetWidth ()
 Get the width 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 voidGetBitInfo ()
 Return information about the bits for this structure - dwc 2/1/99.
virtual PRBool GetIsRowOrderTopToBottom ()
 Get whether rows are organized top to bottom, or bottom to top - syd 3/29/99.
virtual PRInt32 GetLineStride ()
 Get the number of bytes needed to get to the next scanline for the pixelmap - 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 DrawToImage (nsIImage *aDstImage, nscoord aDX, nscoord aDY, nscoord aDWidth, nscoord aDHeight)
 BitBlit the entire (no cropping) nsIImage to another nsImage, the source and dest can be scaled - saari 03/08/01.
NS_IMETHOD DrawTile (nsIRenderingContext &aContext, nsIDrawingSurface *aSurface, PRInt32 aSXOffset, PRInt32 aSYOffset, PRInt32 aPadX, PRInt32 aPadY, const nsRect &aTileRect)
void UpdateCachedImage ()
virtual void ImageUpdated (nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect)
 Update the nsIImage color table - dwc 2/1/99.
virtual PRBool GetIsImageComplete ()
 
See documentation in nsIImage.h
virtual nsresult Init (PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements)
 Build and initialize the nsIImage.
virtual nsresult Optimize (nsIDeviceContext *aContext)
 Converted this pixelmap to an optimized pixelmap for the device - 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 PRInt8 GetAlphaDepth ()
 Get the alpha depth for the image mask - lordpixel 2001/05/16.
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.

Static Public Member Functions

static void Startup ()
static void Shutdown ()

Private Member Functions

void ComputeMetrics ()
 Calculate the amount of memory needed for the initialization of the image.
void ComputePaletteSize (PRIntn nBitCount)
void DrawComposited32 (PRBool isLSB, PRBool flipBytes, PRUint8 *imageOrigin, PRUint32 imageStride, PRUint8 *alphaOrigin, PRUint32 alphaStride, unsigned width, unsigned height, XImage *ximage, unsigned char *readData, unsigned char *srcData)
void DrawComposited24 (PRBool isLSB, PRBool flipBytes, PRUint8 *imageOrigin, PRUint32 imageStride, PRUint8 *alphaOrigin, PRUint32 alphaStride, unsigned width, unsigned height, XImage *ximage, unsigned char *readData, unsigned char *srcData)
void DrawComposited16 (PRBool isLSB, PRBool flipBytes, PRUint8 *imageOrigin, PRUint32 imageStride, PRUint8 *alphaOrigin, PRUint32 alphaStride, unsigned width, unsigned height, XImage *ximage, unsigned char *readData, unsigned char *srcData)
void DrawCompositedGeneral (PRBool isLSB, PRBool flipBytes, PRUint8 *imageOrigin, PRUint32 imageStride, PRUint8 *alphaOrigin, PRUint32 alphaStride, unsigned width, unsigned height, XImage *ximage, unsigned char *readData, unsigned char *srcData)
void DrawComposited (nsIRenderingContext &aContext, nsIDrawingSurface *aSurface, PRInt32 srcWidth, PRInt32 srcHeight, PRInt32 dstWidth, PRInt32 dstHeight, PRInt32 dstOrigX, PRInt32 dstOrigY, PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
void DrawCompositeTile (nsIRenderingContext &aContext, nsIDrawingSurface *aSurface, PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight, PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
void TilePixmap (GdkPixmap *src, GdkPixmap *dest, PRInt32 aSXOffset, PRInt32 aSYOffset, const nsRect &destRect, const nsRect &clipRect, PRBool useClip)
void CreateOffscreenPixmap (PRInt32 aWidth, PRInt32 aHeight)
void SetupGCForAlpha (GdkGC *aGC, PRInt32 aX, PRInt32 aY)
void SlowTile (nsDrawingSurfaceGTK *aSurface, const nsRect &aTileRect, PRInt32 aSXOffset, PRInt32 aSYOffset, const nsRect &aRect, PRBool aIsValid)

Private Attributes

PRUint8mImageBits
GdkPixmap * mImagePixmap
PRUint8mTrueAlphaBits
PRUint8mAlphaBits
GdkPixmap * mAlphaPixmap
XImage * mAlphaXImage
PRInt32 mWidth
PRInt32 mHeight
PRInt32 mRowBytes
PRInt32 mSizeImage
PRInt32 mDecodedX1
PRInt32 mDecodedY1
PRInt32 mDecodedX2
PRInt32 mDecodedY2
nsRegion mUpdateRegion
PRInt32 mAlphaRowBytes
PRInt32 mTrueAlphaRowBytes
PRInt8 mAlphaDepth
PRInt8 mTrueAlphaDepth
PRPackedBool mIsSpacer
PRPackedBool mPendingUpdate
PRInt8 mNumBytesPixel
PRUint8 mFlags
PRInt8 mDepth
PRPackedBool mOptimized

Static Private Attributes

static unsigned scaled6 [1<< 6]
static unsigned scaled5 [1<< 5]

Detailed Description

Definition at line 53 of file nsImageGTK.h.


Constructor & Destructor Documentation

Definition at line 85 of file nsImageGTK.cpp.

nsImageGTK::~nsImageGTK ( ) [virtual]

Definition at line 115 of file nsImageGTK.cpp.

{
  if(nsnull != mImageBits) {
    free(mImageBits);
    mImageBits = nsnull;
  }

  if (nsnull != mAlphaBits) {
    free(mAlphaBits);
    mAlphaBits = nsnull;
  }

  if (nsnull != mTrueAlphaBits) {
    free(mTrueAlphaBits);
    mTrueAlphaBits = nsnull;
  }

  if (mAlphaPixmap) {
    gdk_pixmap_unref(mAlphaPixmap);
  }

  if (mImagePixmap) {
    gdk_pixmap_unref(mImagePixmap);
  }

  if (mAlphaXImage) {
    mAlphaXImage->data = 0;
    XDestroyImage(mAlphaXImage);
  }

#ifdef TRACE_IMAGE_ALLOCATION
  printf("nsImageGTK::~nsImageGTK(this=%p)\n",
         this);
#endif
}

Member Function Documentation

void nsImageGTK::ComputeMetrics ( ) [inline, private]

Calculate the amount of memory needed for the initialization of the image.

Definition at line 137 of file nsImageGTK.h.

                        {
    mRowBytes = (mWidth * mDepth) >> 5;

    if (((PRUint32)mWidth * mDepth) & 0x1F)
      mRowBytes++;
    mRowBytes <<= 2;
    
    mSizeImage = mRowBytes * mHeight;
  };

Here is the caller graph for this function:

void nsImageGTK::ComputePaletteSize ( PRIntn  nBitCount) [private]
void nsImageGTK::CreateOffscreenPixmap ( PRInt32  aWidth,
PRInt32  aHeight 
) [inline, private]

Definition at line 1599 of file nsImageGTK.cpp.

{
  // Render unique image bits onto an off screen pixmap only once
  // The image bits can change as a result of ImageUpdated() - for
  // example: animated GIFs.
  if (!mImagePixmap) {
#ifdef TRACE_IMAGE_ALLOCATION
    printf("nsImageGTK::Draw(this=%p) gdk_pixmap_new(nsnull,width=%d,height=%d,depth=%d)\n",
           this,
           aWidth, aHeight,
           mDepth);
#endif

    // Create an off screen pixmap to hold the image bits.
    mImagePixmap = gdk_pixmap_new(nsnull, aWidth, aHeight,
                                  gdk_rgb_get_visual()->depth);
#ifdef MOZ_WIDGET_GTK2
    gdk_drawable_set_colormap(GDK_DRAWABLE(mImagePixmap), gdk_rgb_get_colormap());
#endif
  }

    // Ditto for the clipmask
  if ((!mAlphaPixmap) && (mAlphaDepth==1)) {
    mAlphaPixmap = gdk_pixmap_new(nsnull, aWidth, aHeight, 1);

    // Need an XImage for clipmask updates (XPutImage)
    mAlphaXImage = XCreateImage(GDK_WINDOW_XDISPLAY(mAlphaPixmap),
                                GDK_VISUAL_XVISUAL(gdk_rgb_get_visual()),
                                1, /* visual depth...1 for bitmaps */
                                XYPixmap,
                                0, /* x offset, XXX fix this */
                                (char *)mAlphaBits,  /* cast away our sign. */
                                aWidth,
                                aHeight,
                                32,/* bitmap pad */
                                mAlphaRowBytes); /* bytes per line */

    mAlphaXImage->bits_per_pixel=1;

    /* Image library always places pixels left-to-right MSB to LSB */
    mAlphaXImage->bitmap_bit_order = MSBFirst;

    /* This definition doesn't depend on client byte ordering
       because the image library ensures that the bytes in
       bitmask data are arranged left to right on the screen,
       low to high address in memory. */
    mAlphaXImage->byte_order = MSBFirst;

    if (!s1bitGC) {
      GdkColor fg = { 1, 0, 0, 0 };
      s1bitGC = gdk_gc_new(mAlphaPixmap);
      gdk_gc_set_foreground(s1bitGC, &fg);
    }
  }

  if (!sXbitGC)
    sXbitGC = gdk_gc_new(mImagePixmap);
}

Here is the caller graph for this function:

NS_IMETHODIMP nsImageGTK::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 1680 of file nsImageGTK.cpp.

{
#ifdef TRACE_IMAGE_ALLOCATION
  printf("nsImageGTK::Draw(this=%p,x=%d,y=%d,width=%d,height=%d)\n",
         this,
         aX, aY,
         aWidth, aHeight);
#endif

  return Draw(aContext, aSurface,
              0, 0, mWidth, mHeight,
              aX, aY, mWidth, mHeight);
}

Here is the caller graph for this function:

NS_IMETHODIMP nsImageGTK::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 668 of file nsImageGTK.cpp.

{
  g_return_val_if_fail ((aSurface != nsnull), NS_ERROR_FAILURE);

  if (mPendingUpdate)
    UpdateCachedImage();

  if ((mAlphaDepth==1) && mIsSpacer)
    return NS_OK;

  if (mDecodedX2 < mDecodedX1 || mDecodedY2 < mDecodedY1)
    return NS_OK;

#ifdef TRACE_IMAGE_ALLOCATION
  fprintf(stderr, "nsImageGTK::Draw(%p) s=(%4d %4d %4d %4d) d=(%4d %4d %4d %4d)\n",
         this,
         aSX, aSY, aSWidth, aSHeight,
         aDX, aDY, aDWidth, aDHeight);
#endif

  if (aSWidth <= 0 || aDWidth <= 0 || aSHeight <= 0 || aDHeight <= 0) {
    return NS_OK;
  }

  // store some values we'll need for scaling...

  PRInt32 srcWidth, srcHeight, dstWidth, dstHeight;
  PRInt32 dstOrigX, dstOrigY;

  srcWidth = aSWidth;
  srcHeight = aSHeight;
  dstWidth = aDWidth;
  dstHeight = aDHeight;
  dstOrigX = aDX;
  dstOrigY = aDY;

  // clip to decode region
  PRInt32 j = aSX + aSWidth;
  PRInt32 z;
  if (j > mDecodedX2) {
    z = j - mDecodedX2;
    aDWidth -= z*dstWidth/srcWidth;
    aSWidth -= z;
  }
  if (aSX < mDecodedX1) {
    aDX += (mDecodedX1 - aSX)*dstWidth/srcWidth;
    aSX = mDecodedX1;
  }

  j = aSY + aSHeight;
  if (j > mDecodedY2) {
    z = j - mDecodedY2;
    aDHeight -= z*dstHeight/srcHeight;
    aSHeight -= z;
  }
  if (aSY < mDecodedY1) {
    aDY += (mDecodedY1 - aSY)*dstHeight/srcHeight;
    aSY = mDecodedY1;
  }

  if (aDWidth <= 0 || aDHeight <= 0 || aSWidth <= 0 || aSHeight <= 0) {
    return NS_OK;
  }

  // clip to drawing surface
  nsDrawingSurfaceGTK *drawing = (nsDrawingSurfaceGTK*)aSurface;
  PRUint32 surfaceWidth, surfaceHeight;
  drawing->GetDimensions(&surfaceWidth, &surfaceHeight);

  if (aDX + aDWidth > (PRInt32)surfaceWidth) {
    z = aDX + aDWidth - surfaceWidth;
    aDWidth -= z;
    aSWidth -= z*srcWidth/dstWidth;
  }

  if (aDX < 0) {
    aDWidth += aDX;
    aSWidth += aDX*srcWidth/dstWidth;
    aSX -= aDX*srcWidth/dstWidth;
    aDX = 0;
  }

  if (aDY + aDHeight > (PRInt32)surfaceHeight) {
    z = aDY + aDHeight - surfaceHeight;
    aDHeight -= z;
    aSHeight -= z*srcHeight/dstHeight;
  }

  if (aDY < 0) {
    aDHeight += aDY;
    aSHeight += aDY*srcHeight/dstHeight;
    aSY -= aDY*srcHeight/dstHeight;
    aDY = 0;
  }

  if (aDWidth <= 0 || aDHeight <= 0 || aSWidth <= 0 || aSHeight <= 0) {
    return NS_OK;
  }

  if ((srcWidth != dstWidth) || (srcHeight != dstHeight)) {
    GdkPixmap *pixmap = 0;
    GdkGC *gc = 0;
    nsRegionGTK clipRgn;

    switch (mAlphaDepth) {
    case 8:
      DrawComposited(aContext, aSurface,
                     srcWidth, srcHeight,
                     dstWidth, dstHeight,
                     dstOrigX, dstOrigY,
                     aDX, aDY,
                     aDWidth, aDHeight);
      break;
    case 1:
      pixmap = gdk_pixmap_new(nsnull, dstWidth, dstHeight, 1);
      if (pixmap) {
        XlibRectStretch(srcWidth, srcHeight,
                        dstWidth, dstHeight,
                        0, 0,
                        0, 0,
                        dstWidth, dstHeight,
                        mAlphaPixmap, pixmap,
                        s1bitGC, s1bitGC, 1);
        gc = gdk_gc_new(drawing->GetDrawable());
        if (gc) {
          gdk_gc_set_clip_origin(gc, dstOrigX, dstOrigY);
          gdk_gc_set_clip_mask(gc, pixmap);
        }
      }

      if (gdk_rgb_get_visual()->depth <= 8) {
        PRUint8 *scaledRGB = (PRUint8 *)nsMemory::Alloc(3*dstWidth*dstHeight);

        if (!scaledRGB)
          return NS_ERROR_OUT_OF_MEMORY;

        RectStretch(mWidth, mHeight,
                    dstWidth, dstHeight,
                    0, 0, dstWidth-1, dstHeight-1,
                    mImageBits, mRowBytes, scaledRGB, 3*dstWidth, 24);

        if (NS_SUCCEEDED(((nsRenderingContextGTK&)aContext).CopyClipRegion(clipRgn))) {
          // we have both a set of rectangles and a bitmap defining the clip
          // let X11 clip to the bitmap, do the rectangles by hand
          nsRegionRectSet *rectSet = nsnull;
          clipRgn.Intersect(aDX, aDY, aDWidth, aDHeight);
          clipRgn.GetRects(&rectSet);
          for (PRUint32 i=0; i<rectSet->mRectsLen; i++) {
            nsRegionRect *rect = &(rectSet->mRects[i]);

            gdk_draw_rgb_image_dithalign(drawing->GetDrawable(), gc,
                                         rect->x, rect->y, rect->width, rect->height,
                                         GDK_RGB_DITHER_MAX, 
                                         scaledRGB + 3*((rect->y-dstOrigY)*dstWidth+(rect->x-dstOrigX)),
                                         3*dstWidth,
                                         (rect->x-dstOrigX), (rect->y-dstOrigY));
          }
          clipRgn.FreeRects(rectSet);
        } else {
          gdk_draw_rgb_image_dithalign(drawing->GetDrawable(), gc,
                                       aDX, aDY, aDWidth, aDHeight,
                                       GDK_RGB_DITHER_MAX, 
                                       scaledRGB + 3*((aDY-dstOrigY)*dstWidth+(aDX-dstOrigX)),
                                       3*dstWidth,
                                       (aDX-dstOrigX), (aDY-dstOrigY));
        }
        nsMemory::Free(scaledRGB);
      } else {
        if (NS_SUCCEEDED(((nsRenderingContextGTK&)aContext).CopyClipRegion(clipRgn))) {
          // we have both a set of rectangles and a bitmap defining the clip
          // let X11 clip to the bitmap, do the rectangles by hand
          nsRegionRectSet *rectSet = nsnull;
          clipRgn.Intersect(aDX, aDY, aDWidth, aDHeight);
          clipRgn.GetRects(&rectSet);
          for (PRUint32 i=0; i<rectSet->mRectsLen; i++) {
            nsRegionRect *rect = &(rectSet->mRects[i]);
            
            XlibRectStretch(srcWidth, srcHeight,
                            dstWidth, dstHeight,
                            dstOrigX, dstOrigY,
                            rect->x, rect->y,
                            rect->width, rect->height,
                            mImagePixmap, drawing->GetDrawable(),
                            gc, sXbitGC, gdk_rgb_get_visual()->depth);
          }
          clipRgn.FreeRects(rectSet);
        } else {
          // only a mask
          XlibRectStretch(srcWidth, srcHeight,
                          dstWidth, dstHeight,
                          dstOrigX, dstOrigY,
                          aDX, aDY,
                          aDWidth, aDHeight,
                          mImagePixmap, drawing->GetDrawable(),
                          gc, sXbitGC, gdk_rgb_get_visual()->depth);
        }
      }

      break;
    case 0:
      if (!gc)
        gc = ((nsRenderingContextGTK&)aContext).GetGC();

      if (gdk_rgb_get_visual()->depth <= 8) {
        PRUint8 *scaledRGB = (PRUint8 *)nsMemory::Alloc(3*dstWidth*dstHeight);
        if (!scaledRGB)
          break;
        RectStretch(mWidth, mHeight,
                    dstWidth, dstHeight,
                    0, 0, dstWidth-1, dstHeight-1,
                    mImageBits, mRowBytes, scaledRGB, 3*dstWidth, 24);
    
        gdk_draw_rgb_image_dithalign(drawing->GetDrawable(), gc,
                                     aDX, aDY, aDWidth, aDHeight,
                                     GDK_RGB_DITHER_MAX, 
                                     scaledRGB + 3*((aDY-dstOrigY)*dstWidth+(aDX-dstOrigX)),
                                     3*dstWidth,
                                     (aDX-dstOrigX), (aDY-dstOrigY));

        nsMemory::Free(scaledRGB);
      }
      else
        XlibRectStretch(srcWidth, srcHeight,
                        dstWidth, dstHeight,
                        dstOrigX, dstOrigY,
                        aDX, aDY,
                        aDWidth, aDHeight,
                        mImagePixmap, drawing->GetDrawable(),
                        gc, sXbitGC, gdk_rgb_get_visual()->depth);
      break;
    }
    if (gc)
      gdk_gc_unref(gc);
    if (pixmap)
      gdk_pixmap_unref(pixmap);

    mFlags = 0;
    return NS_OK;
  }

  // now start drawing...

  if (mAlphaDepth==8) {
    DrawComposited(aContext, aSurface, 
                   srcWidth, srcHeight,
                   dstWidth, dstHeight,
                   aDX-aSX, aDY-aSY,
                   aDX, aDY,
                   aDWidth, aDHeight);
    return NS_OK;
  }

  GdkGC *copyGC;
  if (mAlphaPixmap) {
    copyGC = gdk_gc_new(drawing->GetDrawable());
    GdkGC *gc = ((nsRenderingContextGTK&)aContext).GetGC();
    gdk_gc_copy(copyGC, gc);
    gdk_gc_unref(gc); // unref the one we got
    
    SetupGCForAlpha(copyGC, aDX-aSX, aDY-aSY);
  } else {
    // don't make a copy... we promise not to change it
    copyGC = ((nsRenderingContextGTK&)aContext).GetGC();
  }

  nsRegionGTK clipRgn;
  if (mAlphaPixmap &&
      NS_SUCCEEDED(((nsRenderingContextGTK&)aContext).CopyClipRegion(clipRgn))) {
    // we have both a set of rectangles and a bitmap defining the clip
    // let X11 clip to the bitmap, do the rectangles by hand
    nsRegionRectSet *rectSet = nsnull;
    clipRgn.Intersect(aDX, aDY, aSWidth, aSHeight);
    clipRgn.GetRects(&rectSet);
    for (PRUint32 i=0; i<rectSet->mRectsLen; i++) {
      nsRegionRect *rect = &(rectSet->mRects[i]);
      gdk_window_copy_area(drawing->GetDrawable(),      // dest window
                           copyGC,                      // gc
                           rect->x,                     // xdest
                           rect->y,                     // ydest
                           mImagePixmap,                // source window
                           aSX+(rect->x-aDX),           // xsrc
                           aSY+(rect->y-aDY),           // ysrc
                           rect->width,                 // width
                           rect->height);               // height
    }
    clipRgn.FreeRects(rectSet);
  } else {
    // normal case - let X11 take care of all the clipping
    gdk_window_copy_area(drawing->GetDrawable(),      // dest window
                         copyGC,                      // gc
                         aDX,                         // xdest
                         aDY,                         // ydest
                         mImagePixmap,                // source window
                         aSX,                         // xsrc
                         aSY,                         // ysrc
                         aSWidth,                     // width
                         aSHeight);                   // height
  }
 
  gdk_gc_unref(copyGC);
  mFlags = 0;

  return NS_OK;
}

Here is the call graph for this function:

void nsImageGTK::DrawComposited ( nsIRenderingContext aContext,
nsIDrawingSurface aSurface,
PRInt32  srcWidth,
PRInt32  srcHeight,
PRInt32  dstWidth,
PRInt32  dstHeight,
PRInt32  dstOrigX,
PRInt32  dstOrigY,
PRInt32  aDX,
PRInt32  aDY,
PRInt32  aDWidth,
PRInt32  aDHeight 
) [inline, private]

Definition at line 1298 of file nsImageGTK.cpp.

{
  nsDrawingSurfaceGTK* drawing = (nsDrawingSurfaceGTK*) aSurface;
  GdkVisual *visual = gdk_rgb_get_visual();
    
  Display *dpy = GDK_WINDOW_XDISPLAY(drawing->GetDrawable());
  Drawable drawable = GDK_WINDOW_XWINDOW(drawing->GetDrawable());

  int readX, readY;
  unsigned readWidth, readHeight, destX, destY;

  destX = aDX-dstOrigX;
  destY = aDY-dstOrigY;
  readX = aDX;
  readY = aDY;
  readWidth = aDWidth;
  readHeight = aDHeight;

//  fprintf(stderr, "dstOrigX=%d dstOrigY=%d, dstWidth=%u dstHeight=%u\n", dstOrigX, dstOrigY, dstWidth, dstHeight);
//  fprintf(stderr, "srcWidth=%u srcHeight=%u\n", srcWidth, srcHeight);
//  fprintf(stderr, "readX=%u readY=%u readWidth=%u readHeight=%u destX=%u destY=%u\n\n",
//          readX, readY, readWidth, readHeight, destX, destY);

  XImage *ximage = XGetImage(dpy, drawable,
                             readX, readY, readWidth, readHeight, 
                             AllPlanes, ZPixmap);

  NS_ASSERTION((ximage!=NULL), "XGetImage() failed");
  if (!ximage)
    return;

  unsigned char *readData = 
    (unsigned char *)nsMemory::Alloc(3*readWidth*readHeight);
  if (!readData) {
    XDestroyImage(ximage);
    return;
  }

  PRUint8 *scaledImage = 0;
  PRUint8 *scaledAlpha = 0;
  PRUint8 *imageOrigin, *alphaOrigin;
  PRUint32 imageStride, alphaStride;
  if ((srcWidth!=dstWidth) || (srcHeight!=dstHeight)) {
    PRUint32 x1, y1, x2, y2;
    x1 = destX*srcWidth/dstWidth;
    y1 = destY*srcHeight/dstHeight;
    x2 = (destX+aDWidth)*srcWidth/dstWidth;
    y2 = (destY+aDHeight)*srcHeight/dstHeight;

    scaledImage = (PRUint8 *)nsMemory::Alloc(3*aDWidth*aDHeight);
    scaledAlpha = (PRUint8 *)nsMemory::Alloc(aDWidth*aDHeight);
    if (!scaledImage || !scaledAlpha) {
      XDestroyImage(ximage);
      nsMemory::Free(readData);
      if (scaledImage)
        nsMemory::Free(scaledImage);
      if (scaledAlpha)
        nsMemory::Free(scaledAlpha);
      return;
    }
    RectStretch(srcWidth, srcHeight,
                dstWidth, dstHeight,
                destX, destY,
                destX+aDWidth-1, destY+aDHeight-1,
                mImageBits, mRowBytes, scaledImage, 3*readWidth, 24);
    RectStretch(srcWidth, srcHeight,
                dstWidth, dstHeight,
                destX, destY,
                destX+aDWidth-1, destY+aDHeight-1,
                mAlphaBits, mAlphaRowBytes, scaledAlpha, readWidth, 8);
    imageOrigin = scaledImage;
    imageStride = 3*readWidth;
    alphaOrigin = scaledAlpha;
    alphaStride = readWidth;
  } else {
    imageOrigin = mImageBits + destY*mRowBytes + 3*destX;
    imageStride = mRowBytes;
    alphaOrigin = mAlphaBits + destY*mAlphaRowBytes + destX;
    alphaStride = mAlphaRowBytes;
  }

  PRBool isLSB;
  unsigned test = 1;
  isLSB = (((char *)&test)[0]) ? 1 : 0;

  PRBool flipBytes = 
    ( isLSB && ximage->byte_order != LSBFirst) ||
    (!isLSB && ximage->byte_order == LSBFirst);

  if ((ximage->bits_per_pixel==32) &&
      (visual->red_prec == 8) &&
      (visual->green_prec == 8) &&
      (visual->blue_prec == 8))
    DrawComposited32(isLSB, flipBytes, 
                     imageOrigin, imageStride,
                     alphaOrigin, alphaStride, 
                     readWidth, readHeight, ximage, readData, (unsigned char *)ximage->data);
  else if ((ximage->bits_per_pixel==24) &&
           (visual->red_prec == 8) && 
           (visual->green_prec == 8) &&
           (visual->blue_prec == 8))
    DrawComposited24(isLSB, flipBytes, 
                     imageOrigin, imageStride,
                     alphaOrigin, alphaStride, 
                     readWidth, readHeight, ximage, readData, (unsigned char *)ximage->data);
  else if ((ximage->bits_per_pixel==16) &&
           ((visual->red_prec == 5)   || (visual->red_prec == 6)) &&
           ((visual->green_prec == 5) || (visual->green_prec == 6)) &&
           ((visual->blue_prec == 5)  || (visual->blue_prec == 6)))
    DrawComposited16(isLSB, flipBytes,
                     imageOrigin, imageStride,
                     alphaOrigin, alphaStride, 
                     readWidth, readHeight, ximage, readData, (unsigned char *)ximage->data);
  else
    DrawCompositedGeneral(isLSB, flipBytes,
                     imageOrigin, imageStride,
                     alphaOrigin, alphaStride, 
                     readWidth, readHeight, ximage, readData, (unsigned char *)ximage->data);

  GdkGC *imageGC = ((nsRenderingContextGTK&)aContext).GetGC();
  gdk_draw_rgb_image(drawing->GetDrawable(), imageGC,
                     readX, readY, readWidth, readHeight,
                     GDK_RGB_DITHER_MAX,
                     readData, 3*readWidth);
  gdk_gc_unref(imageGC);

  XDestroyImage(ximage);
  nsMemory::Free(readData);
  if (scaledImage)
    nsMemory::Free(scaledImage);
  if (scaledAlpha)
    nsMemory::Free(scaledAlpha);
  mFlags = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImageGTK::DrawComposited16 ( PRBool  isLSB,
PRBool  flipBytes,
PRUint8 imageOrigin,
PRUint32  imageStride,
PRUint8 alphaOrigin,
PRUint32  alphaStride,
unsigned  width,
unsigned  height,
XImage *  ximage,
unsigned char *  readData,
unsigned char *  srcData 
) [private]

Definition at line 1113 of file nsImageGTK.cpp.

{
  GdkVisual *visual   = gdk_rgb_get_visual();

  unsigned *redScale   = (visual->red_prec   == 5) ? scaled5 : scaled6;
  unsigned *greenScale = (visual->green_prec == 5) ? scaled5 : scaled6;
  unsigned *blueScale  = (visual->blue_prec  == 5) ? scaled5 : scaled6;

  for (unsigned y=0; y<height; y++) {
    unsigned char *baseRow   = srcData     + y*ximage->bytes_per_line;
    unsigned char *targetRow = readData    + 3*(y*ximage->width);
    unsigned char *imageRow  = imageOrigin + y*imageStride;
    unsigned char *alphaRow  = alphaOrigin + y*alphaStride;

    for (unsigned i=0; i<width;
         i++, baseRow+=2, targetRow+=3, imageRow+=3, alphaRow++) {
      unsigned pix;
      if (flipBytes) {
        unsigned char tmp[2];
        tmp[0] = baseRow[1];
        tmp[1] = baseRow[0]; 
        pix = *((short *)tmp); 
      } else
        pix = *((short *)baseRow);
      unsigned alpha = *alphaRow;
      MOZ_BLEND(targetRow[0],
                redScale[(pix&visual->red_mask)>>visual->red_shift], 
                imageRow[0], alpha);
      MOZ_BLEND(targetRow[1],
                greenScale[(pix&visual->green_mask)>>visual->green_shift], 
                imageRow[1], alpha);
      MOZ_BLEND(targetRow[2],
                blueScale[(pix&visual->blue_mask)>>visual->blue_shift], 
                imageRow[2], alpha);
    }
  }
}

Here is the caller graph for this function:

void nsImageGTK::DrawComposited24 ( PRBool  isLSB,
PRBool  flipBytes,
PRUint8 imageOrigin,
PRUint32  imageStride,
PRUint8 alphaOrigin,
PRUint32  alphaStride,
unsigned  width,
unsigned  height,
XImage *  ximage,
unsigned char *  readData,
unsigned char *  srcData 
) [private]

Definition at line 1066 of file nsImageGTK.cpp.

{
  GdkVisual *visual   = gdk_rgb_get_visual();
  unsigned redIndex   = findIndex24(visual->red_mask);
  unsigned greenIndex = findIndex24(visual->green_mask);
  unsigned blueIndex  = findIndex24(visual->blue_mask);

  if (flipBytes^isLSB) {
    redIndex   = 2-redIndex;
    greenIndex = 2-greenIndex;
    blueIndex  = 2-blueIndex;
  }

  for (unsigned y=0; y<height; y++) {
    unsigned char *baseRow   = srcData     + y*ximage->bytes_per_line;
    unsigned char *targetRow = readData    + 3*(y*ximage->width);
    unsigned char *imageRow  = imageOrigin + y*imageStride;
    unsigned char *alphaRow  = alphaOrigin + y*alphaStride;

    for (unsigned i=0; i<width;
         i++, baseRow+=3, targetRow+=3, imageRow+=3, alphaRow++) {
      unsigned alpha = *alphaRow;
      MOZ_BLEND(targetRow[0], baseRow[redIndex],   imageRow[0], alpha);
      MOZ_BLEND(targetRow[1], baseRow[greenIndex], imageRow[1], alpha);
      MOZ_BLEND(targetRow[2], baseRow[blueIndex],  imageRow[2], alpha);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImageGTK::DrawComposited32 ( PRBool  isLSB,
PRBool  flipBytes,
PRUint8 imageOrigin,
PRUint32  imageStride,
PRUint8 alphaOrigin,
PRUint32  alphaStride,
unsigned  width,
unsigned  height,
XImage *  ximage,
unsigned char *  readData,
unsigned char *  srcData 
) [private]

Definition at line 1027 of file nsImageGTK.cpp.

{
  GdkVisual *visual   = gdk_rgb_get_visual();
  unsigned redIndex   = findIndex32(visual->red_mask);
  unsigned greenIndex = findIndex32(visual->green_mask);
  unsigned blueIndex  = findIndex32(visual->blue_mask);

  if (flipBytes^isLSB) {
    redIndex   = 3-redIndex;
    greenIndex = 3-greenIndex;
    blueIndex  = 3-blueIndex;
  }

//  fprintf(stderr, "startX=%u startY=%u activeX=%u activeY=%u\n",
//          startX, startY, activeX, activeY);
//  fprintf(stderr, "width=%u height=%u\n", ximage->width, ximage->height);

  for (unsigned y=0; y<height; y++) {
    unsigned char *baseRow   = srcData     + y*ximage->bytes_per_line;
    unsigned char *targetRow = readData    + 3*(y*ximage->width);
    unsigned char *imageRow  = imageOrigin + y*imageStride;
    unsigned char *alphaRow  = alphaOrigin + y*alphaStride;

    for (unsigned i=0; i<width;
         i++, baseRow+=4, targetRow+=3, imageRow+=3, alphaRow++) {
      unsigned alpha = *alphaRow;
      MOZ_BLEND(targetRow[0], baseRow[redIndex],   imageRow[0], alpha);
      MOZ_BLEND(targetRow[1], baseRow[greenIndex], imageRow[1], alpha);
      MOZ_BLEND(targetRow[2], baseRow[blueIndex],  imageRow[2], alpha);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImageGTK::DrawCompositedGeneral ( PRBool  isLSB,
PRBool  flipBytes,
PRUint8 imageOrigin,
PRUint32  imageStride,
PRUint8 alphaOrigin,
PRUint32  alphaStride,
unsigned  width,
unsigned  height,
XImage *  ximage,
unsigned char *  readData,
unsigned char *  srcData 
) [private]

Definition at line 1157 of file nsImageGTK.cpp.

{
  GdkVisual *visual     = gdk_rgb_get_visual();
  GdkColormap *colormap = gdk_rgb_get_cmap();

  // flip bytes
  if (flipBytes && (ximage->bits_per_pixel>=16)) {
    for (int row=0; row<ximage->height; row++) {
      unsigned char *ptr = srcData + row*ximage->bytes_per_line;
      if (ximage->bits_per_pixel==24) {  // Aurgh....
        for (int col=0;
             col<ximage->bytes_per_line;
             col+=(ximage->bits_per_pixel/8)) {
          unsigned char tmp;
          tmp = *ptr;
          *ptr = *(ptr+2);
          *(ptr+2) = tmp;
          ptr+=3;
        }
        continue;
      }
      
      for (int col=0; 
               col<ximage->bytes_per_line;
               col+=(ximage->bits_per_pixel/8)) {
        unsigned char tmp;
        switch (ximage->bits_per_pixel) {
        case 16:
          tmp = *ptr;
          *ptr = *(ptr+1);
          *(ptr+1) = tmp;
          ptr+=2;
          break; 
        case 32:
          tmp = *ptr;
          *ptr = *(ptr+3);
          *(ptr+3) = tmp;
          tmp = *(ptr+1);
          *(ptr+1) = *(ptr+2);
          *(ptr+2) = tmp;
          ptr+=4;
          break;
        }
      }
    }
  }

  unsigned redScale, greenScale, blueScale, redFill, greenFill, blueFill;
  redScale =   8-visual->red_prec;
  greenScale = 8-visual->green_prec;
  blueScale =  8-visual->blue_prec;
  redFill =   0xff>>visual->red_prec;
  greenFill = 0xff>>visual->green_prec;
  blueFill =  0xff>>visual->blue_prec;

  for (unsigned row=0; row<height; row++) {
    unsigned char *ptr = srcData + row*ximage->bytes_per_line;
    unsigned char *target = readData+3*row*ximage->width;
    for (unsigned col=0; col<width; col++) {
      unsigned pix;
      switch (ximage->bits_per_pixel) {
      case 1:
        pix = (*ptr>>(col%8))&1;
        if ((col%8)==7)
          ptr++;
        break;
      case 4:
        pix = (col&1)?(*ptr>>4):(*ptr&0xf);
        if (col&1)
          ptr++;
        break;
      case 8:
        pix = *ptr++;
        break;
      case 16:
        pix = *((short *)ptr);
        ptr+=2;
        break;
      case 24:
        if (isLSB)
          pix = (*(ptr+2)<<16) | (*(ptr+1)<<8) | *ptr;
        else
          pix = (*ptr<<16) | (*(ptr+1)<<8) | *(ptr+2);
        ptr+=3;
        break;
      case 32:
        pix = *((unsigned *)ptr);
        ptr+=4;
        break;
      }
      switch (visual->type) {
      case GDK_VISUAL_STATIC_GRAY:
      case GDK_VISUAL_GRAYSCALE:
      case GDK_VISUAL_STATIC_COLOR:
      case GDK_VISUAL_PSEUDO_COLOR:
        *target++ = colormap->colors[pix].red   >>8;
        *target++ = colormap->colors[pix].green >>8;
        *target++ = colormap->colors[pix].blue  >>8;
        break;
        
      case GDK_VISUAL_DIRECT_COLOR:
        *target++ = 
          colormap->colors[(pix&visual->red_mask)>>visual->red_shift].red       >> 8;
        *target++ = 
          colormap->colors[(pix&visual->green_mask)>>visual->green_shift].green >> 8;
        *target++ =
          colormap->colors[(pix&visual->blue_mask)>>visual->blue_shift].blue    >> 8;
        break;
        
      case GDK_VISUAL_TRUE_COLOR:
        *target++ = 
          redFill|((pix&visual->red_mask)>>visual->red_shift)<<redScale;
        *target++ = 
          greenFill|((pix&visual->green_mask)>>visual->green_shift)<<greenScale;
        *target++ = 
          blueFill|((pix&visual->blue_mask)>>visual->blue_shift)<<blueScale;
        break;
      }
    }
  }

  // now composite
  for (unsigned y=0; y<height; y++) {
    unsigned char *targetRow = readData+3*y*ximage->width;
    unsigned char *imageRow  = imageOrigin + y*imageStride;
    unsigned char *alphaRow  = alphaOrigin + y*alphaStride;
    
    for (unsigned i=0; i<width; i++) {
      unsigned alpha = alphaRow[i];
      MOZ_BLEND(targetRow[3*i],   targetRow[3*i],   imageRow[3*i],   alpha);
      MOZ_BLEND(targetRow[3*i+1], targetRow[3*i+1], imageRow[3*i+1], alpha);
      MOZ_BLEND(targetRow[3*i+2], targetRow[3*i+2], imageRow[3*i+2], alpha);
    }
  }
}

Here is the caller graph for this function:

void nsImageGTK::DrawCompositeTile ( nsIRenderingContext aContext,
nsIDrawingSurface aSurface,
PRInt32  aSX,
PRInt32  aSY,
PRInt32  aSWidth,
PRInt32  aSHeight,
PRInt32  aDX,
PRInt32  aDY,
PRInt32  aDWidth,
PRInt32  aDHeight 
) [inline, private]

Definition at line 1441 of file nsImageGTK.cpp.

{
  if ((aDWidth==0) || (aDHeight==0))
    return;

  nsDrawingSurfaceGTK* drawing = (nsDrawingSurfaceGTK*) aSurface;
  GdkVisual *visual = gdk_rgb_get_visual();
    
  Display *dpy = GDK_WINDOW_XDISPLAY(drawing->GetDrawable());
  Drawable drawable = GDK_WINDOW_XWINDOW(drawing->GetDrawable());

  // I hate clipping...
  PRUint32 surfaceWidth, surfaceHeight;
  drawing->GetDimensions(&surfaceWidth, &surfaceHeight);
  
  int readX, readY;
  unsigned readWidth, readHeight;
  PRInt32 destX, destY;

  if ((aDY>=(int)surfaceHeight) || (aDX>=(int)surfaceWidth) ||
      (aDY+aDHeight<=0) || (aDX+aDWidth<=0)) {
    // This should never happen if the layout engine is sane,
    // as it means we're trying to draw an image which is outside
    // the drawing surface.  Bulletproof gfx for now...
    return;
  }

  if (aDX<0) {
    readX = 0;   readWidth = aDWidth+aDX;    destX = aSX-aDX;
  } else {
    readX = aDX;  readWidth = aDWidth;       destX = aSX;
  }
  if (aDY<0) {
    readY = 0;   readHeight = aDHeight+aDY;  destY = aSY-aDY;
  } else {
    readY = aDY;  readHeight = aDHeight;     destY = aSY;
  }

  if (readX+readWidth > surfaceWidth)
    readWidth = surfaceWidth-readX;
  if (readY+readHeight > surfaceHeight)
    readHeight = surfaceHeight-readY;

  if ((readHeight <= 0) || (readWidth <= 0))
    return;

  XImage *ximage = XGetImage(dpy, drawable,
                             readX, readY, readWidth, readHeight, 
                             AllPlanes, ZPixmap);

  NS_ASSERTION((ximage!=NULL), "XGetImage() failed");
  if (!ximage)
    return;

  unsigned char *readData = 
    (unsigned char *)nsMemory::Alloc(3*readWidth*readHeight);
  if (!readData) {
    XDestroyImage(ximage);
    return;
  }

  PRBool isLSB;
  unsigned test = 1;
  isLSB = (((char *)&test)[0]) ? 1 : 0;

  PRBool flipBytes = 
    ( isLSB && ximage->byte_order != LSBFirst) ||
    (!isLSB && ximage->byte_order == LSBFirst);


  PRUint8 *imageOrigin, *alphaOrigin;
  PRUint32 imageStride, alphaStride;
  PRUint32 compX, compY;
  PRUint8 *compTarget, *compSource;

  imageStride = mRowBytes;
  alphaStride = mAlphaRowBytes;

  if (destX==mWidth)
    destX = 0;
  if (destY==mHeight)
    destY = 0;

  for (unsigned y=0; y<readHeight; y+=compY) {
    if (y==0) {
      compY = PR_MIN(mHeight-destY, readHeight-y);
    } else {
      destY = 0;
      compY = PR_MIN(mHeight, readHeight-y);
    }

    compTarget = readData + 3*y*ximage->width;
    compSource = (unsigned char *)ximage->data + y*ximage->bytes_per_line;

    for (unsigned x=0; x<readWidth; x+=compX) {
      if (x==0) {
        compX = PR_MIN(mWidth-destX, readWidth-x);
        imageOrigin = mImageBits + destY*mRowBytes + 3*destX;
        alphaOrigin = mAlphaBits + destY*mAlphaRowBytes + destX;
      } else {
        compX = PR_MIN(mWidth, readWidth-x);
        imageOrigin = mImageBits + destY*mRowBytes;
        alphaOrigin = mAlphaBits + destY*mAlphaRowBytes;
      }

      if ((ximage->bits_per_pixel==32) &&
          (visual->red_prec == 8) &&
          (visual->green_prec == 8) &&
          (visual->blue_prec == 8))
        DrawComposited32(isLSB, flipBytes, 
                         imageOrigin, imageStride,
                         alphaOrigin, alphaStride, 
                         compX, compY, ximage, compTarget, compSource);
      else if ((ximage->bits_per_pixel==24) &&
               (visual->red_prec == 8) && 
               (visual->green_prec == 8) &&
               (visual->blue_prec == 8))
        DrawComposited24(isLSB, flipBytes, 
                         imageOrigin, imageStride,
                         alphaOrigin, alphaStride, 
                         compX, compY, ximage, compTarget, compSource);
      else if ((ximage->bits_per_pixel==16) &&
               ((visual->red_prec == 5)   || (visual->red_prec == 6)) &&
               ((visual->green_prec == 5) || (visual->green_prec == 6)) &&
               ((visual->blue_prec == 5)  || (visual->blue_prec == 6)))
        DrawComposited16(isLSB, flipBytes,
                         imageOrigin, imageStride,
                         alphaOrigin, alphaStride, 
                         compX, compY, ximage, compTarget, compSource);
      else
        DrawCompositedGeneral(isLSB, flipBytes,
                              imageOrigin, imageStride,
                              alphaOrigin, alphaStride, 
                              compX, compY, ximage, compTarget, compSource);

      compTarget += 3*compX;
      compSource += (ximage->bits_per_pixel*compX)/8;
    }
  }

  GdkGC *imageGC = ((nsRenderingContextGTK&)aContext).GetGC();
  gdk_draw_rgb_image(drawing->GetDrawable(), imageGC,
                     readX, readY, readWidth, readHeight,
                     GDK_RGB_DITHER_MAX,
                     readData, 3*readWidth);
  gdk_gc_unref(imageGC);

  XDestroyImage(ximage);
  nsMemory::Free(readData);
  mFlags = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

Implements nsIImage.

Definition at line 1779 of file nsImageGTK.cpp.

{
#ifdef DEBUG_TILING
  printf("nsImageGTK::DrawTile: mWidth=%d, mHeight=%d\n", mWidth, mHeight);
  printf("nsImageGTK::DrawTile((src: %d, %d), (tile: %d,%d, %d, %d) %p\n", aSXOffset, aSYOffset,
         aTileRect.x, aTileRect.y,
         aTileRect.width, aTileRect.height, this);
#endif
  if (mPendingUpdate)
    UpdateCachedImage();

  if ((mAlphaDepth==1) && mIsSpacer)
    return NS_OK;

  if (mDecodedX2 < mDecodedX1 || mDecodedY2 < mDecodedY1)
    return NS_OK;

  nsDrawingSurfaceGTK *drawing = (nsDrawingSurfaceGTK*)aSurface;
  PRBool partial = PR_FALSE;

  PRInt32
    validX = 0,
    validY = 0,
    validWidth  = mWidth,
    validHeight = mHeight;
  
  // limit the image rectangle to the size of the image data which
  // has been validated.
  if (mDecodedY2 < mHeight) {
    validHeight = mDecodedY2 - mDecodedY1;
    partial = PR_TRUE;
  }
  if (mDecodedX2 < mWidth) {
    validWidth = mDecodedX2 - mDecodedX1;
    partial = PR_TRUE;
  }
  if (mDecodedY1 > 0) {   
    validHeight -= mDecodedY1;
    validY = mDecodedY1;
    partial = PR_TRUE;
  }
  if (mDecodedX1 > 0) {
    validWidth -= mDecodedX1;
    validX = mDecodedX1; 
    partial = PR_TRUE;
  }

  if (aTileRect.width == 0 || aTileRect.height == 0 ||
      validWidth == 0 || validHeight == 0) {
    return NS_OK;
  }

  if (partial || (mAlphaDepth == 8) || (aPadX || aPadY)) {
    PRInt32 aY0 = aTileRect.y - aSYOffset,
            aX0 = aTileRect.x - aSXOffset,
            aY1 = aTileRect.y + aTileRect.height,
            aX1 = aTileRect.x + aTileRect.width;

    // Set up clipping and call Draw().
    aContext.PushState();
    ((nsRenderingContextGTK&)aContext).SetClipRectInPixels(
      aTileRect, nsClipCombine_kIntersect);
    ((nsRenderingContextGTK&)aContext).UpdateGC();

    if (mAlphaDepth==8) {
      DrawCompositeTile(aContext, aSurface,
                        aSXOffset, aSYOffset, mWidth, mHeight,
                        aTileRect.x, aTileRect.y,
                        aTileRect.width, aTileRect.height);
    } else {
#ifdef DEBUG_TILING
      printf("Warning: using slow tiling\n");
#endif
      for (PRInt32 y = aY0; y < aY1; y += mHeight + aPadY)
        for (PRInt32 x = aX0; x < aX1; x += mWidth + aPadX)
          Draw(aContext,aSurface, x,y,
               PR_MIN(validWidth, aX1-x),
               PR_MIN(validHeight, aY1-y));
    }

    aContext.PopState();

    return NS_OK;
  }

  nsRect clipRect;
  PRBool isNonEmpty;
  PRBool haveClip = NS_SUCCEEDED(aContext.GetClipRect(clipRect, isNonEmpty));
  if (haveClip && !isNonEmpty) {
    return NS_OK;
  }
    
  if (mAlphaDepth == 1) {
    if (sNeedSlowTile) {
      SlowTile(drawing, aTileRect, aSXOffset, aSYOffset, clipRect, haveClip);
      return NS_OK;
    }

    GdkGC *tileGC;
    GdkGCValues values;
    GdkGCValuesMask valuesMask;

    memset(&values, 0, sizeof(GdkGCValues));
    values.fill = GDK_STIPPLED;
    values.function = GDK_AND;
    values.stipple = mAlphaPixmap;
    values.ts_x_origin = aTileRect.x - aSXOffset;
    values.ts_y_origin = aTileRect.y - aSYOffset;
    valuesMask = GdkGCValuesMask(GDK_GC_FOREGROUND | GDK_GC_FUNCTION | 
                                 GDK_GC_FILL | GDK_GC_STIPPLE | 
                                 GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN);
    tileGC = gdk_gc_new_with_values(drawing->GetDrawable(), &values, valuesMask);
    
    if (haveClip) {
      GdkRectangle gdkrect = {clipRect.x, clipRect.y,
                              clipRect.width, clipRect.height};
      gdk_gc_set_clip_rectangle(tileGC, &gdkrect);
    }

    gdk_draw_rectangle(drawing->GetDrawable(), tileGC, PR_TRUE,
                       aTileRect.x, aTileRect.y,
                       aTileRect.width, aTileRect.height);

    gdk_gc_set_fill(tileGC, GDK_TILED);
    gdk_gc_set_function(tileGC, GDK_OR);
    gdk_gc_set_tile(tileGC, mImagePixmap);

    gdk_draw_rectangle(drawing->GetDrawable(), tileGC, PR_TRUE,
                       aTileRect.x, aTileRect.y,
                       aTileRect.width, aTileRect.height);

    gdk_gc_unref(tileGC);
  } else {
    // In the non-alpha case, gdk can tile for us
    TilePixmap(mImagePixmap, drawing->GetDrawable(), aSXOffset, aSYOffset,
               aTileRect, clipRect, haveClip);
  }

  mFlags = 0;
  return NS_OK;
}

Here is the call graph for this function:

NS_IMETHODIMP nsImageGTK::DrawToImage ( nsIImage aDstImage,
nscoord  aDX,
nscoord  aDY,
nscoord  aDWidth,
nscoord  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 2106 of file nsImageGTK.cpp.

{
  nsImageGTK *dest = NS_STATIC_CAST(nsImageGTK *, aDstImage);

  if (!dest)
    return NS_ERROR_FAILURE;
    
  if (aDX >= dest->mWidth || aDY >= dest->mHeight)
    return NS_OK;

  PRUint8 *rgbPtr=0, *alphaPtr=0;
  PRUint32 rgbStride, alphaStride;

  rgbPtr = mImageBits;
  rgbStride = mRowBytes;
  alphaPtr = mAlphaBits;
  alphaStride = mAlphaRowBytes;

  PRInt32 y;
  PRInt32 ValidWidth = ( aDWidth < ( dest->mWidth - aDX ) ) ? aDWidth : ( dest->mWidth - aDX ); 
  PRInt32 ValidHeight = ( aDHeight < ( dest->mHeight - aDY ) ) ? aDHeight : ( dest->mHeight - aDY );

  // now composite the two images together
  switch (mAlphaDepth) {
  case 1:
    {
      PRUint8 *dst = dest->mImageBits + aDY*dest->mRowBytes + 3*aDX;
      PRUint8 *dstAlpha = dest->mAlphaBits + aDY*dest->mAlphaRowBytes;
      PRUint8 *src = rgbPtr;
      PRUint8 *alpha = alphaPtr;
      PRUint8 offset = aDX & 0x7; // x starts at 0
      int iterations = (ValidWidth+7)/8; // round up

      for (y=0; y<ValidHeight; y++) {
        for (int x=0; x<ValidWidth; x += 8, dst += 3*8, src += 3*8) {
          PRUint8 alphaPixels = *alpha++;
          if (alphaPixels == 0) {
            // all 8 transparent; jump forward
            continue;
          }

          // 1 or more bits are set, handle dstAlpha now - may not be aligned.
          // Are all 8 of these alpha pixels used?
          if (x+7 >= ValidWidth) {
            alphaPixels &= 0xff << (8 - (ValidWidth-x)); // no, mask off unused
            if (alphaPixels == 0)
              continue;  // no 1 alpha pixels left
          }
          if (offset == 0) {
            dstAlpha[(aDX+x)>>3] |= alphaPixels; // the cheap aligned case
          }
          else {
            dstAlpha[(aDX+x)>>3]       |= alphaPixels >> offset;
            // avoid write if no 1's to write - also avoids going past end of array
            PRUint8 alphaTemp = alphaPixels << (8U - offset);
            if (alphaTemp & 0xff)
              dstAlpha[((aDX+x)>>3) + 1] |= alphaTemp;
          }
          
          if (alphaPixels == 0xff) {
            // fix - could speed up by gathering a run of 0xff's and doing 1 memcpy
            // all 8 pixels set; copy and jump forward
            memcpy(dst,src,8*3);
            continue;
          }
          else {
            // else mix of 1's and 0's in alphaPixels, do 1 bit at a time
            // Don't go past end of line!
            PRUint8 *d = dst, *s = src;
            for (PRUint8 aMask = 1<<7, j = 0; aMask && j < ValidWidth-x; aMask >>= 1, j++) {
              // if this pixel is opaque then copy into the destination image
              if (alphaPixels & aMask) {
                // might be faster with *d++ = *s++ 3 times?
                d[0] = s[0];
                d[1] = s[1];
                d[2] = s[2];
                // dstAlpha bit already set
              }
              d += 3;
              s += 3;
            }
          }
        }
        // at end of each line, bump pointers.  Use wordy code because of
        // bug 127455 to avoid possibility of unsigned underflow
        dst = (dst - 3*8*iterations) + dest->mRowBytes;
        src = (src - 3*8*iterations) + rgbStride;
        alpha = (alpha - iterations) + alphaStride;
        dstAlpha += dest->mAlphaRowBytes;
      }
    }
    break;
  case 0:
  default:
    for (y=0; y<ValidHeight; y++)
      memcpy(dest->mImageBits + (y+aDY)*dest->mRowBytes + 3*aDX, 
             rgbPtr + y*rgbStride,
             3*ValidWidth);
  }

  nsRect rect(aDX, aDY, ValidWidth, ValidHeight);
  dest->ImageUpdated(nsnull, 0, &rect);

  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 281 of file nsImageGTK.cpp.

{
  if (mTrueAlphaBits)
    return mTrueAlphaBits;
  else
    return mAlphaBits;
}
virtual PRInt8 nsImageGTK::GetAlphaDepth ( ) [inline, 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 119 of file nsImageGTK.h.

                                 { 
    if (mTrueAlphaBits)
      return mTrueAlphaDepth;
    else
      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 290 of file nsImageGTK.cpp.

{
  if (mTrueAlphaBits)
    return mTrueAlphaRowBytes;
  else
    return mAlphaRowBytes;
}
void * nsImageGTK::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 266 of file nsImageGTK.cpp.

{
  return nsnull;
}
PRUint8 * nsImageGTK::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 261 of file nsImageGTK.cpp.

{
  return mImageBits;
}
virtual NS_DECL_ISUPPORTS PRInt32 nsImageGTK::GetBytesPix ( ) [inline, virtual]
See also:
nsIImage.h

Implements nsIImage.

Definition at line 72 of file nsImageGTK.h.

{ return mNumBytesPixel; }

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 276 of file nsImageGTK.cpp.

{
  return nsnull;
}
virtual PRBool nsImageGTK::GetHasAlphaMask ( ) [inline, virtual]

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 110 of file nsImageGTK.h.

{ return mAlphaBits != nsnull || mAlphaPixmap != nsnull; }

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

Returns:
The height in pixels for the pixelmap

Implements nsIImage.

Definition at line 251 of file nsImageGTK.cpp.

{
  return mHeight;
}


See documentation in nsIImage.h

Implements nsIImage.

Definition at line 317 of file nsImageGTK.cpp.

                                      {
  return mDecodedX1 == 0 &&
         mDecodedY1 == 0 &&
         mDecodedX2 == mWidth &&
         mDecodedY2 == mHeight;
}
virtual PRBool nsImageGTK::GetIsRowOrderTopToBottom ( ) [inline, virtual]

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 77 of file nsImageGTK.h.

{ return PR_TRUE; }

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 271 of file nsImageGTK.cpp.

{
  return mRowBytes;
}

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

Returns:
The width in pixels for the pixelmap

Implements nsIImage.

Definition at line 256 of file nsImageGTK.cpp.

{
  return mWidth;
}
void nsImageGTK::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 298 of file nsImageGTK.cpp.

{
  mPendingUpdate = PR_TRUE;
  mUpdateRegion.Or(mUpdateRegion, *aUpdateRect);

  mDecodedX1 = PR_MIN(mDecodedX1, aUpdateRect->x);
  mDecodedY1 = PR_MIN(mDecodedY1, aUpdateRect->y);

  if (aUpdateRect->YMost() > mDecodedY2)
    mDecodedY2 = aUpdateRect->YMost();
  if (aUpdateRect->XMost() > mDecodedX2)
    mDecodedX2 = aUpdateRect->XMost();
}

Here is the caller graph for this function:

nsresult nsImageGTK::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 175 of file nsImageGTK.cpp.

{
  // Assumed: Init only gets called once by gfxIImageFrame
  g_return_val_if_fail ((aWidth != 0) || (aHeight != 0), NS_ERROR_FAILURE);

  // X Protocol limits us to image dimensions less than 32767
  // unless we want to go through lots of pain and suffering.
  if (aWidth > SHRT_MAX || aHeight > SHRT_MAX)
    return NS_ERROR_FAILURE;

  if (24 == aDepth) {
    mNumBytesPixel = 3;
  } else {
    NS_ASSERTION(PR_FALSE, "unexpected image depth");
    return NS_ERROR_UNEXPECTED;
  }

  mWidth = aWidth;
  mHeight = aHeight;
  mDepth = aDepth;

#ifdef TRACE_IMAGE_ALLOCATION
  printf("nsImageGTK::Init(this=%p,%d,%d,%d,%d)\n",
         this,
         aWidth,
         aHeight,
         aDepth,
         aMaskRequirements);
#endif

  // create the memory for the image
  ComputeMetrics();

  mImageBits = (PRUint8*)malloc(mSizeImage);
  if (!mImageBits)
    return NS_ERROR_OUT_OF_MEMORY;

  switch(aMaskRequirements)
  {
    case nsMaskRequirements_kNeeds8Bit:
      mTrueAlphaRowBytes = aWidth;
      mTrueAlphaDepth = 8;

      // 32-bit align each row
      mTrueAlphaRowBytes = (mTrueAlphaRowBytes + 3) & ~0x3;
      mTrueAlphaBits = (PRUint8*)calloc(mTrueAlphaRowBytes * aHeight, 1);
      if (!mTrueAlphaBits)
        return NS_ERROR_OUT_OF_MEMORY;

      // FALL THROUGH

    case nsMaskRequirements_kNeeds1Bit:
      mAlphaRowBytes = (aWidth + 7) / 8;
      mAlphaDepth = 1;

      // 32-bit align each row
      mAlphaRowBytes = (mAlphaRowBytes + 3) & ~0x3;

      mAlphaBits = (PRUint8*)calloc(mAlphaRowBytes * aHeight, 1);
      if (!mAlphaBits)
        return NS_ERROR_OUT_OF_MEMORY;
      break;

    default:
      break; // avoid compiler warning
  }

  if (aMaskRequirements == nsMaskRequirements_kNeeds8Bit)
    mAlphaDepth = 0;
  
  return NS_OK;
}

Here is the call graph for this function:

NS_IMETHODIMP nsImageGTK::LockImagePixels ( PRBool  aMaskPixels) [virtual]

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 1979 of file nsImageGTK.cpp.

{
  if (!mOptimized)
    return NS_OK;

  if (aMaskPixels) {
    if (mAlphaDepth != 1 || !mAlphaPixmap)
      return NS_OK;

    XImage *xmask = XGetImage(GDK_WINDOW_XDISPLAY(mAlphaPixmap),
                              GDK_WINDOW_XWINDOW(mAlphaPixmap),
                              0, 0, mWidth, mHeight,
                              AllPlanes, XYPixmap);

    mAlphaBits = (PRUint8*)calloc(mAlphaRowBytes * mHeight, 1);
    if (!mAlphaBits)
      return NS_ERROR_OUT_OF_MEMORY;

    for (PRInt32 y = 0; y < mHeight; ++y) {
      PRUint8 *alphaTarget = mAlphaBits + y*mAlphaRowBytes;
      PRUint32 alphaBitPos = 7;

      for (PRInt32 x = 0; x < mWidth; ++x) {
        *alphaTarget |= (XGetPixel(xmask, x, y) << alphaBitPos);
        if (alphaBitPos-- == 0) {
          ++alphaTarget;
          alphaBitPos = 7;
        }
      }
    }

    XDestroyImage(xmask);
    return NS_OK;
  }

  if (!mImagePixmap)
    return NS_OK;

  XImage *ximage, *xmask=0;
  unsigned pix;

  ximage = XGetImage(GDK_WINDOW_XDISPLAY(mImagePixmap),
                     GDK_WINDOW_XWINDOW(mImagePixmap),
                     0, 0, mWidth, mHeight,
                     AllPlanes, ZPixmap);

  if ((mAlphaDepth==1) && mAlphaPixmap)
    xmask = XGetImage(GDK_WINDOW_XDISPLAY(mAlphaPixmap),
                      GDK_WINDOW_XWINDOW(mAlphaPixmap),
                      0, 0, mWidth, mHeight,
                      AllPlanes, XYPixmap);

  mImageBits = (PRUint8*)malloc(mSizeImage);
  if (!mImageBits)
    return NS_ERROR_OUT_OF_MEMORY;

  GdkVisual *visual = gdk_rgb_get_visual();
  GdkColormap *colormap = gdk_rgb_get_cmap();

  unsigned redScale, greenScale, blueScale, redFill, greenFill, blueFill;
  redScale   = 8 - visual->red_prec;
  greenScale = 8 - visual->green_prec;
  blueScale  = 8 - visual->blue_prec;
  redFill    = 0xff >> visual->red_prec;
  greenFill  = 0xff >> visual->green_prec;
  blueFill   = 0xff >> visual->blue_prec;

  /* read back the image in the slowest (but simplest) way possible... */
  for (PRInt32 y=0; y<mHeight; y++) {
    PRUint8 *target = mImageBits + y*mRowBytes;
    for (PRInt32 x=0; x<mWidth; x++) {
      if (xmask && !XGetPixel(xmask, x, y)) {
        *target++ = 0xFF;
        *target++ = 0xFF;
        *target++ = 0xFF;
      } else {
        pix = XGetPixel(ximage, x, y);
        switch (visual->type) {
        case GDK_VISUAL_STATIC_GRAY:
        case GDK_VISUAL_GRAYSCALE:
        case GDK_VISUAL_STATIC_COLOR:
        case GDK_VISUAL_PSEUDO_COLOR:
          *target++ = colormap->colors[pix].red   >>8;
          *target++ = colormap->colors[pix].green >>8;
          *target++ = colormap->colors[pix].blue  >>8;
          break;

        case GDK_VISUAL_DIRECT_COLOR:
          *target++ = 
            colormap->colors[(pix&visual->red_mask)>>visual->red_shift].red       >> 8;
          *target++ = 
            colormap->colors[(pix&visual->green_mask)>>visual->green_shift].green >> 8;
          *target++ =
            colormap->colors[(pix&visual->blue_mask)>>visual->blue_shift].blue    >> 8;
          break;

        case GDK_VISUAL_TRUE_COLOR:
          *target++ = 
            redFill|((pix&visual->red_mask)>>visual->red_shift)<<redScale;
          *target++ = 
            greenFill|((pix&visual->green_mask)>>visual->green_shift)<<greenScale;
          *target++ = 
            blueFill|((pix&visual->blue_mask)>>visual->blue_shift)<<blueScale;
          break;
        }
      }
    }
  }

  XDestroyImage(ximage);
  if (xmask)
    XDestroyImage(xmask);

  return NS_OK;
}

Here is the call graph for this function:

nsresult nsImageGTK::Optimize ( nsIDeviceContext aContext) [virtual]

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 1929 of file nsImageGTK.cpp.

{
  if (!mOptimized)
    UpdateCachedImage();

  if (mAlphaBits && mTrueAlphaBits) {
    // 8-bit alpha image turned out to be 1-bit - blacken transparent
    // areas so that we can draw it using the fast tile path
    for (PRInt32 y = 0; y < mHeight; y++)
      for (PRInt32 x = 0; x < mWidth; x++)
        if (!mTrueAlphaBits[y * mTrueAlphaRowBytes + x]) {
          mImageBits[y * mRowBytes + 3 * x]     = 0;
          mImageBits[y * mRowBytes + 3 * x + 1] = 0;
          mImageBits[y * mRowBytes + 3 * x + 2] = 0;
        }
    nsRect rect(0, 0, mWidth, mHeight);
    ImageUpdated(nsnull, 0, &rect);
    UpdateCachedImage();
  }

  if ((gdk_rgb_get_visual()->depth > 8) && (mAlphaDepth != 8)) {
    if(nsnull != mImageBits) {
      free(mImageBits);
      mImageBits = nsnull;
    }

    if (nsnull != mAlphaBits) {
      free(mAlphaBits);
      mAlphaBits = nsnull;
    }
  }
    
  if (mTrueAlphaBits) {
    free(mTrueAlphaBits);
    mTrueAlphaBits = nsnull;
  }

  if ((mAlphaDepth==0) && mAlphaPixmap) {
    gdk_pixmap_unref(mAlphaPixmap);
    mAlphaPixmap = nsnull;
  }

  mOptimized = PR_TRUE;

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImageGTK::SetupGCForAlpha ( GdkGC *  aGC,
PRInt32  aX,
PRInt32  aY 
) [inline, private]

Definition at line 1659 of file nsImageGTK.cpp.

{
  // XXX should use (different?) GC cache here
  if (mAlphaPixmap) {
    // Setup gc to use the given alpha-pixmap for clipping
    XGCValues xvalues;
    memset(&xvalues, 0, sizeof(XGCValues));
    unsigned long xvalues_mask = 0;
    xvalues.clip_x_origin = aX;
    xvalues.clip_y_origin = aY;
    xvalues_mask = GCClipXOrigin | GCClipYOrigin;

    xvalues.clip_mask = GDK_WINDOW_XWINDOW(mAlphaPixmap);
    xvalues_mask |= GCClipMask;

    XChangeGC(GDK_DISPLAY(), GDK_GC_XGC(aGC), xvalues_mask, &xvalues);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImageGTK::Shutdown ( ) [static]

Definition at line 161 of file nsImageGTK.cpp.

{
  if (s1bitGC) {
    gdk_gc_unref(s1bitGC);
    s1bitGC = nsnull;
  }
  if (sXbitGC) {
    gdk_gc_unref(sXbitGC);
    sXbitGC = nsnull;
  }
}

Here is the caller graph for this function:

void nsImageGTK::SlowTile ( nsDrawingSurfaceGTK aSurface,
const nsRect aTileRect,
PRInt32  aSXOffset,
PRInt32  aSYOffset,
const nsRect aRect,
PRBool  aIsValid 
) [private]

Definition at line 1733 of file nsImageGTK.cpp.

{
  GdkPixmap *tileImg;
  GdkPixmap *tileMask;

  nsRect tmpRect(0,0,aTileRect.width, aTileRect.height);

  tileImg = gdk_pixmap_new(nsnull, aTileRect.width, 
                           aTileRect.height, aSurface->GetDepth());
#ifdef MOZ_WIDGET_GTK2
  gdk_drawable_set_colormap(GDK_DRAWABLE(tileImg), gdk_rgb_get_colormap());
#endif

  TilePixmap(mImagePixmap, tileImg, aSXOffset, aSYOffset, tmpRect,
             tmpRect, PR_FALSE);

  // tile alpha mask
  tileMask = gdk_pixmap_new(nsnull, aTileRect.width, aTileRect.height,
                            mAlphaDepth);
  TilePixmap(mAlphaPixmap, tileMask, aSXOffset, aSYOffset, tmpRect,
             tmpRect, PR_FALSE);

  GdkGC *fgc = gdk_gc_new(aSurface->GetDrawable());
  gdk_gc_set_clip_mask(fgc, (GdkBitmap*)tileMask);
  gdk_gc_set_clip_origin(fgc, aTileRect.x, aTileRect.y);

  nsRect drawRect = aTileRect;
  if (aHaveClip) {
    drawRect.IntersectRect(drawRect, aClipRect);
  }

  // and copy it back
  gdk_window_copy_area(aSurface->GetDrawable(), fgc, drawRect.x,
                       drawRect.y, tileImg,
                       drawRect.x - aTileRect.x, drawRect.y - aTileRect.y,
                       drawRect.width, drawRect.height);
  gdk_gc_unref(fgc);

  gdk_pixmap_unref(tileImg);
  gdk_pixmap_unref(tileMask);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImageGTK::Startup ( ) [static]

Definition at line 152 of file nsImageGTK.cpp.

{
  Display *dpy = GDK_DISPLAY();

  if (strstr(ServerVendor(dpy), "XFree86") && VendorRelease(dpy) < 40400000)
    sNeedSlowTile = PR_TRUE;
}

Here is the caller graph for this function:

void nsImageGTK::TilePixmap ( GdkPixmap *  src,
GdkPixmap *  dest,
PRInt32  aSXOffset,
PRInt32  aSYOffset,
const nsRect destRect,
const nsRect clipRect,
PRBool  useClip 
) [inline, private]

Definition at line 1698 of file nsImageGTK.cpp.

{
  GdkGC *gc;
  GdkGCValues values;
  GdkGCValuesMask valuesMask;
  memset(&values, 0, sizeof(GdkGCValues));
  values.fill = GDK_TILED;
  values.tile = src;
  values.ts_x_origin = destRect.x - aSXOffset;
  values.ts_y_origin = destRect.y - aSYOffset;
  valuesMask = GdkGCValuesMask(GDK_GC_FILL | GDK_GC_TILE | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN);
  gc = gdk_gc_new_with_values(src, &values, valuesMask);

  if (aHaveClip) {
    GdkRectangle gdkrect = {clipRect.x, clipRect.y, clipRect.width, clipRect.height};
    gdk_gc_set_clip_rectangle(gc, &gdkrect);
  }

  // draw to destination window
  #ifdef DEBUG_TILING
  printf("nsImageGTK::TilePixmap(..., %d, %d, %d, %d)\n",
         destRect.x, destRect.y, 
         destRect.width, destRect.height);
  #endif

  gdk_draw_rectangle(dest, gc, PR_TRUE,
                     destRect.x, destRect.y,
                     destRect.width, destRect.height);

  gdk_gc_unref(gc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

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 2098 of file nsImageGTK.cpp.

{
  if (mOptimized)
    Optimize(nsnull);

  return NS_OK;
} 

Here is the call graph for this function:

Definition at line 324 of file nsImageGTK.cpp.

{
#ifdef TRACE_IMAGE_ALLOCATION
  printf("nsImageGTK::ImageUpdated(this=%p)\n",
         this);
#endif

  nsRegionRectIterator ri(mUpdateRegion);
  const nsRect *rect;

  while ((rect = ri.Next()) != nsnull) {

//  fprintf(stderr, "ImageUpdated %p x,y=(%d %d) width,height=(%d %d)\n",
//          this, rect->x, rect->y, rect->width, rect->height);

    unsigned bottom, left, right;
    bottom = rect->y + rect->height;
    left   = rect->x;
    right  = left + rect->width;

    // check if the image has an all-opaque 8-bit alpha mask
    if ((mTrueAlphaDepth==8) && (mAlphaDepth<mTrueAlphaDepth)) {
      for (unsigned y=rect->y; 
           (y<bottom) && (mAlphaDepth<mTrueAlphaDepth); 
           y++) {
        unsigned char *alpha = mTrueAlphaBits + mTrueAlphaRowBytes*y + left;
        unsigned char *mask = mAlphaBits + mAlphaRowBytes*y;
        for (unsigned x=left; x<right; x++) {
          switch (*(alpha++)) {
          case 255:
            NS_SET_BIT(mask,x);
            break;
          case 0:
            NS_CLEAR_BIT(mask,x);
            if (mAlphaDepth == 0) {
              mAlphaDepth=1;

              // promoting an image from no alpha channel to 1-bit, so
              // we need to create/clear the alpha pixmap
              CreateOffscreenPixmap(mWidth, mHeight);

              XFillRectangle(GDK_WINDOW_XDISPLAY(mAlphaPixmap),
                             GDK_WINDOW_XWINDOW(mAlphaPixmap),
                             GDK_GC_XGC(s1bitGC),
                             mDecodedX1, mDecodedY1,
                             mDecodedX2 - mDecodedX1 + 1,
                             mDecodedY2 - mDecodedY1 + 1);
            }
            break;
          default:
            mAlphaDepth=8;
            break;
          }
        }
      }
      
      if (mAlphaDepth==8) {
        if (mImagePixmap) {
          gdk_pixmap_unref(mImagePixmap);
          mImagePixmap = 0;
        }
        if (mAlphaPixmap) {
          gdk_pixmap_unref(mAlphaPixmap);
          mAlphaPixmap = 0;
        }
        if (mAlphaBits) {
          free(mAlphaBits);
          mAlphaBits = mTrueAlphaBits;
          mAlphaRowBytes = mTrueAlphaRowBytes;
          mTrueAlphaBits = 0;
        }
      }
    }

    // check if the image is a spacer
    if ((mAlphaDepth==1) && mIsSpacer) {
      // mask of the leading/trailing bits in the update region
      PRUint8  leftmask   = 0xff  >> (left & 0x7);
      PRUint8  rightmask  = 0xff  << (7 - ((right-1) & 0x7));

      // byte where the first/last bits of the update region are located
      PRUint32 leftindex  = left      >> 3;
      PRUint32 rightindex = (right-1) >> 3;

      // first/last bits in the same byte - combine mask into leftmask
      // and fill rightmask so we don't try using it
      if (leftindex == rightindex) {
        leftmask &= rightmask;
        rightmask = 0xff;
      }

      // check the leading bits
      if (leftmask != 0xff) {
        PRUint8 *ptr = mAlphaBits + mAlphaRowBytes * rect->y + leftindex;
        for (unsigned y=rect->y; y<bottom; y++, ptr+=mAlphaRowBytes) {
          if (*ptr & leftmask) {
            mIsSpacer = PR_FALSE;
            break;
          }
        }
        // move to first full byte
        leftindex++;
      }

      // check the trailing bits
      if (mIsSpacer && (rightmask != 0xff)) {
        PRUint8 *ptr = mAlphaBits + mAlphaRowBytes * rect->y + rightindex;
        for (unsigned y=rect->y; y<bottom; y++, ptr+=mAlphaRowBytes) {
          if (*ptr & rightmask) {
            mIsSpacer = PR_FALSE;
            break;
          }
        }
        // move to last full byte
        rightindex--;
      }
    
      // check the middle bytes
      if (mIsSpacer && (leftindex <= rightindex)) {
        for (unsigned y=rect->y; (y<bottom) && mIsSpacer; y++) {
          unsigned char *alpha = mAlphaBits + mAlphaRowBytes*y + leftindex;
          for (unsigned x=leftindex; x<=rightindex; x++) {
            if (*(alpha++)!=0) {
              mIsSpacer = PR_FALSE;
              break;
            }
          }
        }
      }
    }

    if (mAlphaDepth != 8) {
      CreateOffscreenPixmap(mWidth, mHeight);

      gdk_draw_rgb_image_dithalign(mImagePixmap, sXbitGC, 
                                   rect->x, rect->y,
                                   rect->width, rect->height,
                                   GDK_RGB_DITHER_MAX,
                                   mImageBits + mRowBytes*rect->y + 3*rect->x,
                                   mRowBytes,
                                   0, 0);
    }

    if (mAlphaDepth==1) {
      XPutImage(GDK_WINDOW_XDISPLAY(mAlphaPixmap),
                GDK_WINDOW_XWINDOW(mAlphaPixmap),
                GDK_GC_XGC(s1bitGC),
                mAlphaXImage,
                rect->x, rect->y, 
                rect->x, rect->y,
                rect->width, rect->height);
    }
  }
  
  mUpdateRegion.SetEmpty();
  mPendingUpdate = PR_FALSE;
  mFlags = nsImageUpdateFlags_kBitsChanged; // this should be 0'd out by Draw()
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 198 of file nsImageGTK.h.

PRInt8 nsImageGTK::mAlphaDepth [private]

Definition at line 217 of file nsImageGTK.h.

GdkPixmap* nsImageGTK::mAlphaPixmap [private]

Definition at line 199 of file nsImageGTK.h.

Definition at line 215 of file nsImageGTK.h.

XImage* nsImageGTK::mAlphaXImage [private]

Definition at line 200 of file nsImageGTK.h.

Definition at line 207 of file nsImageGTK.h.

Definition at line 209 of file nsImageGTK.h.

Definition at line 208 of file nsImageGTK.h.

Definition at line 210 of file nsImageGTK.h.

PRInt8 nsImageGTK::mDepth [private]

Definition at line 224 of file nsImageGTK.h.

Definition at line 223 of file nsImageGTK.h.

Definition at line 203 of file nsImageGTK.h.

Definition at line 195 of file nsImageGTK.h.

GdkPixmap* nsImageGTK::mImagePixmap [private]

Definition at line 196 of file nsImageGTK.h.

Definition at line 219 of file nsImageGTK.h.

PRInt8 nsImageGTK::mNumBytesPixel [private]

Definition at line 222 of file nsImageGTK.h.

Definition at line 226 of file nsImageGTK.h.

Definition at line 220 of file nsImageGTK.h.

Definition at line 204 of file nsImageGTK.h.

Definition at line 205 of file nsImageGTK.h.

Definition at line 197 of file nsImageGTK.h.

PRInt8 nsImageGTK::mTrueAlphaDepth [private]

Definition at line 218 of file nsImageGTK.h.

Definition at line 216 of file nsImageGTK.h.

nsRegion nsImageGTK::mUpdateRegion [private]

Definition at line 212 of file nsImageGTK.h.

Definition at line 202 of file nsImageGTK.h.

unsigned nsImageGTK::scaled5 [static, private]
Initial value:
 {
  7,  15,  23,  31,  39,  47,  55,  63,  71,  79,  87,  95, 103, 111, 119, 127,
135, 143, 151, 159, 167, 175, 183, 191, 199, 207, 215, 223, 231, 239, 247, 255
}

Definition at line 151 of file nsImageGTK.h.

unsigned nsImageGTK::scaled6 [static, private]
Initial value:
 {
  3,   7,  11,  15,  19,  23,  27,  31,  35,  39,  43,  47,  51,  55,  59,  63,
 67,  71,  75,  79,  83,  87,  91,  95,  99, 103, 107, 111, 115, 119, 123, 127,
131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 183, 187, 191,
195, 199, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255
}

Definition at line 150 of file nsImageGTK.h.


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