зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
093f0c93a0
Коммит
9815acc8a3
|
@ -1720,6 +1720,101 @@ NS_IMETHODIMP nsImageGTK::DrawToImage(nsIImage* aDstImage,
|
|||
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче