made CopyBits() more flexible. added better ddraw support for windows rendering

context. added ddraw support to windows blender. made CreateDrawingSurface()
able to be smarter.
This commit is contained in:
michaelp%netscape.com 1998-10-23 17:58:18 +00:00
Родитель a4a92311b9
Коммит 2812cd80c1
14 изменённых файлов: 877 добавлений и 377 удалений

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

@ -91,7 +91,7 @@ NS_IMETHODIMP nsDeviceContextMac :: GetScrollBarDimensions(float &aWidth, float
NS_IMETHODIMP nsDeviceContextMac :: GetDrawingSurface(nsIRenderingContext &aContext, nsDrawingSurface &aSurface)
{
aSurface = aContext.CreateDrawingSurface(nsnull);
aSurface = aContext.CreateDrawingSurface(nsnull, 0);
return nsnull == aSurface ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
}

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

@ -213,7 +213,11 @@ nsresult nsRenderingContextMac :: CommonInit()
nsresult nsRenderingContextMac :: SelectOffScreenDrawingSurface(nsDrawingSurface aSurface)
{
mRenderingSurface = (nsDrawingSurfaceMac)aSurface;
if (nsnull == aSurface)
mRenderingSurface = mFrontBuffer;
else
mRenderingSurface = (nsDrawingSurfaceMac)aSurface;
return NS_OK;
}
@ -594,7 +598,7 @@ nsTransform2D * nsRenderingContextMac :: GetCurrentTransform()
//------------------------------------------------------------------------
nsDrawingSurface nsRenderingContextMac :: CreateDrawingSurface(nsRect *aBounds)
nsDrawingSurface nsRenderingContextMac :: CreateDrawingSurface(nsRect *aBounds, PRUint32 aSurfFlags)
{
PRUint32 depth;
GWorldPtr theoff;
@ -1088,25 +1092,50 @@ nsRect tr;
//------------------------------------------------------------------------
nsresult nsRenderingContextMac :: CopyOffScreenBits(nsRect &aBounds)
NS_IMETHODIMP nsRenderingContextMac :: CopyOffScreenBits(nsDrawingSurface aSrcSurf,
PRInt32 aSrcX, PRInt32 aSrcY,
const nsRect &aDestBounds,
PRUint32 aCopyFlags)
{
PixMapHandle offscreenPM;
PixMapPtr srcpix;
PixMapPtr destpix;
RGBColor rgbblack = {0x0000,0x0000,0x0000};
RGBColor rgbwhite = {0xFFFF,0xFFFF,0xFFFF};
Rect srcrect,dstrect;
PixMapHandle offscreenPM;
PixMapPtr srcpix;
PixMapPtr destpix;
RGBColor rgbblack = {0x0000,0x0000,0x0000};
RGBColor rgbwhite = {0xFFFF,0xFFFF,0xFFFF};
Rect srcrect,dstrect;
PRInt32 x = aSrcX;
PRInt32 y = aSrcY;
nsRect drect = aDestBounds;
nsDrawingSurfaceMac destport;
::SetRect(&srcrect,0,0,aBounds.width,aBounds.height);
::SetRect(&dstrect,0,0,aBounds.width,aBounds.height);
if (aCopyFlags & NS_COPYBITS_TO_BACK_BUFFER)
{
NS_ASSERTION(!(nsnull == destport), "no back buffer");
destport = mRenderingSurface;
}
else
destport = mFrontBuffer;
::SetPort(mFrontBuffer);
::SetEmptyRgn(mFrontBuffer->clipRgn);
::CopyRgn(mRenderingSurface->clipRgn, mFrontBuffer->clipRgn);
if (aCopyFlags & NS_COPYBITS_XFORM_SOURCE_VALUES)
mTMatrix->TransformCoord(&x, &y);
destpix = *((CGrafPtr)mFrontBuffer)->portPixMap;
if (aCopyFlags & NS_COPYBITS_XFORM_DEST_VALUES)
mTMatrix->TransformCoord(&drect.x, &drect.y, &drect.width, &drect.height);
offscreenPM = ::GetGWorldPixMap((GWorldPtr)mRenderingSurface);
::SetRect(&srcrect,x,y,drect.width,drect.height);
::SetRect(&dstrect,drect.x,drect.y,drect.width,drect.height);
::SetPort(destport);
if (aCopyFlags & NS_COPYBITS_USE_SOURCE_CLIP_REGION)
{
::SetEmptyRgn(destport->clipRgn);
::CopyRgn(((nsDrawingSurfaceMac)aSrcSurf)->clipRgn, desport->clipRgn);
}
destpix = *((CGrafPtr)destport)->portPixMap;
offscreenPM = ::GetGWorldPixMap((GWorldPtr)aSrcSurf);
LockPixels(offscreenPM);
srcpix = (PixMapPtr)*offscreenPM;
::RGBForeColor(&rgbblack);
@ -1115,7 +1144,6 @@ Rect srcrect,dstrect;
::CopyBits((BitMap*)srcpix,(BitMap*)destpix,&srcrect,&dstrect,ditherCopy,0L);
UnlockPixels(offscreenPM);
return NS_OK;
}

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

@ -81,7 +81,7 @@ public:
virtual void Translate(nscoord aX, nscoord aY);
virtual void Scale(float aSx, float aSy);
virtual nsTransform2D * GetCurrentTransform();
virtual nsDrawingSurface CreateDrawingSurface(nsRect *aBounds);
virtual nsDrawingSurface CreateDrawingSurface(nsRect *aBounds, PRUint32 aSurfFlags);
virtual void DestroyDrawingSurface(nsDrawingSurface aDS);
virtual void DrawLine(nscoord aX0, nscoord aY0, nscoord aX1, nscoord aY1);
virtual void DrawPolyline(const nsPoint aPoints[], PRInt32 aNumPoints);
@ -112,7 +112,8 @@ public:
virtual void DrawImage(nsIImage *aImage, nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
virtual void DrawImage(nsIImage *aImage, const nsRect& aRect);
virtual void DrawImage(nsIImage *aImage, const nsRect& aSRect, const nsRect& aDRect);
virtual nsresult CopyOffScreenBits(nsRect &aBounds);
NS_IMETHOD CopyOffScreenBits(nsDrawingSurface aSrcSurf, PRInt32 aSrcX, PRInt32 aSrcY,
const nsRect &aDestBounds, PRUint32 aCopyFlags);
protected:
nscolor mCurrentColor ;

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

@ -136,7 +136,7 @@ NS_IMETHODIMP nsDeviceContextUnix :: GetScrollBarDimensions(float &aWidth, float
NS_IMETHODIMP nsDeviceContextUnix :: GetDrawingSurface(nsIRenderingContext &aContext, nsDrawingSurface &aSurface)
{
aSurface = aContext.CreateDrawingSurface(nsnull);
aSurface = aContext.CreateDrawingSurface(nsnull, 0);
return nsnull == aSurface ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
}

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

@ -237,7 +237,11 @@ nsresult nsRenderingContextUnix :: CommonInit()
NS_IMETHODIMP
nsRenderingContextUnix :: SelectOffScreenDrawingSurface(nsDrawingSurface aSurface)
{
mRenderingSurface = (nsDrawingSurfaceUnix *) aSurface;
if (nsnull == aSurface)
mRenderingSurface = mFrontBuffer;
else
mRenderingSurface = (nsDrawingSurfaceUnix *)aSurface;
return NS_OK;
}
@ -679,7 +683,7 @@ nsTransform2D * nsRenderingContextUnix :: GetCurrentTransform()
return mTMatrix;
}
nsDrawingSurface nsRenderingContextUnix :: CreateDrawingSurface(nsRect *aBounds)
nsDrawingSurface nsRenderingContextUnix :: CreateDrawingSurface(nsRect *aBounds, PRUint32 aSurfFlags)
{
if (nsnull == mRenderingSurface) {
return nsnull;
@ -1321,14 +1325,39 @@ void nsRenderingContextUnix :: DrawImage(nsIImage *aImage, const nsRect& aRect)
}
NS_IMETHODIMP
nsRenderingContextUnix :: CopyOffScreenBits(nsRect &aBounds)
nsRenderingContextUnix :: CopyOffScreenBits(nsDrawingSurface aSrcSurf,
PRInt32 aSrcX, PRInt32 aSrcY,
const nsRect &aDestBounds,
PRUint32 aCopyFlags)
{
PRInt32 x = aSrcX;
PRInt32 y = aSrcY;
nsRect drect = aDestBounds;
nsDrawingSurfaceUnix *destsurf;
::XCopyArea(mRenderingSurface->display,
mRenderingSurface->drawable,
mFrontBuffer->drawable,
mRenderingSurface->gc,
0,0, aBounds.width, aBounds.height, 0,0);
if (aCopyFlags & NS_COPYBITS_TO_BACK_BUFFER)
{
NS_ASSERTION(!(nsnull == mRenderingSurface), "no back buffer");
destsurf = mRenderingSurface;
}
else
destsurf = mFrontBuffer;
if (aCopyFlags & NS_COPYBITS_XFORM_SOURCE_VALUES)
mTMatrix->TransformCoord(&x, &y);
if (aCopyFlags & NS_COPYBITS_XFORM_DEST_VALUES)
mTMatrix->TransformCoord(&drect.x, &drect.y, &drect.width, &drect.height);
//XXX flags are unused. that would seem to mean that there is
//inefficiency somewhere... MMP
::XCopyArea(((nsDrawingSurfaceUnix *)aSrcSurf)->display,
((nsDrawingSurfaceUnix *)aSrcSurf)->drawable,
destsurf->drawable,
((nsDrawingSurfaceUnix *)aSrcSurf)->gc,
x, y, drect.width, drect.height,
drect.x, drect.y);
return NS_OK;
}

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

@ -99,7 +99,7 @@ public:
virtual void Scale(float aSx, float aSy);
virtual nsTransform2D * GetCurrentTransform();
virtual nsDrawingSurface CreateDrawingSurface(nsRect *aBounds);
virtual nsDrawingSurface CreateDrawingSurface(nsRect *aBounds, PRUint32 aSurfFlags);
virtual void DestroyDrawingSurface(nsDrawingSurface aDS);
virtual void DrawLine(nscoord aX0, nscoord aY0, nscoord aX1, nscoord aY1);
@ -148,7 +148,8 @@ public:
virtual void DrawImage(nsIImage *aImage, const nsRect& aRect);
virtual void DrawImage(nsIImage *aImage, const nsRect& aSRect, const nsRect& aDRect);
NS_IMETHOD CopyOffScreenBits(nsRect &aBounds);
NS_IMETHOD CopyOffScreenBits(nsDrawingSurface aSrcSurf, PRInt32 aSrcX, PRInt32 aSrcY,
const nsRect &aDestBounds, PRUint32 aCopyFlags);
protected:

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

@ -42,11 +42,6 @@ public:
*/
virtual nsresult Init(nsDrawingSurface aSrc,nsDrawingSurface aDst) = 0;
/**
* Clean up the intialization stuff
*/
virtual void CleanUp() = 0;
/**
* NOTE: if we can make this static, that would be great. I don't think we can.
* Blend source and destination nsDrawingSurfaces. Both drawing surfaces

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

@ -101,6 +101,8 @@ public:
/**
* Selects an offscreen drawing surface into the RenderingContext to draw to.
* @param aSurface is the offscreen surface we are going to draw to.
* if nsnull, the original drawing surface obtained at initialization
* should be selected.
*/
NS_IMETHOD SelectOffScreenDrawingSurface(nsDrawingSurface aSurface) = 0;
@ -237,13 +239,16 @@ public:
virtual nsTransform2D * GetCurrentTransform() = 0;
/**
* Create an offscreen drawing surface compatible with this RenderingContext
* Create an offscreen drawing surface compatible with this RenderingContext.
* The rect passed in is not affected by any transforms in the rendering
* context and the values are in device units.
* @param aBounds A rectangle representing the size for the drawing surface.
* if nsnull then a bitmap will not be created and associated
* with the new drawing surface
* @param aSurfFlags see bottom of nsIRenderingContext.h
* @return A nsDrawingSurface
*/
virtual nsDrawingSurface CreateDrawingSurface(nsRect *aBounds) = 0;
virtual nsDrawingSurface CreateDrawingSurface(nsRect *aBounds, PRUint32 aSurfFlags) = 0;
/**
* Destroy a drawing surface created by CreateDrawingSurface()
@ -499,10 +504,15 @@ public:
virtual void DrawImage(nsIImage *aImage, const nsRect& aSRect, const nsRect& aDRect)=0;
/**
* Copy offscreen pixelmap to this RenderingContext
* @param aBounds Destination rectangle to copy to
* Copy offscreen pixelmap to this RenderingContext.
* @param aSrcSurf drawing surface to copy bits from
* @param aSrcX x offset into source pixelmap to copy from
* @param aSrcY y offset into source pixelmap to copy from
* @param aDestBounds Destination rectangle to copy to
* @param aCopyFlags see below
*/
NS_IMETHOD CopyOffScreenBits(nsRect &aBounds) = 0;
NS_IMETHOD CopyOffScreenBits(nsDrawingSurface aSrcSurf, PRInt32 aSrcX, PRInt32 aSrcY,
const nsRect &aDestBounds, PRUint32 aCopyFlags) = 0;
};
//modifiers for text rendering
@ -528,4 +538,33 @@ public:
*/
#define NS_RENDERING_HINT_REMOTE_RENDERING 0x2
//flags for copy CopyOffScreenBits
//when performing the blit, use the region, if any,
//that exists in the source drawingsurface as a
//blit mask.
#define NS_COPYBITS_USE_SOURCE_CLIP_REGION 0x0001
//transform the source offsets by the xform in the
//rendering context
#define NS_COPYBITS_XFORM_SOURCE_VALUES 0x0002
//transform the destination rect by the xform in the
//rendering context
#define NS_COPYBITS_XFORM_DEST_VALUES 0x0004
//this is basically a hack and is used by callers
//who have selected an alternate drawing surface and
//wish the copy to happen to that buffer rather than
//the "front" buffer. i'm not proud of this. MMP
#define NS_COPYBITS_TO_BACK_BUFFER 0x0008
//when creating a drawing surface, you can use this
//to tell the rendering context that you anticipate
//the need to get to the actual bits of the drawing
//surface at some point during it's lifetime. typically
//used when creating bitmaps to be operated on by the
//nsIBlender implementations.
#define NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS 0x0001
#endif /* nsIRenderingContext_h___ */

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

@ -20,30 +20,58 @@
#include "nsBlenderWin.h"
#include "nsRenderingContextWin.h"
#ifdef NGLAYOUT_DDRAW
#include "ddraw.h"
#endif
static NS_DEFINE_IID(kIBlenderIID, NS_IBLENDER_IID);
//------------------------------------------------------------
nsBlenderWin :: nsBlenderWin()
{
NS_INIT_REFCNT();
mSaveBytes = nsnull;
mSrcBytes = nsnull;
mDstBytes = nsnull;
mTempB1 = nsnull;
mTempB2 = nsnull;
mSaveLS = 0;
mSaveNumLines = 0;
mSrcbinfo = nsnull;
mDstbinfo = nsnull;
mRestorePtr = nsnull;
mSaveNumBytes = 0;
mResLS = 0;
mSRowBytes = 0;
mDRowBytes = 0;
mSrcDS = nsnull;
mDstDS = nsnull;
}
//------------------------------------------------------------
nsBlenderWin :: ~nsBlenderWin()
{
CleanUp();
NS_IF_RELEASE(mSrcDS);
NS_IF_RELEASE(mDstDS);
// get rid of the DIB's
if (nsnull != mSrcbinfo)
DeleteDIB(&mSrcbinfo, &mSrcBytes);
if (nsnull != mDstbinfo)
DeleteDIB(&mDstbinfo, &mDstBytes);
if (mSaveBytes != nsnull)
{
delete [] mSaveBytes;
mSaveBytes == nsnull;
}
mDstBytes = nsnull;
mSaveLS = 0;
mSaveNumLines = 0;
}
NS_IMPL_ISUPPORTS(nsBlenderWin, kIBlenderIID);
@ -51,105 +79,145 @@ NS_IMPL_ISUPPORTS(nsBlenderWin, kIBlenderIID);
//------------------------------------------------------------
nsresult
nsBlenderWin::Init(nsDrawingSurface aSrc,nsDrawingSurface aDst)
nsBlenderWin::Init(nsDrawingSurface aSrc, nsDrawingSurface aDst)
{
PRInt32 numbytes;
HDC srcdc,dstdc;
HBITMAP srcbits,dstbits;
NS_ASSERTION(!(aSrc == nsnull), "no source surface");
NS_ASSERTION(!(aDst == nsnull), "no dest surface");
if(mSaveBytes != nsnull)
if (mSaveBytes != nsnull)
{
delete [] mSaveBytes;
mSaveBytes = nsnull;
mSaveBytes = nsnull;
}
// lets build some DIB's for the source and destination from the HDC's
srcdc = ((nsDrawingSurfaceWin *)aSrc)->mDC;
dstdc = ((nsDrawingSurfaceWin *)aDst)->mDC;
mSrcDS = (nsDrawingSurfaceWin *)aSrc;
mDstDS = (nsDrawingSurfaceWin *)aDst;
mSrcDC = aSrc;
mDstDC = aDst;
// source
mTempB1 = CreateCompatibleBitmap(srcdc,3,3);
srcbits = (HBITMAP)::SelectObject(srcdc, mTempB1);
numbytes = ::GetObject(srcbits,sizeof(BITMAP),&mSrcInfo);
BuildDIB(&mSrcbinfo,&mSrcBytes,mSrcInfo.bmWidth,mSrcInfo.bmHeight,mSrcInfo.bmBitsPixel);
numbytes = ::GetDIBits(srcdc,srcbits,0,mSrcInfo.bmHeight,mSrcBytes,(LPBITMAPINFO)mSrcbinfo,DIB_RGB_COLORS);
if(numbytes > 0)
{
// destination
mTempB2 = CreateCompatibleBitmap(dstdc,3,3);
dstbits = (HBITMAP)::SelectObject(dstdc, mTempB2);
::GetObject(dstbits,sizeof(BITMAP),&mDstInfo);
BuildDIB(&mDstbinfo,&mDstBytes,mDstInfo.bmWidth,mDstInfo.bmHeight,mDstInfo.bmBitsPixel);
numbytes = ::GetDIBits(dstdc,dstbits,0,mDstInfo.bmHeight,mDstBytes,(LPBITMAPINFO)mDstbinfo,DIB_RGB_COLORS);
mSRowBytes = CalcBytesSpan(mSrcInfo.bmWidth,mSrcInfo.bmBitsPixel);
mDRowBytes = CalcBytesSpan(mDstInfo.bmWidth,mDstInfo.bmBitsPixel);
// put the old stuff back
::SelectObject(srcdc,srcbits);
::SelectObject(dstdc,dstbits);
}
NS_IF_ADDREF(mSrcDS);
NS_IF_ADDREF(mDstDS);
return NS_OK;
}
//------------------------------------------------------------
void
nsBlenderWin::CleanUp()
{
if(mTempB1)
::DeleteObject(mTempB1);
if(mTempB2)
::DeleteObject(mTempB2);
// get rid of the DIB's
DeleteDIB(&mSrcbinfo,&mSrcBytes);
DeleteDIB(&mDstbinfo,&mDstBytes);
if(mSaveBytes != nsnull)
delete [] mSaveBytes;
mSaveBytes == nsnull;
mTempB1 = nsnull;
mTempB2 = nsnull;
mDstBytes = nsnull;
mSaveLS = 0;
mSaveNumLines = 0;
}
//------------------------------------------------------------
nsresult
nsBlenderWin::Blend(PRInt32 aSX, PRInt32 aSY, PRInt32 aWidth, PRInt32 aHeight,
nsDrawingSurface aDst, PRInt32 aDX, PRInt32 aDY, float aSrcOpacity,PRBool aSaveBlendArea)
nsDrawingSurface aDst, PRInt32 aDX, PRInt32 aDY, float aSrcOpacity,PRBool aSaveBlendArea)
{
nsresult result = NS_ERROR_FAILURE;
HDC dstdc;
HBITMAP dstbits, tb1;
nsPoint srcloc,maskloc;
PRInt32 dlinespan,slinespan,mlinespan,numbytes,numlines,level,size,oldsize;
PRUint8 *s1,*d1,*m1,*mask=NULL;
nsColorMap *colormap;
nsresult result = NS_ERROR_FAILURE;
HBITMAP dstbits, tb1;
nsPoint srcloc, maskloc;
PRInt32 dlinespan, slinespan, mlinespan, numbytes, numlines, level, size, oldsize;
PRUint8 *s1, *d1, *m1, *mask = NULL;
nsColorMap *colormap;
HDC srcdc, dstdc;
PRBool srcissurf = PR_FALSE, dstissurf = PR_FALSE;
// source
#ifdef NGLAYOUT_DDRAW
RECT srect;
srect.left = aSX;
srect.top = aSY;
srect.right = aSX + aWidth;
srect.bottom = aSY + aHeight;
if (PR_TRUE == LockSurface(mSrcDS->mSurface, &mSrcSurf, &mSrcInfo, &srect, DDLOCK_READONLY))
{
srcissurf = PR_TRUE;
mSRowBytes = mSrcInfo.bmWidthBytes;
}
else
#endif
{
if (nsnull == mSrcbinfo)
{
HBITMAP srcbits;
srcdc = mSrcDS->mDC;
if (nsnull == mSrcDS->mSelectedBitmap)
{
HBITMAP hbits = ::CreateCompatibleBitmap(srcdc, 2, 2);
srcbits = (HBITMAP)::SelectObject(srcdc, hbits);
::GetObject(srcbits, sizeof(BITMAP), &mSrcInfo);
::SelectObject(srcdc, srcbits);
::DeleteObject(hbits);
}
else
{
::GetObject(mSrcDS->mSelectedBitmap, sizeof(BITMAP), &mSrcInfo);
srcbits = mSrcDS->mSelectedBitmap;
}
BuildDIB(&mSrcbinfo, &mSrcBytes, mSrcInfo.bmWidth, mSrcInfo.bmHeight, mSrcInfo.bmBitsPixel);
numbytes = ::GetDIBits(srcdc, srcbits, 0, mSrcInfo.bmHeight, mSrcBytes, (LPBITMAPINFO)mSrcbinfo, DIB_RGB_COLORS);
mSRowBytes = CalcBytesSpan(mSrcInfo.bmWidth, mSrcInfo.bmBitsPixel);
}
mSrcInfo.bmBits = mSrcBytes;
}
// destination
#ifdef NGLAYOUT_DDRAW
RECT drect;
drect.left = aDX;
drect.top = aDY;
drect.right = aDX + aWidth;
drect.bottom = aDY + aHeight;
if (PR_TRUE == LockSurface(mDstDS->mSurface, &mDstSurf, &mDstInfo, &drect, 0))
{
dstissurf = PR_TRUE;
mDRowBytes = mDstInfo.bmWidthBytes;
}
else
#endif
{
if (nsnull == mDstbinfo)
{
HBITMAP dstbits;
dstdc = mDstDS->mDC;
if (nsnull == mDstDS->mSelectedBitmap)
{
HBITMAP hbits = CreateCompatibleBitmap(dstdc, 2, 2);
dstbits = (HBITMAP)::SelectObject(dstdc, hbits);
::GetObject(dstbits, sizeof(BITMAP), &mDstInfo);
::SelectObject(dstdc, dstbits);
::DeleteObject(hbits);
}
else
{
::GetObject(mDstDS->mSelectedBitmap, sizeof(BITMAP), &mDstInfo);
dstbits = mDstDS->mSelectedBitmap;
}
BuildDIB(&mDstbinfo, &mDstBytes, mDstInfo.bmWidth, mDstInfo.bmHeight, mDstInfo.bmBitsPixel);
numbytes = ::GetDIBits(dstdc, dstbits, 0, mDstInfo.bmHeight, mDstBytes, (LPBITMAPINFO)mDstbinfo, DIB_RGB_COLORS);
mDRowBytes = CalcBytesSpan(mDstInfo.bmWidth, mDstInfo.bmBitsPixel);
}
mDstInfo.bmBits = mDstBytes;
}
// calculate the metrics, no mask right now
srcloc.x = aSX;
srcloc.y = aSY;
mSrcInfo.bmBits = mSrcBytes;
mDstInfo.bmBits = mDstBytes;
maskloc.x = 0;
maskloc.y = 0;
if(CalcAlphaMetrics(&mSrcInfo,&mDstInfo,&srcloc,NULL,&maskloc,aWidth,aHeight,&numlines,&numbytes,
&s1,&d1,&m1,&slinespan,&dlinespan,&mlinespan))
if (CalcAlphaMetrics(&mSrcInfo, &mDstInfo, &srcloc, NULL, &maskloc, aWidth, aHeight, &numlines, &numbytes,
&s1, &d1, &m1, &slinespan, &dlinespan, &mlinespan))
{
if (nsnull != aSaveBlendArea)
{
if( aSaveBlendArea )
{
oldsize = mSaveLS*mSaveNumLines;
oldsize = mSaveLS * mSaveNumLines;
// allocate some memory
mSaveLS = numbytes;
@ -158,70 +226,98 @@ nsColorMap *colormap;
mSaveNumBytes = numbytes;
if(mSaveBytes != nsnull)
{
{
if(oldsize != size)
{
{
delete [] mSaveBytes;
mSaveBytes = new unsigned char[size];
}
}
}
else
mSaveBytes = new unsigned char[size];
mRestorePtr = d1;
mResLS = dlinespan;
}
// now do the blend
if ((mSrcInfo.bmBitsPixel==24) && (mDstInfo.bmBitsPixel==24))
{
if(mask)
{
this->Do24BlendWithMask(numlines,numbytes,s1,d1,m1,slinespan,dlinespan,mlinespan,nsHighQual,aSaveBlendArea);
result = NS_OK;
}
else
{
level = (PRInt32)(aSrcOpacity*100);
this->Do24Blend(level,numlines,numbytes,s1,d1,slinespan,dlinespan,nsHighQual,aSaveBlendArea);
result = NS_OK;
}
}
else
if ((mSrcInfo.bmBitsPixel==8) && (mDstInfo.bmBitsPixel==8))
{
if(mask)
{
this->Do8BlendWithMask(numlines,numbytes,s1,d1,m1,slinespan,dlinespan,mlinespan,nsHighQual,aSaveBlendArea);
result = NS_OK;
}
else
{
level = (PRInt32)(aSrcOpacity*100);
this->Do8Blend(level,numlines,numbytes,s1,d1,slinespan,dlinespan,colormap,nsHighQual,aSaveBlendArea);
result = NS_OK;
}
}
else
{
if ((mSrcInfo.bmBitsPixel==16) && (mDstInfo.bmBitsPixel==16))
{
if(!mask)
{
this->Do16Blend(level,numlines,numbytes,s1,d1,slinespan,dlinespan,nsHighQual,aSaveBlendArea);
result = NS_OK;
}
}
}
// put the new bits in
dstdc = ((nsDrawingSurfaceWin *)aDst)->mDC;
dstbits = ::CreateDIBitmap(dstdc, mDstbinfo, CBM_INIT, mDstBytes, (LPBITMAPINFO)mDstbinfo, DIB_RGB_COLORS);
tb1 = (HBITMAP)::SelectObject(dstdc,dstbits);
::DeleteObject(tb1);
}
return result;
if (mSrcInfo.bmBitsPixel == mDstInfo.bmBitsPixel)
{
// now do the blend
switch (mSrcInfo.bmBitsPixel)
{
case 32:
if (!mask)
{
level = (PRInt32)(100 - aSrcOpacity*100);
Do32Blend(level,numlines,numbytes,s1,d1,slinespan,dlinespan,nsHighQual,aSaveBlendArea);
result = NS_OK;
}
else
result = NS_ERROR_FAILURE;
break;
case 24:
if (mask)
{
Do24BlendWithMask(numlines,numbytes,s1,d1,m1,slinespan,dlinespan,mlinespan,nsHighQual,aSaveBlendArea);
result = NS_OK;
}
else
{
level = (PRInt32)(100 - aSrcOpacity*100);
Do24Blend(level,numlines,numbytes,s1,d1,slinespan,dlinespan,nsHighQual,aSaveBlendArea);
result = NS_OK;
}
break;
case 16:
if (!mask)
{
level = (PRInt32)(100 - aSrcOpacity*100);
Do16Blend(level,numlines,numbytes,s1,d1,slinespan,dlinespan,nsHighQual,aSaveBlendArea);
result = NS_OK;
}
else
result = NS_ERROR_FAILURE;
break;
case 8:
if (mask)
{
Do8BlendWithMask(numlines,numbytes,s1,d1,m1,slinespan,dlinespan,mlinespan,nsHighQual,aSaveBlendArea);
result = NS_OK;
}
else
{
level = (PRInt32)(100 - aSrcOpacity*100);
Do8Blend(level,numlines,numbytes,s1,d1,slinespan,dlinespan,colormap,nsHighQual,aSaveBlendArea);
result = NS_OK;
}
break;
}
if (PR_FALSE == dstissurf)
{
// put the new bits in
dstdc = ((nsDrawingSurfaceWin *)aDst)->mDC;
dstbits = ::CreateDIBitmap(dstdc, mDstbinfo, CBM_INIT, mDstBytes, (LPBITMAPINFO)mDstbinfo, DIB_RGB_COLORS);
tb1 = (HBITMAP)::SelectObject(dstdc, dstbits);
::DeleteObject(tb1);
}
}
else
result == NS_ERROR_FAILURE;
}
#ifdef NGLAYOUT_DDRAW
if (PR_TRUE == srcissurf)
mSrcDS->mSurface->Unlock(mSrcSurf.lpSurface);
if (PR_TRUE == dstissurf)
mDstDS->mSurface->Unlock(mDstSurf.lpSurface);
#endif
return result;
}
//------------------------------------------------------------
@ -236,35 +332,80 @@ PRUint8 *orgptr,*orgbyteptr;
HDC dstdc;
HBITMAP dstbits, tb1;
//XXX this is busted with directdraw... MMP
if(mSaveBytes!=nsnull)
{
{
result = PR_TRUE;
saveptr = mSaveBytes;
orgptr = mRestorePtr;
for(y=0;y<mSaveNumLines;y++)
{
{
savebyteptr = saveptr;
orgbyteptr = orgptr;
for(x=0;x<mSaveNumBytes;x++)
{
{
*orgbyteptr = *savebyteptr;
savebyteptr++;
orgbyteptr++;
}
}
saveptr+=mSaveLS;
orgptr+=mResLS;
}
}
// put the new bits in
dstdc = ((nsDrawingSurfaceWin *)aDst)->mDC;
dstbits = ::CreateDIBitmap(dstdc, mDstbinfo, CBM_INIT, mDstBytes, (LPBITMAPINFO)mDstbinfo, DIB_RGB_COLORS);
tb1 = (HBITMAP)::SelectObject(dstdc,dstbits);
::DeleteObject(tb1);
}
}
return(result);
}
#ifdef NGLAYOUT_DDRAW
PRBool nsBlenderWin :: LockSurface(IDirectDrawSurface *aSurface, DDSURFACEDESC *aDesc, BITMAP *aBitmap, RECT *aRect, DWORD aLockFlags)
{
if (nsnull != aSurface)
{
aDesc->dwSize = sizeof(DDSURFACEDESC);
if (DD_OK == aSurface->Lock(aRect, aDesc, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR | aLockFlags, NULL))
{
if ((aDesc->ddpfPixelFormat.dwFlags &
(DDPF_ALPHA | DDPF_PALETTEINDEXED1 |
DDPF_PALETTEINDEXED2 | DDPF_PALETTEINDEXED4 |
DDPF_PALETTEINDEXEDTO8 | DDPF_YUV | DDPF_ZBUFFER)) ||
(aDesc->ddpfPixelFormat.dwRGBBitCount < 8))
{
//this is a surface that we can't, or don't want to handle.
aSurface->Unlock(aDesc->lpSurface);
return PR_FALSE;
}
aBitmap->bmType = 0;
aBitmap->bmWidth = aDesc->dwWidth;
aBitmap->bmHeight = aDesc->dwHeight;
aBitmap->bmWidthBytes = aDesc->lPitch;
aBitmap->bmPlanes = 1;
aBitmap->bmBitsPixel = (PRUint16)aDesc->ddpfPixelFormat.dwRGBBitCount;
aBitmap->bmBits = aDesc->lpSurface;
return PR_TRUE;
}
else
return PR_FALSE;
}
else
return PR_FALSE;
}
#endif
//------------------------------------------------------------
@ -280,34 +421,33 @@ PRBool doalpha = PR_FALSE;
nsRect arect,srect,drect,irect;
PRInt32 startx,starty;
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);
//srect.SetRect(aMaskUL->x,aMaskUL->y,aWidth,aHeight);
//arect.IntersectRect(arect,srect);
arect.SetRect(0, 0,aDestInfo->bmWidth, aDestInfo->bmHeight);
}
}
srect.SetRect(aSrcUL->x, aSrcUL->y, aSrcInfo->bmWidth, aSrcInfo->bmHeight);
drect = arect;
if (irect.IntersectRect(srect, drect))
{
{
// calculate destination information
*aDLSpan = mDRowBytes;
*aNumbytes = this->CalcBytesSpan(irect.width,aDestInfo->bmBitsPixel);
*aNumbytes = 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/8) * startx);
*aDImage = ((PRUint8*)aDestInfo->bmBits) + (starty * (*aDLSpan)) + ((aDestInfo->bmBitsPixel >> 3) * startx);
// get the intersection relative to the source rectangle
srect.SetRect(0, 0, aSrcInfo->bmWidth, aSrcInfo->bmHeight);
@ -319,20 +459,20 @@ PRInt32 startx,starty;
*aSLSpan = mSRowBytes;
startx = drect.x;
starty = aSrcInfo->bmHeight - (drect.y + drect.height);
*aSImage = ((PRUint8*)aSrcInfo->bmBits) + (starty * (*aSLSpan)) + ((aDestInfo->bmBitsPixel/8) * startx);
*aSImage = ((PRUint8*)aSrcInfo->bmBits) + (starty * (*aSLSpan)) + ((aDestInfo->bmBitsPixel >> 3) * startx);
doalpha = PR_TRUE;
if(aMaskInfo)
{
{
*aMLSpan = aMaskInfo->bmWidthBytes;
*aMImage = (PRUint8*)aMaskInfo->bmBits;
}
}
else
{
{
aMLSpan = 0;
*aMImage = nsnull;
}
}
}
return doalpha;
@ -341,9 +481,9 @@ PRInt32 startx,starty;
//------------------------------------------------------------
PRInt32
nsBlenderWin :: CalcBytesSpan(PRUint32 aWidth,PRUint32 aBitsPixel)
nsBlenderWin :: CalcBytesSpan(PRUint32 aWidth, PRUint32 aBitsPixel)
{
PRInt32 spanbytes;
PRInt32 spanbytes;
spanbytes = (aWidth * aBitsPixel) >> 5;
@ -352,7 +492,7 @@ PRInt32 spanbytes;
spanbytes <<= 2;
return(spanbytes);
return spanbytes;
}
//-----------------------------------------------------------
@ -360,58 +500,79 @@ PRInt32 spanbytes;
nsresult
nsBlenderWin :: BuildDIB(LPBITMAPINFOHEADER *aBHead,unsigned char **aBits,PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth)
{
PRInt32 numpalletcolors,imagesize,spanbytes;
PRUint8 *colortable;
DWORD bicomp;
PRInt32 palsize, imagesize, spanbytes, allocsize;
PRUint8 *colortable;
DWORD bicomp, masks[3];
switch (aDepth)
{
{
case 8:
numpalletcolors = 256;
palsize = 256;
allocsize = 256;
bicomp = BI_RGB;
break;
case 16:
numpalletcolors = 0;
bicomp = BI_RGB;
palsize = 0;
allocsize = 3;
bicomp = BI_BITFIELDS;
masks[0] = 0xf800;
masks[1] = 0x07e0;
masks[2] = 0x001f;
break;
case 24:
numpalletcolors = 0;
palsize = 0;
allocsize = 0;
bicomp = BI_RGB;
break;
default:
numpalletcolors = -1;
case 32:
palsize = 0;
allocsize = 3;
bicomp = BI_BITFIELDS;
masks[0] = 0xff0000;
masks[1] = 0x00ff00;
masks[2] = 0x0000ff;
break;
}
default:
palsize = -1;
break;
}
if (numpalletcolors >= 0)
{
(*aBHead) = (LPBITMAPINFOHEADER) new char[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * numpalletcolors];
if (palsize >= 0)
{
spanbytes = CalcBytesSpan(aWidth, aDepth);
imagesize = spanbytes * aHeight;
(*aBHead) = (LPBITMAPINFOHEADER) new char[sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * allocsize)];
(*aBHead)->biSize = sizeof(BITMAPINFOHEADER);
(*aBHead)->biWidth = aWidth;
(*aBHead)->biHeight = aHeight;
(*aBHead)->biPlanes = 1;
(*aBHead)->biBitCount = (unsigned short) aDepth;
(*aBHead)->biBitCount = (unsigned short)aDepth;
(*aBHead)->biCompression = bicomp;
(*aBHead)->biSizeImage = 0; // not compressed, so we dont need this to be set
(*aBHead)->biSizeImage = imagesize;
(*aBHead)->biXPelsPerMeter = 0;
(*aBHead)->biYPelsPerMeter = 0;
(*aBHead)->biClrUsed = numpalletcolors;
(*aBHead)->biClrImportant = numpalletcolors;
spanbytes = CalcBytesSpan(aWidth,aDepth);
imagesize = spanbytes * (*aBHead)->biHeight; // no compression
(*aBHead)->biClrUsed = palsize;
(*aBHead)->biClrImportant = palsize;
// 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);
}
if ((aDepth == 16) || (aDepth == 32))
nsCRT::memcpy(colortable, masks, sizeof(DWORD) * allocsize);
else
nsCRT::zero(colortable, sizeof(RGBQUAD) * palsize);
return NS_OK;
*aBits = new unsigned char[imagesize];
return NS_OK;
}
else
return NS_ERROR_FAILURE;
}
//------------------------------------------------------------
@ -429,6 +590,86 @@ nsBlenderWin::DeleteDIB(LPBITMAPINFOHEADER *aBHead,unsigned char **aBits)
//------------------------------------------------------------
// This routine can not be fast enough (and it's the same as the
// 24 bit routine, so maybe it can be killed...)
void
nsBlenderWin::Do32Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea)
{
PRUint8 *d1,*d2,*s1,*s2;
PRUint32 val1,val2;
PRInt32 x,y,temp1,numlines,xinc,yinc;
PRUint8 *saveptr,*sv2;
saveptr = mSaveBytes;
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;
if (aSaveBlendArea)
{
for (y = 0; y < aNumlines; y++)
{
s2 = s1;
d2 = d1;
sv2 = saveptr;
for (x = 0; x < aNumbytes; x++)
{
*sv2 = *d2;
temp1 = (((*d2) * val1) + ((*s2) * val2)) >> 8;
if (temp1 > 255)
temp1 = 255;
*d2 = (PRUint8)temp1;
sv2++;
d2++;
s2++;
}
s1 += aSLSpan;
d1 += aDLSpan;
saveptr+= mSaveLS;
}
}
else
{
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 = (PRUint8)temp1;
d2++;
s2++;
}
s1 += aSLSpan;
d1 += aDLSpan;
}
}
}
//------------------------------------------------------------
// 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,PRBool aSaveBlendArea)
@ -529,7 +770,7 @@ PRUint8 *saveptr,*sv2;
if(temp1>255)
temp1 = 255;
*sv2 = *d2;
*d2 = (unsigned char)temp1;
*d2 = (PRUint8)temp1;
sv2++;
d2++;
@ -553,7 +794,7 @@ PRUint8 *saveptr,*sv2;
temp1 = (((*d2)*val1)+((*s2)*val2))>>8;
if(temp1>255)
temp1 = 255;
*d2 = (unsigned char)temp1;
*d2 = (PRUint8)temp1;
d2++;
s2++;
@ -568,111 +809,115 @@ PRUint8 *saveptr,*sv2;
//------------------------------------------------------------
#define RED16(x) ((x)&0x7C00)>>7
#define GREEN16(x) ((x)&0x3E0)>>2
#define BLUE16(x) ((x)&0x1F)<<3
#define RED16(x) (((x) & 0xf800) >> 8)
#define GREEN16(x) (((x) & 0x07e0) >> 3)
#define BLUE16(x) (((x) & 0x001f) << 3)
// This routine can not be fast enough
void
nsBlenderWin::Do16Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea)
{
PRUint16 *d1,*d2,*s1,*s2;
PRUint32 val1,val2,red,green,blue,t1,t2;
PRUint32 val1,val2,red,green,blue,stemp,dtemp;
PRInt32 x,y,numlines,xinc,yinc;
PRUint16 *saveptr,*sv2;
PRInt16 dspan,sspan,span,savesp;
// since we are using 16 bit pointers, the num bytes need to be cut by 2
saveptr = (PRUint16*)mSaveBytes;
aBlendVal = (aBlendVal*255)/100;
aBlendVal = (aBlendVal * 255) / 100;
val2 = aBlendVal;
val1 = 255-val2;
// now go thru the image and blend (remember, its bottom upwards)
s1 = (PRUint16*)aSImage;
d1 = (PRUint16*)aDImage;
dspan = aDLSpan/2;
sspan = aSLSpan/2;
span = aNumbytes/2;
savesp = mSaveLS/2;
numlines = aNumlines;
dspan = aDLSpan >> 1;
sspan = aSLSpan >> 1;
span = aNumbytes >> 1;
savesp = mSaveLS >> 1;
numlines = aNumlines;
xinc = 1;
yinc = 1;
if(aSaveBlendArea)
if (aSaveBlendArea)
{
for (y = 0; y < aNumlines; y++)
{
for(y = 0; y < aNumlines; y++)
{
s2 = s1;
d2 = d1;
sv2 = saveptr;
for(x=0;x<span;x++)
{
for (x = 0; x < span; x++)
{
stemp = *s2;
dtemp = *d2;
red = (RED16(dtemp) * val1 + RED16(stemp) * val2) >> 8;
t1 = RED16(*d2);
t2 = RED16(*s2);
red = (t1*val1+t2*val2)>>8;
if(red>255)
if (red > 255)
red = 255;
t1 = GREEN16(*d2);
t2 = GREEN16(*s2);
green = (t1*val1+t2*val2)>>8;
if(green>255)
green = (GREEN16(dtemp) * val1 + GREEN16(stemp) * val2) >> 8;
if (green > 255)
green = 255;
t1 = BLUE16(*d2);
t2 = BLUE16(*s2);
blue = (BLUE16(dtemp) * val1 + BLUE16(stemp) * val2) >> 8;
blue = (t1*val1+t2*val2)>>8;
if(blue>255)
if (blue > 255)
blue = 255;
*sv2 = *d2;
*d2 = ((red&0xF8)<<7) | ((green&0xF8)<<2) | (blue&0xF8)>>3;
*d2 = (PRUint16)((red & 0xf8) << 8) | ((green & 0xfc) << 3) | ((blue & 0xf8) >> 3);
sv2++;
d2++;
s2++;
}
}
s1 += sspan;
d1 += dspan;
saveptr += savesp;
}
}
}
else
{
for (y = 0; y < aNumlines; y++)
{
for(y = 0; y < aNumlines; y++)
{
s2 = s1;
d2 = d1;
for(x = 0; x < aNumbytes; x++)
{
red = RED16(*d2)*val1+RED16(*s2)*val2;
if(red>255)
for (x = 0; x < span; x++)
{
stemp = *s2;
dtemp = *d2;
red = (RED16(dtemp) * val1 + RED16(stemp) * val2) >> 8;
if (red > 255)
red = 255;
green = GREEN16(*d2)*val1+GREEN16(*s2)*val2;
if(green>255)
green = (GREEN16(dtemp) * val1 + GREEN16(stemp) * val2) >> 8;
if (green > 255)
green = 255;
blue = BLUE16(*d2)*val1+BLUE16(*s2)*val2;
if(blue>255)
blue = (BLUE16(dtemp) * val1 + BLUE16(stemp) * val2) >> 8;
if (blue > 255)
blue = 255;
*d2 = ((red&0xf8)<<7) | ((green&0xf8)<<2) | ((blue&0xf8)>>3);
*d2 = (PRUint16)((red & 0xf8) << 8) | ((green & 0xfc) << 3) | ((blue & 0xf8) >> 3);
d2++;
s2++;
}
s1 += aSLSpan;
d1 += aDLSpan;
}
s1 += sspan;
d1 += dspan;
}
}
}
//------------------------------------------------------------

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

@ -23,28 +23,30 @@
#include "nsPoint.h"
#include "nsRect.h"
#include "nsIImage.h"
#include "nsRenderingContextWin.h"
#ifdef NGLAYOUT_DDRAW
#include "ddraw.h"
#endif
//----------------------------------------------------------------------
// Blender interface
class nsBlenderWin : public nsIBlender
{
public:
NS_DECL_ISUPPORTS
NS_DECL_ISUPPORTS
nsBlenderWin();
~nsBlenderWin();
nsBlenderWin();
~nsBlenderWin();
virtual nsresult Init(nsDrawingSurface aSrc,nsDrawingSurface aDst);
virtual void CleanUp();
virtual nsresult Blend(PRInt32 aSX, PRInt32 aSY, PRInt32 aWidth, PRInt32 aHeight,
nsDrawingSurface aDest, PRInt32 aDX, PRInt32 aDY, float aSrcOpacity,PRBool aSaveBlendArea);
nsDrawingSurface GetSrcDS() {return(mSrcDC);}
nsDrawingSurface GetDstDS() {return(mDstDC);}
nsDrawingSurface GetSrcDS() {return(mSrcDS);}
nsDrawingSurface GetDstDS() {return(mDstDS);}
PRBool RestoreImage(nsDrawingSurface aDst);
@ -75,6 +77,9 @@ public:
*/
void DeleteDIB(LPBITMAPINFOHEADER *aBHead,unsigned char **aBits);
void Do32Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,
PRInt32 aSLSpan,PRInt32 aDLSpan,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea);
/**
* Blend two 24 bit image arrays using an 8 bit alpha mask
* @param aNumlines Number of lines to blend
@ -157,15 +162,16 @@ public:
void Do8Blend(PRUint8 aBlendVal,PRInt32 aNumlines,PRInt32 aNumbytes,PRUint8 *aSImage,PRUint8 *aDImage,
PRInt32 aSLSpan,PRInt32 aDLSpan,nsColorMap *aColorMap,nsBlendQuality aBlendQuality,PRBool aSaveBlendArea);
#ifdef NGLAYOUT_DDRAW
PRBool LockSurface(IDirectDrawSurface *aSurface, DDSURFACEDESC *aDesc, BITMAP *aBitmap, RECT *aRect, DWORD aLockFlags);
#endif
private:
LPBITMAPINFOHEADER mDstbinfo,mSrcbinfo;
BITMAPINFOHEADER *mDstbinfo, *mSrcbinfo;
PRUint8 *mSrcBytes;
PRUint8 *mDstBytes;
BITMAP mSrcInfo,mDstInfo;
HBITMAP mTempB1,mTempB2;
nsDrawingSurface mSrcDC, mDstDC;
BITMAP mSrcInfo, mDstInfo;
nsDrawingSurfaceWin *mSrcDS, *mDstDS;
PRInt32 mSRowBytes;
PRInt32 mDRowBytes;
@ -177,6 +183,10 @@ public:
PRUint8 *mRestorePtr; // starting area of save dst
PRUint32 mResLS; // line span for restore area
#ifdef NGLAYOUT_DDRAW
DDSURFACEDESC mSrcSurf;
DDSURFACEDESC mDstSurf;
#endif
};
#endif

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

@ -77,7 +77,7 @@ NS_IMETHODIMP nsDeviceContextWin :: GetScrollBarDimensions(float &aWidth, float
NS_IMETHODIMP nsDeviceContextWin :: GetDrawingSurface(nsIRenderingContext &aContext, nsDrawingSurface &aSurface)
{
if (NULL == mSurface) {
mSurface = aContext.CreateDrawingSurface(nsnull);
mSurface = aContext.CreateDrawingSurface(nsnull, 0);
}
aSurface = mSurface;

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

@ -191,6 +191,7 @@ nsDrawingSurfaceWin :: nsDrawingSurfaceWin()
mDC = NULL;
mDCOwner = nsnull;
mOrigBitmap = nsnull;
mSelectedBitmap = nsnull;
#ifdef NGLAYOUT_DDRAW
mSurface = NULL;
@ -209,6 +210,8 @@ nsDrawingSurfaceWin :: ~nsDrawingSurfaceWin()
mOrigBitmap = nsnull;
}
mSelectedBitmap = nsnull;
#ifdef NGLAYOUT_DDRAW
if (NULL != mSurface)
{
@ -283,14 +286,31 @@ nsresult nsDrawingSurfaceWin :: Init(LPDIRECTDRAWSURFACE aSurface)
if (nsnull != aSurface)
{
NS_ADDREF(mSurface);
mSurface->GetDC(&mDC);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
nsresult nsDrawingSurfaceWin :: GetDC()
{
if ((nsnull == mDC) && (nsnull != mSurface))
mSurface->GetDC(&mDC);
return NS_OK;
}
nsresult nsDrawingSurfaceWin :: ReleaseDC()
{
if ((nsnull != mDC) && (nsnull != mSurface))
{
mSurface->ReleaseDC(mDC);
mDC = nsnull;
}
return NS_OK;
}
#endif
static NS_DEFINE_IID(kRenderingContextIID, NS_IRENDERING_CONTEXT_IID);
@ -441,7 +461,16 @@ nsRenderingContextWin :: ~nsRenderingContextWin()
mStateCache = nsnull;
}
NS_IF_RELEASE(mSurface);
if (nsnull != mSurface)
{
#ifdef NGLAYOUT_DDRAW
//kill the DC
mSurface->ReleaseDC();
#endif
NS_RELEASE(mSurface);
}
NS_IF_RELEASE(mMainSurface);
NS_IF_RELEASE(mDCOwner);
@ -507,6 +536,9 @@ nsRenderingContextWin :: Init(nsIDeviceContext* aContext,
mSurface->Init(aWindow);
mDC = mSurface->mDC;
mMainDC = mDC;
mMainSurface = mSurface;
NS_ADDREF(mMainSurface);
}
mDCOwner = aWindow;
@ -531,6 +563,10 @@ nsRenderingContextWin :: Init(nsIDeviceContext* aContext,
{
NS_ADDREF(mSurface);
mDC = mSurface->mDC;
mMainDC = mDC;
mMainSurface = mSurface;
NS_ADDREF(mMainSurface);
}
mDCOwner = nsnull;
@ -567,13 +603,14 @@ nsresult nsRenderingContextWin :: SetupDC(HDC aOldDC, HDC aNewDC)
// If this is a palette device, then select and realize the palette
nsPaletteInfo palInfo;
mContext->GetPaletteInfo(palInfo);
if (palInfo.isPaletteDevice && palInfo.palette) {
if (palInfo.isPaletteDevice && palInfo.palette)
{
// Select the palette in the background
mOrigPalette = ::SelectPalette(aNewDC, (HPALETTE)palInfo.palette, TRUE);
// Don't do the realization for an off-screen memory DC
if (nsnull == aOldDC) {
if (nsnull == aOldDC)
::RealizePalette(aNewDC);
}
}
if (GetDeviceCaps(aNewDC, RASTERCAPS) & (RC_BITBLT))
@ -607,31 +644,56 @@ nsresult nsRenderingContextWin :: CommonInit(void)
NS_IMETHODIMP
nsRenderingContextWin :: SelectOffScreenDrawingSurface(nsDrawingSurface aSurface)
{
NS_ASSERTION(!(nsnull != mMainDC), "offscreen surface already selected");
nsresult rv;
mMainSurface = mSurface;
mMainDC = mDC;
mSurface = (nsDrawingSurfaceWin *)aSurface;
//XXX this should reset the data in the state stack.
if (nsnull != aSurface)
{
NS_ADDREF(mSurface);
mDC = mSurface->mDC;
#ifdef NGLAYOUT_DDRAW
//get back a DC
((nsDrawingSurfaceWin *)aSurface)->GetDC();
#endif
rv = SetupDC(mDC, ((nsDrawingSurfaceWin *)aSurface)->mDC);
#ifdef NGLAYOUT_DDRAW
//kill the DC
mSurface->ReleaseDC();
#endif
NS_IF_RELEASE(mSurface);
mSurface = (nsDrawingSurfaceWin *)aSurface;
}
else
{
rv = SetupDC(mDC, mMainDC);
#ifdef NGLAYOUT_DDRAW
//kill the DC
mSurface->ReleaseDC();
#endif
NS_IF_RELEASE(mSurface);
mSurface = mMainSurface;
}
return SetupDC(mMainDC, mDC);
NS_ADDREF(mSurface);
mDC = mSurface->mDC;
return rv;
}
NS_IMETHODIMP
nsRenderingContextWin::GetHints(PRUint32& aResult)
{
PRUint32 result = 0;
if (gIsWIN95) {
if (gIsWIN95)
result |= NS_RENDERING_HINT_FAST_8BIT_TEXT;
}
aResult = result;
return NS_OK;
}
@ -943,7 +1005,7 @@ nsTransform2D * nsRenderingContextWin :: GetCurrentTransform()
return mTMatrix;
}
nsDrawingSurface nsRenderingContextWin :: CreateDrawingSurface(nsRect *aBounds)
nsDrawingSurface nsRenderingContextWin :: CreateDrawingSurface(nsRect *aBounds, PRUint32 aSurfFlags)
{
nsDrawingSurfaceWin *surf = new nsDrawingSurfaceWin();
@ -952,45 +1014,55 @@ nsDrawingSurface nsRenderingContextWin :: CreateDrawingSurface(nsRect *aBounds)
NS_ADDREF(surf);
#ifdef NGLAYOUT_DDRAW
LPDIRECTDRAWSURFACE ddsurf = nsnull;
if ((NULL != mDDraw2) && (nsnull != aBounds))
if (aSurfFlags & NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS)
{
DDSURFACEDESC ddsd;
LPDIRECTDRAWSURFACE ddsurf = nsnull;
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = aBounds->width;
ddsd.dwHeight = aBounds->height;
if ((NULL != mDDraw2) && (nsnull != aBounds))
{
DDSURFACEDESC ddsd;
nsresult res = mDDraw2->CreateSurface(&ddsd, &ddsurf, NULL);
}
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN |
((aSurfFlags & NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS) ?
DDSCAPS_SYSTEMMEMORY : 0);
ddsd.dwWidth = aBounds->width;
ddsd.dwHeight = aBounds->height;
if (NULL != ddsurf)
{
surf->Init(ddsurf);
NS_RELEASE(ddsurf);
mDDraw2->CreateSurface(&ddsd, &ddsurf, NULL);
}
if (NULL != ddsurf)
{
surf->Init(ddsurf);
NS_RELEASE(ddsurf);
}
else
surf->Init(::CreateCompatibleDC(mMainDC));
}
else
#endif
surf->Init(::CreateCompatibleDC(mDC));
surf->Init(::CreateCompatibleDC(mMainDC));
HBITMAP hBits;
if (nsnull != aBounds)
hBits = ::CreateCompatibleBitmap(mDC, aBounds->width, aBounds->height);
else
#ifdef NGLAYOUT_DDRAW
if (nsnull == surf->mSurface)
#endif
{
//we do this to make sure that the memory DC knows what the
//bitmap format of the original DC was. this way, later
//operations to create bitmaps from the memory DC will create
//bitmaps with the correct properties.
if (nsnull != aBounds)
surf->mSelectedBitmap = ::CreateCompatibleBitmap(mMainDC, aBounds->width, aBounds->height);
else
{
//we do this to make sure that the memory DC knows what the
//bitmap format of the original DC was. this way, later
//operations to create bitmaps from the memory DC will create
//bitmaps with the correct properties.
hBits = ::CreateCompatibleBitmap(mDC, 2, 2);
surf->mSelectedBitmap = ::CreateCompatibleBitmap(mMainDC, 2, 2);
}
surf->mOrigBitmap = (HBITMAP)::SelectObject(surf->mDC, surf->mSelectedBitmap);
}
surf->mOrigBitmap = (HBITMAP)::SelectObject(surf->mDC, hBits);
}
return (nsDrawingSurface)surf;
@ -1000,6 +1072,12 @@ void nsRenderingContextWin :: DestroyDrawingSurface(nsDrawingSurface aDS)
{
nsDrawingSurfaceWin *surf = (nsDrawingSurfaceWin *)aDS;
if (surf->mDC == mDC)
{
mDC = mMainDC;
mSurface = mMainSurface;
}
NS_IF_RELEASE(surf);
}
@ -1023,7 +1101,9 @@ void nsRenderingContextWin :: DrawLine(nscoord aX0, nscoord aY0, nscoord aX1, ns
LineDDA((int)(aX0),(int)(aY0),(int)(aX1),(int)(aY1),(LINEDDAPROC) LineDDAFunc,(long)&dda_struct);
} else {
}
else
{
::MoveToEx(mDC, (int)(aX0), (int)(aY0), NULL);
::LineTo(mDC, (int)(aX1), (int)(aY1));
}
@ -1377,12 +1457,14 @@ void nsRenderingContextWin :: DrawString(const char *aString, PRUint32 aLength,
nscoord aX, nscoord aY,
nscoord aWidth)
{
int x = aX;
int y = aY;
PRInt32 x = aX;
PRInt32 y = aY;
SetupFontAndColor();
mTMatrix->TransformCoord(&x,&y);
::ExtTextOut(mDC,x,y,0,NULL,aString,aLength,NULL);
mTMatrix->TransformCoord(&x, &y);
::ExtTextOut(mDC, x, y, 0, NULL, aString, aLength, NULL);
if (nsnull != mFontMetrics)
{
@ -1401,12 +1483,14 @@ void nsRenderingContextWin :: DrawString(const char *aString, PRUint32 aLength,
void nsRenderingContextWin :: DrawString(const PRUnichar *aString, PRUint32 aLength,
nscoord aX, nscoord aY, nscoord aWidth)
{
int x = aX;
int y = aY;
PRInt32 x = aX;
PRInt32 y = aY;
SetupFontAndColor();
mTMatrix->TransformCoord(&x,&y);
::ExtTextOutW(mDC,x,y,0,NULL,aString,aLength,NULL);
mTMatrix->TransformCoord(&x, &y);
::ExtTextOutW(mDC, x, y, 0, NULL, aString, aLength, NULL);
if (nsnull != mFontMetrics)
{
@ -1476,45 +1560,87 @@ void nsRenderingContextWin :: DrawImage(nsIImage *aImage, const nsRect& aRect)
((nsImageWin *)aImage)->Draw(*this, mSurface, tr.x, tr.y, tr.width, tr.height);
}
NS_IMETHODIMP nsRenderingContextWin :: CopyOffScreenBits(nsRect &aBounds)
NS_IMETHODIMP nsRenderingContextWin :: CopyOffScreenBits(nsDrawingSurface aSrcSurf,
PRInt32 aSrcX, PRInt32 aSrcY,
const nsRect &aDestBounds,
PRUint32 aCopyFlags)
{
if ((nsnull != mDC) && (nsnull != mMainDC))
if ((nsnull != aSrcSurf) && (nsnull != mMainDC))
{
HRGN tregion = ::CreateRectRgn(0, 0, 0, 0);
PRInt32 x = aSrcX;
PRInt32 y = aSrcY;
nsRect drect = aDestBounds;
HDC destdc;
if (::GetClipRgn(mDC, tregion) == 1)
::SelectClipRgn(mMainDC, tregion);
// else
// ::SelectClipRgn(mMainDC, NULL);
#ifdef NGLAYOUT_DDRAW
PRBool dccreated = PR_FALSE;
::DeleteObject(tregion);
//get back a DC
#if 0
GraphicsState *pstate = mStates;
//look for a cliprect somewhere in the stack...
while ((nsnull != pstate) && !(pstate->mFlags & FLAG_CLIP_VALID))
pstate = pstate->mNext;
if (nsnull != pstate)
::SelectClipRgn(mMainDC, pstate->mClipRegion);
else
::SelectClipRgn(mMainDC, NULL);
if ((nsnull == ((nsDrawingSurfaceWin *)aSrcSurf)->mDC) &&
(nsnull != ((nsDrawingSurfaceWin *)aSrcSurf)->mSurface))
{
((nsDrawingSurfaceWin *)aSrcSurf)->GetDC();
dccreated = PR_TRUE;
}
#endif
// If there's a palette make sure it's selected.
// XXX This doesn't seem like the best place to be doing this...
nsPaletteInfo palInfo;
HPALETTE oldPalette;
mContext->GetPaletteInfo(palInfo);
if (palInfo.isPaletteDevice && palInfo.palette) {
oldPalette = ::SelectPalette(mMainDC, (HPALETTE)palInfo.palette, TRUE);
}
::BitBlt(mMainDC, 0, 0, aBounds.width, aBounds.height, mDC, 0, 0, SRCCOPY);
if (palInfo.isPaletteDevice && palInfo.palette) {
::SelectPalette(mMainDC, oldPalette, TRUE);
if (nsnull != ((nsDrawingSurfaceWin *)aSrcSurf)->mDC)
{
if (aCopyFlags & NS_COPYBITS_TO_BACK_BUFFER)
{
NS_ASSERTION(!(nsnull == mDC), "no back buffer");
destdc = mDC;
}
else
destdc = mMainDC;
if (aCopyFlags & NS_COPYBITS_USE_SOURCE_CLIP_REGION)
{
HRGN tregion = ::CreateRectRgn(0, 0, 0, 0);
if (::GetClipRgn(((nsDrawingSurfaceWin *)aSrcSurf)->mDC, tregion) == 1)
::SelectClipRgn(destdc, tregion);
::DeleteObject(tregion);
}
// If there's a palette make sure it's selected.
// XXX This doesn't seem like the best place to be doing this...
nsPaletteInfo palInfo;
HPALETTE oldPalette;
mContext->GetPaletteInfo(palInfo);
if (palInfo.isPaletteDevice && palInfo.palette)
oldPalette = ::SelectPalette(destdc, (HPALETTE)palInfo.palette, TRUE);
if (aCopyFlags & NS_COPYBITS_XFORM_SOURCE_VALUES)
mTMatrix->TransformCoord(&x, &y);
if (aCopyFlags & NS_COPYBITS_XFORM_DEST_VALUES)
mTMatrix->TransformCoord(&drect.x, &drect.y, &drect.width, &drect.height);
::BitBlt(destdc, drect.x, drect.y,
drect.width, drect.height,
((nsDrawingSurfaceWin *)aSrcSurf)->mDC,
x, y, SRCCOPY);
if (palInfo.isPaletteDevice && palInfo.palette)
::SelectPalette(destdc, oldPalette, TRUE);
#ifdef NGLAYOUT_DDRAW
if (PR_TRUE == dccreated)
{
//kill the DC
((nsDrawingSurfaceWin *)aSrcSurf)->ReleaseDC();
}
#endif
}
else
NS_ASSERTION(0, "attempt to blit with bad DCs");
}
else
NS_ASSERTION(0, "attempt to blit with bad DCs");
@ -1733,6 +1859,21 @@ nsresult nsRenderingContextWin :: CreateDDraw()
return mDDrawResult;
}
nsresult nsRenderingContextWin :: GetDDraw(IDirectDraw2 **aDDraw)
{
CreateDDraw();
if (NULL != mDDraw2)
{
NS_ADDREF(mDDraw2);
*aDDraw = mDDraw2;
}
else
*aDDraw = NULL;
return NS_OK;
}
#endif
NS_IMETHODIMP

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

@ -95,7 +95,7 @@ public:
virtual void Scale(float aSx, float aSy);
virtual nsTransform2D * GetCurrentTransform();
virtual nsDrawingSurface CreateDrawingSurface(nsRect *aBounds);
virtual nsDrawingSurface CreateDrawingSurface(nsRect *aBounds, PRUint32 aSurfFlags);
virtual void DestroyDrawingSurface(nsDrawingSurface aDS);
virtual void DrawLine(nscoord aX0, nscoord aY0, nscoord aX1, nscoord aY1);
@ -145,7 +145,8 @@ public:
virtual void DrawImage(nsIImage *aImage, const nsRect& aRect);
virtual void DrawImage(nsIImage *aImage, const nsRect& aSRect, const nsRect& aDRect);
NS_IMETHOD CopyOffScreenBits(nsRect &aBounds);
NS_IMETHOD CopyOffScreenBits(nsDrawingSurface aSrcSurf, PRInt32 aSrcX, PRInt32 aSrcY,
const nsRect &aDestBounds, PRUint32 aCopyFlags);
// nsIScriptObjectOwner
NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
@ -154,6 +155,11 @@ public:
// nsIDOMRenderingContext
NS_DECL_IDOMRENDERINGCONTEXT
// locals
#ifdef NGLAYOUT_DDRAW
nsresult GetDDraw(IDirectDraw2 **aDDraw);
#endif
private:
nsresult CommonInit(void);
nsresult SetupDC(HDC aOldDC, HDC aNewDC);
@ -164,7 +170,9 @@ private:
HPEN SetupDottedPen(void);
void SetupFontAndColor(void);
void PushClipState(void);
#ifdef NGLAYOUT_DDRAW
nsresult CreateDDraw(void);
#endif
protected:
nscolor mCurrentColor;
@ -229,14 +237,17 @@ public:
nsresult Init(nsIWidget *aOwner);
#ifdef NGLAYOUT_DDRAW
nsresult Init(LPDIRECTDRAWSURFACE aSurface);
nsresult GetDC();
nsresult ReleaseDC();
#endif
nsIWidget *mDCOwner;
HDC mDC;
HBITMAP mOrigBitmap;
HBITMAP mSelectedBitmap;
#ifdef NGLAYOUT_DDRAW
LPDIRECTDRAWSURFACE mSurface;
IDirectDrawSurface *mSurface;
#endif
};

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

@ -91,7 +91,7 @@ NS_IMETHODIMP nsDeviceContextMac :: GetScrollBarDimensions(float &aWidth, float
NS_IMETHODIMP nsDeviceContextMac :: GetDrawingSurface(nsIRenderingContext &aContext, nsDrawingSurface &aSurface)
{
aSurface = aContext.CreateDrawingSurface(nsnull);
aSurface = aContext.CreateDrawingSurface(nsnull, 0);
return nsnull == aSurface ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
}