Bug 187819. Make nsImageWin::Draw easier to read. r=smontagu, sr=roc+moz

This commit is contained in:
paper%animecity.nu 2003-02-24 08:14:55 +00:00
Родитель d1ea99b3c8
Коммит 9d1714d8b4
1 изменённых файлов: 125 добавлений и 136 удалений

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

@ -440,40 +440,37 @@ nsImageWin :: CreateDDB(nsDrawingSurface aSurface)
* @update 3/27/00 dwc * @update 3/27/00 dwc
*/ */
NS_IMETHODIMP NS_IMETHODIMP
nsImageWin :: Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface, nsImageWin::Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight, PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight) PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
{ {
HDC TheHDC; if (mBHead == nsnull ||
PRInt32 canRaster,srcy; aSWidth < 0 || aDWidth < 0 || aSHeight < 0 || aDHeight < 0)
HBITMAP oldBits;
DWORD rop;
PRInt32 origSHeight = aSHeight, origDHeight = aDHeight;
PRInt32 origSWidth = aSWidth, origDWidth = aDWidth;
if (mBHead == nsnull || aSWidth < 0 || aDWidth < 0 || aSHeight < 0 || aDHeight < 0)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
if (0 == aSWidth || 0 == aDWidth || 0 == aSHeight || 0 == aDHeight) if (0 == aSWidth || 0 == aDWidth || 0 == aSHeight || 0 == aDHeight)
return NS_OK; return NS_OK;
PRInt32 origSHeight = aSHeight, origDHeight = aDHeight;
PRInt32 origSWidth = aSWidth, origDWidth = aDWidth;
// limit the size of the blit to the amount of the image read in // limit the size of the blit to the amount of the image read in
if (aSX + aSWidth > mDecodedX2) { if (aSX + aSWidth > mDecodedX2) {
aDWidth -= ((aSX + aSWidth - mDecodedX2)*origDWidth)/origSWidth; aDWidth -= ((aSX + aSWidth - mDecodedX2) * origDWidth) / origSWidth;
aSWidth -= (aSX + aSWidth) - mDecodedX2; aSWidth -= (aSX + aSWidth) - mDecodedX2;
} }
if (aSX < mDecodedX1) { if (aSX < mDecodedX1) {
aDX += ((mDecodedX1 - aSX)*origDWidth)/origSWidth; aDX += ((mDecodedX1 - aSX) * origDWidth) / origSWidth;
aSX = mDecodedX1; aSX = mDecodedX1;
} }
if (aSY + aSHeight > mDecodedY2) { if (aSY + aSHeight > mDecodedY2) {
aDHeight -= ((aSY + aSHeight - mDecodedY2)*origDHeight)/origSHeight; aDHeight -= ((aSY + aSHeight - mDecodedY2) * origDHeight) / origSHeight;
aSHeight -= (aSY + aSHeight) - mDecodedY2; aSHeight -= (aSY + aSHeight) - mDecodedY2;
} }
if (aSY < mDecodedY1) { if (aSY < mDecodedY1) {
aDY += ((mDecodedY1 - aSY)*origDHeight)/origSHeight; aDY += ((mDecodedY1 - aSY) * origDHeight) / origSHeight;
aSY = mDecodedY1; aSY = mDecodedY1;
} }
@ -481,88 +478,78 @@ nsImageWin :: Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
return NS_OK; return NS_OK;
// Translate to bottom-up coordinates for the source bitmap // Translate to bottom-up coordinates for the source bitmap
srcy = mBHead->biHeight - (aSY + aSHeight); PRInt32 srcy = mBHead->biHeight - (aSY + aSHeight);
HDC TheHDC;
// if DC is not for a printer, and the image can be optimized,
((nsDrawingSurfaceWin *)aSurface)->GetDC(&TheHDC); ((nsDrawingSurfaceWin *)aSurface)->GetDC(&TheHDC);
if (!TheHDC)
return NS_ERROR_FAILURE;
// find out if the surface is a printer. // find out if the surface is a printer.
PRInt32 canRaster;
((nsDrawingSurfaceWin *)aSurface)->GetTECHNOLOGY(&canRaster); ((nsDrawingSurfaceWin *)aSurface)->GetTECHNOLOGY(&canRaster);
if (nsnull != TheHDC){
PRBool didComposite = PR_FALSE; PRBool didComposite = PR_FALSE;
if (!mIsOptimized || nsnull==mHBitmap){ if (!mIsOptimized || !mHBitmap) {
rop = SRCCOPY; DWORD rop = SRCCOPY;
if (mAlphaBits) {
if (nsnull != mAlphaBits){ if (1 == mAlphaDepth) {
if (1==mAlphaDepth){
if(canRaster == DT_RASPRINTER){
MONOBITMAPINFO bmi(mBHead->biWidth, mBHead->biHeight); MONOBITMAPINFO bmi(mBHead->biWidth, mBHead->biHeight);
CompositeBitsInMemory(TheHDC,aDX,aDY,aDWidth,aDHeight,aSX,aSY,aSWidth,aSHeight,srcy,
mAlphaBits,&bmi,mImageBits,mBHead,mNumPaletteColors); if (canRaster == DT_RASPRINTER) {
CompositeBitsInMemory(TheHDC, aDX, aDY, aDWidth, aDHeight,
aSX, aSY, aSWidth, aSHeight,
srcy, mAlphaBits, &bmi, mImageBits, mBHead,
mNumPaletteColors);
didComposite = PR_TRUE; didComposite = PR_TRUE;
} else { } else {
// Put the mask down
::StretchDIBits(TheHDC, aDX, aDY, aDWidth, aDHeight,
MONOBITMAPINFO bmi(mBHead->biWidth, mBHead->biHeight); aSX, srcy, aSWidth, aSHeight, mAlphaBits,
::StretchDIBits(TheHDC, aDX, aDY, aDWidth, aDHeight,aSX, srcy,aSWidth, aSHeight, mAlphaBits,
(LPBITMAPINFO)&bmi, DIB_RGB_COLORS, SRCAND); (LPBITMAPINFO)&bmi, DIB_RGB_COLORS, SRCAND);
rop = SRCPAINT; rop = SRCPAINT;
} }
} } else if (8 == mAlphaDepth) {
}
if (PR_FALSE == didComposite){
if (8==mAlphaDepth) {
nsresult rv = DrawComposited(TheHDC, aDX, aDY, aDWidth, aDHeight, nsresult rv = DrawComposited(TheHDC, aDX, aDY, aDWidth, aDHeight,
aSX, srcy, aSWidth, aSHeight); aSX, srcy, aSWidth, aSHeight);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
((nsDrawingSurfaceWin *)aSurface)->ReleaseDC(); ((nsDrawingSurfaceWin *)aSurface)->ReleaseDC();
return rv; return rv;
} }
didComposite = PR_TRUE;
}
} // mAlphaBits
// Put the Image down
if (!didComposite) {
::StretchDIBits(TheHDC, aDX, aDY, aDWidth, aDHeight,
aSX, srcy, aSWidth, aSHeight, mImageBits,
(LPBITMAPINFO)mBHead, 256 == mNumPaletteColors ?
DIB_PAL_COLORS : DIB_RGB_COLORS, rop);
}
} else { } else {
::StretchDIBits(TheHDC, aDX, aDY, aDWidth, aDHeight,aSX, srcy, aSWidth, aSHeight, mImageBits, // Optimized. mHBitmap contains the DDB
(LPBITMAPINFO)mBHead, 256 == mNumPaletteColors ? DIB_PAL_COLORS : DWORD rop = SRCCOPY;
DIB_RGB_COLORS, rop);
}
}
}else{
nsIDeviceContext *dx;
aContext.GetDeviceContext(dx);
nsDrawingSurface ds;
NS_STATIC_CAST(nsDeviceContextWin*, dx)->GetDrawingSurface(aContext, ds);
nsDrawingSurfaceWin *srcDS = (nsDrawingSurfaceWin *)ds;
HDC srcDC;
if (nsnull != srcDS){
srcDS->GetDC(&srcDC);
rop = SRCCOPY;
if (nsnull != mAlphaBits){
if (1==mAlphaDepth){
MONOBITMAPINFO bmi(mBHead->biWidth, mBHead->biHeight);
if (canRaster == DT_RASPRINTER) { if (canRaster == DT_RASPRINTER) {
// To Printer
if (mAlphaBits && mAlphaDepth == 1) {
MONOBITMAPINFO bmi(mBHead->biWidth, mBHead->biHeight); MONOBITMAPINFO bmi(mBHead->biWidth, mBHead->biHeight);
if (mImageBits != nsnull) { if (mImageBits) {
CompositeBitsInMemory(TheHDC,aDX,aDY,aDWidth,aDHeight,aSX,aSY,aSWidth,aSHeight,srcy, CompositeBitsInMemory(TheHDC, aDX, aDY, aDWidth, aDHeight,
mAlphaBits,&bmi,mImageBits,mBHead,mNumPaletteColors); aSX, aSY, aSWidth, aSHeight, srcy,
mAlphaBits, &bmi, mImageBits, mBHead,
mNumPaletteColors);
didComposite = PR_TRUE; didComposite = PR_TRUE;
} else { } else {
ConvertDDBtoDIB(); // Create mImageBits ConvertDDBtoDIB(); // Create mImageBits
if (mImageBits != nsnull) { if (mImageBits) {
CompositeBitsInMemory(TheHDC,aDX,aDY,aDWidth,aDHeight,aSX,aSY,aSWidth,aSHeight,srcy, CompositeBitsInMemory(TheHDC, aDX, aDY, aDWidth, aDHeight,
mAlphaBits,&bmi,mImageBits,mBHead,mNumPaletteColors); aSX, aSY, aSWidth, aSHeight, srcy,
mAlphaBits,
&bmi, mImageBits, mBHead,
mNumPaletteColors);
// Clean up the image bits // Clean up the image bits
delete [] mImageBits; delete [] mImageBits;
mImageBits = nsnull; mImageBits = nsnull;
@ -570,61 +557,63 @@ nsImageWin :: Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
} else { } else {
NS_WARNING("Could not composite bits in memory because conversion to DIB failed\n"); NS_WARNING("Could not composite bits in memory because conversion to DIB failed\n");
} }
} } // mImageBits
} // mAlphaBits && mAlphaDepth == 1
if (!didComposite &&
(GetDeviceCaps(TheHDC, RASTERCAPS) & (RC_BITBLT | RC_STRETCHBLT)))
PrintDDB(aSurface, aDX, aDY, aDWidth, aDHeight, rop);
} else { } else {
::StretchDIBits(TheHDC, aDX, aDY, aDWidth, aDHeight,aSX, srcy, aSWidth, aSHeight, mAlphaBits, // we are going to the device that created this DDB
// Get srcDC from the drawing surface of aContext's (RenderingContext)
// DeviceContext. Should be the same each time.
nsIDeviceContext *dx;
aContext.GetDeviceContext(dx);
nsDrawingSurface ds;
NS_STATIC_CAST(nsDeviceContextWin*, dx)->GetDrawingSurface(aContext, ds);
nsDrawingSurfaceWin *srcDS = (nsDrawingSurfaceWin *)ds;
if (!srcDS) {
NS_RELEASE(dx);
((nsDrawingSurfaceWin *)aSurface)->ReleaseDC();
return NS_ERROR_FAILURE;
}
HDC srcDC;
srcDS->GetDC(&srcDC);
// Draw the Alpha/Mask
if (mAlphaBits && mAlphaDepth == 1) {
MONOBITMAPINFO bmi(mBHead->biWidth, mBHead->biHeight);
::StretchDIBits(TheHDC, aDX, aDY, aDWidth, aDHeight,
aSX, srcy, aSWidth, aSHeight, mAlphaBits,
(LPBITMAPINFO)&bmi, DIB_RGB_COLORS, SRCAND); (LPBITMAPINFO)&bmi, DIB_RGB_COLORS, SRCAND);
rop = SRCPAINT; rop = SRCPAINT;
} }
}
} // Draw the Image
// if this is for a printer.. we have to convert it back to a DIB HBITMAP oldBits = (HBITMAP)::SelectObject(srcDC, mHBitmap);
if (canRaster == DT_RASPRINTER){
if (!(GetDeviceCaps(TheHDC,RASTERCAPS) &(RC_BITBLT | RC_STRETCHBLT))) {
// we have an error with the printer not supporting a raster device
} else {
// if we did not convert to a DDB already
if (nsnull == mHBitmap) {
oldBits = (HBITMAP)::SelectObject(srcDC, mHBitmap);
if (8 == mAlphaDepth) { if (8 == mAlphaDepth) {
BLENDFUNCTION blendFunction; BLENDFUNCTION blendFunction;
blendFunction.BlendOp = AC_SRC_OVER; blendFunction.BlendOp = AC_SRC_OVER;
blendFunction.BlendFlags = 0; blendFunction.BlendFlags = 0;
blendFunction.SourceConstantAlpha = 255; blendFunction.SourceConstantAlpha = 255;
blendFunction.AlphaFormat = 1 /*AC_SRC_ALPHA*/; blendFunction.AlphaFormat = 1; // AC_SRC_ALPHA
gAlphaBlend(TheHDC, aDX, aDY, aDWidth, aDHeight, srcDC, aSX, aSY, aSWidth, aSHeight, blendFunction); gAlphaBlend(TheHDC, aDX, aDY, aDWidth, aDHeight,
srcDC, aSX, aSY, aSWidth, aSHeight, blendFunction);
} else { } else {
::StretchBlt(TheHDC, aDX, aDY, aDWidth, aDHeight, srcDC, aSX, aSY,aSWidth, aSHeight, rop); ::StretchBlt(TheHDC, aDX, aDY, aDWidth, aDHeight,
srcDC, aSX, aSY, aSWidth, aSHeight, rop);
} }
}else{
if (! didComposite)
PrintDDB(aSurface,aDX,aDY,aDWidth,aDHeight,rop);
}
}
} else {
// we are going to the device that created this DDB
oldBits = (HBITMAP)::SelectObject(srcDC, mHBitmap);
if (8 == mAlphaDepth) {
BLENDFUNCTION blendFunction;
blendFunction.BlendOp = AC_SRC_OVER;
blendFunction.BlendFlags = 0;
blendFunction.SourceConstantAlpha = 255;
blendFunction.AlphaFormat = 1 /*AC_SRC_ALPHA*/;
gAlphaBlend(TheHDC, aDX, aDY, aDWidth, aDHeight, srcDC, aSX, aSY, aSWidth, aSHeight, blendFunction);
} else {
::StretchBlt(TheHDC,aDX,aDY,aDWidth,aDHeight,srcDC,aSX,aSY,aSWidth,aSHeight,rop);
}
}
::SelectObject(srcDC, oldBits); ::SelectObject(srcDC, oldBits);
srcDS->ReleaseDC(); srcDS->ReleaseDC();
}
NS_RELEASE(dx); NS_RELEASE(dx);
} }
((nsDrawingSurfaceWin *)aSurface)->ReleaseDC();
} }
((nsDrawingSurfaceWin *)aSurface)->ReleaseDC();
return NS_OK; return NS_OK;
} }