зеркало из https://github.com/mozilla/gecko-dev.git
bug=102321 Speed up the background tiling r=kmcclusky sr=attinasi
This commit is contained in:
Родитель
df2c867541
Коммит
50b46f9fc1
|
@ -40,9 +40,6 @@
|
|||
#include "nsImageWin.h"
|
||||
#include "nsRenderingContextWin.h"
|
||||
|
||||
#define MAX_BUFFER_WIDTH 128
|
||||
#define MAX_BUFFER_HEIGHT 128
|
||||
|
||||
static nsresult BuildDIB(LPBITMAPINFOHEADER *aBHead,PRInt32 aWidth,PRInt32 aHeight,PRInt32 aDepth,PRInt8 *aNumBitPix);
|
||||
|
||||
|
||||
|
@ -661,25 +658,29 @@ NS_IMETHODIMP nsImageWin :: Draw(nsIRenderingContext &aContext, nsDrawingSurface
|
|||
NS_IMETHODIMP nsImageWin::DrawTile(nsIRenderingContext &aContext,
|
||||
nsDrawingSurface aSurface,
|
||||
PRInt32 aSXOffset, PRInt32 aSYOffset,
|
||||
const nsRect &aTileRect)
|
||||
const nsRect &aDestRect)
|
||||
{
|
||||
float scale;
|
||||
|
||||
{
|
||||
unsigned char *targetRow,*imageRow,*alphaRow;
|
||||
PRBool result;
|
||||
PRInt32 numTiles,x0,y0,x1,y1,destScaledWidth,destScaledHeight;
|
||||
PRInt32 validWidth,validHeight,validX,validY,targetRowBytes;
|
||||
PRInt32 temp1,temp2,ScaledTileHeight_Offset,ScaledTileWidth_Offset;
|
||||
PRInt32 x,y,width,height,canRaster;
|
||||
nsCOMPtr<nsIDeviceContext> theDeviceContext;
|
||||
HDC theHDC;
|
||||
nsRect destRect,srcRect;
|
||||
nscoord ScaledTileWidth,ScaledTileHeight;
|
||||
|
||||
aContext.GetDeviceContext(*getter_AddRefs(theDeviceContext));
|
||||
theDeviceContext->GetCanonicalPixelScale(scale);
|
||||
}
|
||||
|
||||
destScaledWidth = PR_MAX(PRInt32(mBHead->biWidth*scale), 1);
|
||||
destScaledHeight = PR_MAX(PRInt32(mBHead->biHeight*scale), 1);
|
||||
|
||||
PRInt32
|
||||
destScaledWidth = PR_MAX(int(mBHead->biWidth*scale), 1),
|
||||
destScaledHeight = PR_MAX(int(mBHead->biHeight*scale), 1);
|
||||
|
||||
PRInt32
|
||||
validX = 0,
|
||||
validY = 0,
|
||||
validWidth = mBHead->biWidth,
|
||||
validX = 0;
|
||||
validY = 0;
|
||||
validWidth = mBHead->biWidth;
|
||||
validHeight = mBHead->biHeight;
|
||||
|
||||
|
||||
|
@ -687,92 +688,88 @@ NS_IMETHODIMP nsImageWin::DrawTile(nsIRenderingContext &aContext,
|
|||
// has been validated.
|
||||
if (mDecodedY2 < mBHead->biHeight) {
|
||||
validHeight = mDecodedY2 - mDecodedY1;
|
||||
destScaledHeight = PR_MAX(int(validHeight*scale), 1);
|
||||
destScaledHeight = PR_MAX(PRInt32(validHeight*scale), 1);
|
||||
}
|
||||
if (mDecodedX2 < mBHead->biWidth) {
|
||||
validWidth = mDecodedX2 - mDecodedX1;
|
||||
destScaledWidth = PR_MAX(int(validWidth*scale), 1);
|
||||
destScaledWidth = PR_MAX(PRInt32(validWidth*scale), 1);
|
||||
}
|
||||
if (mDecodedY1 > 0) {
|
||||
validHeight -= mDecodedY1;
|
||||
destScaledHeight = PR_MAX(int(validHeight*scale), 1);
|
||||
destScaledHeight = PR_MAX(PRInt32(validHeight*scale), 1);
|
||||
validY = mDecodedY1;
|
||||
}
|
||||
if (mDecodedX1 > 0) {
|
||||
validWidth -= mDecodedX1;
|
||||
destScaledWidth = PR_MAX(int(validWidth*scale), 1);
|
||||
destScaledWidth = PR_MAX(PRInt32(validWidth*scale), 1);
|
||||
validX = mDecodedX1;
|
||||
}
|
||||
|
||||
// put the width and hieght into the devices coordinates
|
||||
|
||||
PRInt32 aY0 = aTileRect.y - aSYOffset,
|
||||
aX0 = aTileRect.x - aSXOffset,
|
||||
aY1 = aTileRect.y + aTileRect.height,
|
||||
aX1 = aTileRect.x + aTileRect.width;
|
||||
// put the DestRect into absolute coordintes of the device
|
||||
|
||||
y0 = aDestRect.y - aSYOffset;
|
||||
x0 = aDestRect.x - aSXOffset;
|
||||
y1 = aDestRect.y + aDestRect.height;
|
||||
x1 = aDestRect.x + aDestRect.width;
|
||||
|
||||
// this is the width and height of the image in pixels
|
||||
// we need to map this to the pixel height of the device
|
||||
nscoord imageScaledWidth = PR_MAX(int(mBHead->biWidth*scale), 1);
|
||||
nscoord imageScaledHeight = PR_MAX(int(mBHead->biHeight*scale), 1);
|
||||
|
||||
nscoord tileWidth = aTileRect.width;
|
||||
nscoord tileHeight = aTileRect.height;
|
||||
|
||||
PRBool tryAgain = PR_FALSE;
|
||||
nsRect destRect,srcRect,tvrect;
|
||||
HDC TheHDC,offDC,maskDC;
|
||||
PRInt32 x,y,width,height,canRaster,TileBufferWidth,TileBufferHeight;
|
||||
HBITMAP maskBits,tileBits,oldBits,oldMaskBits;
|
||||
ScaledTileWidth = PR_MAX(PRInt32(mBHead->biWidth*scale), 1);
|
||||
ScaledTileHeight = PR_MAX(PRInt32(mBHead->biHeight*scale), 1);
|
||||
|
||||
|
||||
|
||||
// The slower tiling will need to be used for the following cases:
|
||||
// 1.) Printers 2.) When in 256 color mode 3.) when the tile is larger than the buffer
|
||||
tvrect.SetRect(0,0,aX1-aX0,aY1-aY0);
|
||||
((nsDrawingSurfaceWin *)aSurface)->GetTECHNOLOGY(&canRaster);
|
||||
|
||||
|
||||
// do alpha depth equal to 8 here.. this needs some special attention
|
||||
|
||||
if ( mAlphaDepth == 8) {
|
||||
unsigned char *screenBits=nsnull;
|
||||
HDC memDC=nsnull;
|
||||
HBITMAP tmpBitmap=nsnull,oldBitmap;
|
||||
unsigned char alpha;
|
||||
|
||||
if (!mImageBits) {
|
||||
ConvertDDBtoDIB();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
// draw the alpha and the bitmap to an offscreen buffer.. for the blend.. first
|
||||
((nsDrawingSurfaceWin *)aSurface)->GetDC(&theHDC);
|
||||
if (theHDC) {
|
||||
// create a buffer for the blend
|
||||
HDC memDC = CreateCompatibleDC(TheHDC);
|
||||
unsigned char *screenBits;
|
||||
width = aX1-aX0;
|
||||
height = aY1-aY0;
|
||||
memDC = CreateCompatibleDC(theHDC);
|
||||
width = x1-x0;
|
||||
height = y1-y0;
|
||||
|
||||
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){
|
||||
tmpBitmap = ::CreateDIBSection(memDC, (LPBITMAPINFO)&bmi, DIB_RGB_COLORS, (LPVOID *)&screenBits, NULL, 0);
|
||||
oldBitmap = (HBITMAP)::SelectObject(memDC, tmpBitmap);
|
||||
}
|
||||
|
||||
if (!tmpBitmap) {
|
||||
if (memDC) {
|
||||
::DeleteObject(memDC);
|
||||
tryAgain = PR_TRUE;
|
||||
}
|
||||
// this failed..and will fall into the slow blitting code
|
||||
NS_WARNING("The Creation of the tmpBitmap failed \n");
|
||||
} else {
|
||||
// Copy from the HDC to the memory DC
|
||||
::StretchBlt(memDC, 0, 0, width, height,TheHDC, 0, 0, width, height, SRCCOPY);
|
||||
::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;
|
||||
targetRowBytes = ((width * 3) + 3) & ~3;
|
||||
ScaledTileHeight_Offset = ScaledTileHeight + aSYOffset;
|
||||
ScaledTileWidth_Offset = ScaledTileWidth + aSXOffset;
|
||||
|
||||
|
||||
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){
|
||||
if (byw >= ScaledTileHeight_Offset) {
|
||||
byw = aSYOffset;
|
||||
}
|
||||
targetRow = screenBits + y * targetRowBytes;
|
||||
|
@ -780,12 +777,12 @@ NS_IMETHODIMP nsImageWin::DrawTile(nsIRenderingContext &aContext,
|
|||
alphaRow = mAlphaBits + byw * temp2;
|
||||
|
||||
for (int x=0,bxw=aSXOffset;x<width;x++,targetRow+=3,imageRow+=3,bxw++, alphaRow++) {
|
||||
if(bxw>=imageScaledWidthPlus){
|
||||
if (bxw>=ScaledTileWidth_Offset) {
|
||||
bxw = aSXOffset;
|
||||
imageRow = mImageBits + byw * mRowBytes + ((3*bxw)%mRowBytes);
|
||||
alphaRow = mAlphaBits + byw * mARowBytes + (bxw%mRowBytes);
|
||||
}
|
||||
unsigned alpha = *alphaRow;
|
||||
alpha = *alphaRow;
|
||||
|
||||
MOZ_BLEND(targetRow[0], targetRow[0], imageRow[0], alpha);
|
||||
MOZ_BLEND(targetRow[1], targetRow[1], imageRow[1], alpha);
|
||||
|
@ -794,87 +791,71 @@ NS_IMETHODIMP nsImageWin::DrawTile(nsIRenderingContext &aContext,
|
|||
}
|
||||
|
||||
// Copy back to the HDC
|
||||
::StretchBlt(TheHDC, 0, 0, width, height,memDC, 0, 0, width, height, SRCCOPY);
|
||||
::StretchBlt(theHDC, 0, 0, width, height,memDC, 0, 0, width, height, SRCCOPY);
|
||||
|
||||
::SelectObject(memDC, oldBitmap);
|
||||
::DeleteObject(tmpBitmap);
|
||||
::DeleteObject(memDC);
|
||||
|
||||
return(PR_TRUE);
|
||||
return(NS_OK);
|
||||
}
|
||||
}
|
||||
|
||||
numTiles = (aDestRect.width*aDestRect.height)/(ScaledTileWidth*ScaledTileHeight);
|
||||
|
||||
// figure out which case to use for tiling
|
||||
PRBool useSlow = PR_FALSE;
|
||||
|
||||
if ((mAlphaDepth>8) || ((mAlphaDepth==8)&&tryAgain) || (canRaster==DT_RASPRINTER)
|
||||
|| (256==mNumPaletteColors)){
|
||||
// CASE 1 -- ALPHA DEPTH IS TO HIGH OR WE ARE PRINTING OR ALPHA ALGORITHM FROM ABOVE FAILED
|
||||
useSlow = PR_TRUE;
|
||||
} else if ( (imageScaledWidth>MAX_BUFFER_WIDTH) || (imageScaledHeight>MAX_BUFFER_HEIGHT)) {
|
||||
if(PR_TRUE != gIsWinNT){
|
||||
// CASE 2 -- THE PLATFORM IS NOT ON NT AND CAN NOT USE A PATBLT
|
||||
useSlow = PR_TRUE;
|
||||
} else {
|
||||
if( (imageScaledWidth < MAX_BUFFER_WIDTH) || (imageScaledHeight < MAX_BUFFER_HEIGHT) ) {
|
||||
// CASE 3 -- THE PLATFORM IS ON NT AND WE HAVE ONE LARGE AND ONE SMALL WIDTH AND HEIGHT
|
||||
if (PatBltTile(aContext,aSurface,aX0,aY0,aX1,aY1)) {
|
||||
return(PR_TRUE);
|
||||
}
|
||||
// If PatBltTile returns PR_FALSE then we must drop through to the slow tiling
|
||||
// code because either the width or height of the tiling buffer has been exceeded
|
||||
useSlow = PR_TRUE;
|
||||
} else {
|
||||
// CASE 4 -- THE PLATFORM IS ON NT AND BOTH THE WIDTH AND HEIGHT ARE LARGE.
|
||||
// -- THIS IS AN ODD CASE.. SEEMS PATBLT WITH LARGER BRUSHES HAS A DIFFICULT TIME
|
||||
// -- AND THE TIMES ARE SLOWER.
|
||||
useSlow = PR_TRUE;
|
||||
}
|
||||
// if alpha is less than 8,not printing, and not 8 bit palette image then we can do
|
||||
// a progressive tile and the tile is at least 4 times smaller than the area to update
|
||||
if ( (mAlphaDepth < 8) && (canRaster!=DT_RASPRINTER) && (256!=mNumPaletteColors) &&
|
||||
(numTiles > 3) ) {
|
||||
result = ProgressiveDoubleBlit(aSurface,aDestRect.width, aDestRect.height,
|
||||
ScaledTileWidth,ScaledTileHeight, x0,y0,x1,y1);
|
||||
if (result ) {
|
||||
return(NS_OK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(useSlow){
|
||||
for(y=aY0;y<aY1;y+=imageScaledHeight){
|
||||
for(x=aX0;x<aX1;x+=imageScaledWidth){
|
||||
// if we got to this point.. everything else failed.. and the slow blit backstop
|
||||
// will finish this tiling
|
||||
for (y=y0;y<y1;y+=ScaledTileHeight) {
|
||||
for (x=x0;x<x1;x+=ScaledTileWidth) {
|
||||
Draw(aContext, aSurface,
|
||||
0, 0, PR_MIN(validWidth, aX1-x), PR_MIN(validHeight, aY1-y),
|
||||
x, y, PR_MIN(destScaledWidth, aX1-x), PR_MIN(destScaledHeight, aY1-y));
|
||||
0, 0, PR_MIN(validWidth, x1-x), PR_MIN(validHeight, y1-y),
|
||||
x, y, PR_MIN(destScaledWidth, x1-x), PR_MIN(destScaledHeight, y1-y));
|
||||
}
|
||||
}
|
||||
return(PR_TRUE);
|
||||
return(NS_OK);
|
||||
}
|
||||
|
||||
/** ---------------------------------------------------
|
||||
* See documentation in nsImageWin.h
|
||||
* @update 4/16/02 dwc
|
||||
*/
|
||||
PRBool
|
||||
nsImageWin::ProgressiveDoubleBlit(nsDrawingSurface aSurface,
|
||||
PRInt32 aDestBufferWidth, PRInt32 aDestBufferHeight,
|
||||
PRInt32 aScaledTileWidth,PRInt32 aScaledTileHeight,
|
||||
PRInt32 aX0,PRInt32 aY0,
|
||||
PRInt32 aX1,PRInt32 aY1)
|
||||
{
|
||||
PRInt32 x,y,width,height;
|
||||
nsRect destRect,srcRect;
|
||||
HDC theHDC,offDC,maskDC;
|
||||
HBITMAP maskBits,tileBits,oldBits,oldMaskBits;
|
||||
|
||||
// create a larger tile from the smaller one
|
||||
((nsDrawingSurfaceWin *)aSurface)->GetDC(&TheHDC);
|
||||
if (NULL == TheHDC){
|
||||
((nsDrawingSurfaceWin *)aSurface)->GetDC(&theHDC);
|
||||
if (NULL == theHDC) {
|
||||
return (PR_FALSE);
|
||||
}
|
||||
|
||||
// IF WE MADE IT THIS FAR.. A PROGRESSIVE DOUBLING ALGORITHM WILL BE USED TO TILE
|
||||
|
||||
// so we will create a screen compatible bitmap and then install this into the offscreen DC
|
||||
tvrect.SetRect(0,0,aX1-aX0,aY1-aY0);
|
||||
offDC = ::CreateCompatibleDC(TheHDC);
|
||||
offDC = ::CreateCompatibleDC(theHDC);
|
||||
|
||||
if (NULL ==offDC) {
|
||||
return (PR_FALSE);
|
||||
}
|
||||
|
||||
if (tileWidth < tvrect.width){
|
||||
TileBufferWidth = MAX_BUFFER_WIDTH;
|
||||
} else {
|
||||
TileBufferWidth = tileWidth;
|
||||
}
|
||||
|
||||
if (tileHeight < tvrect.height){
|
||||
TileBufferHeight = MAX_BUFFER_HEIGHT;
|
||||
} else {
|
||||
TileBufferHeight = tileHeight;
|
||||
}
|
||||
|
||||
tileBits = ::CreateCompatibleBitmap(TheHDC, TileBufferWidth,TileBufferHeight);
|
||||
tileBits = ::CreateCompatibleBitmap(theHDC, aDestBufferWidth,aDestBufferHeight);
|
||||
|
||||
if (NULL == tileBits) {
|
||||
::DeleteObject(offDC);
|
||||
|
@ -882,17 +863,16 @@ NS_IMETHODIMP nsImageWin::DrawTile(nsIRenderingContext &aContext,
|
|||
}
|
||||
oldBits =(HBITMAP) ::SelectObject(offDC,tileBits);
|
||||
|
||||
|
||||
if (1==mAlphaDepth) {
|
||||
// larger tile for mask
|
||||
maskDC = ::CreateCompatibleDC(TheHDC);
|
||||
maskDC = ::CreateCompatibleDC(theHDC);
|
||||
if (NULL ==maskDC){
|
||||
::SelectObject(offDC,oldBits);
|
||||
::DeleteObject(tileBits);
|
||||
::DeleteObject(offDC);
|
||||
return (PR_FALSE);
|
||||
}
|
||||
maskBits = ::CreateCompatibleBitmap(TheHDC, TileBufferWidth, TileBufferHeight);
|
||||
maskBits = ::CreateCompatibleBitmap(theHDC, aDestBufferWidth, aDestBufferHeight);
|
||||
if (NULL ==maskBits) {
|
||||
::SelectObject(offDC,oldBits);
|
||||
::DeleteObject(tileBits);
|
||||
|
@ -905,30 +885,29 @@ NS_IMETHODIMP nsImageWin::DrawTile(nsIRenderingContext &aContext,
|
|||
|
||||
// get the mask into our new tiled mask
|
||||
MONOBITMAPINFO bmi(mAlphaWidth,mAlphaHeight);
|
||||
::StretchDIBits(maskDC, 0, 0, imageScaledWidth, imageScaledHeight,0, 0,
|
||||
::StretchDIBits(maskDC, 0, 0, aScaledTileWidth, aScaledTileHeight,0, 0,
|
||||
mAlphaWidth, mAlphaHeight, mAlphaBits,(LPBITMAPINFO)&bmi, DIB_RGB_COLORS, SRCCOPY);
|
||||
|
||||
::BitBlt(maskDC,0,0,imageScaledWidth,imageScaledHeight,maskDC,0,0,SRCCOPY);
|
||||
srcRect.SetRect(0,0,imageScaledWidth,imageScaledHeight);
|
||||
BuildTile(maskDC,srcRect,TileBufferWidth/2,TileBufferHeight/2,SRCCOPY);
|
||||
::BitBlt(maskDC,0,0,aScaledTileWidth,aScaledTileHeight,maskDC,0,0,SRCCOPY);
|
||||
srcRect.SetRect(0,0,aScaledTileWidth,aScaledTileHeight);
|
||||
BuildTile(maskDC,srcRect,aDestBufferWidth/2,aDestBufferHeight/2,SRCCOPY);
|
||||
}
|
||||
|
||||
// put the initial tile of background image into the offscreen
|
||||
if (!IsOptimized() || nsnull==mHBitmap) {
|
||||
::StretchDIBits(offDC, 0, 0, imageScaledWidth, imageScaledHeight,0, 0, imageScaledWidth, imageScaledHeight, mImageBits,
|
||||
::StretchDIBits(offDC, 0, 0, aScaledTileWidth, aScaledTileHeight,0, 0, aScaledTileWidth, aScaledTileHeight, mImageBits,
|
||||
(LPBITMAPINFO)mBHead, 256 == mNumPaletteColors ? DIB_PAL_COLORS:DIB_RGB_COLORS,
|
||||
SRCCOPY);
|
||||
} else {
|
||||
// need to select install this bitmap into this DC first
|
||||
HBITMAP oldBits;
|
||||
|
||||
oldBits = (HBITMAP)::SelectObject(TheHDC, mHBitmap);
|
||||
::BitBlt(offDC,0,0,imageScaledWidth,imageScaledHeight,TheHDC,0,0,SRCCOPY);
|
||||
::SelectObject(TheHDC, oldBits);
|
||||
oldBits = (HBITMAP)::SelectObject(theHDC, mHBitmap);
|
||||
::BitBlt(offDC,0,0,aScaledTileWidth,aScaledTileHeight,theHDC,0,0,SRCCOPY);
|
||||
::SelectObject(theHDC, oldBits);
|
||||
}
|
||||
|
||||
srcRect.SetRect(0,0,imageScaledWidth,imageScaledHeight);
|
||||
BuildTile(offDC,srcRect,TileBufferWidth/2,TileBufferHeight/2,SRCCOPY);
|
||||
srcRect.SetRect(0,0,aScaledTileWidth,aScaledTileHeight);
|
||||
BuildTile(offDC,srcRect,aDestBufferWidth/2,aDestBufferHeight/2,SRCCOPY);
|
||||
|
||||
// now duplicate our tile into the background
|
||||
destRect = srcRect;
|
||||
|
@ -940,7 +919,7 @@ NS_IMETHODIMP nsImageWin::DrawTile(nsIRenderingContext &aContext,
|
|||
for (x=aX0;x<aX1;x+=srcRect.width) {
|
||||
destRect.x = x;
|
||||
destRect.y = y;
|
||||
::BitBlt(TheHDC,x,y,width,height,offDC,0,0,SRCCOPY);
|
||||
::BitBlt(theHDC,x,y,width,height,offDC,0,0,SRCCOPY);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -948,8 +927,8 @@ NS_IMETHODIMP nsImageWin::DrawTile(nsIRenderingContext &aContext,
|
|||
for (x=aX0;x<aX1;x+=srcRect.width) {
|
||||
destRect.x = x;
|
||||
destRect.y = y;
|
||||
::BitBlt(TheHDC,x,y,width,height,maskDC,0,0,SRCAND);
|
||||
::BitBlt(TheHDC,x,y,width,height,offDC,0,0,SRCPAINT);
|
||||
::BitBlt(theHDC,x,y,width,height,maskDC,0,0,SRCAND);
|
||||
::BitBlt(theHDC,x,y,width,height,offDC,0,0,SRCPAINT);
|
||||
}
|
||||
}
|
||||
::SelectObject(maskDC,oldMaskBits);
|
||||
|
@ -961,89 +940,10 @@ NS_IMETHODIMP nsImageWin::DrawTile(nsIRenderingContext &aContext,
|
|||
::DeleteObject(tileBits);
|
||||
::DeleteObject(offDC);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/** ---------------------------------------------------
|
||||
* See documentation in nsIRenderingContext.h
|
||||
* @update 3/16/00 dwc
|
||||
*/
|
||||
PRBool
|
||||
nsImageWin :: PatBltTile(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
|
||||
nscoord aX0,nscoord aY0,nscoord aX1,nscoord aY1)
|
||||
{
|
||||
HDC TheHDC;
|
||||
HBRUSH hBrush,oldBrush;
|
||||
BOOL success,problem=FALSE;
|
||||
DWORD rop;
|
||||
HBITMAP theBits;
|
||||
POINT originalPoint;
|
||||
|
||||
|
||||
if (PR_TRUE != gIsWinNT) {
|
||||
// Windows 98 can not have a brush smaller than 8x8. There is also a know bug
|
||||
// that crashes windows 98
|
||||
// (http://support.microsoft.com/default.aspx?scid=kb;EN-US;q235618)
|
||||
// if you have the wrong driver installed.. and the patBlt
|
||||
// for some reason.. really hits this problem..
|
||||
// Windows 95 seems to have other requirements that may have to do with a power
|
||||
// of 2 size requirement based on some comments in other bugs.
|
||||
// I will have 98 and 95 fail this test because of all the problems those OS's cause
|
||||
// Win 2k, NT and XP all tested and seem to work fine with PatBlt.
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (PR_FALSE==mCanOptimize) {
|
||||
return (PR_FALSE);
|
||||
}
|
||||
|
||||
if (nsnull==mHBitmap) {
|
||||
CreateDDB(aSurface);
|
||||
}
|
||||
|
||||
((nsDrawingSurfaceWin *)aSurface)->GetDC(&TheHDC);
|
||||
if (NULL == TheHDC){
|
||||
return (PR_FALSE);
|
||||
}
|
||||
|
||||
// default copy mode
|
||||
rop = PATCOPY;
|
||||
|
||||
|
||||
// we have to reset the origin here..
|
||||
::SetBrushOrgEx(TheHDC,aX0,aY0,&originalPoint);
|
||||
|
||||
// if there is an alpha layer, lay down the mask first
|
||||
if (1==mAlphaDepth){
|
||||
((nsDrawingSurfaceWin *)aSurface)->GetDC(&TheHDC);
|
||||
theBits = ::CreateBitmap(mAlphaWidth,mAlphaHeight,1,1,NULL);
|
||||
MONOBITMAPINFO bmi(mAlphaWidth, mAlphaHeight);
|
||||
SetDIBits(TheHDC,theBits,0,mAlphaHeight,mAlphaBits,(LPBITMAPINFO)&bmi,DIB_RGB_COLORS);
|
||||
hBrush = CreatePatternBrush(theBits);
|
||||
oldBrush = (HBRUSH)SelectObject(TheHDC,hBrush);
|
||||
success = PatBlt( TheHDC, aX0,aY0,aX1-aX0,aY1-aY0,0xA000C9);
|
||||
SelectObject(TheHDC,oldBrush);
|
||||
DeleteObject(hBrush);
|
||||
DeleteObject(theBits);
|
||||
rop = 0xFA0089;
|
||||
}
|
||||
|
||||
// do a pattern blit
|
||||
if (mHBitmap == NULL) {
|
||||
problem = TRUE;
|
||||
}
|
||||
|
||||
hBrush = CreatePatternBrush(mHBitmap);
|
||||
oldBrush = (HBRUSH)SelectObject(TheHDC,hBrush);
|
||||
success = PatBlt( TheHDC, aX0,aY0,aX1-aX0,aY1-aY0,rop);
|
||||
SelectObject(TheHDC,oldBrush);
|
||||
DeleteObject(hBrush);
|
||||
|
||||
::SetBrushOrgEx(TheHDC,originalPoint.x,originalPoint.y,NULL);
|
||||
|
||||
return(PR_TRUE);
|
||||
}
|
||||
|
||||
|
||||
ALPHABLENDPROC nsImageWin::gAlphaBlend = NULL;
|
||||
|
||||
PRBool nsImageWin::CanAlphaBlend(void)
|
||||
|
|
|
@ -126,15 +126,22 @@ public:
|
|||
const nsRect &aTileRect);
|
||||
|
||||
/**
|
||||
* Draw a tiled version of the bitmap, but use the windows specific highly optimized PatBlt
|
||||
* @update - dwc 3/30/00
|
||||
* Progressivly double the bitmap size as we blit.. very fast way to tile
|
||||
* @update - dwc 4/160/02
|
||||
* @param aSurface the surface to blit to
|
||||
* @param aX The destination horizontal location
|
||||
* @param aY The destination vertical location
|
||||
* @param aDestBufferWidth Width of buffer
|
||||
* @param aDestBufferHeight Height of buffer
|
||||
* @param aScaledTileWidth Width of tile
|
||||
* @param aScaledTileHeight Height of tile
|
||||
* @param aX0,aY0,aX1,aY1 Coordinates of screen to blit to
|
||||
* @return if TRUE, no errors
|
||||
*/
|
||||
PRBool PatBltTile(nsIRenderingContext &aContext, nsDrawingSurface aSurface,nscoord aX0,nscoord aY0,nscoord aX1,nscoord aY1);
|
||||
|
||||
PRBool ProgressiveDoubleBlit(nsDrawingSurface aSurface,
|
||||
PRInt32 aDestBufferWidth, PRInt32 aDestBufferHeight,
|
||||
PRInt32 aScaledTileWidth,PRInt32 aScaledTileHeight,
|
||||
PRInt32 aX0,PRInt32 aY0,
|
||||
PRInt32 aX1,PRInt32 aY1);
|
||||
|
||||
/**
|
||||
* Return the header size of the Device Independent Bitmap(DIB).
|
||||
|
|
Загрузка…
Ссылка в новой задаче