Bug 86600 - nsImageGTK::DrawToImage() was only updating the server side

pixmap.  Add code for the client side copy.  r=pavlov, sr=blizzard, a=asa
This commit is contained in:
tor%cs.brown.edu 2001-06-20 01:56:39 +00:00
Родитель 093f0c93a0
Коммит 9815acc8a3
1 изменённых файлов: 95 добавлений и 0 удалений

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

@ -1720,6 +1720,101 @@ NS_IMETHODIMP nsImageGTK::DrawToImage(nsIImage* aDstImage,
gdk_gc_unref(gc); gdk_gc_unref(gc);
// need to copy the mImageBits in case we're rendered scaled
PRUint8 *scaledImage = 0, *scaledAlpha = 0;
PRUint8 *rgbPtr=0, *alphaPtr=0;
PRUint32 rgbStride, alphaStride;
if ((aDWidth != mWidth) || (aDHeight != mHeight)) {
// scale factor in DrawTo... start scaling
scaledImage = (PRUint8 *)nsMemory::Alloc(3*aDWidth*aDHeight);
if (!scaledImage)
return NS_ERROR_OUT_OF_MEMORY;
RectStretch(0, 0, mWidth-1, mHeight-1, 0, 0, aDWidth-1, aDHeight-1,
mImageBits, mRowBytes, scaledImage, 3*aDWidth, 24);
if (mAlphaDepth) {
if (mAlphaDepth==1)
alphaStride = (aDWidth+7)>>3; // round to next byte
else
alphaStride = aDWidth;
scaledAlpha = (PRUint8 *)nsMemory::Alloc(alphaStride*aDHeight);
if (!scaledAlpha) {
nsMemory::Free(scaledImage);
return NS_ERROR_OUT_OF_MEMORY;
}
RectStretch(0, 0, mWidth-1, mHeight-1, 0, 0, aDWidth-1, aDHeight-1,
mAlphaBits, mAlphaRowBytes, scaledAlpha, alphaStride,
mAlphaDepth);
}
rgbPtr = scaledImage;
rgbStride = 3*aDWidth;
alphaPtr = scaledAlpha;
} else {
rgbPtr = mImageBits;
rgbStride = mRowBytes;
alphaPtr = mAlphaBits;
alphaStride = mAlphaRowBytes;
}
// now composite the two images together
switch (mAlphaDepth) {
case 1:
for (int y=0; y<aDHeight; y++) {
PRUint8 *dst = dest->mImageBits + (y+aDY)*dest->mRowBytes + 3*aDX;
PRUint8 *dstAlpha = dest->mAlphaBits + (y+aDY)*dest->mAlphaRowBytes;
PRUint8 *src = rgbPtr + y*rgbStride;
PRUint8 *alpha = alphaPtr + y*alphaStride;
for (int x=0; x<aDWidth; x++, dst+=3, src+=3) {
#define GET_BIT(rowptr, x) (rowptr[(x)>>3] & (1<<(7-(x)&0x7)))
#define SET_BIT(rowptr, x) (rowptr[(x)>>3] |= (1<<(7-(x)&0x7)))
// if this pixel is opaque then copy into the destination image
if (GET_BIT(alpha, x)) {
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
SET_BIT(dstAlpha, aDX+x);
}
#undef GET_BIT
#undef SET_BIT
}
}
break;
case 8:
for (int y=0; y<aDHeight; y++) {
PRUint8 *dst = dest->mImageBits + (y+aDY)*dest->mRowBytes + 3*aDX;
PRUint8 *dstAlpha =
dest->mAlphaBits + (y+aDY)*dest->mAlphaRowBytes + aDX;
PRUint8 *src = rgbPtr + y*rgbStride;
PRUint8 *alpha = alphaPtr + y*alphaStride;
for (int x=0; x<aDWidth; x++, dst+=3, dstAlpha++, src+=3, alpha++) {
// blend this pixel over the destination image
unsigned val = *alpha;
MOZ_BLEND(dst[0], dst[0], src[0], val);
MOZ_BLEND(dst[1], dst[1], src[1], val);
MOZ_BLEND(dst[2], dst[2], src[2], val);
MOZ_BLEND(*dstAlpha, *dstAlpha, val, val);
}
}
break;
case 0:
default:
for (int y=0; y<aDHeight; y++)
memcpy(dest->mImageBits + (y+aDY)*dest->mRowBytes + 3*aDX,
rgbPtr + y*rgbStride,
3*aDWidth);
}
if (scaledAlpha)
nsMemory::Free(scaledAlpha);
if (scaledImage)
nsMemory::Free(scaledImage);
return NS_OK; return NS_OK;
} }
#endif #endif