Bug 150881 - rendering artifacts painting scaled alpha composited

images on gtk+ and win32.  r=pavlov, sr=bryner, a=asa
This commit is contained in:
tor%cs.brown.edu 2003-11-23 15:23:52 +00:00
Родитель 0b1339f7cf
Коммит cb0625606f
9 изменённых файлов: 274 добавлений и 181 удалений

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

@ -108,7 +108,7 @@ CPPSRCS += \
$(NULL) $(NULL)
endif endif
ifneq (,$(filter gtk gtk2 xlib beos,$(MOZ_WIDGET_TOOLKIT))) ifneq (,$(filter gtk gtk2 xlib beos windows,$(MOZ_WIDGET_TOOLKIT)))
CPPSRCS += imgScaler.cpp CPPSRCS += imgScaler.cpp
endif endif

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

@ -475,8 +475,9 @@ NS_IMETHODIMP nsImageBeOS::DrawToImage(nsIImage *aDstImage, nscoord aDX, nscoord
scaledImage = (PRUint8 *)nsMemory::Alloc(3 * aDWidth * aDHeight); scaledImage = (PRUint8 *)nsMemory::Alloc(3 * aDWidth * aDHeight);
if (!scaledImage) return NS_ERROR_OUT_OF_MEMORY; if (!scaledImage) return NS_ERROR_OUT_OF_MEMORY;
RectStretch(0, 0, mWidth - 1, mHeight - 1, 0, 0, aDWidth - 1, aDHeight - 1, RectStretch(mWidth, mHeight, aDWidth, aDHeight,
mImageBits, mRowBytes, scaledImage, 3 * aDWidth, 24); 0, 0, aDWidth-1, aDHeight-1,
mImageBits, mRowBytes, scaledImage, 3 * aDWidth, 24);
if (mAlphaDepth) { if (mAlphaDepth) {
if (mAlphaDepth == 1) { if (mAlphaDepth == 1) {
@ -492,8 +493,9 @@ NS_IMETHODIMP nsImageBeOS::DrawToImage(nsIImage *aDstImage, nscoord aDX, nscoord
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
RectStretch(0, 0, mWidth - 1, mHeight - 1, 0, 0, aDWidth - 1, aDHeight - 1, RectStretch(mWidth, mHeight, aDWidth, aDHeight,
mAlphaBits, mAlphaRowBytes, scaledAlpha, alphaStride, mAlphaDepth); aDWidth-1, aDHeight-1,
mAlphaBits, mAlphaRowBytes, scaledAlpha, alphaStride, mAlphaDepth);
} }
rgbPtr = scaledImage; rgbPtr = scaledImage;
rgbStride = 3 * aDWidth; rgbStride = 3 * aDWidth;

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

@ -465,8 +465,8 @@ XlibRectStretch(PRInt32 srcWidth, PRInt32 srcHeight,
xd2 = dstWidth-1; xd2 = dstWidth-1;
yd2 = dstHeight-1; yd2 = dstHeight-1;
// fprintf(stderr, "%p (%ld %ld)-(%ld %ld) (%ld %ld)-(%ld %ld)\n", // fprintf(stderr, "XRS %p (%ld %ld)-(%ld %ld) (%ld %ld)-(%ld %ld)\n",
// aDstImage, xs1, ys1, xs2, ys2, xd1, yd1, xd2, yd2); // (void *)aDstImage, xs1, ys1, xs2, ys2, xd1, yd1, xd2, yd2);
startColumn = aDX-dstOrigX; startColumn = aDX-dstOrigX;
startRow = aDY-dstOrigY; startRow = aDY-dstOrigY;
@ -733,7 +733,8 @@ nsImageGTK::Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
if (!scaledRGB) if (!scaledRGB)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
RectStretch(0, 0, mWidth-1, mHeight-1, RectStretch(mWidth, mHeight,
dstWidth, dstHeight,
0, 0, dstWidth-1, dstHeight-1, 0, 0, dstWidth-1, dstHeight-1,
mImageBits, mRowBytes, scaledRGB, 3*dstWidth, 24); mImageBits, mRowBytes, scaledRGB, 3*dstWidth, 24);
@ -801,7 +802,8 @@ nsImageGTK::Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
if (gdk_rgb_get_visual()->depth <= 8) { if (gdk_rgb_get_visual()->depth <= 8) {
PRUint8 *scaledRGB = (PRUint8 *)nsMemory::Alloc(3*dstWidth*dstHeight); PRUint8 *scaledRGB = (PRUint8 *)nsMemory::Alloc(3*dstWidth*dstHeight);
RectStretch(0, 0, mWidth-1, mHeight-1, RectStretch(mWidth, mHeight,
dstWidth, dstHeight,
0, 0, dstWidth-1, dstHeight-1, 0, 0, dstWidth-1, dstHeight-1,
mImageBits, mRowBytes, scaledRGB, 3*dstWidth, 24); mImageBits, mRowBytes, scaledRGB, 3*dstWidth, 24);
@ -1245,10 +1247,10 @@ nsImageGTK::DrawComposited(nsIRenderingContext &aContext,
readWidth = aDWidth; readWidth = aDWidth;
readHeight = aDHeight; readHeight = aDHeight;
// fprintf(stderr, "aX=%d aY=%d, aWidth=%u aHeight=%u\n", aX, aY, aWidth, aHeight); // fprintf(stderr, "dstOrigX=%d dstOrigY=%d, dstWidth=%u dstHeight=%u\n", dstOrigX, dstOrigY, dstWidth, dstHeight);
// fprintf(stderr, "surfaceWidth=%u surfaceHeight=%u\n", surfaceWidth, surfaceHeight); // fprintf(stderr, "srcWidth=%u srcHeight=%u\n", srcWidth, srcHeight);
// fprintf(stderr, "readX=%u readY=%u readWidth=%u readHeight=%u destX=%u destY=%u\n\n", // fprintf(stderr, "readX=%u readY=%u readWidth=%u readHeight=%u destX=%u destY=%u\n\n",
// readX, readY, readWidth, readHeight, destX, destY); // readX, readY, readWidth, readHeight, destX, destY);
XImage *ximage = XGetImage(dpy, drawable, XImage *ximage = XGetImage(dpy, drawable,
readX, readY, readWidth, readHeight, readX, readY, readWidth, readHeight,
@ -1283,11 +1285,15 @@ nsImageGTK::DrawComposited(nsIRenderingContext &aContext,
nsMemory::Free(scaledAlpha); nsMemory::Free(scaledAlpha);
return; return;
} }
RectStretch(x1, y1, x2-1, y2-1, RectStretch(srcWidth, srcHeight,
0, 0, readWidth-1, readHeight-1, dstWidth, dstHeight,
destX, destY,
destX+aDWidth-1, destY+aDHeight-1,
mImageBits, mRowBytes, scaledImage, 3*readWidth, 24); mImageBits, mRowBytes, scaledImage, 3*readWidth, 24);
RectStretch(x1, y1, x2-1, y2-1, RectStretch(srcWidth, srcHeight,
0, 0, readWidth-1, readHeight-1, dstWidth, dstHeight,
destX, destY,
destX+aDWidth-1, destY+aDHeight-1,
mAlphaBits, mAlphaRowBytes, scaledAlpha, readWidth, 8); mAlphaBits, mAlphaRowBytes, scaledAlpha, readWidth, 8);
imageOrigin = scaledImage; imageOrigin = scaledImage;
imageStride = 3*readWidth; imageStride = 3*readWidth;

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

@ -35,23 +35,26 @@ Fast Bitmap Stretching
Tomas Mšller Tomas Mšller
*/ */
#define sign(x) ((x)>0 ? 1:-1) static void
Stretch24(unsigned x1, unsigned x2, unsigned y1, unsigned y2,
unsigned yr, unsigned yw,
unsigned aStartRow, unsigned aStartColumn, unsigned aEndColumn,
unsigned char *aSrcImage, unsigned aSrcStride,
unsigned char *aDstImage, unsigned aDstStride);
void RectStretch(long xs1,long ys1,long xs2,long ys2, static void
long xd1,long yd1,long xd2,long yd2, Stretch8(unsigned x1, unsigned x2, unsigned y1, unsigned y2,
unsigned char *aSrcImage, unsigned aSrcStride, unsigned yr, unsigned yw,
unsigned char *aDstImage, unsigned aDstStride, unsigned aStartRow, unsigned aStartColumn, unsigned aEndColumn,
unsigned aDepth); unsigned char *aSrcImage, unsigned aSrcStride,
unsigned char *aDstImage, unsigned aDstStride);
static void Stretch24(long x1,long x2,long y1,long y2,long yr,long yw, static void
unsigned char *aSrcImage, unsigned aSrcStride, Stretch1(unsigned x1, unsigned x2, unsigned y1, unsigned y2,
unsigned char *aDstImage, unsigned aDstStride); unsigned yr, unsigned yw,
static void Stretch8(long x1,long x2,long y1,long y2,long yr,long yw, unsigned aStartRow, unsigned aStartColumn, unsigned aEndColumn,
unsigned char *aSrcImage, unsigned aSrcStride, unsigned char *aSrcImage, unsigned aSrcStride,
unsigned char *aDstImage, unsigned aDstStride); unsigned char *aDstImage, unsigned aDstStride);
static void Stretch1(long x1,long x2,long y1,long y2,long yr,long yw,
unsigned char *aSrcImage, unsigned aSrcStride,
unsigned char *aDstImage, unsigned aDstStride);
/********************************************************** /**********************************************************
RectStretch enlarges or diminishes a source rectangle of a bitmap to RectStretch enlarges or diminishes a source rectangle of a bitmap to
@ -63,58 +66,78 @@ static void Stretch1(long x1,long x2,long y1,long y2,long yr,long yw,
then stretching that bitmap in y-direction. then stretching that bitmap in y-direction.
Entry: Entry:
xs1,ys1 - first point of source rectangle aSrcWidth, aSrcHeight - size of entire original image
xs2,ys2 - second point of source rectangle aDstWidth, aDstHeight - size of entire scaled image
xd1,yd1 - first point of destination rectangle
xd2,yd2 - second point of destination rectangle aStartColumn, aStartRow - upper corner of desired area (inclusive)
aEndColumn, aEndRow - bottom corner of desired area (inclusive)
unsigned char *aSrcImage, aSrcStride - start of original image data
unsigned char *aDstStride, aDstStride - start of desired area image data
unsigned aDepth - bit depth of image (24, 8, or 1)
**********************************************************/ **********************************************************/
void NS_GFX_(void)
RectStretch(long xs1,long ys1,long xs2,long ys2, RectStretch(unsigned aSrcWidth, unsigned aSrcHeight,
long xd1,long yd1,long xd2,long yd2, unsigned aDstWidth, unsigned aDstHeight,
unsigned aStartColumn, unsigned aStartRow,
unsigned aEndColumn, unsigned aEndRow,
unsigned char *aSrcImage, unsigned aSrcStride, unsigned char *aSrcImage, unsigned aSrcStride,
unsigned char *aDstImage, unsigned aDstStride, unsigned char *aDstImage, unsigned aDstStride,
unsigned aDepth) unsigned aDepth)
{ {
long dx,dy,e,d,dx2; int e;
short sx,sy; unsigned dx, dy;
void (*Stretch)(long x1,long x2,long y1,long y2,long yr,long yw, void (*Stretch)(unsigned x1, unsigned x2, unsigned y1, unsigned y2,
unsigned char *aSrcImage, unsigned aSrcStride, unsigned yr, unsigned yw,
unsigned char *aDstImage, unsigned aDstStride); unsigned aStartRow, unsigned aStartColumn,
unsigned aEndColumn,
unsigned char *aSrcImage, unsigned aSrcStride,
unsigned char *aDstImage, unsigned aDstStride);
// fprintf(stderr, "(%ld %ld)-(%ld %ld) (%ld %ld)-(%ld %ld) %d %d %d\n", unsigned xs1, ys1, xs2, ys2, xd1, yd1, xd2, yd2;
// xs1, ys1, xs2, ys2, xd1, yd1, xd2, yd2,
// aSrcStride, aDstStride, aDepth);
switch (aDepth) { xs1 = ys1 = xd1 = yd1 = 0;
case 24: xs2 = aSrcWidth - 1;
Stretch = Stretch24; ys2 = aSrcHeight - 1;
break; xd2 = aDstWidth - 1;
case 8: yd2 = aDstHeight - 1;
Stretch = Stretch8;
break; // fprintf(stderr, "RS (%d %d)-(%d %d) (%d %d)-(%d %d) %d %d %d\n",
case 1: // xs1, ys1, xs2, ys2, xd1, yd1, xd2, yd2,
Stretch = Stretch1; // aSrcStride, aDstStride, aDepth);
break;
default: switch (aDepth) {
return; case 24:
} Stretch = Stretch24;
dx = abs((int)(yd2-yd1)); break;
dy = abs((int)(ys2-ys1)); case 8:
sx = sign(yd2-yd1); Stretch = Stretch8;
sy = sign(ys2-ys1); break;
e = dy-dx; case 1:
dx2 = dx; Stretch = Stretch1;
dy += 1; break;
if (!dx2) dx2=1; default:
for (d=0; d<=dx; d++) { return;
Stretch(xd1,xd2,xs1,xs2,ys1,yd1,aSrcImage,aSrcStride,aDstImage,aDstStride); }
while (e>=0) { dx = yd2 - yd1;
ys1 += sy; dy = ys2 - ys1;
e -= dx2; e = dy - dx;
dy += 1;
if (!dx)
dx = 1;
for (yd1 = 0; yd1 <= aEndRow; yd1++) {
if (yd1 >= aStartRow)
Stretch(xd1, xd2, xs1, xs2, ys1, yd1,
aStartRow, aStartColumn, aEndColumn,
aSrcImage, aSrcStride, aDstImage, aDstStride);
while (e >= 0) {
ys1++;
e -= dx;
}
e += dy;
} }
yd1 += sx;
e += dy;
}
} }
/********************************************************** /**********************************************************
@ -128,88 +151,98 @@ RectStretch(long xs1,long ys1,long xs2,long ys2,
yw - y-coordinate of destination line yw - y-coordinate of destination line
**********************************************************/ **********************************************************/
static void static void
Stretch24(long x1,long x2,long y1,long y2,long yr,long yw, Stretch24(unsigned x1, unsigned x2, unsigned y1, unsigned y2,
unsigned yr, unsigned yw,
unsigned aStartRow, unsigned aStartColumn, unsigned aEndColumn,
unsigned char *aSrcImage, unsigned aSrcStride, unsigned char *aSrcImage, unsigned aSrcStride,
unsigned char *aDstImage, unsigned aDstStride) unsigned char *aDstImage, unsigned aDstStride)
{ {
long dx,dy,e,d,dx2; int e;
short sx,sy; unsigned dx, dy, d;
unsigned char *src, *dst; unsigned char *src, *dst;
dx = abs((int)(x2-x1));
dy = abs((int)(y2-y1)); dx = x2 - x1;
sx = 3*sign(x2-x1); dy = y2 - y1;
sy = 3*sign(y2-y1); e = dy - dx;
e = dy-dx; dy += 1;
dx2 = dx; src = aSrcImage + yr * aSrcStride + 3 * y1;
dy += 1; dst = aDstImage + (yw - aStartRow) * aDstStride;
src=aSrcImage+yr*aSrcStride+3*y1; if (!dx)
dst=aDstImage+yw*aDstStride+3*x1; dx = 1;
if (!dx2) dx2=1; for (d = 0; d <= aEndColumn; d++) {
for (d=0; d<=dx; d++) { if (d >= aStartColumn) {
dst[0] = src[0]; *dst++ = src[0];
dst[1] = src[1]; *dst++ = src[1];
dst[2] = src[2]; *dst++ = src[2];
while (e>=0) { }
src += sy; while (e >= 0) {
e -= dx2; src += 3;
e -= dx;
}
e += dy;
} }
dst += sx;
e += dy;
}
} }
static void static void
Stretch8(long x1,long x2,long y1,long y2,long yr,long yw, Stretch8(unsigned x1, unsigned x2, unsigned y1, unsigned y2,
unsigned char *aSrcImage, unsigned aSrcStride, unsigned yr, unsigned yw,
unsigned char *aDstImage, unsigned aDstStride) unsigned aStartRow, unsigned aStartColumn, unsigned aEndColumn,
{
long dx,dy,e,d,dx2;
short sx,sy;
unsigned char *src, *dst;
dx = abs((int)(x2-x1));
dy = abs((int)(y2-y1));
sx = sign(x2-x1);
sy = sign(y2-y1);
e = dy-dx;
dx2 = dx;
dy += 1;
src=aSrcImage+yr*aSrcStride+y1;
dst=aDstImage+yw*aDstStride+x1;
if (!dx2) dx2=1;
for (d=0; d<=dx; d++) {
*dst = *src;
while (e>=0) {
src += sy;
e -= dx2;
}
dst += sx;
e += dy;
}
}
static void
Stretch1(long x1,long x2,long y1,long y2,long yr,long yw,
unsigned char *aSrcImage, unsigned aSrcStride, unsigned char *aSrcImage, unsigned aSrcStride,
unsigned char *aDstImage, unsigned aDstStride) unsigned char *aDstImage, unsigned aDstStride)
{ {
long dx,dy,e,d,dx2; int e;
short sx,sy; unsigned dx, dy, d;
dx = abs((int)(x2-x1)); unsigned char *src, *dst;
dy = abs((int)(y2-y1));
sx = sign(x2-x1); dx = x2 - x1;
sy = sign(y2-y1); dy = y2 - y1;
e = dy-dx; e = dy - dx;
dx2 = dx; dy += 1;
dy += 1; src = aSrcImage + yr * aSrcStride + y1;
if (!dx2) dx2=1; dst = aDstImage + (yw - aStartRow) * aDstStride;
for (d=0; d<=dx; d++) { if (!dx)
if (*(aSrcImage+yr*aSrcStride+(y1>>3)) & 1<<(7-y1&0x7)) dx = 1;
*(aDstImage+yw*aDstStride+(x1>>3)) |= 1<<(7-x1&0x7); for (d = 0; d <= aEndColumn; d++) {
while (e>=0) { if (d >= aStartColumn) {
y1 += sy; *dst = *src;
e -= dx2; dst++;
}
while (e >= 0) {
src++;
e -= dx;
}
e += dy;
}
}
static void
Stretch1(unsigned x1, unsigned x2, unsigned y1, unsigned y2,
unsigned yr, unsigned yw,
unsigned aStartRow, unsigned aStartColumn, unsigned aEndColumn,
unsigned char *aSrcImage, unsigned aSrcStride,
unsigned char *aDstImage, unsigned aDstStride)
{
int e;
unsigned dx, dy, d;
dx = x2 - x1;
dy = y2 - y1;
e = dy - dx;
dy += 1;
if (!dx)
dx = 1;
for (d = 0; d <= aEndColumn; d++) {
if ((d >= aStartColumn) &&
(*(aSrcImage + yr * aSrcStride + (y1 >> 3)) & 1 << (7 - y1 & 0x7)))
*(aDstImage +
(yw - aStartRow) * aDstStride +
((x1 - aStartColumn) >> 3))
|= 1 << (7 - x1 & 0x7);
while (e >= 0) {
y1++;
e -= dx;
}
x1++;
e += dy;
} }
x1 += sx;
e += dy;
}
} }

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

@ -20,8 +20,13 @@
* Tim Rowley <tor@cs.brown.edu> * Tim Rowley <tor@cs.brown.edu>
*/ */
void RectStretch(long xs1,long ys1,long xs2,long ys2, #include "nsComObsolete.h"
long xd1,long yd1,long xd2,long yd2,
unsigned char *aSrcImage, unsigned aSrcStride, NS_GFX_(void)
unsigned char *aDstImage, unsigned aDstStride, RectStretch(unsigned aSrcWidth, unsigned aSrcHeight,
unsigned aDepth); unsigned aDstWidth, unsigned aDstHeight,
unsigned aStartColumn, unsigned aStartRow,
unsigned aEndColumn, unsigned aEndRowe,
unsigned char *aSrcImage, unsigned aSrcStride,
unsigned char *aDstImage, unsigned aDstStride,
unsigned aDepth);

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

@ -41,6 +41,7 @@
#include "nsImageWin.h" #include "nsImageWin.h"
#include "nsRenderingContextWin.h" #include "nsRenderingContextWin.h"
#include "nsDeviceContextWin.h" #include "nsDeviceContextWin.h"
#include "imgScaler.h"
static nsresult BuildDIB(LPBITMAPINFOHEADER *aBHead, PRInt32 aWidth, static nsresult BuildDIB(LPBITMAPINFOHEADER *aBHead, PRInt32 aWidth,
PRInt32 aHeight, PRInt32 aDepth, PRInt8 *aNumBitPix); PRInt32 aHeight, PRInt32 aDepth, PRInt8 *aNumBitPix);
@ -636,14 +637,16 @@ nsImageWin::Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
* This is a helper routine to do the blending for the DrawComposited method * This is a helper routine to do the blending for the DrawComposited method
* @update 1/04/02 dwc * @update 1/04/02 dwc
*/ */
void nsImageWin::DrawComposited24(unsigned char *aBits, int aX, int aY, int aWidth, int aHeight) void nsImageWin::DrawComposited24(unsigned char *aBits,
PRUint8 *aImageRGB, PRUint32 aStrideRGB,
PRUint8 *aImageAlpha, PRUint32 aStrideAlpha,
int aWidth, int aHeight)
{ {
PRInt32 targetRowBytes = ((aWidth * 3) + 3) & ~3; PRInt32 targetRowBytes = ((aWidth * 3) + 3) & ~3;
for (int y = 0; y < aHeight; y++) { for (int y = 0; y < aHeight; y++) {
unsigned char *targetRow = aBits + y * targetRowBytes; unsigned char *targetRow = aBits + y * targetRowBytes;
unsigned char *imageRow = mImageBits + (y + aY) * mRowBytes + 3 * aX; unsigned char *imageRow = aImageRGB + y * aStrideRGB;
unsigned char *alphaRow = mAlphaBits + (y + aY) * mARowBytes + aX; unsigned char *alphaRow = aImageAlpha + y * aStrideAlpha;
for (int x = 0; x < aWidth; for (int x = 0; x < aWidth;
x++, targetRow += 3, imageRow += 3, alphaRow++) { x++, targetRow += 3, imageRow += 3, alphaRow++) {
@ -660,14 +663,15 @@ void nsImageWin::DrawComposited24(unsigned char *aBits, int aX, int aY, int aWid
* Blend the image into a 24 bit buffer.. using an 8 bit alpha mask * Blend the image into a 24 bit buffer.. using an 8 bit alpha mask
* @update 1/04/02 dwc * @update 1/04/02 dwc
*/ */
nsresult nsImageWin::DrawComposited(HDC TheHDC, int aDX, int aDY, int aDWidth, int aDHeight, nsresult nsImageWin::DrawComposited(HDC TheHDC, int aDX, int aDY,
int aSX, int aSY, int aSWidth, int aSHeight) int aDWidth, int aDHeight,
int aSX, int aSY, int aSWidth, int aSHeight)
{ {
HDC memDC = ::CreateCompatibleDC(TheHDC); HDC memDC = ::CreateCompatibleDC(TheHDC);
if (!memDC) if (!memDC)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
unsigned char *screenBits; unsigned char *screenBits;
ALPHA24BITMAPINFO bmi(aSWidth, aSHeight); ALPHA24BITMAPINFO bmi(aDWidth, aDHeight);
HBITMAP tmpBitmap = ::CreateDIBSection(memDC, (LPBITMAPINFO)&bmi, DIB_RGB_COLORS, HBITMAP tmpBitmap = ::CreateDIBSection(memDC, (LPBITMAPINFO)&bmi, DIB_RGB_COLORS,
(LPVOID *)&screenBits, NULL, 0); (LPVOID *)&screenBits, NULL, 0);
if (!tmpBitmap) { if (!tmpBitmap) {
@ -682,10 +686,9 @@ nsresult nsImageWin::DrawComposited(HDC TheHDC, int aDX, int aDY, int aDWidth, i
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
/* Copy from the HDC */ /* Copy from the HDC */
BOOL retval = ::StretchBlt(memDC, 0, 0, aSWidth, aSHeight, BOOL retval = ::BitBlt(memDC, 0, 0, aDWidth, aDHeight,
TheHDC, aDX, aDY, aDWidth, aDHeight, SRCCOPY); TheHDC, aDX, aDY, SRCCOPY);
if (!retval) { if (!retval) {
/* select the old object again... */ /* select the old object again... */
::SelectObject(memDC, oldBitmap); ::SelectObject(memDC, oldBitmap);
@ -694,13 +697,53 @@ nsresult nsImageWin::DrawComposited(HDC TheHDC, int aDX, int aDY, int aDWidth, i
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
/* Do composite */ PRUint8 *imageRGB, *imageAlpha;
DrawComposited24(screenBits, aSX, aSY, aSWidth, aSHeight); PRUint32 strideRGB, strideAlpha;
/* Both scaled and unscaled images come through this code - save
work if not scaling */
if ((aSWidth != aDWidth) || (aSHeight != aDHeight)) {
/* Scale our image to match */
imageRGB = (PRUint8 *)nsMemory::Alloc(3*aDWidth*aDHeight);
imageAlpha = (PRUint8 *)nsMemory::Alloc(aDWidth*aDHeight);
if (!imageRGB || !imageAlpha) {
if (imageRGB)
nsMemory::Free(imageRGB);
if (imageAlpha)
nsMemory::Free(imageAlpha);
::SelectObject(memDC, oldBitmap);
::DeleteObject(tmpBitmap);
::DeleteDC(memDC);
return NS_ERROR_FAILURE;
}
strideRGB = 3 * aDWidth;
strideAlpha = aDWidth;
RectStretch(aSWidth, aSHeight, aDWidth, aDHeight, 0, 0, aDWidth-1, aDHeight-1,
mImageBits, mRowBytes, imageRGB, strideRGB, 24);
RectStretch(aSWidth, aSHeight, aDWidth, aDHeight, 0, 0, aDWidth-1, aDHeight-1,
mAlphaBits, mARowBytes, imageAlpha, strideAlpha, 8);
} else {
imageRGB = mImageBits + aSY * mRowBytes + aSX * 3;
imageAlpha = mAlphaBits + aSY * mARowBytes + aSX;
strideRGB = mRowBytes;
strideAlpha = mARowBytes;
}
/* Do composite */
DrawComposited24(screenBits, imageRGB, strideRGB, imageAlpha, strideAlpha,
aDWidth, aDHeight);
if ((aSWidth != aDWidth) || (aSHeight != aDHeight)) {
/* Free scaled images */
nsMemory::Free(imageRGB);
nsMemory::Free(imageAlpha);
}
/* Copy back to the HDC */ /* Copy back to the HDC */
retval = ::StretchBlt(TheHDC, aDX, aDY, aDWidth, aDHeight, retval = ::BitBlt(TheHDC, aDX, aDY, aDWidth, aDHeight,
memDC, 0, 0, aSWidth, aSHeight, SRCCOPY); memDC, 0, 0, SRCCOPY);
if (!retval) { if (!retval) {
::SelectObject(memDC, oldBitmap); ::SelectObject(memDC, oldBitmap);
::DeleteObject(tmpBitmap); ::DeleteObject(tmpBitmap);

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

@ -171,7 +171,10 @@ private:
*/ */
void CreateDDB(nsDrawingSurface aSurface); void CreateDDB(nsDrawingSurface aSurface);
void DrawComposited24(unsigned char *aBits, int aX, int aY, int aWidth, int aHeight); void DrawComposited24(unsigned char *aBits,
PRUint8 *aImageRGB, PRUint32 aStrideRGB,
PRUint8 *aImageAlpha, PRUint32 aStrideAlpha,
int aWidth, int aHeight);
nsresult DrawComposited(HDC TheHDC, int aDX, int aDY, int aDWidth, int aDHeight, nsresult DrawComposited(HDC TheHDC, int aDX, int aDY, int aDWidth, int aDHeight,
int aSX, int aSY, int aSWidth, int aSHeight); int aSX, int aSY, int aSWidth, int aSHeight);
static PRBool CanAlphaBlend(void); static PRBool CanAlphaBlend(void);

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

@ -471,9 +471,9 @@ nsImageXlib::DrawScaled(nsIRenderingContext &aContext,
// creation fails for some reason. thus no easy-out "return" // creation fails for some reason. thus no easy-out "return"
if (scaledAlpha) { if (scaledAlpha) {
memset(scaledAlpha, 0, aDHeight*scaledRowBytes); memset(scaledAlpha, 0, aDHeight*scaledRowBytes);
RectStretch(aSX, aSY, aSX+aSWidth-1, aSY+aSHeight-1, RectStretch(mWidth, mHeight, origDWidth, origDHeight,
0, 0, aDWidth-1, aDHeight-1, aDX + aDWidth - 1, aDY + aDHeight - 1,
mAlphaBits, mAlphaRowBytes, scaledAlpha, scaledRowBytes, 1); mAlphaBits, mAlphaRowBytes, scaledAlpha, scaledRowBytes, 1);
pixmap = XCreatePixmap(mDisplay, DefaultRootWindow(mDisplay), pixmap = XCreatePixmap(mDisplay, DefaultRootWindow(mDisplay),
aDWidth, aDHeight, 1); aDWidth, aDHeight, 1);
@ -533,8 +533,8 @@ nsImageXlib::DrawScaled(nsIRenderingContext &aContext,
PRUint8 *scaledRGB = (PRUint8 *)nsMemory::Alloc(3*aDWidth*aDHeight); PRUint8 *scaledRGB = (PRUint8 *)nsMemory::Alloc(3*aDWidth*aDHeight);
if (scaledRGB && gc) { if (scaledRGB && gc) {
RectStretch(aSX, aSY, aSX+aSWidth-1, aSY+aSHeight-1, RectStretch(mWidth, mHeight, origDWidth, origDHeight,
0, 0, aDWidth-1, aDHeight-1, aDX + aDWidth - 1, aDY + aDHeight - 1,
mImageBits, mRowBytes, scaledRGB, 3*aDWidth, 24); mImageBits, mRowBytes, scaledRGB, 3*aDWidth, 24);
Drawable drawable; drawing->GetDrawable(drawable); Drawable drawable; drawing->GetDrawable(drawable);
@ -1046,11 +1046,11 @@ nsImageXlib::DrawComposited(nsIRenderingContext &aContext,
nsMemory::Free(scaledAlpha); nsMemory::Free(scaledAlpha);
return; return;
} }
RectStretch(x1, y1, x2-1, y2-1, RectStretch(aSWidth, aSHeight, aDWidth, aDHeight,
0, 0, readWidth-1, readHeight-1, 0, 0, aDWidth-1, aDHeight-1,
mImageBits, mRowBytes, scaledImage, 3*readWidth, 24); mImageBits, mRowBytes, scaledImage, 3*readWidth, 24);
RectStretch(x1, y1, x2-1, y2-1, RectStretch(x1, y1, x2-1, y2-1,
0, 0, readWidth-1, readHeight-1, 0, 0, aDWidth-1, aDHeight-1,
mAlphaBits, mAlphaRowBytes, scaledAlpha, readWidth, 8); mAlphaBits, mAlphaRowBytes, scaledAlpha, readWidth, 8);
imageOrigin = scaledImage; imageOrigin = scaledImage;
imageStride = 3*readWidth; imageStride = 3*readWidth;
@ -1536,7 +1536,7 @@ NS_IMETHODIMP nsImageXlib::DrawToImage(nsIImage* aDstImage,
if (!scaledImage) if (!scaledImage)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
RectStretch(0, 0, mWidth-1, mHeight-1, 0, 0, aDWidth-1, aDHeight-1, RectStretch(mWidth, mHeight, aDWidth, aDHeight, aDWidth-1, aDHeight-1,
mImageBits, mRowBytes, scaledImage, 3*aDWidth, 24); mImageBits, mRowBytes, scaledImage, 3*aDWidth, 24);
if (mAlphaDepth) { if (mAlphaDepth) {
@ -1551,7 +1551,7 @@ NS_IMETHODIMP nsImageXlib::DrawToImage(nsIImage* aDstImage,
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
RectStretch(0, 0, mWidth-1, mHeight-1, 0, 0, aDWidth-1, aDHeight-1, RectStretch(mWidth, mHeight, aDWidth, aDHeight, aDWidth-1, aDHeight-1,
mAlphaBits, mAlphaRowBytes, scaledAlpha, alphaStride, mAlphaBits, mAlphaRowBytes, scaledAlpha, alphaStride,
mAlphaDepth); mAlphaDepth);
} }

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

@ -1166,8 +1166,9 @@ nsXPrintContext::DrawImageBitsScaled(xGC *xgc, nsIImage *aImage,
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
RectStretch(aSX, aSY, aSX+aSWidth-1, aSY+aSHeight-1, RectStretch(aSWidth, aSHeight,
0, 0, (aDWidth-1), (aDHeight-1), aDWidth, aDHeight,
0, 0, aDWidth-1, aDHeight-1,
srcimg_data, srcimg_bytes_per_line, srcimg_data, srcimg_bytes_per_line,
dstimg_data, dstimg_bytes_per_line, dstimg_data, dstimg_bytes_per_line,
imageDepth); imageDepth);