updated blending code, and tests

This commit is contained in:
dcone 1998-06-11 17:33:26 +00:00
parent eb233c5c40
commit 06a3dd1232
9 changed files with 274 additions and 9 deletions

View File

@ -23,6 +23,8 @@
#include "nsIFactory.h"
#include "nsRepository.h"
#define NS_IMAGE_CID \
{ 0x6049b260, 0xc1e6, 0x11d1, \
{ 0xa8, 0x27, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } }
@ -43,4 +45,8 @@
{ 0xe12752f0, 0xee9a, 0x11d1, \
{ 0xa8, 0x2a, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } }
#define NS_BLENDER_CID \
{ 0x6049b264, 0xc1e6, 0x11d1, \
{ 0xa8, 0x27, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } }
#endif

View File

@ -23,7 +23,7 @@
#include "nsISupports.h"
#include "nsIRenderingContext.h"
// IID for the nsIRenderingContext interface
// IID for the nsIBlender interface
#define NS_IBLENDER_IID \
{ 0xbdb4b5b0, 0xf0db, 0x11d1, \
{ 0xa8, 0x2a, 0x00, 0x40, 0x95, 0x9a, 0x28, 0xc9 } }

View File

@ -230,6 +230,12 @@ public:
*/
virtual PRInt32 GetAlphaLevel() = 0;
/**
* Return information about the bits for this structure
@return a bitmap info structure for the Device Dependent Bits
*/
virtual void* GetBitInfo() = 0;
//get the color space metrics for this image
//virtual NI_ColorSpec * GetColorSpec() = 0; fix

View File

@ -16,6 +16,7 @@
* Reserved.
*/
#include <windows.h>
#include "nsBlenderWin.h"
static NS_DEFINE_IID(kIBlenderIID, NS_IBLENDER_IID);
@ -24,6 +25,7 @@ static NS_DEFINE_IID(kIBlenderIID, NS_IBLENDER_IID);
nsBlenderWin :: nsBlenderWin()
{
NS_INIT_REFCNT();
}
@ -39,7 +41,7 @@ NS_IMPL_ISUPPORTS(nsBlenderWin, kIBlenderIID);
//------------------------------------------------------------
nsresult
nsresult
nsBlenderWin::Init()
{
@ -50,8 +52,187 @@ nsBlenderWin::Init()
void
nsBlenderWin::Blend(nsDrawingSurface aSrc,PRInt32 aSX, PRInt32 aSY, PRInt32 aWidth, PRInt32 aHeight,
nsDrawingSurface aDest, PRInt32 aDX, PRInt32 aDY, float aSrcOpacity)
nsDrawingSurface aDst, PRInt32 aDX, PRInt32 aDY, float aSrcOpacity)
{
HDC srcdc,dstdc;
HBITMAP srcbits,dstbits,tb1,tb2;
BITMAP srcinfo,dstinfo;
nsPoint srcloc,maskloc;
PRInt32 dlinespan,slinespan,mlinespan,numbytes,numlines;
PRUint8 *s1,*d1,*m1,*srcbytes,*dstbytes;
LPBITMAPINFOHEADER srcbinfo,dstbinfo;
// we have to extract the bitmaps from the nsDrawingSurface, which in this case is a hdc
srcdc = (HDC)aSrc;
dstdc = (HDC)aDst;
// we use this bitmap to select into the HDC's while we work on the ones they give us
tb1 = CreateCompatibleBitmap(aSrc,3,3);
// get the HBITMAP, and then grab the information about the source bitmap and bits
srcbits = ::SelectObject(srcdc, tb1);
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);
// get the HBITMAP, and then grab the information about the destination bitmap
tb2 = CreateCompatibleBitmap(aSrc,3,3);
dstbits = ::SelectObject(dstdc, tb2);
::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);
// calculate the metrics, no mask right now
if(CalcAlphaMetrics(&srcinfo,&dstinfo,&srcloc,NULL,&maskloc,&numlines,&numbytes,
&s1,&d1,&m1,&slinespan,&dlinespan,&mlinespan))
{
// now do the blend
}
::SelectObject(srcdc,srcbits);
::SelectObject(dstdc,dstbits);
}
//------------------------------------------------------------
PRBool
nsBlenderWin::CalcAlphaMetrics(BITMAP *aSrcInfo,BITMAP *aDestInfo,nsPoint *aSrcUL,
BITMAP *aMaskInfo,nsPoint *aMaskUL,
PRInt32 *aNumlines,
PRInt32 *aNumbytes,PRUint8 **aSImage,PRUint8 **aDImage,
PRUint8 **aMImage,PRInt32 *aSLSpan,PRInt32 *aDLSpan,PRInt32 *aMLSpan)
{
PRBool doalpha = PR_FALSE;
nsRect arect,srect,drect,irect;
PRInt32 startx,starty,x,y;
if(aMaskInfo)
{
arect.SetRect(0,0,aDestInfo->bmWidth,aDestInfo->bmHeight);
srect.SetRect(aMaskUL->x,aMaskUL->y,aMaskInfo->bmWidth,aSrcInfo->bmHeight);
arect.IntersectRect(arect,srect);
}
else
{
arect.SetRect(0, 0,aDestInfo->bmWidth, aDestInfo->bmHeight);
x = y = 0;
}
srect.SetRect(aSrcUL->x, aSrcUL->y, aSrcInfo->bmWidth, aSrcInfo->bmHeight);
drect = arect;
if (irect.IntersectRect(srect, drect))
{
// calculate destination information
*aDLSpan = aDestInfo->bmWidthBytes;
*aNumbytes = this->CalcBytesSpan(irect.width,aDestInfo->bmBitsPixel);
*aNumlines = irect.height;
startx = irect.x;
starty = aDestInfo->bmHeight - (irect.y + irect.height);
*aDImage = ((PRUint8*)aDestInfo->bmBits) + (starty * (*aDLSpan)) + (aDestInfo->bmBitsPixel * startx);
// get the intersection relative to the source rectangle
srect.SetRect(0, 0, aSrcInfo->bmWidth, aSrcInfo->bmHeight);
drect = irect;
drect.MoveBy(-aSrcUL->x, -aSrcUL->y);
drect.IntersectRect(drect,srect);
*aSLSpan = aSrcInfo->bmWidthBytes;
startx = drect.x;
starty = aSrcInfo->bmHeight - (drect.y + drect.height);
*aSImage = ((PRUint8*)aSrcInfo->bmBits) + (starty * (*aSLSpan)) + (aDestInfo->bmBitsPixel * startx);
doalpha = PR_TRUE;
if(aMaskInfo)
{
*aMLSpan = aMaskInfo->bmWidthBytes;
*aMImage = (PRUint8*)aMaskInfo->bmBits;
}
else
{
aMLSpan = 0;
*aMImage = nsnull;
}
}
return doalpha;
}
//------------------------------------------------------------
PRInt32
nsBlenderWin :: CalcBytesSpan(PRUint32 aWidth,PRUint32 aBitsPixel)
{
PRInt32 spanbytes;
spanbytes = (aWidth * aBitsPixel) >> 5;
if ((aWidth * aBitsPixel) & 0x1F)
spanbytes++;
spanbytes <<= 2;
return(spanbytes);
}
//-----------------------------------------------------------
nsresult
nsBlenderWin :: 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 = ((*aBHead)->biWidth * (*aBHead)->biBitCount) >> 5;
if (((PRUint32)(*aBHead)->biWidth * (*aBHead)->biBitCount) & 0x1F)
spanbytes++;
spanbytes <<= 2;
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;
}

View File

@ -20,7 +20,8 @@
#define nsBlenderWin_h___
#include "nsIBlender.h"
#include "nsPoint.h"
#include "nsRect.h"
//----------------------------------------------------------------------
@ -43,6 +44,18 @@ public:
virtual void Blend(nsDrawingSurface aSrc,
PRInt32 aSX, PRInt32 aSY, PRInt32 aWidth, PRInt32 aHeight,
nsDrawingSurface aDest, PRInt32 aDX, PRInt32 aDY, float aSrcOpacity);
PRBool CalcAlphaMetrics(BITMAP *aSrcInfo,BITMAP *aDestInfo,nsPoint *ASrcUL,
BITMAP *aMapInfo,nsPoint *aMaskUL,
PRInt32 *aNumlines,
PRInt32 *aNumbytes,PRUint8 **aSImage,PRUint8 **aDImage,
PRUint8 **aMImage,PRInt32 *aSLSpan,PRInt32 *aDLSpan,PRInt32 *aMLSpan);
PRInt32 CalcBytesSpan(PRUint32 aWidth,PRUint32 aBitsPixel);
private:
nsresult BuildDIB(LPBITMAPINFOHEADER *aBHead,unsigned char **aBits,PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth);
};
#endif

View File

@ -25,10 +25,12 @@
#include "nsImageWin.h"
#include "nsDeviceContextWin.h"
#include "nsRegionWin.h"
#include "nsBlenderWin.h"
static NS_DEFINE_IID(kCFontMetrics, NS_FONT_METRICS_CID);
static NS_DEFINE_IID(kCRenderingContext, NS_RENDERING_CONTEXT_CID);
static NS_DEFINE_IID(kCImage, NS_IMAGE_CID);
static NS_DEFINE_IID(kCBlender, NS_BLENDER_CID);
static NS_DEFINE_IID(kCDeviceContext, NS_DEVICE_CONTEXT_CID);
static NS_DEFINE_IID(kCRegion, NS_REGION_CID);
@ -135,6 +137,9 @@ nsresult nsGfxFactoryWin::CreateInstance(nsISupports *aOuter,
else if (mClassID.Equals(kCRegion)) {
inst = (nsISupports *)new nsRegionWin();
}
else if (mClassID.Equals(kCBlender)) {
inst = (nsISupports *)new nsBlenderWin();
}
if (inst == NULL) {
return NS_ERROR_OUT_OF_MEMORY;

View File

@ -812,7 +812,7 @@ PRBool nsImageWin :: SetSystemPalette(HDC* aHdc)
// creates an optimized bitmap, or HBITMAP
nsresult nsImageWin :: Optimize(nsDrawingSurface aSurface)
{
//return NS_OK; // TAKE THIS OUT
return NS_OK; // TAKE THIS OUT
HDC the_hdc = (HDC)aSurface;

View File

@ -104,6 +104,8 @@ public:
void MoveAlphaMask(PRInt32 aX, PRInt32 aY){mLocation.x=aX;mLocation.y=aY;}
void* GetBitInfo() {return mBHead;}
private:
/**
@ -227,6 +229,7 @@ private:
HPALETTE mHPalette;
HBITMAP mHBitmap; // the GDI bitmap
LPBITMAPINFOHEADER mBHead; // BITMAPINFOHEADER
};
#endif

View File

@ -21,7 +21,6 @@
#undef WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include "prtypes.h"
#include <stdio.h>
#include "resources.h"
@ -38,11 +37,9 @@
#include "nsWidgetsCID.h"
#include "nsGfxCIID.h"
#include "nsFont.h"
#include <windows.h>
#include "nsWidgetsCID.h"
#include "nsITextWidget.h"
#include "nsIBlender.h"
// widget interface
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
@ -72,7 +69,12 @@ static nsITextWidget *gBlendMessage;
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);
#endif
extern PRInt32 speedtest(nsIImage *aTheImage,nsIRenderingContext *aSurface, PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
extern PRInt32 drawtest(nsIRenderingContext *aSurface);
extern PRInt32 filltest(nsIRenderingContext *aSurface);
@ -145,7 +147,38 @@ MyBlendObserver::Notify(nsIImageRequest *aImageRequest,
{
nsColorMap *cmap = (*mImage)->GetColorMap();
nsRect *rect = (nsRect *)aParam3;
#ifdef OLDWAY
Compositetest(gTestNum,gImage,gBlendImage,gMaskImage,gXOff,gYOff);
#else
{
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);
bits1 = gBlendImage->GetBits();
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);
::SelectObject(srcdc, sobits);
::SelectObject(destdc,dobits);
DeleteDC(srcdc);
DeleteDC(destdc);
DeleteObject(srcbits);
DeleteObject(destbits);
}
#endif
}
}
break;
@ -255,6 +288,7 @@ MyObserver::NotifyError(nsIImageRequest *aImageRequest,
//------------------------------------------------------------
#ifdef OLDWAY
// This tests the compositing for the image
void
Compositetest(PRInt32 aTestNum,nsIImage *aImage,nsIImage *aBImage,nsIImage *aMImage, PRInt32 aX, PRInt32 aY)
@ -422,8 +456,23 @@ nsString str;
}
}
#else
void
Compositetest(PRInt32 aTestNum,HDC aSrcHDC,HDC DestHDC)
{
nsIBlender *imageblender;
nsresult rv;
static NS_DEFINE_IID(kBlenderCID, NS_BLENDER_CID);
static NS_DEFINE_IID(kBlenderIID, NS_IBLENDER_IID);
rv = NSRepository::CreateInstance(kBlenderCID, nsnull, kBlenderIID, (void **)&imageblender);
imageblender->Init();
imageblender->Blend(nsDrawingSurface (aSrcHDC),0,0,0,0,(DestHDC),0, 0,(float).5);
}
#endif
//------------------------------------------------------------
// This tests the speed for the bliting,
@ -974,11 +1023,13 @@ WinMain(HANDLE instance, HANDLE prevInstance, LPSTR cmdParam, int nCmdShow)
static NS_DEFINE_IID(kCDeviceContextIID, NS_DEVICE_CONTEXT_CID);
static NS_DEFINE_IID(kCFontMetricsIID, NS_FONT_METRICS_CID);
static NS_DEFINE_IID(kCImageIID, NS_IMAGE_CID);
static NS_DEFINE_IID(kCBlenderIID, NS_BLENDER_CID);
NSRepository::RegisterFactory(kCRenderingContextIID, GFXWIN_DLL, PR_FALSE, PR_FALSE);
NSRepository::RegisterFactory(kCDeviceContextIID, GFXWIN_DLL, PR_FALSE, PR_FALSE);
NSRepository::RegisterFactory(kCFontMetricsIID, GFXWIN_DLL, PR_FALSE, PR_FALSE);
NSRepository::RegisterFactory(kCImageIID, GFXWIN_DLL, PR_FALSE, PR_FALSE);
NSRepository::RegisterFactory(kCBlenderIID, GFXWIN_DLL, PR_FALSE, PR_FALSE);
if (!prevInstance) {
WNDCLASS wndClass;