зеркало из https://github.com/mozilla/pjs.git
b=98252, r=kmcclusk, sr=attinasi. Added support for fast alpha tiling.
This commit is contained in:
Родитель
fb72d889c4
Коммит
303d368fed
|
@ -517,7 +517,7 @@ nsImageWin :: Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
|
||||||
(LPBITMAPINFO)&bmi, DIB_RGB_COLORS, SRCAND);
|
(LPBITMAPINFO)&bmi, DIB_RGB_COLORS, SRCAND);
|
||||||
rop = SRCPAINT;
|
rop = SRCPAINT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -603,6 +603,10 @@ nsImageWin :: Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** ---------------------------------------------------
|
||||||
|
* This is a helper routine to do the blending for the DrawComposited method
|
||||||
|
* @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, int aX, int aY, int aWidth, int aHeight)
|
||||||
{
|
{
|
||||||
PRInt32 targetRowBytes = ((aWidth * 3) + 3) & ~3;
|
PRInt32 targetRowBytes = ((aWidth * 3) + 3) & ~3;
|
||||||
|
@ -622,7 +626,8 @@ void nsImageWin::DrawComposited24(unsigned char *aBits, int aX, int aY, int aWid
|
||||||
}
|
}
|
||||||
|
|
||||||
/** ---------------------------------------------------
|
/** ---------------------------------------------------
|
||||||
* Do alpha blending by hand
|
* Blend the image into a 24 bit buffer.. using an 8 bit alpha mask
|
||||||
|
* @update 1/04/02 dwc
|
||||||
*/
|
*/
|
||||||
void nsImageWin::DrawComposited(HDC TheHDC, int aDX, int aDY, int aDWidth, int aDHeight,
|
void nsImageWin::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)
|
||||||
|
@ -634,14 +639,14 @@ void nsImageWin::DrawComposited(HDC TheHDC, int aDX, int aDY, int aDWidth, int a
|
||||||
(LPVOID *)&screenBits, NULL, 0);
|
(LPVOID *)&screenBits, NULL, 0);
|
||||||
HBITMAP oldBitmap = (HBITMAP)::SelectObject(memDC, tmpBitmap);
|
HBITMAP oldBitmap = (HBITMAP)::SelectObject(memDC, tmpBitmap);
|
||||||
|
|
||||||
/* Copy from the screen */
|
/* Copy from the HDC */
|
||||||
::StretchBlt(memDC, 0, 0, aSWidth, aSHeight,
|
::StretchBlt(memDC, 0, 0, aSWidth, aSHeight,
|
||||||
TheHDC, aDX, aDY, aDWidth, aDHeight, SRCCOPY);
|
TheHDC, aDX, aDY, aDWidth, aDHeight, SRCCOPY);
|
||||||
|
|
||||||
/* Do composite */
|
/* Do composite */
|
||||||
DrawComposited24(screenBits, aSX, aSY, aSWidth, aSHeight);
|
DrawComposited24(screenBits, aSX, aSY, aSWidth, aSHeight);
|
||||||
|
|
||||||
/* Copy back to the screen */
|
/* Copy back to the HDC */
|
||||||
::StretchBlt(TheHDC, aDX, aDY, aDWidth, aDHeight,
|
::StretchBlt(TheHDC, aDX, aDY, aDWidth, aDHeight,
|
||||||
memDC, 0, 0, aSWidth, aSHeight, SRCCOPY);
|
memDC, 0, 0, aSWidth, aSHeight, SRCCOPY);
|
||||||
|
|
||||||
|
@ -679,10 +684,8 @@ NS_IMETHODIMP nsImageWin::DrawTile(nsIRenderingContext &aContext,
|
||||||
|
|
||||||
|
|
||||||
PRInt32
|
PRInt32
|
||||||
destinationX = 0,
|
destScaledWidth = (int) (mBHead->biWidth*scale),
|
||||||
destinationY = 0,
|
destScaledHeight = (int) (mBHead->biHeight*scale);
|
||||||
destinationWidth = mBHead->biWidth*scale,
|
|
||||||
destinationHeight = mBHead->biHeight*scale;
|
|
||||||
|
|
||||||
PRInt32
|
PRInt32
|
||||||
validX = 0,
|
validX = 0,
|
||||||
|
@ -695,22 +698,20 @@ NS_IMETHODIMP nsImageWin::DrawTile(nsIRenderingContext &aContext,
|
||||||
// has been validated.
|
// has been validated.
|
||||||
if (mDecodedY2 < mBHead->biHeight) {
|
if (mDecodedY2 < mBHead->biHeight) {
|
||||||
validHeight = mDecodedY2 - mDecodedY1;
|
validHeight = mDecodedY2 - mDecodedY1;
|
||||||
destinationHeight = validHeight*scale;
|
destScaledHeight = (int)(validHeight*scale);
|
||||||
}
|
}
|
||||||
if (mDecodedX2 < mBHead->biWidth) {
|
if (mDecodedX2 < mBHead->biWidth) {
|
||||||
validWidth = mDecodedX2 - mDecodedX1;
|
validWidth = mDecodedX2 - mDecodedX1;
|
||||||
destinationHeight = validWidth*scale;
|
destScaledHeight = (int)(validWidth*scale);
|
||||||
}
|
}
|
||||||
if (mDecodedY1 > 0) {
|
if (mDecodedY1 > 0) {
|
||||||
validHeight -= mDecodedY1;
|
validHeight -= mDecodedY1;
|
||||||
destinationY -= mDecodedY1*scale;
|
destScaledHeight = (int)(validHeight*scale);
|
||||||
destinationHeight = validHeight*scale;
|
|
||||||
validY = mDecodedY1;
|
validY = mDecodedY1;
|
||||||
}
|
}
|
||||||
if (mDecodedX1 > 0) {
|
if (mDecodedX1 > 0) {
|
||||||
validWidth -= mDecodedX1;
|
validWidth -= mDecodedX1;
|
||||||
destinationX -= mDecodedX1*scale;
|
destScaledHeight = (int)(validWidth*scale);
|
||||||
destinationHeight = validWidth*scale;
|
|
||||||
validX = mDecodedX1;
|
validX = mDecodedX1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -723,12 +724,13 @@ NS_IMETHODIMP nsImageWin::DrawTile(nsIRenderingContext &aContext,
|
||||||
|
|
||||||
// this is the width and height of the image in pixels
|
// this is the width and height of the image in pixels
|
||||||
// we need to map this to the pixel height of the device
|
// we need to map this to the pixel height of the device
|
||||||
nscoord aWidth = mBHead->biWidth*scale;
|
nscoord imageScaledWidth = (int)(mBHead->biWidth*scale);
|
||||||
nscoord aHeight = mBHead->biHeight*scale;
|
nscoord imageScaledHeight = (int)(mBHead->biHeight*scale);
|
||||||
|
|
||||||
nscoord tileWidth = aTileRect.width;
|
nscoord tileWidth = aTileRect.width;
|
||||||
nscoord tileHeight = aTileRect.height;
|
nscoord tileHeight = aTileRect.height;
|
||||||
|
|
||||||
|
PRBool tryAgain = PR_FALSE;
|
||||||
nsRect destRect,srcRect,tvrect;
|
nsRect destRect,srcRect,tvrect;
|
||||||
HDC TheHDC,offDC,maskDC;
|
HDC TheHDC,offDC,maskDC;
|
||||||
PRInt32 x,y,width,height,canRaster,TileBufferWidth,TileBufferHeight;
|
PRInt32 x,y,width,height,canRaster,TileBufferWidth,TileBufferHeight;
|
||||||
|
@ -740,17 +742,88 @@ NS_IMETHODIMP nsImageWin::DrawTile(nsIRenderingContext &aContext,
|
||||||
tvrect.SetRect(0,0,aX1-aX0,aY1-aY0);
|
tvrect.SetRect(0,0,aX1-aX0,aY1-aY0);
|
||||||
((nsDrawingSurfaceWin *)aSurface)->GetTECHNOLOGY(&canRaster);
|
((nsDrawingSurfaceWin *)aSurface)->GetTECHNOLOGY(&canRaster);
|
||||||
|
|
||||||
|
|
||||||
|
if( mAlphaDepth == 8){
|
||||||
|
/**
|
||||||
|
* do alpha depth equal to 8 here.. this needs some special attention
|
||||||
|
* draw the alpha and the bitmap to an offscreen buffer.. for the blend.. first
|
||||||
|
*/
|
||||||
|
// get the current HDC to draw to..
|
||||||
|
((nsDrawingSurfaceWin *)aSurface)->GetDC(&TheHDC);
|
||||||
|
if (NULL == TheHDC){
|
||||||
|
return (PR_FALSE);
|
||||||
|
}
|
||||||
|
// create a buffer for the blend
|
||||||
|
HDC memDC = CreateCompatibleDC(TheHDC);
|
||||||
|
unsigned char *screenBits;
|
||||||
|
width = aX1-aX0;
|
||||||
|
height = aY1-aY0;
|
||||||
|
ALPHA24BITMAPINFO bmi(width, height);
|
||||||
|
HBITMAP tmpBitmap = ::CreateDIBSection(memDC, (LPBITMAPINFO)&bmi, DIB_RGB_COLORS, (LPVOID *)&screenBits, NULL, 0);
|
||||||
|
HBITMAP oldBitmap = (HBITMAP)::SelectObject(memDC, tmpBitmap);
|
||||||
|
if(0 == tmpBitmap){
|
||||||
|
::DeleteObject(memDC);
|
||||||
|
tryAgain = PR_TRUE;
|
||||||
|
} else {
|
||||||
|
// Copy from the HDC to the memory DC
|
||||||
|
::StretchBlt(memDC, 0, 0, width, height,TheHDC, 0, 0, width, height, SRCCOPY);
|
||||||
|
|
||||||
|
PRInt32 targetRowBytes = ((width * 3) + 3) & ~3;
|
||||||
|
unsigned char *targetRow,*imageRow,*alphaRow;
|
||||||
|
PRInt32 temp1,temp2,imageScaledHeightPlus,imageScaledWidthPlus;
|
||||||
|
|
||||||
|
|
||||||
|
imageScaledHeightPlus = imageScaledHeight + aSYOffset;
|
||||||
|
imageScaledWidthPlus = imageScaledWidth + aSXOffset;
|
||||||
|
temp1 = mRowBytes + 3 * aSXOffset;
|
||||||
|
temp2 = mARowBytes + aSXOffset;
|
||||||
|
|
||||||
|
for (int y = 0,byw=aSYOffset; y < height; y++,byw++) {
|
||||||
|
if(byw >= imageScaledHeightPlus){
|
||||||
|
byw = aSYOffset;
|
||||||
|
}
|
||||||
|
targetRow = screenBits + y * targetRowBytes;
|
||||||
|
imageRow = mImageBits + byw * temp1;
|
||||||
|
alphaRow = mAlphaBits + byw * temp2;
|
||||||
|
|
||||||
|
for (int x=0,bxw=aSXOffset;x<width;x++,targetRow+=3,imageRow+=3,bxw++, alphaRow++) {
|
||||||
|
if(bxw>=imageScaledWidthPlus){
|
||||||
|
bxw = aSXOffset;
|
||||||
|
imageRow = mImageBits + byw * mRowBytes + ((3*bxw)%mRowBytes);
|
||||||
|
alphaRow = mAlphaBits + byw * mARowBytes + (bxw%mRowBytes);
|
||||||
|
}
|
||||||
|
unsigned alpha = *alphaRow;
|
||||||
|
|
||||||
|
MOZ_BLEND(targetRow[0], targetRow[0], imageRow[0], alpha);
|
||||||
|
MOZ_BLEND(targetRow[1], targetRow[1], imageRow[1], alpha);
|
||||||
|
MOZ_BLEND(targetRow[2], targetRow[2], imageRow[2], alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy back to the HDC
|
||||||
|
::StretchBlt(TheHDC, 0, 0, width, height,memDC, 0, 0, width, height, SRCCOPY);
|
||||||
|
|
||||||
|
::SelectObject(memDC, oldBitmap);
|
||||||
|
::DeleteObject(tmpBitmap);
|
||||||
|
::DeleteObject(memDC);
|
||||||
|
|
||||||
|
return(PR_TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// we have to use the old way.. for 256 color mode and printing.. slow, but will always work.
|
// we have to use the old way.. for 256 color mode and printing.. slow, but will always work.
|
||||||
if ((mAlphaDepth>1) || (canRaster==DT_RASPRINTER) || (256==mNumPaletteColors)
|
if ((mAlphaDepth>8) || ((mAlphaDepth==8)&&tryAgain) || (canRaster==DT_RASPRINTER) || (256==mNumPaletteColors)
|
||||||
|| (aWidth>MAX_BUFFER_WIDTH) || (aHeight>MAX_BUFFER_HEIGHT)){
|
|| (imageScaledWidth>MAX_BUFFER_WIDTH) || (imageScaledHeight>MAX_BUFFER_HEIGHT)){
|
||||||
for(y=aY0;y<aY1;y+=aHeight){
|
for(y=aY0;y<aY1;y+=imageScaledHeight){
|
||||||
for(x=aX0;x<aX1;x+=aWidth){
|
for(x=aX0;x<aX1;x+=imageScaledWidth){
|
||||||
Draw(aContext, aSurface,
|
Draw(aContext, aSurface,
|
||||||
0, 0, PR_MIN(validWidth, aX1-x), PR_MIN(validHeight, aY1-y),
|
0, 0, PR_MIN(validWidth, aX1-x), PR_MIN(validHeight, aY1-y),
|
||||||
x, y, PR_MIN(destinationWidth, aX1-x), PR_MIN(destinationHeight, aY1-y));
|
x, y, PR_MIN(destScaledWidth, aX1-x), PR_MIN(destScaledHeight, aY1-y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(PR_TRUE);
|
return(PR_TRUE);
|
||||||
|
} else if(mAlphaDepth == 8 ){
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a larger tile from the smaller one
|
// create a larger tile from the smaller one
|
||||||
|
@ -810,17 +883,17 @@ NS_IMETHODIMP nsImageWin::DrawTile(nsIRenderingContext &aContext,
|
||||||
|
|
||||||
// get the mask into our new tiled mask
|
// get the mask into our new tiled mask
|
||||||
MONOBITMAPINFO bmi(mAlphaWidth,mAlphaHeight);
|
MONOBITMAPINFO bmi(mAlphaWidth,mAlphaHeight);
|
||||||
::StretchDIBits(maskDC, 0, 0, aWidth, aHeight,0, 0,
|
::StretchDIBits(maskDC, 0, 0, imageScaledWidth, imageScaledHeight,0, 0,
|
||||||
mAlphaWidth, mAlphaHeight, mAlphaBits,(LPBITMAPINFO)&bmi, DIB_RGB_COLORS, SRCCOPY);
|
mAlphaWidth, mAlphaHeight, mAlphaBits,(LPBITMAPINFO)&bmi, DIB_RGB_COLORS, SRCCOPY);
|
||||||
|
|
||||||
::BitBlt(maskDC,0,0,aWidth,aHeight,maskDC,0,0,SRCCOPY);
|
::BitBlt(maskDC,0,0,imageScaledWidth,imageScaledHeight,maskDC,0,0,SRCCOPY);
|
||||||
srcRect.SetRect(0,0,aWidth,aHeight);
|
srcRect.SetRect(0,0,imageScaledWidth,imageScaledHeight);
|
||||||
BuildTile(maskDC,srcRect,TileBufferWidth/2,TileBufferHeight/2,SRCCOPY);
|
BuildTile(maskDC,srcRect,TileBufferWidth/2,TileBufferHeight/2,SRCCOPY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// put the initial tile of background image into the offscreen
|
// put the initial tile of background image into the offscreen
|
||||||
if (!IsOptimized() || nsnull==mHBitmap){
|
if (!IsOptimized() || nsnull==mHBitmap){
|
||||||
::StretchDIBits(offDC, 0, 0, aWidth, aHeight,0, 0, aWidth, aHeight, mImageBits,
|
::StretchDIBits(offDC, 0, 0, imageScaledWidth, imageScaledHeight,0, 0, imageScaledWidth, imageScaledHeight, mImageBits,
|
||||||
(LPBITMAPINFO)mBHead, 256 == mNumPaletteColors ? DIB_PAL_COLORS:DIB_RGB_COLORS,
|
(LPBITMAPINFO)mBHead, 256 == mNumPaletteColors ? DIB_PAL_COLORS:DIB_RGB_COLORS,
|
||||||
SRCCOPY);
|
SRCCOPY);
|
||||||
}else{
|
}else{
|
||||||
|
@ -828,11 +901,11 @@ NS_IMETHODIMP nsImageWin::DrawTile(nsIRenderingContext &aContext,
|
||||||
HBITMAP oldBits;
|
HBITMAP oldBits;
|
||||||
|
|
||||||
oldBits = (HBITMAP)::SelectObject(TheHDC, mHBitmap);
|
oldBits = (HBITMAP)::SelectObject(TheHDC, mHBitmap);
|
||||||
::BitBlt(offDC,0,0,aWidth,aHeight,TheHDC,0,0,SRCCOPY);
|
::BitBlt(offDC,0,0,imageScaledWidth,imageScaledHeight,TheHDC,0,0,SRCCOPY);
|
||||||
::SelectObject(TheHDC, oldBits);
|
::SelectObject(TheHDC, oldBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
srcRect.SetRect(0,0,aWidth,aHeight);
|
srcRect.SetRect(0,0,imageScaledWidth,imageScaledHeight);
|
||||||
BuildTile(offDC,srcRect,TileBufferWidth/2,TileBufferHeight/2,SRCCOPY);
|
BuildTile(offDC,srcRect,TileBufferWidth/2,TileBufferHeight/2,SRCCOPY);
|
||||||
|
|
||||||
// now duplicate our tile into the background
|
// now duplicate our tile into the background
|
||||||
|
@ -1304,8 +1377,8 @@ nsImageWin::GetBits()
|
||||||
#ifdef USE_IMG2
|
#ifdef USE_IMG2
|
||||||
NS_IMETHODIMP nsImageWin::DrawToImage(nsIImage* aDstImage, nscoord aDX, nscoord aDY, nscoord aDWidth, nscoord aDHeight)
|
NS_IMETHODIMP nsImageWin::DrawToImage(nsIImage* aDstImage, nscoord aDX, nscoord aDY, nscoord aDWidth, nscoord aDHeight)
|
||||||
{
|
{
|
||||||
PRInt32 canRaster,srcy;
|
PRInt32 srcy;
|
||||||
HBITMAP oldSrcBits, oldDstBits;
|
HBITMAP oldDstBits;
|
||||||
DWORD rop;
|
DWORD rop;
|
||||||
PRInt32 origDHeight = aDHeight;
|
PRInt32 origDHeight = aDHeight;
|
||||||
PRInt32 origDWidth = aDWidth;
|
PRInt32 origDWidth = aDWidth;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче