From b050f87ab1d1c727eef2ec212a4cc5607c2e6f1f Mon Sep 17 00:00:00 2001 From: "sfraser%netscape.com" Date: Mon, 14 Jan 2002 23:26:49 +0000 Subject: [PATCH] Fix port/GDevice management issues in Mac code, fixes bugs 113480, 103234, 105946, and 104781. Changes ensure that the current graphics device is set correctly when SetPort is used to change the current graphics port (to window or GWorld). r=pinkerton, rs=brendan --- gfx/src/mac/nsATSUIUtils.cpp | 72 ++++----- gfx/src/mac/nsATSUIUtils.h | 9 +- gfx/src/mac/nsCarbonHelpers.h | 40 +++-- gfx/src/mac/nsDeviceContextMac.cpp | 26 ++-- gfx/src/mac/nsDrawingSurfaceMac.cpp | 82 +++++------ gfx/src/mac/nsDrawingSurfaceMac.h | 11 +- gfx/src/mac/nsGfxUtils.h | 171 +++++++++++++++++++--- gfx/src/mac/nsGraphicState.cpp | 10 +- gfx/src/mac/nsGraphicState.h | 14 +- gfx/src/mac/nsIDrawingSurfaceMac.h | 4 +- gfx/src/mac/nsImageMac.cpp | 75 ++++++---- gfx/src/mac/nsRenderingContextMac.cpp | 129 ++++++++-------- gfx/src/mac/nsRenderingContextMac.h | 22 +-- gfx/src/mac/nsUnicodeRenderingToolkit.cpp | 36 ++--- gfx/src/mac/nsUnicodeRenderingToolkit.h | 10 +- gfx/src/nsRenderingContextImpl.cpp | 8 +- gfx/src/shared/nsRenderingContextImpl.cpp | 8 +- widget/src/mac/nsChildWindow.h | 4 +- widget/src/mac/nsDynamicMDEF.cpp | 5 +- widget/src/mac/nsLookAndFeel.cpp | 4 +- widget/src/mac/nsMacEventHandler.cpp | 8 +- widget/src/mac/nsMacMessagePump.cpp | 17 ++- widget/src/mac/nsMacWindow.cpp | 14 +- widget/src/mac/nsWindow.cpp | 42 +++++- widget/src/mac/nsWindow.h | 21 +-- widget/src/xpwidgets/nsBaseWidget.h | 10 +- 26 files changed, 515 insertions(+), 337 deletions(-) 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;