Make nsImageGTK::LockImagePixels(PR_TRUE) recover the alpha mask if it has been put in a pixmap. Fixes set-as-wallpaper problems with transparency. Bug 250531, r+sr=tor.

This commit is contained in:
bryner%brianryner.com 2004-07-17 21:00:31 +00:00
Родитель 8d85250a37
Коммит bfbb5d039e
1 изменённых файлов: 98 добавлений и 65 удалений

Просмотреть файл

@ -1871,84 +1871,117 @@ nsresult nsImageGTK::Optimize(nsIDeviceContext* aContext)
} }
//------------------------------------------------------------ //------------------------------------------------------------
// lock the image pixels. nothing to do on gtk // lock the image pixels
NS_IMETHODIMP NS_IMETHODIMP
nsImageGTK::LockImagePixels(PRBool aMaskPixels) nsImageGTK::LockImagePixels(PRBool aMaskPixels)
{ {
if (mOptimized && mImagePixmap) { if (!mOptimized)
XImage *ximage, *xmask=0; return NS_OK;
unsigned pix;
ximage = XGetImage(GDK_WINDOW_XDISPLAY(mImagePixmap), if (aMaskPixels) {
GDK_WINDOW_XWINDOW(mImagePixmap), if (mAlphaDepth != 1 || !mAlphaPixmap)
0, 0, mWidth, mHeight, return NS_OK;
AllPlanes, ZPixmap);
if ((mAlphaDepth==1) && mAlphaPixmap) XImage *xmask = XGetImage(GDK_WINDOW_XDISPLAY(mAlphaPixmap),
xmask = XGetImage(GDK_WINDOW_XDISPLAY(mAlphaPixmap), GDK_WINDOW_XWINDOW(mAlphaPixmap),
GDK_WINDOW_XWINDOW(mAlphaPixmap), 0, 0, mWidth, mHeight,
0, 0, mWidth, mHeight, AllPlanes, XYPixmap);
AllPlanes, XYPixmap);
mImageBits = (PRUint8*) new PRUint8[mSizeImage]; mAlphaBits = new PRUint8[mAlphaRowBytes * mHeight];
GdkVisual *visual = gdk_rgb_get_visual(); memset(mAlphaBits, 0, mAlphaRowBytes * mHeight);
GdkColormap *colormap = gdk_rgb_get_cmap();
unsigned redScale, greenScale, blueScale, redFill, greenFill, blueFill; for (PRInt32 y = 0; y < mHeight; ++y) {
redScale = 8 - visual->red_prec; PRUint8 *alphaTarget = mAlphaBits + y*mAlphaRowBytes;
greenScale = 8 - visual->green_prec; PRUint32 alphaBitPos = 7;
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 x = 0; x < mWidth; ++x) {
for (PRInt32 y=0; y<mHeight; y++) { *alphaTarget |= (XGetPixel(xmask, x, y) << alphaBitPos);
PRUint8 *target = mImageBits + y*mRowBytes; if (alphaBitPos-- == 0) {
for (PRInt32 x=0; x<mWidth; x++) { ++alphaTarget;
if (xmask && !XGetPixel(xmask, x, y)) { alphaBitPos = 7;
*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); XDestroyImage(xmask);
if (xmask) return NS_OK;
XDestroyImage(xmask);
} }
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*) new PRUint8[mSizeImage];
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; return NS_OK;
} }