In article <[EMAIL PROTECTED]>, Patrick
Beard <[EMAIL PROTECTED]> wrote:
> Looks like a bug to me! In fact, there are a large number of bugs in
> this file, such as nsDrawingSurfaceMac::IsPixelAddressable() not setting
> its out parameter, and nsDrawingSurfaceMac::GetPixelFormat() also.
> Patches coming up.
Index: mozilla/gfx/src/mac/nsDrawingSurfaceMac.cpp
===================================================================
RCS file: /cvsroot/mozilla/gfx/src/mac/nsDrawingSurfaceMac.cpp,v
retrieving revision 1.14
diff -u -2 -r1.14 nsDrawingSurfaceMac.cpp
--- nsDrawingSurfaceMac.cpp 2000/10/19 21:17:08 1.14
+++ nsDrawingSurfaceMac.cpp 2000/12/05 22:02:43
@@ -1,3 +1,3 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset:
2 -*-
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset:
2 -*-
*
* The contents of this file are subject to the Netscape Public
@@ -25,10 +25,6 @@
#include "nsDrawingSurfaceMac.h"
#include "nsGraphicState.h"
+#include "nsCarbonHelpers.h"
-
-static NS_DEFINE_IID(kIDrawingSurfaceIID, NS_IDRAWING_SURFACE_IID);
-static NS_DEFINE_IID(kIDrawingSurfaceMacIID,
NS_IDRAWING_SURFACE_MAC_IID);
-
-
/** ---------------------------------------------------
* See Documentation in nsIDrawingSurface.h
@@ -38,14 +34,13 @@
nsDrawingSurfaceMac :: nsDrawingSurfaceMac()
{
- NS_INIT_REFCNT();
-
- mPort = NULL;
- mGS = sGraphicStatePool.GetNewGS(); //new nsGraphicState();
- mWidth = mHeight = 0;
- mLockOffset = mLockHeight = 0;
- mLockFlags = 0;
- mIsOffscreen = PR_FALSE;
- mIsLocked = PR_FALSE;
+ NS_INIT_REFCNT();
+ mPort = NULL;
+ mGS = sGraphicStatePool.GetNewGS();
+ mWidth = mHeight = 0;
+ mLockOffset = mLockHeight = 0;
+ mLockFlags = 0;
+ mIsOffscreen = PR_FALSE;
+ mIsLocked = PR_FALSE;
}
@@ -56,58 +51,19 @@
*/
nsDrawingSurfaceMac :: ~nsDrawingSurfaceMac()
-{
- GWorldPtr offscreenGWorld;
-
- if(mIsOffscreen && mPort){
- offscreenGWorld = (GWorldPtr)mPort;
- ::UnlockPixels(::GetGWorldPixMap(offscreenGWorld));
- ::DisposeGWorld(offscreenGWorld);
- }
-
- if (mGS){
- sGraphicStatePool.ReleaseGS(mGS); //delete mGS;
- }
-
-}
-
-/** ---------------------------------------------------
- * See Documentation in nsIDrawingSurface.h
- * @update 3/02/99 dwc
- * @return error status
- */
-NS_IMETHODIMP nsDrawingSurfaceMac :: QueryInterface(REFNSIID aIID,
void** aInstancePtr)
{
- if (nsnull == aInstancePtr)
- return NS_ERROR_NULL_POINTER;
+ GWorldPtr offscreenGWorld;
- if (aIID.Equals(kIDrawingSurfaceIID)){
- nsIDrawingSurface* tmp = this;
- *aInstancePtr = (void*) tmp;
- NS_ADDREF_THIS();
- return NS_OK;
- }
-
- if (aIID.Equals(kIDrawingSurfaceMacIID)){
- nsIDrawingSurfaceMac* tmp = this;
- *aInstancePtr = (void*) tmp;
- NS_ADDREF_THIS();
- return NS_OK;
- }
-
- static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
-
- if (aIID.Equals(kISupportsIID)){
- nsIDrawingSurface* tmp = this;
- nsISupports* tmp2 = tmp;
- *aInstancePtr = (void*) tmp2;
- NS_ADDREF_THIS();
- return NS_OK;
- }
+ if (mIsOffscreen && mPort){
+ offscreenGWorld = (GWorldPtr)mPort;
+ ::UnlockPixels(::GetGWorldPixMap(offscreenGWorld));
+ ::DisposeGWorld(offscreenGWorld);
+ }
- return NS_NOINTERFACE;
+ if (mGS) {
+ sGraphicStatePool.ReleaseGS(mGS);
+ }
}
-NS_IMPL_ADDREF(nsDrawingSurfaceMac);
-NS_IMPL_RELEASE(nsDrawingSurfaceMac);
+NS_IMPL_ISUPPORTS2(nsDrawingSurfaceMac, nsIDrawingSurface,
nsIDrawingSurfaceMac)
#pragma mark-
@@ -123,26 +79,25 @@
PRInt32 *aWidthBytes,
PRUint32 aFlags)
{
- char* baseaddr;
- PRInt32 cmpSize, rowBytes;
- GWorldPtr offscreenGWorld;
- PixMapHandle thePixMap;
-
-
- if ((mIsLocked == PR_FALSE) && mIsOffscreen && mPort) {
- // get the offscreen gworld for our use
- offscreenGWorld = (GWorldPtr)mPort;
-
- // calculate the pixel data size
- thePixMap = ::GetGWorldPixMap(offscreenGWorld);
- baseaddr = GetPixBaseAddr(thePixMap);
- cmpSize = ((**thePixMap).pixelSize >> 3);
- rowBytes = (**thePixMap).rowBytes & 0x3FFF;
- *aBits = baseaddr + (aX * cmpSize) + aY * rowBytes;
- *aStride = rowBytes;
- *aWidthBytes = aWidth * cmpSize;
- mIsLocked = PR_TRUE;
- }
+ char* baseaddr;
+ PRInt32 cmpSize, rowBytes;
+ GWorldPtr offscreenGWorld;
+ PixMapHandle thePixMap;
+
+ if ((mIsLocked == PR_FALSE) && mIsOffscreen && mPort) {
+ // get the offscreen gworld for our use
+ offscreenGWorld = (GWorldPtr)mPort;
+
+ // calculate the pixel data size
+ thePixMap = ::GetGWorldPixMap(offscreenGWorld);
+ baseaddr = GetPixBaseAddr(thePixMap);
+ cmpSize = ((**thePixMap).pixelSize >> 3);
+ rowBytes = (**thePixMap).rowBytes & 0x3FFF;
+ *aBits = baseaddr + (aX * cmpSize) + aY * rowBytes;
+ *aStride = rowBytes;
+ *aWidthBytes = aWidth * cmpSize;
+ mIsLocked = PR_TRUE;
+ }
- return NS_OK;
+ return NS_OK;
}
@@ -154,6 +109,6 @@
NS_IMETHODIMP nsDrawingSurfaceMac :: Unlock(void)
{
- mIsLocked = PR_FALSE;
- return NS_OK;
+ mIsLocked = PR_FALSE;
+ return NS_OK;
}
@@ -165,8 +120,13 @@
NS_IMETHODIMP nsDrawingSurfaceMac :: GetDimensions(PRUint32 *aWidth,
PRUint32 *aHeight)
{
- *aWidth = mWidth;
- *aHeight = mHeight;
+ *aWidth = mWidth;
+ *aHeight = mHeight;
+ return NS_OK;
+}
- return NS_OK;
+NS_IMETHODIMP nsDrawingSurfaceMac :: IsOffscreen(PRBool *aOffScreen)
+{
+ *aOffScreen = mIsOffscreen;
+ return NS_OK;
}
@@ -178,5 +138,6 @@
NS_IMETHODIMP nsDrawingSurfaceMac :: IsPixelAddressable(PRBool
*aAddressable)
{
- return NS_OK;
+ *aAddressable = PR_TRUE;
+ return NS_OK;
}
@@ -188,7 +149,27 @@
NS_IMETHODIMP nsDrawingSurfaceMac :: GetPixelFormat(nsPixelFormat
*aFormat)
{
- //*aFormat = mPixFormat;
+ // TODO: fill in proper fields for 3 most likely bit depths.
+ static nsPixelFormat k8BitPixelFormat = {};
+ static nsPixelFormat k16BitPixelFormat = {};
+ static nsPixelFormat k32BitPixelFormat = {};
+
+ nsPixelFormat* format = NULL;
+ PixMapHandle pixmap = ::GetPortPixMap((CGrafPtr)mPort);
+ short depth = (**pixmap).pixelSize;
+ switch (depth) {
+ case 8:
+ format = &k8BitPixelFormat;
+ break;
+ case 16:
+ format = &k16BitPixelFormat;
+ break;
+ case 32:
+ format = &k32BitPixelFormat;
+ break;
+ }
+ if (format)
+ ::memcpy(aFormat, format, sizeof(nsPixelFormat));
- return NS_OK;
+ return NS_OK;
}
@@ -202,13 +183,8 @@
NS_IMETHODIMP nsDrawingSurfaceMac :: Init(nsDrawingSurface aDS)
{
-GrafPtr gport;
-
- nsDrawingSurfaceMac* surface = static_cast<nsDrawingSurfaceMac*>(aDS);
- surface->GetGrafPtr(&gport);
- mPort = gport;
- mGS->Init(surface);
-
-
- return NS_OK;
+ nsDrawingSurfaceMac* surface =
static_cast<nsDrawingSurfaceMac*>(aDS);
+ surface->GetGrafPtr(&mPort);
+ mGS->Init(surface);
+ return NS_OK;
}
@@ -220,9 +196,8 @@
NS_IMETHODIMP nsDrawingSurfaceMac :: Init(GrafPtr aPort)
{
-
- // set our grafPtr to the passed in port
- mPort = aPort;
- mGS->Init(aPort);
- return NS_OK;
+ // set our grafPtr to the passed in port
+ mPort = aPort;
+ mGS->Init(aPort);
+ return NS_OK;
}
@@ -234,8 +209,8 @@
NS_IMETHODIMP nsDrawingSurfaceMac :: Init(nsIWidget *aTheWidget)
{
- // get our native graphics port from the widget
- mPort =
reinterpret_cast<GrafPtr>(aTheWidget->GetNativeData(NS_NATIVE_GRAPHIC));
- mGS->Init(aTheWidget);
- return NS_OK;
+ // get our native graphics port from the widget
+ mPort =
reinterpret_cast<GrafPtr>(aTheWidget->GetNativeData(NS_NATIVE_GRAPHIC));
+ mGS->Init(aTheWidget);
+ return NS_OK;
}
@@ -248,73 +223,73 @@
NS_IMETHODIMP nsDrawingSurfaceMac :: Init(PRUint32 aDepth,PRUint32
aWidth,PRUint32 aHeight, PRUint32 aFlags)
{
- PRUint32 depth;
- Rect macRect;
- GWorldPtr offscreenGWorld = nsnull;
- GrafPtr savePort;
- Boolean tryTempMemFirst = ((aFlags &
NS_CREATEDRAWINGSURFACE_SHORTLIVED) != 0);
-
- depth = aDepth;
- mWidth = aWidth;
- mHeight = aHeight;
-
-
- // calculate the rectangle
- if (aWidth != 0){
- ::SetRect(&macRect, 0, 0, aWidth, aHeight);
- }else{
- ::SetRect(&macRect, 0, 0, 2, 2);
- }
-
- // create offscreen, first with normal memory, if that fails use temp
memory, if that fails, return
-
- // Quick and dirty check to make sure there is some memory available.
- // GWorld allocations in temp mem can still fail if the heap is
totally
- // full, because some stuff is allocated in the heap
- const long kReserveHeapFreeSpace = (1024 * 1024);
- const long kReserveHeapContigSpace = (512 * 1024);
-
- QDErr err = noErr;
- long totalSpace, contiguousSpace;
-
- if (tryTempMemFirst)
- {
- ::NewGWorld(&offscreenGWorld, depth, &macRect, nsnull, nsnull,
useTempMem);
- if (!offscreenGWorld)
+ PRUint32 depth;
+ Rect macRect;
+ GWorldPtr offscreenGWorld = nsnull;
+ GrafPtr savePort;
+ Boolean tryTempMemFirst = ((aFlags &
NS_CREATEDRAWINGSURFACE_SHORTLIVED) != 0);
+
+ depth = aDepth;
+ mWidth = aWidth;
+ mHeight = aHeight;
+
+
+ // calculate the rectangle
+ if (aWidth != 0) {
+ ::SetRect(&macRect, 0, 0, aWidth, aHeight);
+ } else {
+ ::SetRect(&macRect, 0, 0, 2, 2);
+ }
+
+ // create offscreen, first with normal memory, if that fails use
temp memory, if that fails, return
+
+ // Quick and dirty check to make sure there is some memory
available.
+ // GWorld allocations in temp mem can still fail if the heap is
totally
+ // full, because some stuff is allocated in the heap
+ const long kReserveHeapFreeSpace = (1024 * 1024);
+ const long kReserveHeapContigSpace = (512 * 1024);
+
+ QDErr err = noErr;
+ long totalSpace, contiguousSpace;
+
+ if (tryTempMemFirst)
+ {
+ ::NewGWorld(&offscreenGWorld, depth, &macRect, nsnull, nsnull,
useTempMem);
+ if (!offscreenGWorld)
+ {
+ // only try the heap if there is enough space
+ ::PurgeSpace(&totalSpace, &contiguousSpace); // this
does not purge memory, just measure it
+
+ if (totalSpace > kReserveHeapFreeSpace && contiguousSpace >
kReserveHeapContigSpace)
+ ::NewGWorld(&offscreenGWorld, depth, &macRect, nsnull,
nsnull, 0);
+ }
+ }
+ else // heap first
{
- // only try the heap if there is enough space
- ::PurgeSpace(&totalSpace, &contiguousSpace); // this does not
purge memory, just measure it
+ // only try the heap if there is enough space
+ ::PurgeSpace(&totalSpace, &contiguousSpace); // this does
not purge memory, just measure it
- if (totalSpace > kReserveHeapFreeSpace && contiguousSpace >
kReserveHeapContigSpace)
- ::NewGWorld(&offscreenGWorld, depth, &macRect, nsnull,
nsnull, 0);
+ if (totalSpace > kReserveHeapFreeSpace && contiguousSpace >
kReserveHeapContigSpace)
+ ::NewGWorld(&offscreenGWorld, depth, &macRect, nsnull,
nsnull, 0);
+
+ if (!offscreenGWorld)
+ ::NewGWorld(&offscreenGWorld, depth, &macRect, nsnull,
nsnull, useTempMem);
}
- }
- else // heap first
- {
- // only try the heap if there is enough space
- ::PurgeSpace(&totalSpace, &contiguousSpace); // this does not
purge memory, just measure it
-
- if (totalSpace > kReserveHeapFreeSpace && contiguousSpace >
kReserveHeapContigSpace)
- ::NewGWorld(&offscreenGWorld, depth, &macRect, nsnull,
nsnull, 0);
-
- if (!offscreenGWorld)
- ::NewGWorld(&offscreenGWorld, depth, &macRect, nsnull, nsnull,
useTempMem);
- }
-
- if (!offscreenGWorld)
- return NS_ERROR_OUT_OF_MEMORY;
-
- // keep the pixels locked... that's how it works on Windows and we
are forced to do
- // the same because the API doesn't give us any hook to do it at
drawing time.
- ::LockPixels(::GetGWorldPixMap(offscreenGWorld));
-
- // erase the offscreen area
- ::GetPort(&savePort);
- ::SetPort((GrafPtr)offscreenGWorld);
- ::EraseRect(&macRect);
- ::SetPort(savePort);
-
- this->Init((GrafPtr)offscreenGWorld);
- mIsOffscreen = PR_TRUE;
- return NS_OK;
+
+ if (!offscreenGWorld)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ // keep the pixels locked... that's how it works on Windows and we
are forced to do
+ // the same because the API doesn't give us any hook to do it at
drawing time.
+ ::LockPixels(::GetGWorldPixMap(offscreenGWorld));
+
+ // erase the offscreen area
+ ::GetPort(&savePort);
+ ::SetPort((GrafPtr)offscreenGWorld);
+ ::EraseRect(&macRect);
+ ::SetPort(savePort);
+
+ this->Init((GrafPtr)offscreenGWorld);
+ mIsOffscreen = PR_TRUE;
+ return NS_OK;
}
Index: mozilla/gfx/src/mac/nsDrawingSurfaceMac.h
===================================================================
RCS file: /cvsroot/mozilla/gfx/src/mac/nsDrawingSurfaceMac.h,v
retrieving revision 1.9
diff -u -2 -r1.9 nsDrawingSurfaceMac.h
--- nsDrawingSurfaceMac.h 2000/02/04 15:53:39 1.9
+++ nsDrawingSurfaceMac.h 2000/12/05 22:02:45
@@ -44,5 +44,5 @@
NS_IMETHOD Unlock(void);
NS_IMETHOD GetDimensions(PRUint32 *aWidth, PRUint32 *aHeight);
- NS_IMETHOD IsOffscreen(PRBool *aOffScreen) {return mIsOffscreen;}
+ NS_IMETHOD IsOffscreen(PRBool *aOffScreen);
NS_IMETHOD IsPixelAddressable(PRBool *aAddressable);
NS_IMETHOD GetPixelFormat(nsPixelFormat *aFormat);
@@ -53,21 +53,21 @@
NS_IMETHOD Init(nsIWidget *aTheWidget);
NS_IMETHOD Init(PRUint32 aDepth,PRUint32 aWidth, PRUint32
aHeight,PRUint32 aFlags);
- NS_IMETHOD GetGrafPtr(GrafPtr *aTheGrafPtr) {*aTheGrafPtr =
mPort;return NS_OK;}
+ NS_IMETHOD GetGrafPtr(GrafPtr *aTheGrafPtr) {*aTheGrafPtr =
mPort;return NS_OK;}
// locals
- nsGraphicState* GetGS(void) {return mGS;}
+ nsGraphicState* GetGS(void) {return mGS;}
private:
- GrafPtr mPort; // the onscreen or
offscreen GrafPtr;
+ GrafPtr mPort; // the onscreen or
offscreen GrafPtr;
- PRUint32 mWidth;
- PRUint32 mHeight;
- PRInt32 mLockOffset;
- PRInt32 mLockHeight;
- PRUint32 mLockFlags;
- PRBool mIsOffscreen;
- PRBool mIsLocked;
+ PRUint32 mWidth;
+ PRUint32 mHeight;
+ PRInt32 mLockOffset;
+ PRInt32 mLockHeight;
+ PRUint32 mLockFlags;
+ PRBool mIsOffscreen;
+ PRBool mIsLocked;
- nsGraphicState* mGS; // a graphics state for the
surface
+ nsGraphicState* mGS; // a graphics state
for the surface
};
Index: mozilla/gfx/src/mac/nsIDrawingSurfaceMac.h
===================================================================
RCS file: /cvsroot/mozilla/gfx/src/mac/nsIDrawingSurfaceMac.h,v
retrieving revision 1.3
diff -u -2 -r1.3 nsIDrawingSurfaceMac.h
--- nsIDrawingSurfaceMac.h 1999/11/06 03:21:20 1.3
+++ nsIDrawingSurfaceMac.h 2000/12/05 22:02:45
@@ -39,4 +39,5 @@
{
public:
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_IDRAWING_SURFACE_MAC_IID)
/**
* Initialize a drawing surface using a Macintosh GrafPtr.