diff --git a/gfx/src/gtk/nsImageGTK.cpp b/gfx/src/gtk/nsImageGTK.cpp index ebe15a3d1d91..ef70e52ac109 100644 --- a/gfx/src/gtk/nsImageGTK.cpp +++ b/gfx/src/gtk/nsImageGTK.cpp @@ -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; ymImageBits + (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>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; ymImageBits + (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; xmImageBits + (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