Commit 5633be11 authored by msw%gimp.org's avatar msw%gimp.org
Browse files

First pass of alpha support in images by Chris Blizzard, fixed for endian

problems.  There is still a little work left to do on this.
parent 3f2f09a6
Loading
Loading
Loading
Loading
+106 −16
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
 */

#include <gtk/gtk.h>
#include <gdk/gdkx.h>

#include "nsImageGTK.h"
#include "nsRenderingContextGTK.h"
@@ -37,6 +38,7 @@ nsImageGTK :: nsImageGTK()
  mHeight = 0;
  mDepth = 0;
  mAlphaBits = nsnull;
  mAlphaPixmap = nsnull;
}

//------------------------------------------------------------
@@ -49,7 +51,9 @@ nsImageGTK :: ~nsImageGTK()
  }

  if (nsnull != mAlphaBits) {
    delete mAlphaBits;
    delete[] (PRUint8*)mAlphaBits;
    mAlphaBits = nsnull;
    gdk_pixmap_unref(mAlphaPixmap);
  }
}

@@ -63,7 +67,8 @@ nsresult nsImageGTK :: Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,nsMa
   delete[] (PRUint8*)mImageBits;

  if (nsnull != mAlphaBits) {
    delete mAlphaBits;
    delete[] (PRUint8*)mAlphaBits;
    gdk_pixmap_unref(mAlphaPixmap);
  }

  if (24 == aDepth) {
@@ -81,7 +86,31 @@ nsresult nsImageGTK :: Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,nsMa
  ComputMetrics();

  mImageBits = (PRUint8*) new PRUint8[mSizeImage];
  if (aMaskRequirements == nsMaskRequirements_kNeeds1Bit)
    {
      mAlphaBits = (PRUint8*) new PRUint8[mSizeImage];
//      mAlphaRowBytes = (aWidth + 7) / 8;
      mAlphaRowBytes = aWidth >> 5;
      if (mAlphaRowBytes & 0x1F)
        mAlphaRowBytes++;
      mAlphaRowBytes <<= 2;
      mAlphaDepth = 1;

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

      mAlphaBits = new unsigned char[mAlphaRowBytes * aHeight];
      mAlphaWidth = aWidth;
      mAlphaHeight = aHeight;
      mAlphaPixmap = gdk_pixmap_new(NULL, mWidth, mHeight, 1);

    }
  else
    {
      mAlphaBits = nsnull;
      mAlphaWidth = 0;
      mAlphaHeight = 0;
    }
  return NS_OK;
}

@@ -242,13 +271,74 @@ NS_IMETHODIMP nsImageGTK :: Draw(nsIRenderingContext &aContext,
                                  PRInt32 aWidth, PRInt32 aHeight)
{
  nsDrawingSurfaceGTK *drawing = (nsDrawingSurfaceGTK*) aSurface;

  XImage *x_image = NULL;
  Pixmap pixmap = 0;
  Display *dpy = NULL;
  Visual *visual = NULL;
  GC      gc;
  XGCValues gcv;

  if (mAlphaBits != nsnull)
    {
      /* get the X primitives */
      dpy = GDK_WINDOW_XDISPLAY(mAlphaPixmap);
      visual = GDK_VISUAL_XVISUAL(gdk_rgb_get_visual());
      /* this is the depth of the pixmap that we are going to draw to.
         It's always a bitmap.  We're doing alpha here folks. */
      x_image = XCreateImage(dpy, visual,
                             1, /* visual depth...1 for bitmaps */
                             XYPixmap,
                             0, /* x offset, XXX fix this */
                             (char *)mAlphaBits,  /* cast away our sign. */
                             mWidth,
                             mHeight,
                             32,/* bitmap pad */
                             mAlphaRowBytes); /* bytes per line */
      x_image->bits_per_pixel=1;
      /* Image library always places pixels left-to-right MSB to LSB */
      x_image->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. */
      x_image->byte_order = MSBFirst;
#if defined(IS_LITTLE_ENDIAN)
      // no, it's still MSB
      //      x_image->byte_order = LSBFirst;
#elif defined (IS_BIG_ENDIAN)
      x_image->byte_order = MSBFirst;
#else
#error ERROR! Endianness is unknown;
#endif
      pixmap = GDK_WINDOW_XWINDOW(mAlphaPixmap);
      memset(&gcv, 0, sizeof(XGCValues));
      gcv.function = GXcopy;
      gc = XCreateGC(dpy, pixmap, GCFunction, &gcv);

      XPutImage(dpy, pixmap, gc, x_image, 0, 0, 0, 0,
                mWidth, mHeight);

      XFreeGC(dpy, gc);
      gdk_gc_set_clip_mask(drawing->gc, mAlphaPixmap);
      gdk_gc_set_clip_origin(drawing->gc, aX, aY);
      gdk_flush();
    }
  moz_gdk_draw_bgr_image (drawing->drawable,
                          drawing->gc,
                          aX, aY, aWidth, aHeight,
                          GDK_RGB_DITHER_MAX,
                          mImageBits, mRowBytes);

  gdk_flush();
#if 0
  if (mAlphaBits != nsnull)
    {
      gdk_gc_set_clip_origin(drawing->gc, 0, 0);
      gdk_gc_set_clip_mask(drawing->gc, NULL);
      gdk_flush();
      x_image->data = 0;          /* Don't free the IL_Pixmap's bits. */
      XDestroyImage(x_image);
    }
#endif
  return NS_OK;
}

