зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
a4a92311b9
Коммит
2812cd80c1
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче