diff --git a/gfx/src/mac/nsATSUIUtils.cpp b/gfx/src/mac/nsATSUIUtils.cpp index 48bb4fde7285..1167cfe2f356 100644 --- a/gfx/src/mac/nsATSUIUtils.cpp +++ b/gfx/src/mac/nsATSUIUtils.cpp @@ -358,15 +358,17 @@ ATSUTextLayout nsATSUIToolkit::GetTextLayout(short aFontNum, short aSize, PRBool return txLayout; } + //------------------------------------------------------------------------ // PrepareToDraw // //------------------------------------------------------------------------ -void nsATSUIToolkit::PrepareToDraw(GrafPtr aPort, nsIDeviceContext* aContext) +void nsATSUIToolkit::PrepareToDraw(CGrafPtr aPort, nsIDeviceContext* aContext) { mPort = aPort; mContext = aContext; } + //------------------------------------------------------------------------ // StartDraw // @@ -374,12 +376,8 @@ void nsATSUIToolkit::PrepareToDraw(GrafPtr aPort, nsIDeviceContext* aContext) void nsATSUIToolkit::StartDraw( const PRUnichar *aCharPt, short aSize, short aFontNum, - PRBool aBold, PRBool aItalic, nscolor aColor, - GrafPtr& oSavePort, ATSUTextLayout& oLayout) + PRBool aBold, PRBool aItalic, nscolor aColor, ATSUTextLayout& oLayout) { - ::GetPort(&oSavePort); - ::SetPort(mPort); - OSStatus err = noErr; oLayout = GetTextLayout(aFontNum, aSize, aBold, aItalic, aColor); if (nsnull == oLayout) { @@ -388,20 +386,13 @@ void nsATSUIToolkit::StartDraw( } err = ATSUSetTextPointerLocation( oLayout, (ConstUniCharArrayPtr)aCharPt, 0, 1, 1); - if(noErr != err) { + if (noErr != err) { NS_WARNING("ATSUSetTextPointerLocation failed"); oLayout = nsnull; } return; } -//------------------------------------------------------------------------ -// EndDraw -// -//------------------------------------------------------------------------ -void nsATSUIToolkit::EndDraw(GrafPtr aSavePort) -{ - ::SetPort(aSavePort); -} + //------------------------------------------------------------------------ // GetWidth // @@ -416,33 +407,29 @@ nsATSUIToolkit::GetTextDimensions( if (!nsATSUIUtils::IsAvailable()) return NS_ERROR_NOT_INITIALIZED; - nsresult res = NS_ERROR_FAILURE; - GrafPtr savePort; - ATSUTextLayout aTxtLayout; + StPortSetter setter(mPort); - StartDraw(aCharPt, aSize, aFontNum, aBold, aItalic, aColor , savePort, aTxtLayout); + ATSUTextLayout aTxtLayout; + StartDraw(aCharPt, aSize, aFontNum, aBold, aItalic, aColor, aTxtLayout); if (nsnull == aTxtLayout) - { - return res; - } + return NS_ERROR_FAILURE; OSStatus err = noErr; ATSUTextMeasurement after; ATSUTextMeasurement ascent; ATSUTextMeasurement descent; - err = ATSUMeasureText( aTxtLayout, 0, 1, NULL, &after, &ascent, &descent ); + err = ATSUMeasureText(aTxtLayout, 0, 1, NULL, &after, &ascent, &descent); if (noErr != err) { NS_WARNING("ATSUMeasureText failed"); - EndDraw(savePort); - return res; + return NS_ERROR_FAILURE; } + oDim.width = FixRound(after); oDim.ascent = FixRound(ascent); oDim.descent = FixRound(descent); - res = NS_OK; - EndDraw(savePort); - return res; + // aTxtLayout is cached and does not need to be disposed + return NS_OK; } @@ -462,34 +449,29 @@ nsATSUIToolkit::DrawString( if (!nsATSUIUtils::IsAvailable()) return NS_ERROR_NOT_INITIALIZED; - nsresult res = NS_ERROR_FAILURE; - GrafPtr savePort; + StPortSetter setter(mPort); + ATSUTextLayout aTxtLayout; - StartDraw(aCharPt, aSize, aFontNum, aBold, aItalic, aColor , savePort, aTxtLayout); + StartDraw(aCharPt, aSize, aFontNum, aBold, aItalic, aColor, aTxtLayout); if (nsnull == aTxtLayout) - { - return res; - } + return NS_ERROR_FAILURE; OSStatus err = noErr; ATSUTextMeasurement iAfter; err = ATSUMeasureText( aTxtLayout, 0, 1, NULL, &iAfter, NULL, NULL ); - if(noErr != err) { + if (noErr != err) { NS_WARNING("ATSUMeasureText failed"); - EndDraw(savePort); - return res; + return NS_ERROR_FAILURE; } - err = ATSUDrawText( aTxtLayout, 0, 1, Long2Fix(x), Long2Fix(y)); - if(noErr != err) { + err = ATSUDrawText(aTxtLayout, 0, 1, Long2Fix(x), Long2Fix(y)); + if (noErr != err) { NS_WARNING("ATSUDrawText failed"); - EndDraw(savePort); - return res; + return NS_ERROR_FAILURE; } - oWidth = FixRound(iAfter); - res = NS_OK; - EndDraw(savePort); - return res; + oWidth = FixRound(iAfter); + // aTxtLayout is cached and does not need to be disposed + return NS_OK; } diff --git a/gfx/src/mac/nsATSUIUtils.h b/gfx/src/mac/nsATSUIUtils.h index 2317de0e2d08..bd213884535d 100644 --- a/gfx/src/mac/nsATSUIUtils.h +++ b/gfx/src/mac/nsATSUIUtils.h @@ -72,7 +72,7 @@ public: nsATSUIToolkit(); ~nsATSUIToolkit() {}; - void PrepareToDraw(GrafPtr aPort, nsIDeviceContext* aContext); + void PrepareToDraw(CGrafPtr aPort, nsIDeviceContext* aContext); nsresult GetTextDimensions(const PRUnichar *aCharPt, nsTextDimensions &oDim, short aSize, short fontNum, PRBool aBold, @@ -83,14 +83,13 @@ public: private: void StartDraw(const PRUnichar *aCharPt, short aSize, short fontNum, PRBool aBold, - PRBool aItalic, nscolor aColor, - GrafPtr& oSavePort, ATSUTextLayout& oLayout); - void EndDraw(GrafPtr aSavePort); + PRBool aItalic, nscolor aColor, ATSUTextLayout& oLayout); + ATSUTextLayout GetTextLayout(short aFontNum, short aSize, PRBool aBold, PRBool aItalic, nscolor aColor); private: - GrafPtr mPort; + CGrafPtr mPort; nsIDeviceContext* mContext; }; diff --git a/gfx/src/mac/nsCarbonHelpers.h b/gfx/src/mac/nsCarbonHelpers.h index eb676ba0cad0..6d028a7952f2 100644 --- a/gfx/src/mac/nsCarbonHelpers.h +++ b/gfx/src/mac/nsCarbonHelpers.h @@ -48,6 +48,7 @@ #endif #include #include +#include #if UNIVERSAL_INTERFACES_VERSION < 0x0341 enum { @@ -86,14 +87,24 @@ inline void SetControlPopupMenuStuff ( ControlHandle control, MenuHandle menu, s } +inline WindowRef GetTheWindowList(void) +{ +#if TARGET_CARBON + return GetWindowList(); +#else + return LMGetWindowList(); +#endif +} + + #if !TARGET_CARBON -inline void GetPortHiliteColor ( GrafPtr port, RGBColor* color ) +inline void GetPortHiliteColor(CGrafPtr port, RGBColor* color) { // is this really a color grafport? - if (port->portBits.rowBytes & 0xC000) + if (port->portVersion & 0xC000) { - GrafVars** grafVars = (GrafVars**)((CGrafPtr)port)->grafVars; + GrafVars** grafVars = (GrafVars**)port->grafVars; *color = (*grafVars)->rgbHiliteColor; } else @@ -103,6 +114,11 @@ inline void GetPortHiliteColor ( GrafPtr port, RGBColor* color ) } } +inline Boolean IsPortOffscreen(CGrafPtr port) +{ + return ((UInt16)port->portVersion == 0xC001); +} + inline Rect* GetRegionBounds(RgnHandle region, Rect* rect) { *rect = (**region).rgnBBox; @@ -114,48 +130,48 @@ inline Boolean IsRegionComplex(RgnHandle region) return (**region).rgnSize != sizeof(MacRegion); } -inline void GetPortVisibleRegion(GrafPtr port, RgnHandle visRgn) +inline void GetPortVisibleRegion(CGrafPtr port, RgnHandle visRgn) { ::CopyRgn(port->visRgn, visRgn); } -inline void GetPortClipRegion(GrafPtr port, RgnHandle clipRgn) +inline void GetPortClipRegion(CGrafPtr port, RgnHandle clipRgn) { ::CopyRgn(port->clipRgn, clipRgn); } -inline short GetPortTextFace ( GrafPtr port ) +inline short GetPortTextFace(CGrafPtr port) { return port->txFace; } -inline short GetPortTextFont ( GrafPtr port ) +inline short GetPortTextFont(CGrafPtr port) { return port->txFont; } -inline short GetPortTextSize ( GrafPtr port ) +inline short GetPortTextSize(CGrafPtr port) { return port->txSize; } -inline Rect* GetPortBounds(GrafPtr port, Rect* portRect) +inline Rect* GetPortBounds(CGrafPtr port, Rect* portRect) { *portRect = port->portRect; return portRect; } -inline PixMapHandle GetPortPixMap ( CGrafPtr port ) +inline PixMapHandle GetPortPixMap(CGrafPtr port) { return port->portPixMap; } -inline Boolean IsRegionRectangular ( RgnHandle rgn ) +inline Boolean IsRegionRectangular(RgnHandle rgn) { return (**rgn).rgnSize == 10; } -inline GrafPtr GetQDGlobalsThePort ( ) +inline GrafPtr GetQDGlobalsThePort() { return qd.thePort; } diff --git a/gfx/src/mac/nsDeviceContextMac.cpp b/gfx/src/mac/nsDeviceContextMac.cpp index a89db71a0ff5..605f321b4e0e 100644 --- a/gfx/src/mac/nsDeviceContextMac.cpp +++ b/gfx/src/mac/nsDeviceContextMac.cpp @@ -131,21 +131,17 @@ NS_IMETHODIMP nsDeviceContextMac :: CreateRenderingContext(nsIRenderingContext * } #endif -nsRenderingContextMac *pContext; -nsresult rv; -GrafPtr thePort; + nsRenderingContextMac *pContext; + nsresult rv; pContext = new nsRenderingContextMac(); - if (nsnull != pContext){ + if (nsnull != pContext) { NS_ADDREF(pContext); - ::GetPort(&thePort); + CGrafPtr thePort; + ::GetPort((GrafPtr*)&thePort); - if (nsnull != thePort){ - rv = pContext->Init(this,thePort); - } - else - rv = NS_ERROR_OUT_OF_MEMORY; + rv = pContext->Init(this, thePort); } else rv = NS_ERROR_OUT_OF_MEMORY; @@ -435,9 +431,6 @@ nsDeviceContextMac :: FindScreenForSurface ( nsIScreen** outScreen ) return; } - GrafPtr savedPort; - ::GetPort ( &savedPort ); - // we have a widget stashed inside, get a native WindowRef out of it nsIWidget* widget = reinterpret_cast(mWidget); // PRAY! NS_ASSERTION ( widget, "No Widget --> No Window" ); @@ -446,6 +439,9 @@ nsDeviceContextMac :: FindScreenForSurface ( nsIScreen** outScreen ) return; } WindowRef window = reinterpret_cast(widget->GetNativeData(NS_NATIVE_DISPLAY)); + + StPortSetter setter(window); + Rect bounds; ::GetWindowPortBounds ( window, &bounds ); @@ -456,8 +452,6 @@ nsDeviceContextMac :: FindScreenForSurface ( nsIScreen** outScreen ) NS_IF_ADDREF(*outScreen = mPrimaryScreen.get()); } else { - ::SetPortWindowPort( window ); - // convert window bounds to global coordinates Point topLeft = { bounds.top, bounds.left }; Point bottomRight = { bounds.bottom, bounds.right }; @@ -473,8 +467,6 @@ nsDeviceContextMac :: FindScreenForSurface ( nsIScreen** outScreen ) else *outScreen = nsnull; - ::SetPort ( savedPort ); - } // FindScreenForSurface diff --git a/gfx/src/mac/nsDrawingSurfaceMac.cpp b/gfx/src/mac/nsDrawingSurfaceMac.cpp index 628693dbaa47..31320115c952 100644 --- a/gfx/src/mac/nsDrawingSurfaceMac.cpp +++ b/gfx/src/mac/nsDrawingSurfaceMac.cpp @@ -51,7 +51,7 @@ static NS_DEFINE_IID(kIDrawingSurfaceMacIID, NS_IDRAWING_SURFACE_MAC_IID); * @update 3/02/99 dwc * @return error status */ -nsDrawingSurfaceMac :: nsDrawingSurfaceMac() +nsDrawingSurfaceMac::nsDrawingSurfaceMac() { NS_INIT_REFCNT(); @@ -70,20 +70,19 @@ nsDrawingSurfaceMac :: nsDrawingSurfaceMac() * @update 3/02/99 dwc * @return error status */ -nsDrawingSurfaceMac :: ~nsDrawingSurfaceMac() +nsDrawingSurfaceMac::~nsDrawingSurfaceMac() { - GWorldPtr offscreenGWorld; - if(mIsOffscreen && mPort){ - offscreenGWorld = (GWorldPtr)mPort; + GWorldPtr offscreenGWorld = (GWorldPtr)mPort; ::UnlockPixels(::GetGWorldPixMap(offscreenGWorld)); ::DisposeGWorld(offscreenGWorld); + + nsGraphicsUtils::SetPortToKnownGoodPort(); } if (mGS){ sGraphicStatePool.ReleaseGS(mGS); //delete mGS; } - } /** --------------------------------------------------- @@ -91,7 +90,7 @@ nsDrawingSurfaceMac :: ~nsDrawingSurfaceMac() * @update 3/02/99 dwc * @return error status */ -NS_IMETHODIMP nsDrawingSurfaceMac :: QueryInterface(REFNSIID aIID, void** aInstancePtr) +NS_IMETHODIMP nsDrawingSurfaceMac::QueryInterface(REFNSIID aIID, void** aInstancePtr) { if (nsnull == aInstancePtr) return NS_ERROR_NULL_POINTER; @@ -133,31 +132,34 @@ NS_IMPL_RELEASE(nsDrawingSurfaceMac); * @update 3/02/99 dwc * @return error status */ -NS_IMETHODIMP nsDrawingSurfaceMac :: Lock(PRInt32 aX, PRInt32 aY, +NS_IMETHODIMP nsDrawingSurfaceMac::Lock(PRInt32 aX, PRInt32 aY, PRUint32 aWidth, PRUint32 aHeight, void **aBits, PRInt32 *aStride, PRInt32 *aWidthBytes, PRUint32 aFlags) { - char* baseaddr; - PRInt32 cmpSize, rowBytes; - GWorldPtr offscreenGWorld; - PixMapHandle thePixMap; - - if ((mIsLocked == PR_FALSE) && mIsOffscreen && mPort) { + if (!mIsLocked && mIsOffscreen && mPort) + { // get the offscreen gworld for our use - offscreenGWorld = (GWorldPtr)mPort; + GWorldPtr offscreenGWorld = (GWorldPtr)mPort; // calculate the pixel data size - thePixMap = ::GetGWorldPixMap(offscreenGWorld); - baseaddr = GetPixBaseAddr(thePixMap); - cmpSize = ((**thePixMap).pixelSize >> 3); - rowBytes = (**thePixMap).rowBytes & 0x3FFF; + PixMapHandle thePixMap = ::GetGWorldPixMap(offscreenGWorld); + Ptr baseaddr = ::GetPixBaseAddr(thePixMap); + PRInt32 cmpSize = ((**thePixMap).pixelSize >> 3); + PRInt32 rowBytes = (**thePixMap).rowBytes & 0x3FFF; + *aBits = baseaddr + (aX * cmpSize) + aY * rowBytes; *aStride = rowBytes; *aWidthBytes = aWidth * cmpSize; + mIsLocked = PR_TRUE; } + else + { + NS_ASSERTION(0, "nested lock attempt"); + return NS_ERROR_FAILURE; + } return NS_OK; } @@ -167,7 +169,7 @@ NS_IMETHODIMP nsDrawingSurfaceMac :: Lock(PRInt32 aX, PRInt32 aY, * @update 3/02/99 dwc * @return error status */ -NS_IMETHODIMP nsDrawingSurfaceMac :: Unlock(void) +NS_IMETHODIMP nsDrawingSurfaceMac::Unlock(void) { mIsLocked = PR_FALSE; return NS_OK; @@ -178,11 +180,10 @@ NS_IMETHODIMP nsDrawingSurfaceMac :: Unlock(void) * @update 3/02/99 dwc * @return error status */ -NS_IMETHODIMP nsDrawingSurfaceMac :: GetDimensions(PRUint32 *aWidth, PRUint32 *aHeight) +NS_IMETHODIMP nsDrawingSurfaceMac::GetDimensions(PRUint32 *aWidth, PRUint32 *aHeight) { *aWidth = mWidth; *aHeight = mHeight; - return NS_OK; } @@ -191,9 +192,10 @@ NS_IMETHODIMP nsDrawingSurfaceMac :: GetDimensions(PRUint32 *aWidth, PRUint32 *a * @update 3/02/99 dwc * @return error status */ -NS_IMETHODIMP nsDrawingSurfaceMac :: IsPixelAddressable(PRBool *aAddressable) +NS_IMETHODIMP nsDrawingSurfaceMac::IsPixelAddressable(PRBool *aAddressable) { - return NS_OK; + NS_ASSERTION(0, "Not implemented!"); + return NS_ERROR_NOT_IMPLEMENTED; } /** --------------------------------------------------- @@ -201,11 +203,11 @@ NS_IMETHODIMP nsDrawingSurfaceMac :: IsPixelAddressable(PRBool *aAddressable) * @update 3/02/99 dwc * @return error status */ -NS_IMETHODIMP nsDrawingSurfaceMac :: GetPixelFormat(nsPixelFormat *aFormat) +NS_IMETHODIMP nsDrawingSurfaceMac::GetPixelFormat(nsPixelFormat *aFormat) { //*aFormat = mPixFormat; - - return NS_OK; + NS_ASSERTION(0, "Not implemented!"); + return NS_ERROR_NOT_IMPLEMENTED; } #pragma mark - @@ -215,16 +217,12 @@ NS_IMETHODIMP nsDrawingSurfaceMac :: GetPixelFormat(nsPixelFormat *aFormat) * @update 3/02/99 dwc * @return error status */ -NS_IMETHODIMP nsDrawingSurfaceMac :: Init(nsDrawingSurface aDS) +NS_IMETHODIMP nsDrawingSurfaceMac::Init(nsDrawingSurface aDS) { -GrafPtr gport; - nsDrawingSurfaceMac* surface = static_cast(aDS); - surface->GetGrafPtr(&gport); - mPort = gport; + surface->GetGrafPtr(&mPort); mGS->Init(surface); - return NS_OK; } @@ -233,9 +231,8 @@ GrafPtr gport; * @update 3/02/99 dwc * @return error status */ -NS_IMETHODIMP nsDrawingSurfaceMac :: Init(GrafPtr aPort) +NS_IMETHODIMP nsDrawingSurfaceMac::Init(CGrafPtr aPort) { - // set our grafPtr to the passed in port mPort = aPort; mGS->Init(aPort); @@ -247,10 +244,10 @@ NS_IMETHODIMP nsDrawingSurfaceMac :: Init(GrafPtr aPort) * @update 3/02/99 dwc * @return error status */ -NS_IMETHODIMP nsDrawingSurfaceMac :: Init(nsIWidget *aTheWidget) +NS_IMETHODIMP nsDrawingSurfaceMac::Init(nsIWidget *aTheWidget) { // get our native graphics port from the widget - mPort = reinterpret_cast(aTheWidget->GetNativeData(NS_NATIVE_GRAPHIC)); + mPort = reinterpret_cast(aTheWidget->GetNativeData(NS_NATIVE_GRAPHIC)); mGS->Init(aTheWidget); return NS_OK; } @@ -261,12 +258,11 @@ NS_IMETHODIMP nsDrawingSurfaceMac :: Init(nsIWidget *aTheWidget) * @return error status */ -NS_IMETHODIMP nsDrawingSurfaceMac :: Init(PRUint32 aDepth,PRUint32 aWidth,PRUint32 aHeight, PRUint32 aFlags) +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; @@ -324,12 +320,12 @@ NS_IMETHODIMP nsDrawingSurfaceMac :: Init(PRUint32 aDepth,PRUint32 aWidth,PRUint ::LockPixels(::GetGWorldPixMap(offscreenGWorld)); // erase the offscreen area - ::GetPort(&savePort); - ::SetPort((GrafPtr)offscreenGWorld); + { + StGWorldPortSetter setter(offscreenGWorld); ::EraseRect(&macRect); - ::SetPort(savePort); + } - this->Init((GrafPtr)offscreenGWorld); + Init(offscreenGWorld); mIsOffscreen = PR_TRUE; return NS_OK; } diff --git a/gfx/src/mac/nsDrawingSurfaceMac.h b/gfx/src/mac/nsDrawingSurfaceMac.h index 782a1c73fa23..a44d085ac136 100644 --- a/gfx/src/mac/nsDrawingSurfaceMac.h +++ b/gfx/src/mac/nsDrawingSurfaceMac.h @@ -42,6 +42,9 @@ #include "nsIDrawingSurface.h" #include "nsIDrawingSurfaceMac.h" +#include "nsGfxUtils.h" +#include "nsCarbonHelpers.h" + class nsGraphicState; class nsDrawingSurfaceMac : public nsIDrawingSurface, @@ -59,22 +62,22 @@ public: PRUint32 aFlags); NS_IMETHOD Unlock(void); NS_IMETHOD GetDimensions(PRUint32 *aWidth, PRUint32 *aHeight); - NS_IMETHOD IsOffscreen(PRBool *aOffScreen) {return mIsOffscreen;} + NS_IMETHOD IsOffscreen(PRBool *aOffScreen) { *aOffScreen = mIsOffscreen; return NS_OK; } NS_IMETHOD IsPixelAddressable(PRBool *aAddressable); NS_IMETHOD GetPixelFormat(nsPixelFormat *aFormat); //nsIDrawingSurfaceMac interface NS_IMETHOD Init(nsDrawingSurface aDS); - NS_IMETHOD Init(GrafPtr aThePort); + NS_IMETHOD Init(CGrafPtr aThePort); 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(CGrafPtr *aTheGrafPtr) { *aTheGrafPtr = mPort; return NS_OK; } // locals nsGraphicState* GetGS(void) {return mGS;} private: - GrafPtr mPort; // the onscreen or offscreen GrafPtr; + CGrafPtr mPort; // the onscreen or offscreen CGrafPtr; PRUint32 mWidth; PRUint32 mHeight; diff --git a/gfx/src/mac/nsGfxUtils.h b/gfx/src/mac/nsGfxUtils.h index e839c113e721..b69516ebbcbc 100644 --- a/gfx/src/mac/nsGfxUtils.h +++ b/gfx/src/mac/nsGfxUtils.h @@ -63,37 +63,171 @@ inline PRBool CurrentPortIsWMPort() //------------------------------------------------------------------------ -// utility port setting class +// ValidateDrawingState +// +// Test that the current drawing environment is good, which means that +// we have a valid port (as far as we can tell) //------------------------------------------------------------------------ +inline PRBool ValidateDrawingState() +{ + CGrafPtr curPort; + GDHandle curDevice; + + GetGWorld(&curPort, &curDevice); + + if (CurrentPortIsWMPort()) + return false; +#if TARGET_CARBON + if (! IsValidPort(curPort)) + return false; +#else + // all our ports should be onscreen or offscreen color graphics ports + // Onscreen ports have portVersion 0xC000, GWorlds have 0xC001. + if (((UInt16)curPort->portVersion & 0xC000) != 0xC000) + return false; +#endif + + // see if the device is in the device list. If not, it probably means that + // it's the device for an offscreen GWorld. In that case, the current port + // should be set to that GWorld too. + { + GDHandle thisDevice = GetDeviceList(); + while (thisDevice) + { + if (thisDevice == curDevice) + break; + + thisDevice = GetNextDevice(thisDevice); + } + + if ((thisDevice == nil) && !IsPortOffscreen(curPort)) // nil device is OK only with GWorld + return false; + } + + return true; +} + + +//------------------------------------------------------------------------ +// static graphics utility methods +//------------------------------------------------------------------------ +class nsGraphicsUtils +{ +public: + + //------------------------------------------------------------------------ + // SafeSetPort + // + // Set the port, being sure to set the GDevice to a valid device, since + // the current GDevice may belong to a GWorld. + //------------------------------------------------------------------------ + static void SafeSetPort(CGrafPtr newPort) + { + ::SetGWorld(newPort, ::IsPortOffscreen(newPort) ? nsnull : ::GetMainDevice()); + } + + //------------------------------------------------------------------------ + // SafeSetPortWindowPort + // + // Set the port, being sure to set the GDevice to a valid device, since + // the current GDevice may belong to a GWorld. + //------------------------------------------------------------------------ + static void SafeSetPortWindowPort(WindowPtr window) + { + SafeSetPort(::GetWindowPort(window)); + } + + //------------------------------------------------------------------------ + // SetPortToKnownGoodPort + // + // Set the port to a known good port, if possible. + //------------------------------------------------------------------------ + static void SetPortToKnownGoodPort() + { + WindowPtr firstWindow = GetTheWindowList(); + if (firstWindow) + ::SetGWorld(::GetWindowPort(firstWindow), ::GetMainDevice()); + } + +}; + + +//------------------------------------------------------------------------ +// utility port setting class +// +// This code has to deal with the situation where the current port +// is a GWorld, and the current devices that GWorld's device. So +// when setting the port to an onscreen part, we always reset the +// current device to the main device. +//------------------------------------------------------------------------ class StPortSetter { public: - StPortSetter(GrafPtr newPort) - : mNewPort(newPort), mOldPort(::GetQDGlobalsThePort()) + StPortSetter(CGrafPtr newPort) { - if (mOldPort != newPort) - ::SetPort(newPort); + InitSetter(newPort); } -#if TARGET_CARBON - StPortSetter(WindowPtr newWindow) - : mNewPort(GetWindowPort(newWindow)), mOldPort(::GetQDGlobalsThePort()) + StPortSetter(WindowPtr window) { - if (mOldPort != mNewPort) - ::SetPort(mNewPort); + InitSetter(GetWindowPort(window)); } -#endif ~StPortSetter() { - if (mOldPort != mNewPort) - ::SetPort(mOldPort); + if (mPortChanged) + ::SetGWorld(mOldPort, mOldDevice); + NS_ASSERTION(ValidateDrawingState(), "Bad drawing state"); } protected: - GrafPtr mNewPort; - GrafPtr mOldPort; + void InitSetter(CGrafPtr newPort) + { + NS_ASSERTION(ValidateDrawingState(), "Bad drawing state"); + // we assume that if the port has been set, then the port/GDevice are + // valid, and do nothing (for speed) + mPortChanged = (newPort != CGrafPtr(GetQDGlobalsThePort)); + if (mPortChanged) + { + ::GetGWorld(&mOldPort, &mOldDevice); + ::SetGWorld(newPort, ::IsPortOffscreen(newPort) ? nsnull : ::GetMainDevice()); + } + } + +protected: + Boolean mPortChanged; + CGrafPtr mOldPort; + GDHandle mOldDevice; +}; + + +//------------------------------------------------------------------------ +// utility GWorld port setting class +// +// This should *only* be used to set the port temporarily to the +// GWorld, and then restore it. +//------------------------------------------------------------------------ + +class StGWorldPortSetter +{ +public: + StGWorldPortSetter(GWorldPtr destGWorld) + { + NS_ASSERTION(::IsPortOffscreen(destGWorld), "StGWorldPortSetter should only be used for GWorlds"); + ::GetGWorld(&mOldPort, &mOldDevice); + ::SetGWorld(destGWorld, nsnull); + } + + ~StGWorldPortSetter() + { + ::SetGWorld(mOldPort, mOldDevice); + NS_ASSERTION(ValidateDrawingState(), "Bad drawing state"); + } + +protected: + GWorldPtr mOldPort; + GDHandle mOldDevice; }; //------------------------------------------------------------------------ @@ -124,10 +258,10 @@ protected: void SetPortFontStyle(SInt16 fontID, SInt16 fontSize, SInt16 fontFace) { - GrafPtr curPort; - ::GetPort(&curPort); + CGrafPtr curPort; + ::GetPort((GrafPtr*)&curPort); - NS_ASSERTION(!CurrentPortIsWMPort(), "Setting window manager port font"); + NS_ASSERTION(ValidateDrawingState(), "Bad drawing state"); mFontID = ::GetPortTextFont(curPort); mFontSize = ::GetPortTextSize(curPort); @@ -136,6 +270,7 @@ protected: ::TextFont(fontID); ::TextSize(fontSize); ::TextFace(fontFace); + } protected: diff --git a/gfx/src/mac/nsGraphicState.cpp b/gfx/src/mac/nsGraphicState.cpp index 208f027a9779..5ca5bd0f8e28 100644 --- a/gfx/src/mac/nsGraphicState.cpp +++ b/gfx/src/mac/nsGraphicState.cpp @@ -137,7 +137,7 @@ void nsGraphicState::Init(nsDrawingSurface aSurface) { // retrieve the grafPort nsDrawingSurfaceMac* surface = static_cast(aSurface); - GrafPtr port; + CGrafPtr port; surface->GetGrafPtr(&port); // init from grafPort @@ -146,7 +146,7 @@ void nsGraphicState::Init(nsDrawingSurface aSurface) //------------------------------------------------------------------------ -void nsGraphicState::Init(GrafPtr aPort) +void nsGraphicState::Init(CGrafPtr aPort) { // delete old values Clear(); @@ -158,6 +158,11 @@ void nsGraphicState::Init(GrafPtr aPort) ::RectRgn(rgn, ::GetPortBounds(aPort, &bounds)); } + Rect portBounds; + ::GetPortBounds(aPort, &portBounds); + mOffx = -portBounds.left; + mOffy = -portBounds.top; + mMainRegion = rgn; mClipRegion = DuplicateRgn(rgn); } @@ -206,7 +211,6 @@ void nsGraphicState::Duplicate(nsGraphicState* aGS) mChanges = aGS->mChanges; } - //------------------------------------------------------------------------ RgnHandle nsGraphicState::DuplicateRgn(RgnHandle aRgn, RgnHandle aDestRgn) diff --git a/gfx/src/mac/nsGraphicState.h b/gfx/src/mac/nsGraphicState.h index 28e958a5c602..dbd58223a3e6 100644 --- a/gfx/src/mac/nsGraphicState.h +++ b/gfx/src/mac/nsGraphicState.h @@ -60,11 +60,10 @@ public: void Clear(); void Init(nsDrawingSurface aSurface); - void Init(GrafPtr aPort); + void Init(CGrafPtr aPort); void Init(nsIWidget* aWindow); void Duplicate(nsGraphicState* aGS); // would you prefer an '=' operator? // - no thanks, - void SetChanges(PRUint32 aChanges) { mChanges = aChanges; } PRUint32 GetChanges() { return mChanges; } @@ -104,17 +103,6 @@ public: void ReleaseGS(nsGraphicState* aGS); private: -#if 0 - static const short kGSPoolCount = 80; // sizeof(nsGraphicState) = 36 bytes - - typedef struct nsGSRec - { - nsGraphicState* mGS; - PRBool mFree; - } nsGSRec; - - nsGSRec mGSArray[kGSPoolCount]; -#endif nsGraphicState* mFreeList; }; diff --git a/gfx/src/mac/nsIDrawingSurfaceMac.h b/gfx/src/mac/nsIDrawingSurfaceMac.h index 86d7ada28751..367fa8c7b3ba 100644 --- a/gfx/src/mac/nsIDrawingSurfaceMac.h +++ b/gfx/src/mac/nsIDrawingSurfaceMac.h @@ -69,7 +69,7 @@ public: * @param aPort GrafPtr to initialize drawing surface with * @return error status **/ - NS_IMETHOD Init(GrafPtr aPort) = 0; + NS_IMETHOD Init(CGrafPtr aPort) = 0; /** * Initialize a drawing surface using a nsIWidget. @@ -94,7 +94,7 @@ public: * @param aPort out parameter for GrafPtr * @return error status **/ - NS_IMETHOD GetGrafPtr(GrafPtr *aPort) = 0; + NS_IMETHOD GetGrafPtr(CGrafPtr *aPort) = 0; }; diff --git a/gfx/src/mac/nsImageMac.cpp b/gfx/src/mac/nsImageMac.cpp index debfcc978135..a47caa418e01 100644 --- a/gfx/src/mac/nsImageMac.cpp +++ b/gfx/src/mac/nsImageMac.cpp @@ -268,15 +268,16 @@ NS_IMETHODIMP nsImageMac::Draw(nsIRenderingContext &aContext, nsDrawingSurface a maskRect = srcRect; ::SetRect(&dstRect, aDX, aDY, aDX + aDWidth, aDY + aDHeight); - ::ForeColor(blackColor); - ::BackColor(whiteColor); - // get the destination pix map nsDrawingSurfaceMac* surface = static_cast(aSurface); CGrafPtr destPort; - nsresult rv = surface->GetGrafPtr((GrafPtr *)&destPort); + nsresult rv = surface->GetGrafPtr(&destPort); if (NS_FAILED(rv)) return rv; + StPortSetter destSetter(destPort); + ::ForeColor(blackColor); + ::BackColor(whiteColor); + PixMapHandle destPixels = ::GetGWorldPixMap(destPort); NS_ASSERTION(destPixels, "No dest pixels!"); @@ -466,10 +467,10 @@ nsImageMac::UnlockImagePixels(PRBool aMaskPixels) Handle thePixelsHandle = (aMaskPixels ? mMaskBitsHandle : mImageBitsHandle); ::HUnlock(thePixelsHandle); - if(aMaskPixels) - mMaskPixmap.baseAddr = 0; + if (aMaskPixels) + mMaskPixmap.baseAddr = nsnull; else - mImagePixmap.baseAddr = 0; + mImagePixmap.baseAddr = nsnull; return NS_OK; } @@ -497,7 +498,7 @@ OSErr nsImageMac::CreatePixMap( PRInt32 aWidth, PRInt32 aHeight, ioPixMap.cmpSize = 1; // default to black & white colortable ioPixMap.pmTable = aColorTable ? aColorTable : GetCTable(32 + 1); - bufferdepth = 1; + ioPixMap.pixelSize = 1; break; case 2: @@ -524,7 +525,7 @@ OSErr nsImageMac::CreatePixMap( PRInt32 aWidth, PRInt32 aHeight, ioPixMap.cmpSize = 8; // default to gray ramp colortable ioPixMap.pmTable = aColorTable ? aColorTable : GetCTable(32 + 8); - bufferdepth = 8; + ioPixMap.pixelSize = 8; break; case 16: @@ -532,16 +533,27 @@ OSErr nsImageMac::CreatePixMap( PRInt32 aWidth, PRInt32 aHeight, ioPixMap.cmpCount = 3; ioPixMap.cmpSize = 5; ioPixMap.pmTable = nsnull; - bufferdepth = 16; + ioPixMap.pixelSize = 16; break; case 24: // 24 and 32 bit are basically the same - case 32: ioPixMap.pixelType = RGBDirect; ioPixMap.cmpCount = 3; ioPixMap.cmpSize = 8; ioPixMap.pmTable = nsnull; - bufferdepth = 32; + ioPixMap.pixelSize = 32; // ?? + break; + + case 32: + ioPixMap.pixelType = RGBDirect; +#if TARGET_CARBON + ioPixMap.cmpCount = 4; +#else + ioPixMap.cmpCount = 3; +#endif + ioPixMap.cmpSize = 8; + ioPixMap.pmTable = nsnull; + ioPixMap.pixelSize = 32; break; default: @@ -552,7 +564,7 @@ OSErr nsImageMac::CreatePixMap( PRInt32 aWidth, PRInt32 aHeight, if (ioPixMap.cmpCount) { PRInt32 imageSize; - PRInt32 rowBytes = CalculateRowBytes(aWidth, bufferdepth); + PRInt32 rowBytes = CalculateRowBytes(aWidth, ioPixMap.pixelSize); if (rowBytes >= 0x4000) { @@ -574,14 +586,12 @@ OSErr nsImageMac::CreatePixMap( PRInt32 aWidth, PRInt32 aHeight, ioPixMap.bounds.left = 0; ioPixMap.bounds.bottom = aHeight; ioPixMap.bounds.right = aWidth; - ioPixMap.pixelSize = bufferdepth; ioPixMap.packType = 0; ioPixMap.packSize = 0; - // is this correct? printing? - ioPixMap.hRes = nsDeviceContextMac::GetScreenResolution() << 16; - ioPixMap.vRes = nsDeviceContextMac::GetScreenResolution() << 16; + ioPixMap.hRes = 72 << 16; // 72 dpi as Fixed + ioPixMap.vRes = 72 << 16; // 72 dpi as Fixed #if TARGET_CARBON - ioPixMap.pixelFormat = 0; /*fourCharCode representation*/ + ioPixMap.pixelFormat = 0; ioPixMap.pmExt = 0; #else ioPixMap.planeBytes = 0; @@ -675,23 +685,18 @@ PRInt32 nsImageMac::CalculateRowBytes(PRUint32 aWidth, PRUint32 aDepth) void nsImageMac::ClearGWorld(GWorldPtr theGWorld) { PixMapHandle thePixels; - GWorldPtr curPort; - GDHandle curDev; thePixels = ::GetGWorldPixMap(theGWorld); - ::GetGWorld(&curPort, &curDev); StPixelLocker pixelLocker(thePixels); + StGWorldPortSetter tilingWorldSetter(theGWorld); - // Black the offscreen - ::SetGWorld(theGWorld, nil); + // White the offscreen ::BackColor(whiteColor); Rect portRect; - ::GetPortBounds(reinterpret_cast(theGWorld), &portRect); + ::GetPortBounds(theGWorld, &portRect); ::EraseRect(&portRect); - - ::SetGWorld(curPort, curDev); } /** ----------------------------------------------------------------- @@ -1444,6 +1449,9 @@ nsresult nsImageMac::DrawTileQuickly(nsIRenderingContext &aContext, PRInt32 aSXOffset, PRInt32 aSYOffset, const nsRect &aTileRect) { + if (!mImageBitsHandle) + return NS_ERROR_FAILURE; + // lock and set up bits handles StHandleLocker imageBitsLocker(mImageBitsHandle); StHandleLocker maskBitsLocker(mMaskBitsHandle); // ok with nil handle @@ -1458,18 +1466,20 @@ nsresult nsImageMac::DrawTileQuickly(nsIRenderingContext &aContext, imageRect.right = mWidth; imageRect.bottom = mHeight; - // set up the dest port - ::ForeColor(blackColor); - ::BackColor(whiteColor); - // this code assumes that, if we have a mask, it's the same size as the image NS_ASSERTION((mMaskBitsHandle == nsnull) || (mAlphaWidth == mWidth && mAlphaHeight == mHeight), "Mask should be same dimensions as image"); // get the destination pix map - nsDrawingSurfaceMac* surface = static_cast(aSurface); + nsDrawingSurfaceMac* destSurface = static_cast(aSurface); + CGrafPtr destPort; - nsresult rv = surface->GetGrafPtr((GrafPtr *)&destPort); + nsresult rv = destSurface->GetGrafPtr(&destPort); if (NS_FAILED(rv)) return rv; + + StPortSetter destSetter(destPort); + ::ForeColor(blackColor); + ::BackColor(whiteColor); + PixMapHandle destPixels = ::GetGWorldPixMap(destPort); StPixelLocker destPixLocker(destPixels); @@ -1517,6 +1527,7 @@ nsresult nsImageMac::DrawTileQuickly(nsIRenderingContext &aContext, Rect tileRect = tileDestRect; ::OffsetRect(&tileRect, -tileRect.left, -tileRect.top); // offset to {0, 0} + GWorldPtr tilingGWorld = nsnull; OSErr err = AllocateGWorld(mImagePixmap.pixelSize, nsnull, tileRect, &tilingGWorld); if (err != noErr) return NS_ERROR_OUT_OF_MEMORY; diff --git a/gfx/src/mac/nsRenderingContextMac.cpp b/gfx/src/mac/nsRenderingContextMac.cpp index 6a49d35e4d32..282e9e71f5e8 100644 --- a/gfx/src/mac/nsRenderingContextMac.cpp +++ b/gfx/src/mac/nsRenderingContextMac.cpp @@ -37,7 +37,7 @@ * * ***** END LICENSE BLOCK ***** */ - +#include "nsIInterfaceRequestorUtils.h" #include "nsRenderingContextMac.h" #include "nsDeviceContextMac.h" #include "nsFontMetricsMac.h" @@ -71,28 +71,20 @@ //------------------------------------------------------------------------ nsRenderingContextMac::nsRenderingContextMac() +: mP2T(1.0f) +, mContext(nsnull) +, mCurrentSurface(nsnull) +, mPort(nsnull) +, mGS(nsnull) +, mChanges(kEverythingChanged) +#ifdef IBMBIDI +, mRightToLeftText(PR_FALSE) +#endif { NS_INIT_REFCNT(); - mP2T = 1.0f; - mContext = nsnull ; - - mSavePort = nsnull; - mSaveDevice = nsnull; mFrontSurface = new nsDrawingSurfaceMac(); NS_IF_ADDREF(mFrontSurface); - - mCurrentSurface = nsnull; - mPort = nsnull; - mGS = nsnull; - - mGSStack = new nsVoidArray(); - - mChanges = kEverythingChanged; - mLineStyle = nsLineStyle_kSolid; -#ifdef IBMBIDI - mRightToLeftText = PR_FALSE; -#endif } @@ -102,10 +94,6 @@ nsRenderingContextMac::~nsRenderingContextMac() { // restore stuff NS_IF_RELEASE(mContext); - if (mSavePort) { - ::SetGWorld(mSavePort, mSaveDevice); - ::SetOrigin(mSavePortRect.left, mSavePortRect.top); - } // release surfaces NS_IF_RELEASE(mFrontSurface); @@ -115,16 +103,14 @@ nsRenderingContextMac::~nsRenderingContextMac() mGS = nsnull; // delete the stack and its contents - if (mGSStack != nsnull) { - PRInt32 cnt = mGSStack->Count(); + PRInt32 cnt = mGSStack.Count(); for (PRInt32 i = 0; i < cnt; i ++) { - nsGraphicState* gs = (nsGraphicState*)mGSStack->ElementAt(i); + nsGraphicState* gs = (nsGraphicState*)mGSStack.ElementAt(i); if (gs != nsnull) sGraphicStatePool.ReleaseGS(gs); //delete gs; } - delete mGSStack; - mGSStack = nsnull; - } + + NS_ASSERTION(ValidateDrawingState(), "Bad drawing state"); } @@ -135,8 +121,10 @@ NS_IMPL_ISUPPORTS1(nsRenderingContextMac, nsIRenderingContext) NS_IMETHODIMP nsRenderingContextMac::Init(nsIDeviceContext* aContext, nsIWidget* aWindow) { + NS_ASSERTION(ValidateDrawingState(), "Bad drawing state"); + // make sure all allocations in the constructor succeeded. - if (nsnull == mFrontSurface || nsnull == mGSStack) + if (nsnull == mFrontSurface) return NS_ERROR_OUT_OF_MEMORY; if (nsnull == aWindow->GetNativeData(NS_NATIVE_WINDOW)) @@ -168,7 +156,7 @@ NS_IMETHODIMP nsRenderingContextMac::Init(nsIDeviceContext* aContext, nsIWidget* NS_IMETHODIMP nsRenderingContextMac::Init(nsIDeviceContext* aContext, nsDrawingSurface aSurface) { // make sure all allocations in the constructor succeeded. - if (nsnull == mFrontSurface || nsnull == mGSStack) + if (nsnull == mFrontSurface) return NS_ERROR_OUT_OF_MEMORY; mContext = aContext; @@ -184,10 +172,10 @@ NS_IMETHODIMP nsRenderingContextMac::Init(nsIDeviceContext* aContext, nsDrawingS //------------------------------------------------------------------------ // used by nsDeviceContextMac::CreateRenderingContext() for printing -nsresult nsRenderingContextMac::Init(nsIDeviceContext* aContext, GrafPtr aPort) +nsresult nsRenderingContextMac::Init(nsIDeviceContext* aContext, CGrafPtr aPort) { // make sure all allocations in the constructor succeeded. - if (nsnull == mFrontSurface || nsnull == mGSStack) + if (nsnull == mFrontSurface) return NS_ERROR_OUT_OF_MEMORY; mContext = aContext; @@ -208,14 +196,11 @@ void nsRenderingContextMac::SelectDrawingSurface(nsDrawingSurfaceMac* aSurface, if (! aSurface) return; - if (!mSavePort) { - ::GetGWorld(&mSavePort, &mSaveDevice); - if (mSavePort) - ::GetPortBounds((GrafPtr)mSavePort, &mSavePortRect); - } + NS_ASSERTION(ValidateDrawingState(), "Bad drawing state"); // if surface is changing, be extra conservative about graphic state changes. - if (mCurrentSurface != aSurface) { + if (mCurrentSurface != aSurface) + { aChanges = kEverythingChanged; NS_IF_RELEASE(mCurrentSurface); @@ -223,12 +208,13 @@ void nsRenderingContextMac::SelectDrawingSurface(nsDrawingSurfaceMac* aSurface, NS_IF_ADDREF(mCurrentSurface); } - aSurface->GetGrafPtr(&mPort); + CGrafPtr newPort; + aSurface->GetGrafPtr(&newPort); + mPort = newPort; mGS = aSurface->GetGS(); mTranMatrix = &(mGS->mTMatrix); - // quickdraw initialization - ::SetPort(mPort); + nsGraphicsUtils::SafeSetPort(mPort); ::SetOrigin(-mGS->mOffx, -mGS->mOffy); // line order... @@ -240,7 +226,7 @@ void nsRenderingContextMac::SelectDrawingSurface(nsDrawingSurfaceMac* aSurface, ::TextMode(srcOr); if (aChanges & kColorChanged) - this->SetColor(mGS->mColor); + SetColor(mGS->mColor); if (mGS->mFontMetrics && (aChanges & kFontChanged)) SetFont(mGS->mFontMetrics); @@ -261,6 +247,8 @@ void nsRenderingContextMac::SelectDrawingSurface(nsDrawingSurfaceMac* aSurface, mContext->GetAppUnitsToDevUnits(app2dev); mGS->mTMatrix.AddScale(app2dev, app2dev); } + + NS_ASSERTION(ValidateDrawingState(), "Bad drawing state"); } @@ -307,7 +295,7 @@ NS_IMETHODIMP nsRenderingContextMac::PushState(void) gs->Duplicate(mGS); // put the new GS at the end of the stack - mGSStack->AppendElement(gs); + mGSStack.AppendElement(gs); // reset the graphics changes. this always represents a delta from previous state to current. mChanges = 0; @@ -319,22 +307,26 @@ NS_IMETHODIMP nsRenderingContextMac::PushState(void) NS_IMETHODIMP nsRenderingContextMac::PopState(PRBool &aClipEmpty) { - PRInt32 count = mGSStack->Count(); + NS_ASSERTION(ValidateDrawingState(), "Bad drawing state"); + + PRInt32 count = mGSStack.Count(); + NS_ASSERTION(count > 0, "No state to pop"); if (count > 0) { PRInt32 index = count - 1; // get the GS from the stack - nsGraphicState* gs = (nsGraphicState *)mGSStack->ElementAt(index); + nsGraphicState* gs = (nsGraphicState *)mGSStack.ElementAt(index); // copy the GS into the current one and tell the current surface to use it mGS->Duplicate(gs); + SelectDrawingSurface(mCurrentSurface, mChanges); // restore the current set of changes. mChanges = mGS->GetChanges(); // remove the GS object from the stack and delete it - mGSStack->RemoveElementAt(index); + mGSStack.RemoveElementAt(index); sGraphicStatePool.ReleaseGS(gs); // make sure the matrix is pointing at the current matrix @@ -393,6 +385,9 @@ NS_IMETHODIMP nsRenderingContextMac::SelectOffScreenDrawingSurface(nsDrawingSurf NS_IMETHODIMP nsRenderingContextMac::GetDrawingSurface(nsDrawingSurface *aSurface) { *aSurface = mCurrentSurface; + // on Mac, select it too, to ensure that the port gets set correct for + // tiling and image drawing + //SelectDrawingSurface(mCurrentSurface); return NS_OK; } @@ -411,7 +406,7 @@ NS_IMETHODIMP nsRenderingContextMac::CopyOffScreenBits(nsDrawingSurface aSrcSurf // retrieve the surface nsDrawingSurfaceMac* srcSurface = static_cast(aSrcSurf); - GrafPtr srcPort; + CGrafPtr srcPort; srcSurface->GetGrafPtr(&srcPort); // apply the selected transformations @@ -439,7 +434,7 @@ NS_IMETHODIMP nsRenderingContextMac::CopyOffScreenBits(nsDrawingSurface aSrcSurf ::CopyRgn(mGS->mMainRegion, clipRgn); // get the destination port and surface - GrafPtr destPort; + CGrafPtr destPort; nsDrawingSurfaceMac* destSurface; if (aCopyFlags & NS_COPYBITS_TO_BACK_BUFFER) { destSurface = mCurrentSurface; @@ -450,15 +445,8 @@ NS_IMETHODIMP nsRenderingContextMac::CopyOffScreenBits(nsDrawingSurface aSrcSurf mFrontSurface->GetGrafPtr(&destPort); } - // select the destination surface to set the colors - nsDrawingSurfaceMac* saveSurface = nsnull; - if (mCurrentSurface != destSurface) { - saveSurface = mCurrentSurface; - SelectDrawingSurface(destSurface); - } - - // make sure the current port is correct. where else does this need to be done? - StPortSetter setter(destPort); + // set the port to the destination for CopyBits + StPortSetter portSetter(destPort); // set the right colors for CopyBits RGBColor foreColor; @@ -481,13 +469,8 @@ NS_IMETHODIMP nsRenderingContextMac::CopyOffScreenBits(nsDrawingSurface aSrcSurf // copy the bits now ::CopyBits( -#if TARGET_CARBON ::GetPortBitMapForCopyBits(srcPort), ::GetPortBitMapForCopyBits(destPort), -#else - &srcPort->portBits, - &destPort->portBits, -#endif &macSrcRect, &macDstRect, srcCopy, @@ -499,9 +482,6 @@ NS_IMETHODIMP nsRenderingContextMac::CopyOffScreenBits(nsDrawingSurface aSrcSurf if (changedBackColor) ::RGBBackColor(&backColor); - if (saveSurface != nsnull) - SelectDrawingSurface(saveSurface); - return NS_OK; } @@ -546,8 +526,10 @@ NS_IMETHODIMP nsRenderingContextMac::DestroyDrawingSurface(nsDrawingSurface aSur // if that surface is still the current one, select the front surface if (aSurface == mCurrentSurface) + { + NS_ASSERTION(mCurrentSurface != mFrontSurface, "Nuking the front surface"); SelectDrawingSurface(mFrontSurface); - + } // release the surface nsDrawingSurfaceMac* surface = static_cast(aSurface); NS_IF_RELEASE(surface); @@ -1267,7 +1249,7 @@ NS_IMETHODIMP nsRenderingContextMac::GetWidth(const PRUnichar *aString, PRUint32 if (NS_FAILED(rv)) return rv; - rv = mUnicodeRenderingToolkit.PrepareToDraw(mP2T, mContext, mGS,mPort, mRightToLeftText); + rv = mUnicodeRenderingToolkit.PrepareToDraw(mP2T, mContext, mGS, mPort, mRightToLeftText); if (NS_SUCCEEDED(rv)) rv = mUnicodeRenderingToolkit.GetWidth(aString, aLength, aWidth, aFontID); @@ -1299,7 +1281,7 @@ nsRenderingContextMac::GetTextDimensions(const PRUnichar* aString, PRUint32 aLen if (NS_FAILED(rv)) return rv; - rv = mUnicodeRenderingToolkit.PrepareToDraw(mP2T, mContext, mGS,mPort, mRightToLeftText); + rv = mUnicodeRenderingToolkit.PrepareToDraw(mP2T, mContext, mGS, mPort, mRightToLeftText); if (NS_SUCCEEDED(rv)) rv = mUnicodeRenderingToolkit.GetTextDimensions(aString, aLength, aDimensions, aFontID); @@ -1371,7 +1353,7 @@ NS_IMETHODIMP nsRenderingContextMac::DrawString(const PRUnichar *aString, PRUint if (nsnull == mGS->mFontMetrics) return NS_ERROR_NULL_POINTER; - rv = mUnicodeRenderingToolkit.PrepareToDraw(mP2T, mContext, mGS,mPort,mRightToLeftText); + rv = mUnicodeRenderingToolkit.PrepareToDraw(mP2T, mContext, mGS, mPort,mRightToLeftText); if (NS_SUCCEEDED(rv)) rv = mUnicodeRenderingToolkit.DrawString(aString, aLength, aX, aY, aFontID, aSpacing); @@ -1531,3 +1513,12 @@ nsRenderingContextMac::SetRightToLeftText(PRBool aIsRTL) } #endif +#pragma mark - + +// override to set the port back to the window port +NS_IMETHODIMP +nsRenderingContextMac::ReleaseBackbuffer(void) +{ + SelectOffScreenDrawingSurface(nsnull); + return NS_OK; +} diff --git a/gfx/src/mac/nsRenderingContextMac.h b/gfx/src/mac/nsRenderingContextMac.h index 847c603355f3..3584952a774b 100644 --- a/gfx/src/mac/nsRenderingContextMac.h +++ b/gfx/src/mac/nsRenderingContextMac.h @@ -39,21 +39,22 @@ #ifndef nsRenderingContextMac_h___ #define nsRenderingContextMac_h___ +#include +#include + #include "nsRenderingContextImpl.h" #include "nsDrawingSurfaceMac.h" #include "nsUnicodeRenderingToolkit.h" -#include -#include + +#include "nsVoidArray.h" class nsIFontMetrics; class nsIDeviceContext; class nsIRegion; class nsFont; class nsTransform2D; -class nsVoidArray; class nsGraphicState; -class DrawingSurface; // a surface is a combination of a port and a graphic state class nsUnicodeFallbackCache; class nsIGraphics; @@ -156,6 +157,9 @@ public: NS_IMETHOD GetGraphics(nsIGraphics* *aGraphics); + // nsRenderingContextImpl overrides + NS_IMETHOD ReleaseBackbuffer(void); + #ifdef MOZ_MATHML /** * Returns metrics (in app units) of an 8-bit character string @@ -181,7 +185,7 @@ public: #endif // IBMBIDI //locals NS_IMETHOD SetPortTextState(); - nsresult Init(nsIDeviceContext* aContext, GrafPtr aPort); + nsresult Init(nsIDeviceContext* aContext, CGrafPtr aPort); protected: enum GraphicStateChanges { @@ -198,17 +202,13 @@ protected: float mP2T; // Pixel to Twip conversion factor nsIDeviceContext * mContext; - CGrafPtr mSavePort; - GDHandle mSaveDevice; - Rect mSavePortRect; - nsDrawingSurfaceMac* mFrontSurface; nsDrawingSurfaceMac* mCurrentSurface; // pointer to the current surface - GrafPtr mPort; // current grafPort - shortcut for mCurrentSurface->GetPort() + CGrafPtr mPort; // current grafPort - shortcut for mCurrentSurface->GetPort() nsGraphicState * mGS; // current graphic state - shortcut for mCurrentSurface->GetGS() nsUnicodeRenderingToolkit mUnicodeRenderingToolkit; - nsVoidArray * mGSStack; // GraphicStates stack, used for PushState/PopState + nsAutoVoidArray mGSStack; // GraphicStates stack, used for PushState/PopState PRUint32 mChanges; // bit mask of attributes that have changed since last Push(). #ifdef IBMBIDI PRBool mRightToLeftText; diff --git a/gfx/src/mac/nsUnicodeRenderingToolkit.cpp b/gfx/src/mac/nsUnicodeRenderingToolkit.cpp index bea397e5e018..dc0f7ca67a55 100644 --- a/gfx/src/mac/nsUnicodeRenderingToolkit.cpp +++ b/gfx/src/mac/nsUnicodeRenderingToolkit.cpp @@ -495,15 +495,17 @@ PRBool nsUnicodeRenderingToolkit :: ATSUIFallbackDrawChar( } return PR_FALSE; } -static char *question = ""; + +static const char question[] = ""; + //------------------------------------------------------------------------ PRBool nsUnicodeRenderingToolkit :: QuestionMarkFallbackGetWidth( const PRUnichar *aCharPt, short& oWidth) { - GrafPtr thePort; - ::GetPort(&thePort); + CGrafPtr thePort; + ::GetPort((GrafPtr*)&thePort); short saveSize = ::GetPortTextSize(thePort); ::TextSize(QUESTION_FALLBACKSIZE); GetScriptTextWidth(question, 3,oWidth); @@ -518,8 +520,8 @@ PRBool nsUnicodeRenderingToolkit :: QuestionMarkFallbackDrawChar( PRInt32 y, short& oWidth) { - GrafPtr thePort; - ::GetPort(&thePort); + CGrafPtr thePort; + ::GetPort((GrafPtr*)&thePort); short saveSize = ::GetPortTextSize(thePort); ::TextSize(QUESTION_FALLBACKSIZE); DrawScriptText(question, 3, x, y, oWidth); @@ -559,8 +561,8 @@ PRBool nsUnicodeRenderingToolkit :: TransliterateFallbackGetWidth( nsAutoString tmp(aCharPt, 1); char* conv = nsnull; if(NS_SUCCEEDED(mTrans->Convert(tmp.get(), &conv)) && conv) { - GrafPtr thePort; - ::GetPort(&thePort); + CGrafPtr thePort; + ::GetPort((GrafPtr*)&thePort); short aSize = ::GetPortTextSize(thePort); PRInt32 l=nsCRT::strlen(conv); if((l>3) && ('^' == conv[0]) && ('(' == conv[1]) && (')' == conv[l-1])) // sup @@ -619,8 +621,8 @@ PRBool nsUnicodeRenderingToolkit :: TransliterateFallbackDrawChar( nsAutoString tmp(aCharPt, 1); char* conv = nsnull; if(NS_SUCCEEDED(mTrans->Convert(tmp.get(), &conv)) && conv) { - GrafPtr thePort; - ::GetPort(&thePort); + CGrafPtr thePort; + ::GetPort((GrafPtr*)&thePort); short aSize = ::GetPortTextSize(thePort); PRInt32 l=nsCRT::strlen(conv); if((l>3) && ('^' == conv[0]) && ('(' == conv[1]) && (')' == conv[l-1])) // sup @@ -760,8 +762,8 @@ PRBool nsUnicodeRenderingToolkit :: UPlusFallbackGetWidth( const PRUnichar *aCharPt, short& oWidth) { - GrafPtr thePort; - ::GetPort(&thePort); + CGrafPtr thePort; + ::GetPort((GrafPtr*)&thePort); short saveSize = ::GetPortTextSize(thePort); char buf[16]; PRUint32 len = PR_snprintf(buf, 16 , "", *aCharPt); @@ -779,8 +781,8 @@ PRBool nsUnicodeRenderingToolkit :: UPlusFallbackDrawChar( PRInt32 y, short& oWidth) { - GrafPtr thePort; - ::GetPort(&thePort); + CGrafPtr thePort; + ::GetPort((GrafPtr*)&thePort); short saveSize = ::GetPortTextSize(thePort); char buf[16]; PRUint32 len = PR_snprintf(buf, 16 , "", *aCharPt); @@ -814,7 +816,7 @@ PRBool nsUnicodeRenderingToolkit :: UPlusFallbackDrawChar( # H - Hook Above # N - Horn Above */ -static char *g1E00Dec = +static const char * const g1E00Dec = //0 1 2 3 4 5 6 7 8 9 A B C D E F U+1E00 - U+1E0F "Ar ar BD bD Bd bd Bl bl CcAccADD dD Dd dd Dl dl " //0 1 2 3 4 5 6 7 8 9 A B C D E F U+1E10 - U+1E1F @@ -907,8 +909,8 @@ PRBool nsUnicodeRenderingToolkit :: LatinFallbackDrawChar( PRInt32 idx = 3 * ( *aCharPt & 0x00FF); if(' ' != g1E00Dec[idx]) { - GrafPtr thePort; - ::GetPort(&thePort); + CGrafPtr thePort; + ::GetPort((GrafPtr*)&thePort); short aSize = ::GetPortTextSize(thePort); short dummy; short realwidth; @@ -1455,7 +1457,7 @@ nsUnicodeRenderingToolkit::DrawString(const PRUnichar *aString, PRUint32 aLength nsresult nsUnicodeRenderingToolkit::PrepareToDraw(float aP2T, nsIDeviceContext* aContext, nsGraphicState* aGS, - GrafPtr aPort, PRBool aRightToLeftText ) + CGrafPtr aPort, PRBool aRightToLeftText ) { mP2T = aP2T; mContext = aContext; diff --git a/gfx/src/mac/nsUnicodeRenderingToolkit.h b/gfx/src/mac/nsUnicodeRenderingToolkit.h index 48fd46659edb..f8c11cb228b1 100644 --- a/gfx/src/mac/nsUnicodeRenderingToolkit.h +++ b/gfx/src/mac/nsUnicodeRenderingToolkit.h @@ -38,11 +38,15 @@ #ifndef nsUnicodeRenderingToolkit_h__ #define nsUnicodeRenderingToolkit_h__ -#include "nsATSUIUtils.h" + #include + +#include "nsATSUIUtils.h" + #include "nsCOMPtr.h" #include "nsISaveAsCharset.h" #include "nsIRenderingContext.h" + class nsUnicodeFallbackCache; class nsIDeviceContext; class nsGraphicState; @@ -54,7 +58,7 @@ public: virtual ~nsUnicodeRenderingToolkit() {}; nsresult PrepareToDraw(float aP2T, nsIDeviceContext* aContext, nsGraphicState* aGS, - GrafPtr aPort, PRBool aRightToLeftText); + CGrafPtr aPort, PRBool aRightToLeftText); nsresult GetTextDimensions(const PRUnichar *aString, PRUint32 aLength, nsTextDimensions &aDimension, PRInt32 *aFontID); nsresult GetWidth(const PRUnichar *aString, PRUint32 aLength, nscoord &aWidth, @@ -107,7 +111,7 @@ private: nsIDeviceContext *mContext; nsGraphicState *mGS; // current graphic state - shortcut for mCurrentSurface->GetGS() - GrafPtr mPort; // current grafPort - shortcut for mCurrentSurface->GetPort() + CGrafPtr mPort; // current grafPort - shortcut for mCurrentSurface->GetPort() nsATSUIToolkit mATSUIToolkit; nsCOMPtr mTrans; PRBool mRightToLeftText; diff --git a/gfx/src/nsRenderingContextImpl.cpp b/gfx/src/nsRenderingContextImpl.cpp index 3a5228cb5005..8b5db8bbfd9a 100644 --- a/gfx/src/nsRenderingContextImpl.cpp +++ b/gfx/src/nsRenderingContextImpl.cpp @@ -59,10 +59,12 @@ PRInt32 PR_CALLBACK compare_active(const void *u,const void *v){return ((Edge*)u * @update 3/16/00 dwc */ nsRenderingContextImpl :: nsRenderingContextImpl() +: mTranMatrix(nsnull) +, mLineStyle(nsLineStyle_kSolid) +, mAct(0) +, mActive(nsnull) +, mPenMode(nsPenMode_kNone) { - - mPenMode = nsPenMode_kNone; - } /** --------------------------------------------------- diff --git a/gfx/src/shared/nsRenderingContextImpl.cpp b/gfx/src/shared/nsRenderingContextImpl.cpp index 3a5228cb5005..8b5db8bbfd9a 100644 --- a/gfx/src/shared/nsRenderingContextImpl.cpp +++ b/gfx/src/shared/nsRenderingContextImpl.cpp @@ -59,10 +59,12 @@ PRInt32 PR_CALLBACK compare_active(const void *u,const void *v){return ((Edge*)u * @update 3/16/00 dwc */ nsRenderingContextImpl :: nsRenderingContextImpl() +: mTranMatrix(nsnull) +, mLineStyle(nsLineStyle_kSolid) +, mAct(0) +, mActive(nsnull) +, mPenMode(nsPenMode_kNone) { - - mPenMode = nsPenMode_kNone; - } /** --------------------------------------------------- diff --git a/widget/src/mac/nsChildWindow.h b/widget/src/mac/nsChildWindow.h index 318c1df871ed..5caaf0660fda 100644 --- a/widget/src/mac/nsChildWindow.h +++ b/widget/src/mac/nsChildWindow.h @@ -61,8 +61,8 @@ public: virtual void CalcWindowRegions(); protected: - PRBool mClipChildren; - PRBool mClipSiblings; + PRPackedBool mClipChildren; + PRPackedBool mClipSiblings; }; diff --git a/widget/src/mac/nsDynamicMDEF.cpp b/widget/src/mac/nsDynamicMDEF.cpp index a9952493df0a..0e215d18586e 100644 --- a/widget/src/mac/nsDynamicMDEF.cpp +++ b/widget/src/mac/nsDynamicMDEF.cpp @@ -295,7 +295,7 @@ void nsCheckDestroy(MenuHandle theMenu, short * whichItem) if(gCurrentMenuItem == *whichItem) changeOccured = false; - if(!gPreviousMenuHandleStack[gPreviousMenuHandleStack.Count() - 1]) + if(gPreviousMenuHandleStack.Count() == 0 || !gPreviousMenuHandleStack[gPreviousMenuHandleStack.Count() - 1]) changeOccured = false; if(nsIsHierChild(theMenu)) @@ -464,7 +464,8 @@ void nsBuildMenu(MenuHandle theMenu, PRBool isChild) void nsPostBuild(nsIMenu * menu, MenuHandle theMenu, PRBool isChild) { // it is built now - if(isChild || (gPreviousMenuHandleStack[gPreviousMenuHandleStack.Count() - 1] != theMenu)) + if (isChild || (gPreviousMenuHandleStack.Count() == 0 || + gPreviousMenuHandleStack[gPreviousMenuHandleStack.Count() - 1] != theMenu)) { nsPushMenu(menu); nsPushMenuHandle(theMenu); diff --git a/widget/src/mac/nsLookAndFeel.cpp b/widget/src/mac/nsLookAndFeel.cpp index cf99a3a35192..c1dc1614c660 100644 --- a/widget/src/mac/nsLookAndFeel.cpp +++ b/widget/src/mac/nsLookAndFeel.cpp @@ -115,8 +115,8 @@ nsresult nsLookAndFeel::NativeGetColor(const nsColorID aID, nscolor &aColor) case eColor_highlight: // CSS2 color case eColor_TextSelectBackground: RGBColor macColor; - GrafPtr thePort; - ::GetPort(&thePort); + CGrafPtr thePort; + ::GetPort((GrafPtr*)&thePort); if (thePort) { ::GetPortHiliteColor(thePort,&macColor); diff --git a/widget/src/mac/nsMacEventHandler.cpp b/widget/src/mac/nsMacEventHandler.cpp index 5be927fd6d0a..96213d563a46 100644 --- a/widget/src/mac/nsMacEventHandler.cpp +++ b/widget/src/mac/nsMacEventHandler.cpp @@ -47,10 +47,12 @@ #include #include #include + #include "nsCarbonHelpers.h" #include "nsIRollupListener.h" #include "nsIMenuRollup.h" #include "nsTSMStrategy.h" +#include "nsGfxUtils.h" #ifndef XP_MACOSX #include @@ -617,7 +619,7 @@ PRBool nsMacEventHandler::DragEvent ( unsigned int aMessage, Point aMouseGlobal, // stuff just in case it has been changed. Point hitPointLocal = aMouseGlobal; WindowRef wind = reinterpret_cast(mTopLevelWidget->GetNativeData(NS_NATIVE_DISPLAY)); - ::SetPortWindowPort(wind); + nsGraphicsUtils::SafeSetPortWindowPort(wind); Rect savePortRect; ::GetWindowPortBounds(wind, &savePortRect); ::SetOrigin(0, 0); @@ -1679,7 +1681,7 @@ void nsMacEventHandler::ConvertOSEventToMouseEvent( mTopLevelWidget->GetWindowType(wtype); PRBool topLevelIsAPopup = (wtype == eWindowType_popup); WindowRef wind = reinterpret_cast(mTopLevelWidget->GetNativeData(NS_NATIVE_DISPLAY)); - ::SetPortWindowPort(wind); + nsGraphicsUtils::SafeSetPortWindowPort(wind); Rect savePortRect; ::GetWindowPortBounds(wind, &savePortRect); ::SetOrigin(0, 0); @@ -1778,7 +1780,7 @@ nsresult nsMacEventHandler::HandleOffsetToPosition(long offset,Point* thePoint) thePoint->h = mIMEPos.x; printf("local (x,y) = (%d, %d)\n", thePoint->h, thePoint->v); WindowRef wind = reinterpret_cast(mTopLevelWidget->GetNativeData(NS_NATIVE_DISPLAY)); - ::SetPortWindowPort(wind); + nsGraphicsUtils::SafeSetPortWindowPort(wind); Rect savePortRect; ::GetWindowPortBounds(wind, &savePortRect); ::LocalToGlobal(thePoint); diff --git a/widget/src/mac/nsMacMessagePump.cpp b/widget/src/mac/nsMacMessagePump.cpp index 3910119f196c..8ec4d7cf8d85 100644 --- a/widget/src/mac/nsMacMessagePump.cpp +++ b/widget/src/mac/nsMacMessagePump.cpp @@ -411,7 +411,6 @@ PRBool nsMacMessagePump::GetEvent(EventRecord &theEvent) */ void nsMacMessagePump::DispatchEvent(PRBool aRealEvent, EventRecord *anEvent) { - if (aRealEvent == PR_TRUE) { @@ -478,6 +477,7 @@ void nsMacMessagePump::DispatchEvent(PRBool aRealEvent, EventRecord *anEvent) else { DoIdle(*anEvent); + if (mRunning) Repeater::DoIdlers(*anEvent); @@ -487,6 +487,8 @@ void nsMacMessagePump::DispatchEvent(PRBool aRealEvent, EventRecord *anEvent) if (mRunning) Repeater::DoRepeaters(*anEvent); + + NS_ASSERTION(ValidateDrawingState(), "Bad drawing state"); } #pragma mark - @@ -506,7 +508,6 @@ void nsMacMessagePump::DoUpdate(EventRecord &anEvent) // The app can do its own updates here DispatchOSEventToRaptor(anEvent, whichWindow); ::EndUpdate(whichWindow); - } @@ -558,7 +559,7 @@ void nsMacMessagePump::DoMouseDown(EventRecord &anEvent) case inContent: { - ::SetPortWindowPort(whichWindow); + nsGraphicsUtils::SafeSetPortWindowPort(whichWindow); if ( IsWindowHilited(whichWindow) || (gRollupListener && gRollupWidget) ) DispatchOSEventToRaptor(anEvent, whichWindow); else { @@ -598,7 +599,7 @@ void nsMacMessagePump::DoMouseDown(EventRecord &anEvent) case inDrag: { - ::SetPortWindowPort(whichWindow); + nsGraphicsUtils::SafeSetPortWindowPort(whichWindow); // grrr... DragWindow calls SelectWindow, no way to stop it. For now, // we'll just let it come to the front and then push it back if necessary. @@ -635,7 +636,7 @@ void nsMacMessagePump::DoMouseDown(EventRecord &anEvent) case inGrow: { - ::SetPortWindowPort(whichWindow); + nsGraphicsUtils::SafeSetPortWindowPort(whichWindow); // use the cmd-key to do the opposite of the DRAW_ON_RESIZE setting. Boolean cmdKeyDown = (anEvent.modifiers & cmdKey) != 0; @@ -718,7 +719,7 @@ void nsMacMessagePump::DoMouseDown(EventRecord &anEvent) case inGoAway: { nsWatchTask::GetTask().Suspend(); - ::SetPortWindowPort(whichWindow); + nsGraphicsUtils::SafeSetPortWindowPort(whichWindow); if (::TrackGoAway(whichWindow, anEvent.where)) { nsWatchTask::GetTask().Resume(); DispatchOSEventToRaptor(anEvent, whichWindow); @@ -756,7 +757,7 @@ void nsMacMessagePump::DoMouseDown(EventRecord &anEvent) #if TARGET_CARBON case inToolbarButton: // Mac OS X only nsWatchTask::GetTask().Suspend(); - ::SetPortWindowPort(whichWindow); + nsGraphicsUtils::SafeSetPortWindowPort(whichWindow); DispatchOSEventToRaptor(anEvent, whichWindow); nsWatchTask::GetTask().Resume(); break; @@ -934,7 +935,7 @@ void nsMacMessagePump::DoMenu(EventRecord &anEvent, long menuResult) void nsMacMessagePump::DoActivate(EventRecord &anEvent) { WindowPtr whichWindow = (WindowPtr)anEvent.message; - ::SetPortWindowPort(whichWindow); + nsGraphicsUtils::SafeSetPortWindowPort(whichWindow); if (anEvent.modifiers & activeFlag) ::HiliteWindow(whichWindow,TRUE); else diff --git a/widget/src/mac/nsMacWindow.cpp b/widget/src/mac/nsMacWindow.cpp index b477aa1780f2..cc4d4ee05f1c 100644 --- a/widget/src/mac/nsMacWindow.cpp +++ b/widget/src/mac/nsMacWindow.cpp @@ -47,7 +47,7 @@ #include "nsIScreenManager.h" #include "nsGUIEvent.h" #include "nsCarbonHelpers.h" -#include "nsGFXUtils.h" +#include "nsGfxUtils.h" #include "DefProcFakery.h" #include "nsMacResources.h" #include "nsRegionMac.h" @@ -237,8 +237,18 @@ nsMacWindow::~nsMacWindow() ::DisposeDragReceiveHandlerUPP ( mDragReceiveHandlerUPP ); } + // ensure we leave the port in a happy state + CGrafPtr curPort; + CGrafPtr windowPort = ::GetWindowPort(mWindowPtr); + ::GetPort((GrafPtr*)&curPort); + PRBool mustResetPort = (curPort == windowPort); + + ::DisposeWindow(mWindowPtr); mWindowPtr = nsnull; + + if (mustResetPort) + nsGraphicsUtils::SetPortToKnownGoodPort(); } } @@ -570,6 +580,8 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent, } // if we created windowPtr + nsGraphicsUtils::SafeSetPortWindowPort(mWindowPtr); + return NS_OK; } diff --git a/widget/src/mac/nsWindow.cpp b/widget/src/mac/nsWindow.cpp index 8acc2dbbb522..3dfcbe0c3067 100644 --- a/widget/src/mac/nsWindow.cpp +++ b/widget/src/mac/nsWindow.cpp @@ -952,6 +952,32 @@ static void blinkRgn(RgnHandle rgn) #endif +//------------------------------------------------------------------------- +// +// Validate this component's visible area +// +//------------------------------------------------------------------------- +NS_IMETHODIMP nsWindow::Validate() +{ + if (!mWindowPtr || !mVisible) + return NS_OK; + + nsRect wRect = mBounds; + LocalToWindowCoordinate(wRect); + Rect macRect; + nsRectToMacRect(wRect, macRect); + + StPortSetter portSetter(mWindowPtr); + Rect savePortRect; + ::GetWindowPortBounds(mWindowPtr, &savePortRect); + ::SetOrigin(0, 0); + + ::ValidWindowRect(mWindowPtr, &macRect); + ::SetOrigin(savePortRect.left, savePortRect.top); + + return NS_OK; +} + //------------------------------------------------------------------------- // // Invalidate this component's visible area @@ -982,6 +1008,7 @@ NS_IMETHODIMP nsWindow::Invalidate(const nsRect &aRect, PRBool aIsSynchronous) nsRectToMacRect(wRect, macRect); StPortSetter portSetter(mWindowPtr); + Rect savePortRect; ::GetWindowPortBounds(mWindowPtr, &savePortRect); ::SetOrigin(0, 0); @@ -1022,6 +1049,7 @@ NS_IMETHODIMP nsWindow::InvalidateRegion(const nsIRegion *aRegion, PRBool aIsSyn ::OffsetRgn(windowRgn, mBounds.x + offX, mBounds.y + offY); StPortSetter portSetter(mWindowPtr); + Rect savePortRect; ::GetWindowPortBounds(mWindowPtr, &savePortRect); ::SetOrigin(0, 0); @@ -1069,7 +1097,6 @@ void nsWindow::StartDraw(nsIRenderingContext* aRenderingContext) NS_IF_ADDREF(aRenderingContext); mTempRenderingContext = aRenderingContext; mTempRenderingContextMadeHere = PR_FALSE; - mTempRenderingContext->PushState(); // set the environment to the current widget mTempRenderingContext->Init(mContext, this); @@ -1097,6 +1124,7 @@ void nsWindow::StartDraw(nsIRenderingContext* aRenderingContext) ::RGBForeColor(&macColor); mTempRenderingContext->SetColor(color); // just in case, set the rendering context color too + mTempRenderingContext->PushState(); // push the state so we can pop it later } @@ -1110,11 +1138,9 @@ void nsWindow::EndDraw() return; mDrawing = PR_FALSE; - if (mTempRenderingContextMadeHere) - { PRBool clipEmpty; mTempRenderingContext->PopState(clipEmpty); - } + NS_RELEASE(mTempRenderingContext); } @@ -1400,7 +1426,7 @@ else StRegionFromPool damagedRgn; if (!damagedRgn) return NS_ERROR_OUT_OF_MEMORY; - ::GetPortVisibleRegion(GrafPtr(GetWindowPort(mWindowPtr)), damagedRgn); + ::GetPortVisibleRegion(GetWindowPort(mWindowPtr), damagedRgn); #ifdef PAINT_DEBUGGING blinkRgn(damagedRgn); @@ -1525,6 +1551,8 @@ else ProfileStop(); #endif + NS_ASSERTION(ValidateDrawingState(), "Bad drawing state"); + return NS_OK; } @@ -1643,12 +1671,14 @@ void nsWindow::UpdateWidget(nsRect& aRect, nsIRenderingContext* aContext) // draw the widget StartDraw(aContext); + if ( OnPaint(paintEvent) ) { nsEventStatus eventStatus; DispatchWindowEvent(paintEvent,eventStatus); if(eventStatus != nsEventStatus_eIgnore) Flash(paintEvent); } + EndDraw(); // beard: Since we clip so aggressively, drawing from front to back should work, @@ -1689,6 +1719,8 @@ void nsWindow::UpdateWidget(nsRect& aRect, nsIRenderingContext* aContext) #undef FIRST_CHILD #undef NEXT_CHILD + + NS_ASSERTION(ValidateDrawingState(), "Bad drawing state"); } diff --git a/widget/src/mac/nsWindow.h b/widget/src/mac/nsWindow.h index 75e889b76484..758ad9884f73 100644 --- a/widget/src/mac/nsWindow.h +++ b/widget/src/mac/nsWindow.h @@ -141,6 +141,7 @@ public: virtual nsIFontMetrics* GetFont(void); NS_IMETHOD SetFont(const nsFont &aFont); + NS_IMETHOD Validate(); NS_IMETHOD Invalidate(PRBool aIsSynchronous); NS_IMETHOD Invalidate(const nsRect &aRect,PRBool aIsSynchronous); NS_IMETHOD InvalidateRegion(const nsIRegion *aRegion, PRBool aIsSynchronous); @@ -222,10 +223,10 @@ protected: #endif nsIWidget* mParent; - PRBool mResizingChildren; - PRBool mSaveVisible; - PRBool mVisible; - PRBool mEnabled; + PRPackedBool mResizingChildren; + PRPackedBool mSaveVisible; + PRPackedBool mVisible; + PRPackedBool mEnabled; PRInt32 mPreferredWidth; PRInt32 mPreferredHeight; nsIFontMetrics* mFontMetrics; @@ -235,16 +236,18 @@ protected: RgnHandle mVisRegion; WindowPtr mWindowPtr; - PRBool mDestroyCalled; - PRBool mDestructorCalled; + PRPackedBool mDestroyCalled; + PRPackedBool mDestructorCalled; + + PRPackedBool mAcceptFocusOnClick; + + PRPackedBool mDrawing; + PRPackedBool mTempRenderingContextMadeHere; - PRBool mDrawing; nsIRenderingContext* mTempRenderingContext; - PRBool mTempRenderingContextMadeHere; nsPluginPort* mPluginPort; - PRBool mAcceptFocusOnClick; // Routines for iterating over the rects of a region. Carbon and pre-Carbon // do this differently so provide a way to do both. diff --git a/widget/src/xpwidgets/nsBaseWidget.h b/widget/src/xpwidgets/nsBaseWidget.h index 850ea5416ed9..1478dff92817 100644 --- a/widget/src/xpwidgets/nsBaseWidget.h +++ b/widget/src/xpwidgets/nsBaseWidget.h @@ -156,11 +156,11 @@ protected: nsCursor mCursor; nsWindowType mWindowType; nsBorderStyle mBorderStyle; - PRBool mIsShiftDown; - PRBool mIsControlDown; - PRBool mIsAltDown; - PRBool mIsDestroying; - PRBool mOnDestroyCalled; + PRPackedBool mIsShiftDown; + PRPackedBool mIsControlDown; + PRPackedBool mIsAltDown; + PRPackedBool mIsDestroying; + PRPackedBool mOnDestroyCalled; nsRect mBounds; PRInt32 mZIndex; nsSizeMode mSizeMode;