diff --git a/gfx/src/windows/nsBlenderWin.cpp b/gfx/src/windows/nsBlenderWin.cpp index ea974ff58eb..d130c77fc2f 100644 --- a/gfx/src/windows/nsBlenderWin.cpp +++ b/gfx/src/windows/nsBlenderWin.cpp @@ -58,10 +58,11 @@ HDC srcdc,dstdc; HBITMAP srcbits,dstbits,tb1,tb2; BITMAP srcinfo,dstinfo; nsPoint srcloc,maskloc; -PRInt32 dlinespan,slinespan,mlinespan,numbytes,numlines; +PRInt32 dlinespan,slinespan,mlinespan,numbytes,numlines,level; PRUint8 *s1,*d1,*m1,*srcbytes,*dstbytes; LPBITMAPINFOHEADER srcbinfo,dstbinfo; - +PRUint8 *mask=NULL; +nsColorMap *colormap; // we have to extract the bitmaps from the nsDrawingSurface, which in this case is a hdc srcdc = (HDC)aSrc; @@ -75,7 +76,11 @@ LPBITMAPINFOHEADER srcbinfo,dstbinfo; numbytes = ::GetObject(srcbits,sizeof(BITMAP),&srcinfo); // put into a DIB BuildDIB(&srcbinfo,&srcbytes,srcinfo.bmWidth,srcinfo.bmHeight,srcinfo.bmBitsPixel); - numbytes = ::GetDIBits(srcdc,srcbytes,1,srcinfo.bmHeight,srcbits,(LPBITMAPINFO)srcbinfo,DIB_RGB_COLORS); + + if(srcinfo.bmBitsPixel != 24) + numbytes = ::GetDIBits(srcdc,srcbits,1,srcinfo.bmHeight,srcbytes,(LPBITMAPINFO)srcbinfo,DIB_PAL_COLORS); + else + numbytes = ::GetDIBits(srcdc,srcbits,1,srcinfo.bmHeight,srcbytes,(LPBITMAPINFO)srcbinfo,DIB_RGB_COLORS); // get the HBITMAP, and then grab the information about the destination bitmap tb2 = CreateCompatibleBitmap(aSrc,3,3); @@ -83,19 +88,60 @@ LPBITMAPINFOHEADER srcbinfo,dstbinfo; ::GetObject(dstbits,sizeof(BITMAP),&dstinfo); // put into a DIB BuildDIB(&dstbinfo,&dstbytes,dstinfo.bmWidth,dstinfo.bmHeight,dstinfo.bmBitsPixel); - numbytes = ::GetDIBits(dstdc,dstbytes,1,dstinfo.bmHeight,dstbits,(LPBITMAPINFO)dstbinfo,DIB_RGB_COLORS); + numbytes = ::GetDIBits(dstdc,dstbits,1,dstinfo.bmHeight,dstbytes,(LPBITMAPINFO)dstbinfo,DIB_RGB_COLORS); // calculate the metrics, no mask right now + srcloc.x = aSX; + srcloc.y = aSY; + srcinfo.bmBits = srcbytes; + dstinfo.bmBits = dstbytes; if(CalcAlphaMetrics(&srcinfo,&dstinfo,&srcloc,NULL,&maskloc,&numlines,&numbytes, &s1,&d1,&m1,&slinespan,&dlinespan,&mlinespan)) { // now do the blend - + if ((srcinfo.bmBitsPixel==24) && (dstinfo.bmBitsPixel==24)) + { + if(mask) + { + numbytes/=3; // since the mask is only 8 bits, this routine wants number of pixels + this->Do24BlendWithMask(numlines,numbytes,s1,d1,m1,slinespan,dlinespan,mlinespan,nsHighQual); + } + else + { + level = (PRInt32)(aSrcOpacity*100); + this->Do24Blend(level,numlines,numbytes,s1,d1,slinespan,dlinespan,nsHighQual); + } + } + else + if ((srcinfo.bmBitsPixel==8) && (dstinfo.bmBitsPixel==8)) + { + if(mask) + { + this->Do8BlendWithMask(numlines,numbytes,s1,d1,m1,slinespan,dlinespan,mlinespan,nsHighQual); + } + else + { + level = (PRInt32)(aSrcOpacity*100); + this->Do8Blend(level,numlines,numbytes,s1,d1,slinespan,dlinespan,colormap,nsHighQual); + } + } } + // put the new bits in + ::DeleteObject(dstbits); + dstbits = ::CreateDIBitmap(dstdc, dstbinfo, CBM_INIT, dstbytes, (LPBITMAPINFO)dstbinfo, DIB_RGB_COLORS); + + ::SelectObject(srcdc,srcbits); ::SelectObject(dstdc,dstbits); + + ::DeleteObject(tb1); + ::DeleteObject(tb2); + + // get rid of the DIB's + DeleteDIB(&srcbinfo,&srcbytes); + DeleteDIB(&dstbinfo,&dstbytes); } //------------------------------------------------------------ @@ -182,7 +228,6 @@ PRInt32 spanbytes; return(spanbytes); } - //----------------------------------------------------------- nsresult @@ -191,7 +236,6 @@ nsBlenderWin :: BuildDIB(LPBITMAPINFOHEADER *aBHead,unsigned char **aBits,PRInt PRInt32 numpalletcolors,imagesize,spanbytes; PRUint8 *colortable; - switch (aDepth) { case 8: @@ -220,10 +264,8 @@ PRUint8 *colortable; (*aBHead)->biClrUsed = numpalletcolors; (*aBHead)->biClrImportant = numpalletcolors; - spanbytes = ((*aBHead)->biWidth * (*aBHead)->biBitCount) >> 5; - if (((PRUint32)(*aBHead)->biWidth * (*aBHead)->biBitCount) & 0x1F) - spanbytes++; - spanbytes <<= 2; + spanbytes = CalcBytesSpan(aWidth,aDepth); + imagesize = spanbytes * (*aBHead)->biHeight; // no compression // set the color table in the info header @@ -236,3 +278,573 @@ PRUint8 *colortable; return NS_OK; } + +//------------------------------------------------------------ + +void +nsBlenderWin::DeleteDIB(LPBITMAPINFOHEADER *aBHead,unsigned char **aBits) +{ + + delete[] *aBHead; + aBHead = 0; + delete[] *aBits; + aBits = 0; + +} + +//------------------------------------------------------------ + +// This routine can not be fast enough +void +nsBlenderWin::Do24BlendWithMask(PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRUint8 *aMImage,PRInt32 aSLSpan,PRInt32 aDLSpan,PRInt32 aMLSpan,nsBlendQuality aBlendQuality) +{ +PRUint8 *d1,*d2,*s1,*s2,*m1,*m2; +PRInt32 x,y; +PRUint32 val1,val2; +PRUint32 temp1,numlines,xinc,yinc; +PRInt32 sspan,dspan,mspan; + + sspan = aSLSpan; + dspan = aDLSpan; + mspan = aMLSpan; + + // now go thru the image and blend (remember, its bottom upwards) + s1 = aSImage; + d1 = aDImage; + m1 = aMImage; + + numlines = aNumlines; + xinc = 1; + yinc = 1; + + for (y = 0; y < aNumlines; y++) + { + s2 = s1; + d2 = d1; + m2 = m1; + + for(x=0;x>8; + if(temp1>255) + temp1 = 255; + *d2 = (unsigned char)temp1; + d2++; + s2++; + + temp1 = (((*d2)*val1)+((*s2)*val2))>>8; + if(temp1>255) + temp1 = 255; + *d2 = (unsigned char)temp1; + d2++; + s2++; + + temp1 = (((*d2)*val1)+((*s2)*val2))>>8; + if(temp1>255) + temp1 = 255; + *d2 = (unsigned char)temp1; + d2++; + s2++; + m2++; + } + s1 += sspan; + d1 += dspan; + m1 += mspan; + } +} + +//------------------------------------------------------------ + +// This routine can not be fast enough +void +nsBlenderWin::Do24Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality) +{ +PRUint8 *d1,*d2,*s1,*s2; +PRUint32 val1,val2; +PRInt32 x,y,temp1,numlines,xinc,yinc; + + + aBlendVal = (aBlendVal*255)/100; + val2 = aBlendVal; + val1 = 255-val2; + + // now go thru the image and blend (remember, its bottom upwards) + s1 = aSImage; + d1 = aDImage; + + + numlines = aNumlines; + xinc = 1; + yinc = 1; + + for(y = 0; y < aNumlines; y++) + { + s2 = s1; + d2 = d1; + + for(x = 0; x < aNumbytes; x++) + { + temp1 = (((*d2)*val1)+((*s2)*val2))>>8; + if(temp1>255) + temp1 = 255; + *d2 = (unsigned char)temp1; + + d2++; + s2++; + } + + s1 += aSLSpan; + d1 += aDLSpan; + } +} + +//------------------------------------------------------------ + +// This routine can not be fast enough +void +nsBlenderWin::Do8BlendWithMask(PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRUint8 *aMImage,PRInt32 aSLSpan,PRInt32 aDLSpan,PRInt32 aMLSpan,nsBlendQuality aBlendQuality) +{ +PRUint8 *d1,*d2,*s1,*s2,*m1,*m2; +PRInt32 x,y; +PRUint32 val1,val2,temp1,numlines,xinc,yinc; +PRInt32 sspan,dspan,mspan; + + sspan = aSLSpan; + dspan = aDLSpan; + mspan = aMLSpan; + + // now go thru the image and blend (remember, its bottom upwards) + s1 = aSImage; + d1 = aDImage; + m1 = aMImage; + + numlines = aNumlines; + xinc = 1; + yinc = 1; + + for (y = 0; y < aNumlines; y++) + { + s2 = s1; + d2 = d1; + m2 = m1; + + for(x=0;x>8; + if(temp1>255) + temp1 = 255; + *d2 = (unsigned char)temp1; + d2++; + s2++; + m2++; + } + s1 += sspan; + d1 += dspan; + m1 += mspan; + } +} + +//------------------------------------------------------------ + +extern void inv_colormap(PRInt16 colors,PRUint8 *aCMap,PRInt16 bits,PRUint32 *dist_buf,PRUint8 *aRGBMap ); + +// This routine can not be fast enough +void +nsBlenderWin::Do8Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRInt32 aSLSpan,PRInt32 aDLSpan,nsColorMap *aColorMap,nsBlendQuality aBlendQuality) +{ +PRUint32 r,g,b,r1,g1,b1,i; +PRUint8 *d1,*d2,*s1,*s2; +PRInt32 x,y,val1,val2,numlines,xinc,yinc;; +PRUint8 *mapptr,*invermap; +PRUint32 *distbuffer; +PRUint32 quantlevel,tnum,num,shiftnum; + + aBlendVal = (aBlendVal*255)/100; + val2 = aBlendVal; + val1 = 255-val2; + + // calculate the inverse map + mapptr = aColorMap->Index; + quantlevel = aBlendQuality+2; + shiftnum = (8-quantlevel)+8; + tnum = 2; + for(i=1;iIndex[(3 * i) + 2]; + g = aColorMap->Index[(3 * i) + 1]; + b = aColorMap->Index[(3 * i)]; + + i =(*s2); + r1 = aColorMap->Index[(3 * i) + 2]; + g1 = aColorMap->Index[(3 * i) + 1]; + b1 = aColorMap->Index[(3 * i)]; + + r = ((r*val1)+(r1*val2))>>shiftnum; + if(r>tnum) + r = tnum; + + g = ((g*val1)+(g1*val2))>>shiftnum; + if(g>tnum) + g = tnum; + + b = ((b*val1)+(b1*val2))>>shiftnum; + if(b>tnum) + b = tnum; + + r = (r<<(2*quantlevel))+(g<> nbits; + gcenter = g >> nbits; + bcenter = b >> nbits; + + rdist = r - (rcenter * x + x/2); + gdist = g - (gcenter * x + x/2); + cdist = b - (bcenter * x + x/2); + cdist = rdist*rdist + gdist*gdist + cdist*cdist; + + crinc = 2 * ((rcenter + 1) * xsqr - (r * x)); + cginc = 2 * ((gcenter + 1) * xsqr - (g * x)); + cbinc = 2 * ((bcenter + 1) * xsqr - (b * x)); + + // Array starting points. + cdp = dist_buf + rcenter * rstride + gcenter * gstride + bcenter; + crgbp = aRGBMap + rcenter * rstride + gcenter * gstride + bcenter; + + (void)redloop(); + } +} + +//------------------------------------------------------------ + +// redloop -- loop up and down from red center. +static PRInt32 +redloop() +{ +PRInt32 detect,r,first; +PRInt32 txsqr = xsqr + xsqr; +static PRInt32 rxx; + + detect = 0; + + rdist = cdist; + rxx = crinc; + rdp = cdp; + rrgbp = crgbp; + first = 1; + for (r=rcenter;r=0;r--,rdp-=rstride,rrgbp-=rstride,rxx-=txsqr,rdist-=rxx,first=0) + { + if ( greenloop( first ) ) + detect = 1; + else + if ( detect ) + break; + } + + return detect; +} + +//------------------------------------------------------------ + +// greenloop -- loop up and down from green center. +static PRInt32 +greenloop(PRInt32 aRestart) +{ +PRInt32 detect,g,first; +PRInt32 txsqr = xsqr + xsqr; +static PRInt32 here, min, max; +static PRInt32 ginc, gxx, gcdist; +static PRUint32 *gcdp; +static PRUint8 *gcrgbp; + + if(aRestart) + { + here = gcenter; + min = 0; + max = colormax - 1; + ginc = cginc; + } + + detect = 0; + + + gcdp=rdp; + gdp=rdp; + gcrgbp=rrgbp; + grgbp=rrgbp; + gcdist=rdist; + gdist=rdist; + + // loop up. + for(g=here,gxx=ginc,first=1;g<=max; + g++,gdp+=gstride,gcdp+=gstride,grgbp+=gstride,gcrgbp+=gstride, + gdist+=gxx,gcdist+=gxx,gxx+=txsqr,first=0) + { + if(blueloop(first)) + { + if (!detect) + { + if (g>here) + { + here = g; + rdp = gcdp; + rrgbp = gcrgbp; + rdist = gcdist; + ginc = gxx; + } + detect=1; + } + } + else + if (detect) + { + break; + } + } + + // loop down + gcdist = rdist-gxx; + gdist = gcdist; + gdp=rdp-gstride; + gcdp=gdp; + grgbp=rrgbp-gstride; + gcrgbp = grgbp; + + for (g=here-1,gxx=ginc-txsqr, + first=1;g>=min;g--,gdp-=gstride,gcdp-=gstride,grgbp-=gstride,gcrgbp-=gstride, + gxx-=txsqr,gdist-=gxx,gcdist-=gxx,first=0) + { + if (blueloop(first)) + { + if (!detect) + { + here = g; + rdp = gcdp; + rrgbp = gcrgbp; + rdist = gcdist; + ginc = gxx; + detect = 1; + } + } + else + if ( detect ) + { + break; + } + } + return detect; +} + +//------------------------------------------------------------ + +static PRInt32 +blueloop(PRInt32 aRestart ) +{ +PRInt32 detect,b,i=cindex; +register PRUint32 *dp; +register PRUint8 *rgbp; +register PRInt32 bxx; +PRUint32 bdist; +register PRInt32 txsqr = xsqr + xsqr; +register PRInt32 lim; +static PRInt32 here, min, max; +static PRInt32 binc; + + if (aRestart) + { + here = bcenter; + min = 0; + max = colormax - 1; + binc = cbinc; + } + + detect = 0; + bdist = gdist; + +// Basic loop, finds first applicable cell. + for (b=here,bxx=binc,dp=gdp,rgbp=grgbp,lim=max;b<=lim; + b++,dp++,rgbp++,bdist+=bxx,bxx+=txsqr) + { + if(*dp>bdist) + { + if(b>here) + { + here = b; + gdp = dp; + grgbp = rgbp; + gdist = bdist; + binc = bxx; + } + detect = 1; + break; + } + } + +// Second loop fills in a run of closer cells. +for (;b<=lim;b++,dp++,rgbp++,bdist+=bxx,bxx+=txsqr) + { + if (*dp>bdist) + { + *dp = bdist; + *rgbp = i; + } + else + { + break; + } + } + +// Basic loop down, do initializations here +lim = min; +b = here - 1; +bxx = binc - txsqr; +bdist = gdist - bxx; +dp = gdp - 1; +rgbp = grgbp - 1; + +// The 'find' loop is executed only if we didn't already find something. +if (!detect) + for (;b>=lim;b--,dp--,rgbp--,bxx-=txsqr,bdist-=bxx) + { + if (*dp>bdist) + { + here = b; + gdp = dp; + grgbp = rgbp; + gdist = bdist; + binc = bxx; + detect = 1; + break; + } + } + +// Update loop. +for (;b>=lim;b--,dp--,rgbp--,bxx-=txsqr,bdist-=bxx) + { + if (*dp>bdist) + { + *dp = bdist; + *rgbp = i; + } + else + { + break; + } + } + +// If we saw something, update the edge trackers. +return detect; +} + +//------------------------------------------------------------ + +static void +maxfill(PRUint32 *buffer,PRInt32 side ) +{ +register PRInt32 maxv = ~0L; +register PRInt32 i; +register PRUint32 *bp; + +for (i=side*side*side,bp=buffer;i>0;i--,bp++) + *bp = maxv; +} + +//------------------------------------------------------------ + diff --git a/gfx/src/windows/nsBlenderWin.h b/gfx/src/windows/nsBlenderWin.h index 953dec86cb9..b18e7a61a25 100644 --- a/gfx/src/windows/nsBlenderWin.h +++ b/gfx/src/windows/nsBlenderWin.h @@ -22,6 +22,7 @@ #include "nsIBlender.h" #include "nsPoint.h" #include "nsRect.h" +#include "nsIImage.h" //---------------------------------------------------------------------- @@ -54,8 +55,84 @@ public: PRInt32 CalcBytesSpan(PRUint32 aWidth,PRUint32 aBitsPixel); private: + /** + * Create a DIB header and bits for a bitmap + * @param aBHead information header for the DIB + * @param aBits a handle to the 8 bit pointer for the data bits + * @param aWidth width of the bitmap to create + * @param aHeight Height of the bitmap to create + * @param aDepth Bits per pixel of the bitmap to create + */ nsresult BuildDIB(LPBITMAPINFOHEADER *aBHead,unsigned char **aBits,PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth); + /** + * Delete the DIB header and bits created from BuildDIB + * @param aBHead information header for the DIB + * @param aBits a handle to the 8 bit pointer for the data bits + */ + void DeleteDIB(LPBITMAPINFOHEADER *aBHead,unsigned char **aBits); + + /** + * Blend two 24 bit image arrays using an 8 bit alpha mask + * @param aNumlines Number of lines to blend + * @param aNumberBytes Number of bytes per line to blend + * @param aSImage Pointer to beginning of the source bytes + * @param aDImage Pointer to beginning of the destination bytes + * @param aMImage Pointer to beginning of the mask bytes + * @param aSLSpan number of bytes per line for the source bytes + * @param aDLSpan number of bytes per line for the destination bytes + * @param aMLSpan number of bytes per line for the Mask bytes + * @param aBlendQuality The quality of this blend, this is for tweening if neccesary + */ + void Do24BlendWithMask(PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage, + PRUint8 *aMImage,PRInt32 aSLSpan,PRInt32 aDLSpan,PRInt32 aMLSpan,nsBlendQuality aBlendQuality); + + /** + * Blend two 24 bit image arrays using a passed in blend value + * @param aNumlines Number of lines to blend + * @param aNumberBytes Number of bytes per line to blend + * @param aSImage Pointer to beginning of the source bytes + * @param aDImage Pointer to beginning of the destination bytes + * @param aMImage Pointer to beginning of the mask bytes + * @param aSLSpan number of bytes per line for the source bytes + * @param aDLSpan number of bytes per line for the destination bytes + * @param aMLSpan number of bytes per line for the Mask bytes + * @param aBlendQuality The quality of this blend, this is for tweening if neccesary + */ + void Do24Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage, + PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality); + + + /** + * Blend two 8 bit image arrays using an 8 bit alpha mask + * @param aNumlines Number of lines to blend + * @param aNumberBytes Number of bytes per line to blend + * @param aSImage Pointer to beginning of the source bytes + * @param aDImage Pointer to beginning of the destination bytes + * @param aMImage Pointer to beginning of the mask bytes + * @param aSLSpan number of bytes per line for the source bytes + * @param aDLSpan number of bytes per line for the destination bytes + * @param aMLSpan number of bytes per line for the Mask bytes + * @param aBlendQuality The quality of this blend, this is for tweening if neccesary + */ + void Do8BlendWithMask(PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage, + PRUint8 *aMImage,PRInt32 aSLSpan,PRInt32 aDLSpan,PRInt32 aMLSpan,nsBlendQuality aBlendQuality); + + /** + * Blend two 8 bit image arrays using a passed in blend value + * @param aNumlines Number of lines to blend + * @param aNumberBytes Number of bytes per line to blend + * @param aSImage Pointer to beginning of the source bytes + * @param aDImage Pointer to beginning of the destination bytes + * @param aMImage Pointer to beginning of the mask bytes + * @param aSLSpan number of bytes per line for the source bytes + * @param aDLSpan number of bytes per line for the destination bytes + * @param aMLSpan number of bytes per line for the Mask bytes + * @param aBlendQuality The quality of this blend, this is for tweening if neccesary + */ + void Do8Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage, + PRInt32 aSLSpan,PRInt32 aDLSpan,nsColorMap *aColorMap,nsBlendQuality aBlendQuality); + }; #endif \ No newline at end of file diff --git a/gfx/tests/btest/BitTest.cpp b/gfx/tests/btest/BitTest.cpp index ae66347671c..1dcde0b1bc6 100644 --- a/gfx/tests/btest/BitTest.cpp +++ b/gfx/tests/btest/BitTest.cpp @@ -72,7 +72,7 @@ static nsITextWidget *gQualMessage; #ifdef OLDWAY extern void Compositetest(PRInt32 aTestNum,nsIImage *aImage,nsIImage *aBImage,nsIImage *aMImage, PRInt32 aX, PRInt32 aY); #else -extern void Compositetest(PRInt32 aTestNum,HDC aSrcDC,HDC aDestDC); +extern void Compositetest(nsIImage *aImage,PRInt32 aTestNum,HDC aSrcDC,HDC aDestDC); #endif extern PRInt32 speedtest(nsIImage *aTheImage,nsIRenderingContext *aSurface, PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight); @@ -80,6 +80,8 @@ extern PRInt32 drawtest(nsIRenderingContext *aSurface); extern PRInt32 filltest(nsIRenderingContext *aSurface); extern PRInt32 arctest(nsIRenderingContext *aSurface); extern PRBool IsImageLoaded(); +extern nsresult BuildDIB(LPBITMAPINFOHEADER *aBHead,unsigned char **aBits,PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth); +extern PRInt32 CalcBytesSpan(PRUint32 aWidth,PRUint32 aBitsPixel); @@ -151,11 +153,12 @@ MyBlendObserver::Notify(nsIImageRequest *aImageRequest, Compositetest(gTestNum,gImage,gBlendImage,gMaskImage,gXOff,gYOff); #else { - HBITMAP dobits,sobits,srcbits,destbits; - HDC destdc,srcdc,screendc; - void *bits1,*bits2; + HBITMAP dobits,sobits,srcbits,destbits; + HDC destdc,srcdc,screendc; + void *bits1,*bits2; screendc = ::GetDC(gHwnd); + // create everything we need from this DC srcdc = ::CreateCompatibleDC(screendc); destdc = ::CreateCompatibleDC(screendc); @@ -164,19 +167,20 @@ MyBlendObserver::Notify(nsIImageRequest *aImageRequest, bits2 = gImage->GetBits(); srcbits = ::CreateDIBitmap(screendc,(BITMAPINFOHEADER*)gBlendImage->GetBitInfo(), CBM_INIT, bits1, (LPBITMAPINFO)gBlendImage->GetBitInfo(), DIB_RGB_COLORS); destbits = ::CreateDIBitmap(screendc,(BITMAPINFOHEADER*)gImage->GetBitInfo(), CBM_INIT, bits2, (LPBITMAPINFO)gImage->GetBitInfo(), DIB_RGB_COLORS); - sobits = ::SelectObject(srcdc, srcbits); dobits = ::SelectObject(destdc, destbits); - Compositetest(gTestNum,srcdc,destdc); + Compositetest(gImage,gTestNum,srcdc,destdc); ::SelectObject(srcdc, sobits); ::SelectObject(destdc,dobits); + DeleteDC(srcdc); DeleteDC(destdc); DeleteObject(srcbits); DeleteObject(destbits); - } + ReleaseDC(gHwnd,screendc); + } #endif } @@ -382,7 +386,7 @@ nsString str; aImage->CompositeImage(aBImage,&location,quality); // let everyone know that the colors have changed aImage->ImageUpdated(dx, nsImageUpdateFlags_kColorMapChanged, nsnull); - drawCtx->DrawImage(aImage, 0, 0, aImage->GetWidth(), aImage->GetHeight()); + //drawCtx->DrawImage(aImage, 0, 0, aImage->GetWidth(), aImage->GetHeight()); } NS_IF_RELEASE(dx); } @@ -446,7 +450,7 @@ nsString str; } } - //drawCtx->DrawImage(aImage, 0, 0, aImage->GetWidth(), aImage->GetHeight()); + drawCtx->DrawImage(aImage, 0, 0, aImage->GetWidth(), aImage->GetHeight()); // we are finished with this if (gBlendImage) @@ -458,18 +462,58 @@ nsString str; } #else void -Compositetest(PRInt32 aTestNum,HDC aSrcHDC,HDC DestHDC) +Compositetest(nsIImage *aImage,PRInt32 aTestNum,HDC aSrcHDC,HDC DestHDC) { -nsIBlender *imageblender; +PRUint8 *thebytes,*curbyte,*srcbytes,*cursourcebytes; +PRInt32 w,h,ls,x,y,numbytes,sls,numerror; +float blendamount; +nsIBlender *imageblender; nsresult rv; - +HBITMAP srcbits,tb1; +BITMAP srcinfo; +LPBITMAPINFOHEADER srcbinfo; +nsString str; static NS_DEFINE_IID(kBlenderCID, NS_BLENDER_CID); static NS_DEFINE_IID(kBlenderIID, NS_IBLENDER_IID); + gBlendMessage->GetText(str,3); + blendamount = (float)(str.ToInteger(&numerror))/100.0f; + if(blendamount < 0.0) + blendamount = 0.0f; + if(blendamount > 1.0) + blendamount = 1.0f; + rv = NSRepository::CreateInstance(kBlenderCID, nsnull, kBlenderIID, (void **)&imageblender); imageblender->Init(); - imageblender->Blend(nsDrawingSurface (aSrcHDC),0,0,0,0,(DestHDC),0, 0,(float).5); + imageblender->Blend(nsDrawingSurface (aSrcHDC),0,0,0,0,(DestHDC),0, 0,blendamount); + + + // this takes the Destination DC and copies the information into aImage + tb1 = CreateCompatibleBitmap(DestHDC,3,3); + srcbits = ::SelectObject(DestHDC, tb1); + numbytes = ::GetObject(srcbits,sizeof(BITMAP),&srcinfo); + // put into a DIB + BuildDIB(&srcbinfo,&srcbytes,srcinfo.bmWidth,srcinfo.bmHeight,srcinfo.bmBitsPixel); + numbytes = ::GetDIBits(DestHDC,srcbits,1,srcinfo.bmHeight,srcbytes,(LPBITMAPINFO)srcbinfo,DIB_RGB_COLORS); + + thebytes = aImage->GetBits(); + h = aImage->GetHeight(); + w = aImage->GetWidth(); + ls = aImage->GetLineStride(); + sls = CalcBytesSpan(srcinfo.bmWidth,srcinfo.bmBitsPixel); + for(y=0;y> 5; + + if ((aWidth * aBitsPixel) & 0x1F) + spanbytes++; + + spanbytes <<= 2; + + return(spanbytes); +} + +//------------------------------------------------------------ + +nsresult +BuildDIB(LPBITMAPINFOHEADER *aBHead,unsigned char **aBits,PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth) +{ +PRInt32 numpalletcolors,imagesize,spanbytes; +PRUint8 *colortable; + + + switch (aDepth) + { + case 8: + numpalletcolors = 256; + break; + case 24: + numpalletcolors = 0; + break; + default: + numpalletcolors = -1; + break; + } + + if (numpalletcolors >= 0) + { + (*aBHead) = (LPBITMAPINFOHEADER) new char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * numpalletcolors]; + (*aBHead)->biSize = sizeof(BITMAPINFOHEADER); + (*aBHead)->biWidth = aWidth; + (*aBHead)->biHeight = aHeight; + (*aBHead)->biPlanes = 1; + (*aBHead)->biBitCount = (unsigned short) aDepth; + (*aBHead)->biCompression = BI_RGB; + (*aBHead)->biSizeImage = 0; // not compressed, so we dont need this to be set + (*aBHead)->biXPelsPerMeter = 0; + (*aBHead)->biYPelsPerMeter = 0; + (*aBHead)->biClrUsed = numpalletcolors; + (*aBHead)->biClrImportant = numpalletcolors; + + spanbytes = CalcBytesSpan(aWidth,aDepth); + + imagesize = spanbytes * (*aBHead)->biHeight; // no compression + + // set the color table in the info header + colortable = (PRUint8 *)(*aBHead) + sizeof(BITMAPINFOHEADER); + + memset(colortable, 0, sizeof(RGBQUAD) * numpalletcolors); + *aBits = new unsigned char[imagesize]; + memset(*aBits, 128, imagesize); + } + + return NS_OK; +}