зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
8d85250a37
Коммит
bfbb5d039e
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче