fixed image printing -- with a non-printer hdc

This commit is contained in:
dcone%netscape.com 1999-08-10 21:58:06 +00:00
parent 68b1a9ca9b
commit 9ea877130d
2 changed files with 150 additions and 147 deletions

View File

@ -135,7 +135,7 @@ nsresult nsImageWin :: Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,nsMa
// Initialize the array of indexes into the logical palette
WORD* palIndx = (WORD*)(((LPBYTE)mBHead) + mBHead->biSize);
for (WORD index = 0; index < 256; index++) {
*palIndx++ = index;
*palIndx++ = index;
}
}
@ -170,12 +170,12 @@ nsresult nsImageWin :: Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,nsMa
mColorMap->NumColors = mNumPaletteColors;
mColorMap->Index = nsnull;
if (mColorMap->NumColors > 0) {
mColorMap->Index = new PRUint8[3 * mColorMap->NumColors];
mColorMap->Index = new PRUint8[3 * mColorMap->NumColors];
// XXX Note: I added this because purify claims that we make a
// copy of the memory (which we do!). I'm not sure if this
// matters or not, but this shutup purify.
memset(mColorMap->Index, 0, sizeof(PRUint8) * (3 * mColorMap->NumColors));
// XXX Note: I added this because purify claims that we make a
// copy of the memory (which we do!). I'm not sure if this
// matters or not, but this shutup purify.
memset(mColorMap->Index, 0, sizeof(PRUint8) * (3 * mColorMap->NumColors));
}
}
}
@ -193,7 +193,8 @@ nsresult nsImageWin :: Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,nsMa
* @param aUpdateRect - The update rectangle to use
* @result void
*/
void nsImageWin :: ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect)
void
nsImageWin :: ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect)
{
// XXX Any gamma correction should be done in the image library, and not
// here...
@ -271,6 +272,7 @@ struct MONOBITMAPINFO {
bmiColors[1].rgbReserved = 0;
}
};
struct ALPHA8BITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[256];
@ -294,33 +296,33 @@ struct ALPHA8BITMAPINFO {
}
}
};
// Raster op used with MaskBlt(). Assumes our transparency mask has 0 for the
// opaque pixels and 1 for the transparent pixels. That means we want the
// background raster op (value of 0) to be SRCCOPY, and the foreground raster
// (value of 1) to just use the destination bits
#define MASKBLT_ROP MAKEROP4((DWORD)0x00AA0029, SRCCOPY)
/** ----------------------------------------------------------------
* Create a device dependent windows bitmap
* @update dc - 11/20/98
* @param aSurface - The HDC in the form of a drawing surface used to create the DDB
* @result void
*/
void nsImageWin :: CreateDDB(nsDrawingSurface aSurface)
void
nsImageWin :: CreateDDB(nsDrawingSurface aSurface)
{
HDC TheHDC;
((nsDrawingSurfaceWin *)aSurface)->GetDC(&TheHDC);
if (TheHDC != NULL)
{
if (mSizeImage > 0)
{
if (TheHDC != NULL){
if (mSizeImage > 0){
mHBitmap = ::CreateDIBitmap(TheHDC, mBHead, CBM_INIT, mImageBits, (LPBITMAPINFO)mBHead,
256 == mNumPaletteColors ? DIB_PAL_COLORS : DIB_RGB_COLORS);
if (nsnull != mAlphaBits)
{
mIsOptimized = PR_TRUE;
if (nsnull != mAlphaBits){
if(1==mAlphaDepth){
// Create a monochrome bitmap
// XXX Handle the case of 8-bit alpha...
@ -331,8 +333,8 @@ void nsImageWin :: CreateDDB(nsDrawingSurface aSurface)
::SetDIBits(TheHDC, mAlphaHBitmap, 0, mAlphaHeight, mAlphaBits,
(LPBITMAPINFO)&bmi, DIB_RGB_COLORS);
}
if(8==mAlphaDepth)
{
if(8==mAlphaDepth){
NS_ASSERTION(8 == mAlphaDepth, "unexpected alpha depth");
mAlphaHBitmap = ::CreateBitmap(mAlphaWidth, mAlphaHeight, 1, 8, NULL);
@ -341,17 +343,15 @@ void nsImageWin :: CreateDDB(nsDrawingSurface aSurface)
(LPBITMAPINFO)&bmi, DIB_RGB_COLORS);
}
}
CleanUp(PR_FALSE);
}
((nsDrawingSurfaceWin *)aSurface)->ReleaseDC();
}
}
/** ----------------------------------------------------------------
* Draw the bitmap, this method has a source and destination coordinates
* @update dc - 11/20/98
* @update dc - 08/10/99
* @param aContext - the rendering context to draw with
* @param aSurface - The HDC in a nsDrawingsurfaceWin to copy the bits to.
* @param aSX - source horizontal location
@ -364,44 +364,46 @@ void nsImageWin :: CreateDDB(nsDrawingSurface aSurface)
* @param aDHeight - destination height
* @result NS_OK if the draw worked
*/
NS_IMETHODIMP nsImageWin :: Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
NS_IMETHODIMP
nsImageWin :: Draw(nsIRenderingContext &aContext, nsDrawingSurface aSurface,
PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
{
HDC TheHDC;
HDC TheHDC;
PRInt32 canRaster;
if (mBHead == nsnull)
return NS_ERROR_FAILURE;
// if DC is not for a printer, and the image can be optimized,
((nsDrawingSurfaceWin *)aSurface)->GetDC(&TheHDC);
canRaster = ::GetDeviceCaps(TheHDC, TECHNOLOGY);
if(canRaster != DT_RASPRINTER){
if (mCanOptimize && (nsnull == mHBitmap)) {
CreateDDB(aSurface);
}
}
// If the image can be optimized then make sure we've created the DDB
if (mIsOptimized && (nsnull == mHBitmap))
if (mCanOptimize && (nsnull == mHBitmap))
CreateDDB(aSurface);
((nsDrawingSurfaceWin *)aSurface)->GetDC(&TheHDC);
if (nsnull != TheHDC)
{
if (!IsOptimized())
{
if (nsnull != TheHDC){
if (!IsOptimized()){
DWORD rop = SRCCOPY;
if (nsnull != mAlphaBits){
MONOBITMAPINFO bmi(mAlphaWidth, mAlphaHeight);
if (nsnull != mAlphaBits)
{
MONOBITMAPINFO bmi(mAlphaWidth, mAlphaHeight);
::StretchDIBits(TheHDC, aDX, aDY, aDWidth, aDHeight,
aSX, aSY, aSWidth, aSHeight, mAlphaBits,
(LPBITMAPINFO)&bmi, DIB_RGB_COLORS, SRCAND);
rop = SRCPAINT;
::StretchDIBits(TheHDC, aDX, aDY, aDWidth, aDHeight,aSX, aSY, aSWidth, aSHeight, mAlphaBits,
(LPBITMAPINFO)&bmi, DIB_RGB_COLORS, SRCAND);
rop = SRCPAINT;
}
::StretchDIBits(TheHDC, aDX, aDY, aDWidth, aDHeight,
aSX, aSY, aSWidth, aSHeight, mImageBits,
(LPBITMAPINFO)mBHead, 256 == mNumPaletteColors ? DIB_PAL_COLORS :
DIB_RGB_COLORS, rop);
}
else
{
::StretchDIBits(TheHDC, aDX, aDY, aDWidth, aDHeight,aSX, aSY, aSWidth, aSHeight, mImageBits,
(LPBITMAPINFO)mBHead, 256 == mNumPaletteColors ? DIB_PAL_COLORS:DIB_RGB_COLORS, rop);
} else {
nsIDeviceContext *dx;
aContext.GetDeviceContext(dx);
nsDrawingSurface ds;
@ -409,52 +411,42 @@ NS_IMETHODIMP nsImageWin :: Draw(nsIRenderingContext &aContext, nsDrawingSurface
nsDrawingSurfaceWin *srcDS = (nsDrawingSurfaceWin *)ds;
HDC srcDC;
if (nsnull != srcDS)
{
srcDS->GetDC(&srcDC);
if (nsnull != srcDS) {
srcDS->GetDC(&srcDC);
if (NULL != srcDC)
{
HBITMAP oldbits;
if (NULL != srcDC){
HBITMAP oldbits;
if (nsnull == mAlphaHBitmap)
{
oldbits = (HBITMAP)::SelectObject(srcDC, mHBitmap);
::StretchBlt(TheHDC, aDX, aDY, aDWidth, aDHeight, srcDC, aSX, aSY,
aSWidth, aSHeight, SRCCOPY);
}
else if (gIsWinNT && (aDWidth == aSWidth) && (aDHeight == aSHeight)){
oldbits = (HBITMAP)::SelectObject(srcDC, mHBitmap);
::MaskBlt(TheHDC, aDX, aDY, aDWidth, aDHeight,
srcDC, aSX, aSY, mAlphaHBitmap, aSX, aSY, MASKBLT_ROP);
}
else
{
COLORREF oldTextColor = ::SetTextColor(TheHDC, RGB(0, 0, 0));
COLORREF oldBkColor = ::SetBkColor(TheHDC, RGB(255, 255, 255));
oldbits = (HBITMAP)::SelectObject(srcDC, mAlphaHBitmap);
::StretchBlt(TheHDC, aDX, aDY, aDWidth, aDHeight, srcDC, aSX, aSY,
aSWidth, aSHeight, SRCAND);
::SetTextColor(TheHDC, oldTextColor);
::SetBkColor(TheHDC, oldBkColor);
if (nsnull == mAlphaHBitmap){
oldbits = (HBITMAP)::SelectObject(srcDC, mHBitmap);
::StretchBlt(TheHDC, aDX, aDY, aDWidth, aDHeight, srcDC, aSX, aSY,
aSWidth, aSHeight, SRCCOPY);
} else {
if (gIsWinNT && (aDWidth == aSWidth) && (aDHeight == aSHeight)){
oldbits = (HBITMAP)::SelectObject(srcDC, mHBitmap);
::MaskBlt(TheHDC, aDX, aDY, aDWidth, aDHeight,srcDC, aSX, aSY, mAlphaHBitmap, aSX, aSY, MASKBLT_ROP);
} else {
COLORREF oldTextColor = ::SetTextColor(TheHDC, RGB(0, 0, 0));
COLORREF oldBkColor = ::SetBkColor(TheHDC, RGB(255, 255, 255));
oldbits = (HBITMAP)::SelectObject(srcDC, mAlphaHBitmap);
::StretchBlt(TheHDC, aDX, aDY, aDWidth, aDHeight, srcDC, aSX, aSY,
aSWidth, aSHeight, SRCAND);
::SetTextColor(TheHDC, oldTextColor);
::SetBkColor(TheHDC, oldBkColor);
::SelectObject(srcDC, mHBitmap);
::StretchBlt(TheHDC, aDX, aDY, aDWidth, aDHeight, srcDC, aSX, aSY,
aSWidth, aSHeight, SRCPAINT);
}
::SelectObject(srcDC, oldbits);
srcDS->ReleaseDC();
}
::SelectObject(srcDC, mHBitmap);
::StretchBlt(TheHDC, aDX, aDY, aDWidth, aDHeight, srcDC, aSX, aSY,
aSWidth, aSHeight, SRCPAINT);
}
}
::SelectObject(srcDC, oldbits);
srcDS->ReleaseDC();
}
}
NS_RELEASE(dx);
}
((nsDrawingSurfaceWin *)aSurface)->ReleaseDC();
}
return NS_OK;
}
@ -479,14 +471,16 @@ PRInt32 canRaster;
if (mBHead == nsnull)
return NS_ERROR_FAILURE;
// If the image can be optimized then make sure we've created the DDB
if (mIsOptimized && (nsnull == mHBitmap))
CreateDDB(aSurface);
// if DC is not for a printer, and the image can be optimized,
((nsDrawingSurfaceWin *)aSurface)->GetDC(&TheHDC);
canRaster = ::GetDeviceCaps(TheHDC, TECHNOLOGY);
if(canRaster != DT_RASPRINTER){
if (mCanOptimize && (nsnull == mHBitmap))
CreateDDB(aSurface);
}
if (nsnull != TheHDC){
if (!IsOptimized()){
if (!IsOptimized() || nsnull==mHBitmap){
DWORD rop = SRCCOPY;
if (nsnull != mAlphaBits){
@ -525,61 +519,64 @@ PRInt32 canRaster;
if (nsnull != srcDS){
srcDS->GetDC(&srcDC);
if (NULL != srcDC){
HBITMAP oldBits;
if((8 == mAlphaDepth)&&(nsnull==mAlphaHBitmap)){
mAlphaHBitmap = ::CreateBitmap(mAlphaWidth, mAlphaHeight, 1, 8, NULL);
if (NULL != srcDC){
HBITMAP oldBits;
if((8 == mAlphaDepth)&&(nsnull==mAlphaHBitmap)){
mAlphaHBitmap = ::CreateBitmap(mAlphaWidth, mAlphaHeight, 1, 8, NULL);
ALPHA8BITMAPINFO bmi(mAlphaWidth, mAlphaHeight);
::SetDIBits(TheHDC, mAlphaHBitmap, 0, mAlphaHeight, mAlphaBits,
(LPBITMAPINFO)&bmi, DIB_RGB_COLORS);
}
ALPHA8BITMAPINFO bmi(mAlphaWidth, mAlphaHeight);
::SetDIBits(TheHDC,mAlphaHBitmap,0,mAlphaHeight,mAlphaBits,(LPBITMAPINFO)&bmi,DIB_RGB_COLORS);
}
if (nsnull == mAlphaHBitmap){
canRaster = ::GetDeviceCaps(TheHDC, TECHNOLOGY);
if(canRaster == DT_RASPRINTER){
if(!(GetDeviceCaps(TheHDC,RASTERCAPS) &(RC_BITBLT | RC_STRETCHBLT))) {
// we have an error with the printer not supporting a raster device
if (nsnull == mAlphaHBitmap){
canRaster = ::GetDeviceCaps(TheHDC, TECHNOLOGY);
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);
::StretchBlt(TheHDC, aX, aY, aWidth, aHeight, srcDC, 0, 0,
mBHead->biWidth, mBHead->biHeight, SRCCOPY);
}else{
PrintDDB(aSurface,aX,aY,aWidth,aHeight);
}
}
} else {
PrintDDB(aSurface,aX,aY,aWidth,aHeight);
oldBits = (HBITMAP)::SelectObject(srcDC, mHBitmap);
::StretchBlt(TheHDC,aX,aY,aWidth,aHeight,srcDC,0,0,mBHead->biWidth,mBHead->biHeight,SRCCOPY);
}
} else {
oldBits = (HBITMAP)::SelectObject(srcDC, mHBitmap);
::StretchBlt(TheHDC, aX, aY, aWidth, aHeight, srcDC, 0, 0,
mBHead->biWidth, mBHead->biHeight, SRCCOPY);
}
}else {
/* mAlphaHBitmap > 0 */
if( 1==mAlphaDepth ){
if (gIsWinNT && (aWidth == mBHead->biWidth) && (aHeight == mBHead->biHeight)){
oldBits = (HBITMAP)::SelectObject(srcDC, mHBitmap);
::MaskBlt(TheHDC, aX, aY, aWidth, aHeight,
srcDC, 0, 0, mAlphaHBitmap, 0, 0, MASKBLT_ROP);
}else{
COLORREF oldTextColor = ::SetTextColor(TheHDC, RGB(0, 0, 0));
COLORREF oldBkColor = ::SetBkColor(TheHDC, RGB(255, 255, 255));
oldBits = (HBITMAP)::SelectObject(srcDC, mAlphaHBitmap);
::StretchBlt(TheHDC, aX, aY, aWidth, aHeight, srcDC, 0, 0,
mAlphaWidth, mAlphaHeight, SRCAND);
::SetTextColor(TheHDC, oldTextColor);
::SetBkColor(TheHDC, oldBkColor);
}else{
if( 1==mAlphaDepth ){
if (gIsWinNT && (aWidth == mBHead->biWidth) && (aHeight == mBHead->biHeight)){
oldBits = (HBITMAP)::SelectObject(srcDC, mHBitmap);
::MaskBlt(TheHDC, aX, aY, aWidth, aHeight,
srcDC, 0, 0, mAlphaHBitmap, 0, 0, MASKBLT_ROP);
}else{
COLORREF oldTextColor = ::SetTextColor(TheHDC, RGB(0, 0, 0));
COLORREF oldBkColor = ::SetBkColor(TheHDC, RGB(255, 255, 255));
oldBits = (HBITMAP)::SelectObject(srcDC, mAlphaHBitmap);
::StretchBlt(TheHDC, aX, aY, aWidth, aHeight, srcDC, 0, 0,
mAlphaWidth, mAlphaHeight, SRCAND);
::SetTextColor(TheHDC, oldTextColor);
::SetBkColor(TheHDC, oldBkColor);
::SelectObject(srcDC, mHBitmap);
::StretchBlt(TheHDC, aX, aY, aWidth, aHeight, srcDC, 0, 0,
mBHead->biWidth, mBHead->biHeight, SRCPAINT);
}
} //alphadepth
else if(8==mAlphaDepth){
ALPHA8BITMAPINFO bmi(mAlphaWidth, mAlphaHeight);
::SelectObject(srcDC, mHBitmap);
::StretchBlt(TheHDC, aX, aY, aWidth, aHeight, srcDC, 0, 0,
mBHead->biWidth, mBHead->biHeight, SRCPAINT);
}
}else{
if(8==mAlphaDepth){
ALPHA8BITMAPINFO bmi(mAlphaWidth, mAlphaHeight);
::StretchDIBits(TheHDC, aX, aY, aWidth, aHeight,
0, 0, mAlphaWidth, mAlphaHeight, mAlphaBits,
(LPBITMAPINFO)&bmi, DIB_RGB_COLORS, SRCAND);
// rop = SRCPAINT;
::StretchDIBits(TheHDC, aX, aY, aWidth, aHeight,0, 0, mAlphaWidth, mAlphaHeight, mAlphaBits,
(LPBITMAPINFO)&bmi, DIB_RGB_COLORS, SRCAND);
}
}
}
}
::SelectObject(srcDC, oldBits);
srcDS->ReleaseDC();
::SelectObject(srcDC, oldBits);
srcDS->ReleaseDC();
}
}
NS_RELEASE(dx);
@ -596,11 +593,11 @@ PRInt32 canRaster;
* @update dc - 11/20/98
* @param aContext - The device context to use for the optimization
*/
nsresult nsImageWin :: Optimize(nsIDeviceContext* aContext)
nsresult
nsImageWin :: Optimize(nsIDeviceContext* aContext)
{
// Wait until we're asked to draw before creating the DDB, because
// we don't have an HDC now
mIsOptimized = PR_TRUE;
// Just set the flag sinze we may not have a valid HDC, like at startup, but at drawtime we do have a valid HDC
mCanOptimize = PR_TRUE;
return NS_OK;
}
@ -610,7 +607,8 @@ nsresult nsImageWin :: Optimize(nsIDeviceContext* aContext)
* @param aWidth - The width to calulate the number of bytes from
* @return Number of bytes for the span
*/
PRInt32 nsImageWin :: CalcBytesSpan(PRUint32 aWidth)
PRInt32
nsImageWin :: CalcBytesSpan(PRUint32 aWidth)
{
PRInt32 spanBytes;
@ -631,7 +629,8 @@ PRInt32 nsImageWin :: CalcBytesSpan(PRUint32 aWidth)
* @param aWidth - The width to calulate the number of bytes from
* @return Number of bytes for the span
*/
void nsImageWin :: CleanUp(PRBool aCleanUpAll)
void
nsImageWin :: CleanUp(PRBool aCleanUpAll)
{
// this only happens when we need to clean up everything
if (aCleanUpAll == PR_TRUE){
@ -648,6 +647,7 @@ void nsImageWin :: CleanUp(PRBool aCleanUpAll)
mHBitmap = nsnull;
mAlphaHBitmap = nsnull;
mCanOptimize = PR_FALSE;
mIsOptimized = PR_FALSE;
}
@ -679,13 +679,13 @@ void nsImageWin :: CleanUp(PRBool aCleanUpAll)
* @update - dwc 5/20/99
* @return the result of the operation, if NS_OK, then the pixelmap is unoptimized
*/
nsresult nsImageWin::PrintDDB(nsDrawingSurface aSurface,PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
nsresult
nsImageWin::PrintDDB(nsDrawingSurface aSurface,PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
HDC theHDC;
if (mIsOptimized == PR_TRUE){
if (mHBitmap != nsnull){
if (mHBitmap != nsnull){
ConvertDDBtoDIB(aWidth,aHeight);
((nsDrawingSurfaceWin *)aSurface)->GetDC(&theHDC);
::StretchDIBits(theHDC, aX, aY, aWidth, aHeight,
@ -693,7 +693,8 @@ HDC theHDC;
(LPBITMAPINFO)mBHead, 256 == mNumPaletteColors ? DIB_PAL_COLORS :
DIB_RGB_COLORS, SRCCOPY);
if (mImageBits != nsnull) {
// we are finished with this, so delete it
if (mImageBits != nsnull) {
delete [] mImageBits;
mImageBits = nsnull;
}
@ -708,7 +709,8 @@ HDC theHDC;
* @update - dwc 5/20/99
* @return the result of the operation, if NS_OK, then the pixelmap is unoptimized
*/
nsresult nsImageWin::ConvertDDBtoDIB(PRInt32 aWidth, PRInt32 aHeight)
nsresult
nsImageWin::ConvertDDBtoDIB(PRInt32 aWidth, PRInt32 aHeight)
{
PRInt32 numbytes;
BITMAP srcinfo;

View File

@ -143,7 +143,8 @@ private:
PRInt32 mSizeImage; // number of bytes
PRInt32 mRowBytes; // number of bytes per row
PRUint8* mImageBits; // starting address of DIB bits
PRBool mIsOptimized; // Have we turned our DIB into a GDI?
PRBool mCanOptimize; // Can we convert our DIB to a HBITMAP
PRBool mIsOptimized; // Did we convert our DIB to a HBITMAP
nsColorMap* mColorMap; // Redundant with mColorTable, but necessary
// alpha layer members