@@ -256,6 +346,7 @@ NS_IMETHODIMP nsImageGTK :: Draw(nsIRenderingContext &aContext,

void nsImageGTK::CompositeImage(nsIImage *aTheImage, nsPoint *aULLocation,nsBlendQuality aBlendQuality)
{
  printf("nsImageGTK::CompositeImage called!\n");
}

//------------------------------------------------------------
@@ -274,8 +365,8 @@ PRUint8 *srcbits;
    mAlphaWidth = aTheMask->GetWidth();
    mAlphaHeight = aTheMask->GetWidth();
    num = mAlphaWidth*mAlphaHeight;
    mARowBytes = aTheMask->GetLineStride();
    mAlphaBits = new unsigned char[mARowBytes * mAlphaHeight];
    mAlphaRowBytes = aTheMask->GetLineStride();
    mAlphaBits = new unsigned char[mAlphaRowBytes * mAlphaHeight];

    srcbits = aTheMask->GetBits();
    memcpy(mAlphaBits,srcbits,num);
@@ -286,7 +377,6 @@ PRUint8 *srcbits;
  return(PR_FALSE);
}


//------------------------------------------------------------

nsresult nsImageGTK::Optimize(nsIDeviceContext* aContext)
+8 −6
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@

#include "X11/Xlib.h"
#include "X11/Xutil.h"
#include <gdk/gdk.h>

#undef Bool

@@ -52,11 +53,11 @@ public:

  virtual nsresult    Optimize(nsIDeviceContext* aContext);
  virtual PRUint8*    GetAlphaBits()      { return mAlphaBits; }
  virtual PRInt32     GetAlphaWidth()     { return 0; }
  virtual PRInt32     GetAlphaHeight()    { return 0; }
  virtual PRInt32     GetAlphaWidth()     { return mAlphaWidth; }
  virtual PRInt32     GetAlphaHeight()    { return mAlphaHeight; }
  virtual PRInt32     GetAlphaXLoc()      { return 0; }
  virtual PRInt32     GetAlphaYLoc()      { return 0; }
  virtual PRInt32     GetAlphaLineStride(){ return 0; }
  virtual PRInt32     GetAlphaLineStride(){ return mAlphaRowBytes; }
  virtual void        CompositeImage(nsIImage *aTheImage,nsPoint *aULLocation,nsBlendQuality aQuality);
  virtual nsIImage*   DuplicateImage() {return(nsnull);}

@@ -92,8 +93,9 @@ private:

 // alpha layer members
  PRUint8    *mAlphaBits;
  GdkPixmap  *mAlphaPixmap;
  PRInt8     mAlphaDepth;        // alpha layer depth
  PRInt16    mARowBytes;
  PRInt16    mAlphaRowBytes;     // alpha bytes per row
  PRInt16    mAlphaWidth;        // alpha layer width
  PRInt16    mAlphaHeight;       // alpha layer height
  nsPoint    mLocation;          // alpha mask location