diff --git a/gfx/src/os2/nsImageOS2.cpp b/gfx/src/os2/nsImageOS2.cpp index b709e36d2b9c..4a8c5c8e1b71 100644 --- a/gfx/src/os2/nsImageOS2.cpp +++ b/gfx/src/os2/nsImageOS2.cpp @@ -475,7 +475,7 @@ nsresult nsImageOS2::Optimize( nsIDeviceContext* aContext) void nsImageOS2::CreateBitmaps( nsDrawingSurfaceOS2 *surf) { - mBitmap = GFX (::GpiCreateBitmap (surf->GetPS (), (PBITMAPINFOHEADER2)mInfo, + mBitmap = GFX (::GpiCreateBitmap (surf->GetPS(), (PBITMAPINFOHEADER2)mInfo, CBM_INIT, (PBYTE)mImageBits, mInfo), GPI_ERROR); @@ -484,7 +484,7 @@ void nsImageOS2::CreateBitmaps( nsDrawingSurfaceOS2 *surf) if( mAlphaDepth == 1) { MONOBITMAPINFO maskInfo( mInfo); - mABitmap = GFX (::GpiCreateBitmap (surf->GetPS (), maskInfo, CBM_INIT, + mABitmap = GFX (::GpiCreateBitmap (surf->GetPS(), maskInfo, CBM_INIT, (PBYTE)mAlphaBits, maskInfo), GPI_ERROR); } @@ -710,10 +710,114 @@ PRBool nsImageOS2::SlowTile (nsIRenderingContext& aContext, nsDrawingSurface aSu } #ifdef USE_IMG2 +void nsImageOS2::NS2PM_ININ( const nsRect &in, RECTL &rcl) +{ + PRUint32 ulHeight = GetHeight (); + + rcl.xLeft = in.x; + rcl.xRight = in.x + in.width - 1; + rcl.yTop = ulHeight - in.y - 1; + rcl.yBottom = rcl.yTop - in.height + 1; +} + + +// --------------------------------------------------- +// Update mImageBits with content of new mBitmap +// +NS_IMETHODIMP nsImageOS2::UpdateImageBits( HPS mPS ) +{ + BITMAPINFOHEADER2 rawInfo = { 0 }; + rawInfo.cbFix = sizeof (BITMAPINFOHEADER2); + rawInfo.cPlanes = 1; + rawInfo.cBitCount = mInfo->cBitCount; + + int RawDataSize = mInfo->cy * RASWIDTH (mInfo->cx, mInfo->cBitCount); + PRUint8* pRawBitData = (PRUint8*)malloc (RawDataSize); + + if (pRawBitData) + { + GFX (::GpiQueryBitmapBits (mPS, 0, mInfo->cy, (PBYTE)pRawBitData, (PBITMAPINFO2)&rawInfo), GPI_ALTERROR); + free (mImageBits); + mImageBits = pRawBitData; + return NS_OK; + } + else + return NS_ERROR_OUT_OF_MEMORY; +} + NS_IMETHODIMP nsImageOS2::DrawToImage(nsIImage* aDstImage, nscoord aDX, nscoord aDY, nscoord aDWidth, nscoord aDHeight) { - return NS_ERROR_FAILURE; + HBITMAP oldBitmap; + int rc = NS_OK; + + DEVOPENSTRUC dop = { 0, 0, 0, 0, 0 }; + SIZEL sizel = { 0, 0 }; + + if (mInfo == nsnull || aDWidth < 0 || aDHeight < 0) + return NS_ERROR_FAILURE; + + if (0 == aDWidth || 0 == aDHeight) + return NS_OK; + + // Create a memory DC that is compatible with the screen + HDC destDC = GFX (::DevOpenDC( 0/*hab*/, OD_MEMORY, "*", 5, + (PDEVOPENDATA) &dop, (HDC)0), DEV_ERROR); + + // create the PS + HPS destPS = GFX (::GpiCreatePS (0/*hab*/, destDC, &sizel, + PU_PELS | GPIT_MICRO | GPIA_ASSOC), GPI_ERROR); + + nsImageOS2* destImg = NS_STATIC_CAST(nsImageOS2*, aDstImage); + + if(!destImg->mBitmap) + { + destImg->mBitmap = GFX (::GpiCreateBitmap (destPS, + (PBITMAPINFOHEADER2)destImg->mInfo, + CBM_INIT, (PBYTE)destImg->mImageBits, + destImg->mInfo), + GPI_ERROR); + destImg->mIsOptimized = PR_TRUE; + } + + oldBitmap = GFX (::GpiSetBitmap (destPS, destImg->mBitmap), HBM_ERROR); + + nsRect trect( aDX, aDY, aDWidth, aDHeight); + RECTL rcl; + destImg->NS2PM_ININ (trect, rcl); + + // Set up blit coord array + POINTL aptl[ 4] = { { rcl.xLeft, rcl.yBottom }, + { rcl.xRight, rcl.yTop }, + { 0, mInfo->cy - mNaturalHeight }, + { mNaturalWidth, mInfo->cy } }; + + if( 1==mAlphaDepth && mAlphaBits){ + // Apply mask to target, clear pels we will fill in from the image + MONOBITMAPINFO MaskBitmapInfo (mInfo); + GFX (::GpiDrawBits (destPS, mAlphaBits, MaskBitmapInfo, 4, aptl, ROP_SRCAND, + BBO_IGNORE), GPI_ERROR); + + // Now combine image with target + GFX (::GpiDrawBits (destPS, mImageBits, mInfo, 4, aptl, ROP_SRCPAINT, + BBO_IGNORE), GPI_ERROR); + } else { + // alpha depth of 8 not used (yet?) + NS_ASSERTION( mAlphaDepth != 8, "Alpha depth of 8 not implemented in DrawToImage" ); + + // no transparency, just blit it + GFX (::GpiDrawBits (destPS, mImageBits, mInfo, 4, aptl, ROP_SRCCOPY, + BBO_IGNORE), GPI_ERROR); + } + + rc = destImg->UpdateImageBits (destPS); + + GFX (::GpiSetBitmap (destPS, oldBitmap), HBM_ERROR); + + GFX (::GpiDestroyPS (destPS), FALSE); + GFX (::DevCloseDC (destDC), DEV_ERROR); + + return rc; } #endif diff --git a/gfx/src/os2/nsImageOS2.h b/gfx/src/os2/nsImageOS2.h index 5ff00744ba07..916f29f52b01 100644 --- a/gfx/src/os2/nsImageOS2.h +++ b/gfx/src/os2/nsImageOS2.h @@ -218,6 +218,8 @@ public: static PRUint8 FAST_BLEND (PRUint8 Source, PRUint8 Dest, PRUint8 Alpha) { return gBlenderLookup [(Alpha << 8) + Source] + gBlenderLookup [((255 - Alpha) << 8) + Dest]; } + NS_IMETHODIMP UpdateImageBits( HPS mPS ); + void NS2PM_ININ( const nsRect &in, RECTL &rcl); void CreateBitmaps( nsDrawingSurfaceOS2 *surf); PRBool SlowTile(nsIRenderingContext &aContext, nsDrawingSurface aSurface,nscoord aX0,nscoord aY0,nscoord aX1,nscoord aY1,nscoord aWidth,nscoord aHeight); diff --git a/gfx/src/os2/nsRenderingContextOS2.cpp b/gfx/src/os2/nsRenderingContextOS2.cpp index 2f8a37961761..363567f9bfa2 100644 --- a/gfx/src/os2/nsRenderingContextOS2.cpp +++ b/gfx/src/os2/nsRenderingContextOS2.cpp @@ -113,21 +113,79 @@ GraphicsState :: ~GraphicsState() { if (NULL != mClipRegion) { -// VERIFY(::DeleteObject(mClipRegion)); printf( "oops, leaked a region from rc-gs\n"); mClipRegion = NULL; } - - //these are killed by the rendering context... -// mSolidPen = NULL; -// mDashedPen = NULL; -// mDottedPen = NULL; } // Rendering context ------------------------------------------------------- -NS_IMPL_ADDREF(nsRenderingContextOS2) -NS_IMPL_RELEASE(nsRenderingContextOS2) +// Init-term stuff --------------------------------------------------------- + +nsRenderingContextOS2::nsRenderingContextOS2() +{ + NS_INIT_REFCNT(); + + mContext = nsnull; + mSurface = nsnull; + mPS = 0; + mMainSurface = nsnull; + mColor = NS_RGB( 0, 0, 0); + mFontMetrics = nsnull; + mLineStyle = nsLineStyle_kSolid; + mPreservedInitialClipRegion = PR_FALSE; + mPaletteMode = PR_FALSE; + + // Need to enforce setting color values for first time. Make cached values different from current ones. + mCurrFontMetrics = mFontMetrics + 1; + mCurrTextColor = mColor + 1; + mCurrLineColor = mColor + 1; + mCurrLineStyle = (nsLineStyle)((int)mLineStyle + 1); + mCurrFillColor = mColor + 1; + + mStateCache = new nsVoidArray(); + + //create an initial GraphicsState + + PushState(); + + mP2T = 1.0f; +} + +nsRenderingContextOS2::~nsRenderingContextOS2() +{ + NS_IF_RELEASE(mContext); + NS_IF_RELEASE(mFontMetrics); + + //destroy the initial GraphicsState + PRBool clipState; + PopState (clipState); + + if (nsnull != mStateCache) + { + PRInt32 cnt = mStateCache->Count(); + + while (--cnt >= 0) + { + GraphicsState *state = (GraphicsState *)mStateCache->ElementAt(cnt); + if (state->mClipRegion) { + GFX (::GpiDestroyRegion (mPS, state->mClipRegion), FALSE); + state->mClipRegion = 0; + } + mStateCache->RemoveElementAt(cnt); + + if (nsnull != state) + delete state; + } + + delete mStateCache; + mStateCache = nsnull; + } + + // Release surfaces and the palette + NS_IF_RELEASE(mMainSurface); + NS_IF_RELEASE(mSurface); +} nsresult nsRenderingContextOS2::QueryInterface( REFNSIID aIID, void **aInstancePtr) @@ -152,69 +210,57 @@ nsRenderingContextOS2::QueryInterface( REFNSIID aIID, void **aInstancePtr) return NS_OK; } -// Init-term stuff --------------------------------------------------------- +NS_IMPL_ADDREF(nsRenderingContextOS2) +NS_IMPL_RELEASE(nsRenderingContextOS2) -nsRenderingContextOS2::nsRenderingContextOS2() +NS_IMETHODIMP +nsRenderingContextOS2::Init( nsIDeviceContext *aContext, + nsIWidget *aWindow) { - NS_INIT_REFCNT(); + mContext = aContext; + NS_IF_ADDREF(mContext); - mContext = nsnull; - mSurface = nsnull; - mPS = 0; - mMainSurface = nsnull; - mColor = NS_RGB( 0, 0, 0); - mP2T = 1.0f; - mStateCache = new nsVoidArray(); - mFontMetrics = nsnull; - mLineStyle = nsLineStyle_kSolid; - mPreservedInitialClipRegion = PR_FALSE; - mPaletteMode = PR_FALSE; + // Create & remember an on-screen surface + nsWindowSurface *surf = new nsWindowSurface; + if (!surf) + return NS_ERROR_OUT_OF_MEMORY; - // Need to enforce setting color values for first time. Make cached values different from current ones. - mCurrFontMetrics = mFontMetrics + 1; - mCurrTextColor = mColor + 1; - mCurrLineColor = mColor + 1; - mCurrLineStyle = (nsLineStyle)((int)mLineStyle + 1); - mCurrFillColor = mColor + 1; - PushState(); + surf->Init(aWindow); + + mSurface = surf; + mPS = mSurface->GetPS (); + NS_ADDREF(mSurface); + + mDCOwner = aWindow; + NS_IF_ADDREF(mDCOwner); + + // Grab another reference to the onscreen for later uniformity + mMainSurface = mSurface; + NS_ADDREF(mMainSurface); + + return CommonInit(); } -nsRenderingContextOS2::~nsRenderingContextOS2() +NS_IMETHODIMP +nsRenderingContextOS2::Init( nsIDeviceContext *aContext, + nsDrawingSurface aSurface) { - NS_IF_RELEASE(mContext); + mContext = aContext; + NS_IF_ADDREF(mContext); - //destroy the initial GraphicsState - if (mPreservedInitialClipRegion == PR_TRUE) - { - PRBool clipState; - PopState (clipState); - } + // Add a couple of references to the onscreen (or print, more likely) + mSurface = (nsDrawingSurfaceOS2 *) aSurface; - if (nsnull != mStateCache) + if (nsnull != mSurface) { - PRInt32 cnt = mStateCache->Count(); + mPS = mSurface->GetPS (); + NS_ADDREF(mSurface); - while (--cnt >= 0) - { - GraphicsState *state = (GraphicsState *)mStateCache->ElementAt(cnt); - if (state->mClipRegion) { - GFX (::GpiDestroyRegion (mPS, state->mClipRegion), FALSE); - state->mClipRegion = 0; - } /* endif */ - mStateCache->RemoveElementAt(cnt); - - if (nsnull != state) - delete state; - } - - delete mStateCache; - mStateCache = nsnull; + mMainSurface = mSurface; + NS_ADDREF(mMainSurface); } - // Release surfaces and the palette - NS_IF_RELEASE(mMainSurface); - NS_IF_RELEASE(mSurface); - NS_IF_RELEASE(mFontMetrics); + return CommonInit(); } nsresult nsRenderingContextOS2::SetupPS (void) @@ -269,76 +315,52 @@ nsresult nsRenderingContextOS2::SetupPS (void) return NS_OK; } -nsresult nsRenderingContextOS2::Init( nsIDeviceContext *aContext, - nsIWidget *aWindow) -{ - mContext = aContext; - NS_ADDREF(mContext); - - // Create & remember an on-screen surface - nsWindowSurface *surf = new nsWindowSurface; - if (!surf) - return NS_ERROR_OUT_OF_MEMORY; - - surf->Init(aWindow); - - mSurface = surf; - mPS = mSurface->GetPS (); - NS_ADDREF(mSurface); - - mDCOwner = aWindow; - NS_IF_ADDREF(mDCOwner); - - // Grab another reference to the onscreen for later uniformity - mMainSurface = mSurface; - NS_ADDREF(mMainSurface); - - PushState(); - mPreservedInitialClipRegion = PR_TRUE; - - return CommonInit(); -} - -nsresult nsRenderingContextOS2::Init( nsIDeviceContext *aContext, - nsDrawingSurface aSurface) -{ - mContext = aContext; - NS_IF_ADDREF(mContext); - - // Add a couple of references to the onscreen (or print, more likely) - mSurface = (nsDrawingSurfaceOS2 *) aSurface; - mPS = mSurface->GetPS (); - NS_ADDREF(mSurface); - mMainSurface = mSurface; - NS_ADDREF(mMainSurface); - - PushState(); - mPreservedInitialClipRegion = PR_TRUE; - - return CommonInit(); -} - // Presentation space page units (& so world coords) are PU_PELS. // We have a matrix, mTMatrix, which converts from the passed in app units // to pels. Note there is *no* guarantee that app units == twips. nsresult nsRenderingContextOS2::CommonInit() { - mContext->GetGammaTable(mGammaTable); - float app2dev = 0; + float app2dev; + mContext->GetAppUnitsToDevUnits( app2dev); mTranMatrix->AddScale( app2dev, app2dev); mContext->GetDevUnitsToAppUnits( mP2T); + mContext->GetGammaTable(mGammaTable); + return SetupPS (); } // PS & drawing surface management ----------------------------------------- -nsresult nsRenderingContextOS2::SelectOffScreenDrawingSurface( nsDrawingSurface aSurface) +NS_IMETHODIMP nsRenderingContextOS2::LockDrawingSurface( PRInt32 aX, PRInt32 aY, + PRUint32 aWidth, PRUint32 aHeight, + void **aBits, + PRInt32 *aStride, PRInt32 *aWidthBytes, + PRUint32 aFlags) +{ + PushState(); + + return mSurface->Lock( aX, aY, aWidth, aHeight, aBits, + aStride, aWidthBytes, aFlags); +} + +NS_IMETHODIMP nsRenderingContextOS2::UnlockDrawingSurface() +{ + mSurface->Unlock(); + + PRBool clipstate; + PopState (clipstate); + + return NS_OK; +} + +NS_IMETHODIMP +nsRenderingContextOS2::SelectOffScreenDrawingSurface( nsDrawingSurface aSurface) { if (aSurface != mSurface) { - if( aSurface) + if(nsnull != aSurface) { NS_IF_RELEASE(mSurface); mSurface = (nsDrawingSurfaceOS2 *) aSurface; @@ -363,110 +385,36 @@ nsresult nsRenderingContextOS2::SelectOffScreenDrawingSurface( nsDrawingSurface // !! This is a bit dodgy; nsDrawingSurface *really* needs to be XP-comified // !! properly... -nsresult nsRenderingContextOS2::GetDrawingSurface( nsDrawingSurface *aSurface) +NS_IMETHODIMP +nsRenderingContextOS2::GetDrawingSurface( nsDrawingSurface *aSurface) { if( !aSurface) return NS_ERROR_NULL_POINTER; -#if 0 - NS_IF_RELEASE( *aSurface); -#endif - *aSurface = (void*)((nsDrawingSurfaceOS2 *) mSurface); - // !! probably don't want to addref this 'cos client can't release it... - return NS_OK; } -// The idea here is to create an offscreen surface for blitting with. -// I can't find any way for people to resize the bitmap created here, -// so I guess this gets called quite often. -// -// I'm reliably told that 'aBounds' is in device units, and that the -// position oughtn't to be ignored, but for all intents & purposes can be. -// -nsresult nsRenderingContextOS2::CreateDrawingSurface( nsRect *aBounds, - PRUint32 aSurfFlags, nsDrawingSurface &aSurface) +NS_IMETHODIMP +nsRenderingContextOS2::GetHints(PRUint32& aResult) { - nsresult rc = NS_ERROR_FAILURE; + PRUint32 result = 0; - nsOffscreenSurface *surf = new nsOffscreenSurface; - - if (!surf) - return NS_ERROR_OUT_OF_MEMORY; - - rc = surf->Init( mMainSurface->GetPS (), aBounds->width, aBounds->height, aSurfFlags); - - if(NS_SUCCEEDED(rc)) - { - NS_ADDREF(surf); - aSurface = (void*)((nsDrawingSurfaceOS2 *) surf); - } - else - delete surf; - - return rc; -} - -NS_IMETHODIMP nsRenderingContextOS2::CreateDrawingSurface(HPS aPS, nsDrawingSurface &aSurface, nsIWidget *aWidget) -{ - nsWindowSurface *surf = new nsWindowSurface(); - - if (nsnull != surf) - { - NS_ADDREF(surf); - surf->Init(aPS, aWidget); - } - - aSurface = (nsDrawingSurface)surf; + aResult = result; return NS_OK; } -nsresult nsRenderingContextOS2::DestroyDrawingSurface( nsDrawingSurface aDS) +NS_IMETHODIMP nsRenderingContextOS2::Reset() { - nsDrawingSurfaceOS2 *surf = (nsDrawingSurfaceOS2 *) aDS; - nsresult rc = NS_ERROR_NULL_POINTER; - - // If the surface being destroyed is the one we're currently using for - // offscreen, then lose our reference to it & hook back to the onscreen. - if( surf && surf == mSurface) - { - NS_RELEASE(mSurface); // ref. from SelectOffscreen - mSurface = mMainSurface; - mPS = mSurface->GetPS (); - NS_ADDREF(mSurface); - } - - if( surf) - { - NS_RELEASE(surf); // ref. from CreateSurface - rc = NS_OK; - } - - return rc; + // okay, what's this supposed to do? Empty the state stack? + return NS_OK; } - -NS_IMETHODIMP nsRenderingContextOS2::LockDrawingSurface( PRInt32 aX, PRInt32 aY, - PRUint32 aWidth, PRUint32 aHeight, - void **aBits, - PRInt32 *aStride, PRInt32 *aWidthBytes, - PRUint32 aFlags) +NS_IMETHODIMP nsRenderingContextOS2::GetDeviceContext( nsIDeviceContext *&aContext) { - PushState(); - - return mSurface->Lock( aX, aY, aWidth, aHeight, aBits, - aStride, aWidthBytes, aFlags); -} - -NS_IMETHODIMP nsRenderingContextOS2::UnlockDrawingSurface() -{ - mSurface->Unlock(); - - PRBool clipstate; - PopState (clipstate); - + NS_IF_ADDREF(mContext); + aContext = mContext; return NS_OK; } @@ -492,8 +440,10 @@ NS_IMETHODIMP nsRenderingContextOS2 :: PushState(void) state->mMatrix = mStates->mMatrix; state->mLocalClip = mStates->mLocalClip; - // clip region: get current & copy it. - state->mClipRegion = OS2_CopyClipRegion( mPS); +// we don't want to NULL this out since we reuse the region +// from state to state. if we NULL it, we need to also delete it, +// which means we'll just re-create it when we push the clip state. MMP +// state->mClipRegion = OS2_CopyClipRegion( mPS); state->mFlags = ~FLAGS_ALL; state->mLineStyle = mStates->mLineStyle; @@ -534,7 +484,6 @@ NS_IMETHODIMP nsRenderingContextOS2 :: PopState(PRBool &aClipEmpty) GraphicsState *pstate; -#ifdef OLDCODE if (oldstate->mFlags & FLAG_CLIP_CHANGED) { pstate = mStates; @@ -547,19 +496,15 @@ NS_IMETHODIMP nsRenderingContextOS2 :: PopState(PRBool &aClipEmpty) if (nsnull != pstate) { - int cliptype = ::SelectClipRgn(mDC, pstate->mClipRegion); + // set copy of pstate->mClipRegion as current clip region + HRGN hrgn = GFX (::GpiCreateRegion (mPS, 0, NULL), RGN_ERROR); + GFX (::GpiCombineRegion (mPS, hrgn, pstate->mClipRegion, 0, CRGN_COPY), RGN_ERROR); + int cliptype = OS2_SetClipRegion (mPS, hrgn); - if (cliptype == NULLREGION) + if (cliptype == RGN_NULL) retval = PR_TRUE; } } -#endif - OS2_SetClipRegion( mPS, mStates->mClipRegion); - if( mStates->mClipRegion != 0) - { - mStates->mClipRegion = 0; - retval = PR_FALSE; - } oldstate->mFlags &= ~FLAGS_ALL; @@ -567,7 +512,6 @@ NS_IMETHODIMP nsRenderingContextOS2 :: PopState(PRBool &aClipEmpty) mFontMetrics = mStates->mFontMetrics; mColor = mStates->mColor; - SetColor( mStates->mColor); SetLineStyle(mStates->mLineStyle); } @@ -580,16 +524,8 @@ NS_IMETHODIMP nsRenderingContextOS2 :: PopState(PRBool &aClipEmpty) return NS_OK; } -nsresult nsRenderingContextOS2::Reset() -{ - // okay, what's this supposed to do? Empty the state stack? - return NS_OK; -} - -// Clip region management -------------------------------------------------- - -nsresult nsRenderingContextOS2::IsVisibleRect( const nsRect &aRect, - PRBool &aIsVisible) +NS_IMETHODIMP nsRenderingContextOS2::IsVisibleRect( const nsRect &aRect, + PRBool &aIsVisible) { nsRect trect( aRect); mTranMatrix->TransformCoord( &trect.x, &trect.y, @@ -606,108 +542,122 @@ nsresult nsRenderingContextOS2::IsVisibleRect( const nsRect &aRect, } // Return PR_TRUE if clip region is now empty -nsresult nsRenderingContextOS2::SetClipRect( const nsRect& aRect, nsClipCombine aCombine, PRBool &aClipEmpty) +NS_IMETHODIMP nsRenderingContextOS2::SetClipRect( const nsRect& aRect, nsClipCombine aCombine, PRBool &aClipEmpty) { - nsRect trect = aRect; - mTranMatrix->TransformCoord( &trect.x, &trect.y, &trect.width, &trect.height); - long lrc = RGN_ERROR; + nsRect trect = aRect; + RECTL rcl; + int cliptype = RGN_ERROR; - if( trect.width == 0 || trect.height == 0) - { - // Mozilla assumes that clip region with zero width or height does not produce any output - everything is clipped. - // GPI does not support clip regions with zero width or height. We cheat by creating 1x1 clip region far outside - // of real drawing region limits. + mTranMatrix->TransformCoord(&trect.x, &trect.y, + &trect.width, &trect.height); - if( aCombine == nsClipCombine_kIntersect || aCombine == nsClipCombine_kReplace) - { - RECTL rcl; - rcl.xLeft = -1000; - rcl.xRight = -999; - rcl.yBottom = -1000; - rcl.yTop = -999; + mStates->mLocalClip = aRect; + mStates->mFlags |= FLAG_LOCAL_CLIP_VALID; - HRGN hrgn = GFX (::GpiCreateRegion( mPS, 1, &rcl), RGN_ERROR); - OS2_SetClipRegion (mPS, hrgn); + //how we combine the new rect with the previous? - lrc = PR_TRUE; // Should pretend that clipping region is empty - } else - { - // Clipping region is already correct. Just need to obtain it's complexity - POINTL Offset = { 0, 0 }; + if( trect.width == 0 || trect.height == 0) + { + // Mozilla assumes that clip region with zero width or height does not produce any output - everything is clipped. + // GPI does not support clip regions with zero width or height. We cheat by creating 1x1 clip region far outside + // of real drawing region limits. - lrc = GFX (::GpiOffsetClipRegion (mPS, &Offset), RGN_ERROR); - } - } - else - { - RECTL rcl; + if( aCombine == nsClipCombine_kIntersect || aCombine == nsClipCombine_kReplace) + { + PushClipState(); - switch( aCombine) - { - case nsClipCombine_kIntersect: - case nsClipCombine_kSubtract: - mSurface->NS2PM_ININ (trect, rcl); - if( aCombine == nsClipCombine_kIntersect) - lrc = GFX (::GpiIntersectClipRectangle( mPS, &rcl), RGN_ERROR); - else - lrc = GFX (::GpiExcludeClipRectangle( mPS, &rcl), RGN_ERROR); - break; + rcl.xLeft = -10000; + rcl.xRight = -9999; + rcl.yBottom = -10000; + rcl.yTop = -9999; - case nsClipCombine_kUnion: - case nsClipCombine_kReplace: - { - // need to create a new region & fiddle with it - mSurface->NS2PM_INEX (trect, rcl); - HRGN hrgn = GFX (::GpiCreateRegion( mPS, 1, &rcl), RGN_ERROR); - if( hrgn && aCombine == nsClipCombine_kReplace) - lrc = OS2_SetClipRegion( mPS, hrgn); - else if( hrgn) - lrc = OS2_CombineClipRegion( mPS, hrgn, CRGN_OR); - break; - } - default: - // compiler informational... - NS_ASSERTION( 0, "illegal clip combination"); - break; - } - } + HRGN hrgn = GFX (::GpiCreateRegion( mPS, 1, &rcl), RGN_ERROR); + OS2_SetClipRegion (mPS, hrgn); - aClipEmpty = (lrc == RGN_NULL) ? PR_TRUE : PR_FALSE; + cliptype = RGN_NULL; // Should pretend that clipping region is empty + } + else if( aCombine == nsClipCombine_kUnion || aCombine == nsClipCombine_kSubtract) + { + PushClipState(); - return NS_OK; + // Clipping region is already correct. Just need to obtain it's complexity + POINTL Offset = { 0, 0 }; + + cliptype = GFX (::GpiOffsetClipRegion (mPS, &Offset), RGN_ERROR); + } + else + NS_ASSERTION(PR_FALSE, "illegal clip combination"); + } + else + { + if (aCombine == nsClipCombine_kIntersect) + { + PushClipState(); + + mSurface->NS2PM_ININ (trect, rcl); + cliptype = GFX (::GpiIntersectClipRectangle(mPS, &rcl), RGN_ERROR); + } + else if (aCombine == nsClipCombine_kUnion) + { + PushClipState(); + + mSurface->NS2PM_INEX (trect, rcl); + HRGN hrgn = GFX (::GpiCreateRegion(mPS, 1, &rcl), RGN_ERROR); + + if( hrgn ) + cliptype = OS2_CombineClipRegion(mPS, hrgn, CRGN_OR); + } + else if (aCombine == nsClipCombine_kSubtract) + { + PushClipState(); + + mSurface->NS2PM_ININ (trect, rcl); + cliptype = GFX (::GpiExcludeClipRectangle(mPS, &rcl), RGN_ERROR); + } + else if (aCombine == nsClipCombine_kReplace) + { + PushClipState(); + + mSurface->NS2PM_INEX (trect, rcl); + HRGN hrgn = GFX (::GpiCreateRegion(mPS, 1, &rcl), RGN_ERROR); + + if( hrgn ) + cliptype = OS2_SetClipRegion(mPS, hrgn); + } + else + NS_ASSERTION(PR_FALSE, "illegal clip combination"); + } + + if (cliptype == RGN_NULL) + aClipEmpty = PR_TRUE; + else + aClipEmpty = PR_FALSE; + + return NS_OK; } // rc is whether there is a cliprect to return -// !! Potential problems here: I think we ought to return the rect -// !! transformed by the inverse of our xformation matrix. Which, -// !! frankly, I can't be bothered to write the code for - it ought -// !! to be a method in nsTransform2D. -nsresult nsRenderingContextOS2::GetClipRect( nsRect &aRect, PRBool &aHasLocalClip) +NS_IMETHODIMP nsRenderingContextOS2::GetClipRect( nsRect &aRect, PRBool &aClipValid) { - RECTL rcl; - long rc = GFX (::GpiQueryClipBox (mPS, &rcl), RGN_ERROR); + if (mStates->mFlags & FLAG_LOCAL_CLIP_VALID) + { + aRect = mStates->mLocalClip; + aClipValid = PR_TRUE; + } + else + aClipValid = PR_FALSE; - PRBool brc = PR_FALSE; - - if( rc != RGN_NULL && rc != RGN_ERROR) - { - mSurface->PM2NS_ININ (rcl, aRect); - brc = PR_TRUE; - } - - aHasLocalClip = brc; - - return NS_OK; + return NS_OK; } // Return PR_TRUE if clip region is now empty -nsresult nsRenderingContextOS2::SetClipRegion( const nsIRegion &aRegion, nsClipCombine aCombine, PRBool &aClipEmpty) +NS_IMETHODIMP nsRenderingContextOS2::SetClipRegion( const nsIRegion &aRegion, nsClipCombine aCombine, PRBool &aClipEmpty) { nsRegionOS2 *pRegion = (nsRegionOS2 *) &aRegion; PRUint32 ulHeight = mSurface->GetHeight (); HRGN hrgn = pRegion->GetHRGN( ulHeight, mPS); - long cmode = 0; + int cmode, cliptype; switch( aCombine) { @@ -729,15 +679,40 @@ nsresult nsRenderingContextOS2::SetClipRegion( const nsIRegion &aRegion, nsClipC break; } - long lrc = OS2_CombineClipRegion( mPS, hrgn, cmode); + if (NULL != hrgn) + { + mStates->mFlags &= ~FLAG_LOCAL_CLIP_VALID; + PushClipState(); + cliptype = OS2_CombineClipRegion( mPS, hrgn, cmode); + } + else + return PR_FALSE; - aClipEmpty = (lrc == RGN_NULL) ? PR_TRUE : PR_FALSE; + if (cliptype == RGN_NULL) + aClipEmpty = PR_TRUE; + else + aClipEmpty = PR_FALSE; return NS_OK; } +/** + * Fills in |aRegion| with a copy of the current clip region. + */ +NS_IMETHODIMP nsRenderingContextOS2::CopyClipRegion(nsIRegion &aRegion) +{ + HRGN hr = OS2_CopyClipRegion(mPS); + + if (hr == HRGN_ERROR) + return NS_ERROR_FAILURE; + + //((nsRegionOS2 *)&aRegion)->mRegion = hr; + + return NS_OK; +} + // Somewhat dubious & rather expensive -nsresult nsRenderingContextOS2::GetClipRegion( nsIRegion **aRegion) +NS_IMETHODIMP nsRenderingContextOS2::GetClipRegion( nsIRegion **aRegion) { if( !aRegion) return NS_ERROR_NULL_POINTER; @@ -771,107 +746,145 @@ nsresult nsRenderingContextOS2::GetClipRegion( nsIRegion **aRegion) return NS_OK; } -/** - * Fills in |aRegion| with a copy of the current clip region. - */ -nsresult nsRenderingContextOS2::CopyClipRegion(nsIRegion &aRegion) -{ - HRGN hr = OS2_CopyClipRegion(mPS); - - if (hr == HRGN_ERROR) - return NS_ERROR_FAILURE; - else - return NS_OK; -} - -// Setters & getters ------------------------------------------------------- - -nsresult nsRenderingContextOS2::GetDeviceContext( nsIDeviceContext *&aDeviceContext) -{ -// NS_IF_RELEASE(aDeviceContext); - aDeviceContext = mContext; - NS_IF_ADDREF( mContext); - return NS_OK; -} - -nsresult nsRenderingContextOS2::SetColor( nscolor aColor) +NS_IMETHODIMP nsRenderingContextOS2::SetColor( nscolor aColor) { mColor = aColor; return NS_OK; } -nsresult nsRenderingContextOS2::GetColor( nscolor &aColor) const +NS_IMETHODIMP nsRenderingContextOS2::GetColor( nscolor &aColor) const { aColor = mColor; return NS_OK; } -nsresult nsRenderingContextOS2::SetLineStyle( nsLineStyle aLineStyle) +NS_IMETHODIMP nsRenderingContextOS2::SetLineStyle( nsLineStyle aLineStyle) { mLineStyle = aLineStyle; return NS_OK; } -nsresult nsRenderingContextOS2::GetLineStyle( nsLineStyle &aLineStyle) +NS_IMETHODIMP nsRenderingContextOS2::GetLineStyle( nsLineStyle &aLineStyle) { aLineStyle = mLineStyle; return NS_OK; } -nsresult nsRenderingContextOS2::SetFont( const nsFont &aFont) +NS_IMETHODIMP nsRenderingContextOS2::SetFont( const nsFont &aFont) { NS_IF_RELEASE( mFontMetrics); mContext->GetMetricsFor( aFont, mFontMetrics); + return NS_OK; } -nsresult nsRenderingContextOS2::SetFont( nsIFontMetrics *aFontMetrics) +NS_IMETHODIMP nsRenderingContextOS2::SetFont( nsIFontMetrics *aFontMetrics) { NS_IF_RELEASE( mFontMetrics); mFontMetrics = aFontMetrics; NS_IF_ADDREF( mFontMetrics); + return NS_OK; } -nsresult nsRenderingContextOS2::GetFontMetrics( nsIFontMetrics*& aFontMetrics) +NS_IMETHODIMP nsRenderingContextOS2::GetFontMetrics( nsIFontMetrics*& aFontMetrics) { -// Commented out because clients misuse the interface. -// -// NS_IF_RELEASE(aFontMetrics); - aFontMetrics = mFontMetrics; - NS_IF_ADDREF( mFontMetrics); - return NS_OK; + NS_IF_ADDREF(mFontMetrics); + aFontMetrics = mFontMetrics; + + return NS_OK; } // add the passed in translation to the current translation -nsresult nsRenderingContextOS2::Translate( nscoord aX, nscoord aY) +NS_IMETHODIMP nsRenderingContextOS2::Translate( nscoord aX, nscoord aY) { mTranMatrix->AddTranslation( (float) aX, (float) aY); return NS_OK; } // add the passed in scale to the current scale -nsresult nsRenderingContextOS2::Scale( float aSx, float aSy) +NS_IMETHODIMP nsRenderingContextOS2::Scale( float aSx, float aSy) { mTranMatrix->AddScale(aSx, aSy); return NS_OK; } -nsresult nsRenderingContextOS2::GetCurrentTransform( nsTransform2D *&aTransform) +NS_IMETHODIMP nsRenderingContextOS2::GetCurrentTransform( nsTransform2D *&aTransform) { -/* JSK0126 - Assign mTMatrix into aTransform, since aTransform is not a valid object yet */ - aTransform = mTranMatrix; - - /* - NS_PRECONDITION(aTransform,"Null transform ptr"); - if( !aTransform) - return NS_ERROR_NULL_POINTER; - aTransform->SetMatrix( mTranMatrix); - */ - return NS_OK; + aTransform = mTranMatrix; + return NS_OK; } +// The idea here is to create an offscreen surface for blitting with. +// I can't find any way for people to resize the bitmap created here, +// so I guess this gets called quite often. +// +// I'm reliably told that 'aBounds' is in device units, and that the +// position oughtn't to be ignored, but for all intents & purposes can be. +// +NS_IMETHODIMP nsRenderingContextOS2::CreateDrawingSurface( nsRect *aBounds, + PRUint32 aSurfFlags, nsDrawingSurface &aSurface) +{ + nsresult rc = NS_ERROR_FAILURE; + + nsOffscreenSurface *surf = new nsOffscreenSurface; + + if (!surf) + return NS_ERROR_OUT_OF_MEMORY; + + rc = surf->Init( mMainSurface->GetPS (), aBounds->width, aBounds->height, aSurfFlags); + + if(NS_SUCCEEDED(rc)) + { + NS_ADDREF(surf); + aSurface = (void*)((nsDrawingSurfaceOS2 *) surf); + } + else + delete surf; + + return rc; +} + +NS_IMETHODIMP nsRenderingContextOS2::CreateDrawingSurface(HPS aPS, nsDrawingSurface &aSurface, nsIWidget *aWidget) +{ + nsWindowSurface *surf = new nsWindowSurface(); + + if (nsnull != surf) + { + NS_ADDREF(surf); + surf->Init(aPS, aWidget); + } + + aSurface = (nsDrawingSurface)surf; + + return NS_OK; +} + +NS_IMETHODIMP nsRenderingContextOS2::DestroyDrawingSurface( nsDrawingSurface aDS) +{ + nsDrawingSurfaceOS2 *surf = (nsDrawingSurfaceOS2 *) aDS; + nsresult rc = NS_ERROR_NULL_POINTER; + + // If the surface being destroyed is the one we're currently using for + // offscreen, then lose our reference to it & hook back to the onscreen. + if( surf && surf == mSurface) + { + NS_RELEASE(mSurface); // ref. from SelectOffscreen + mSurface = mMainSurface; + mPS = mSurface->GetPS (); + NS_ADDREF(mSurface); + } + + if( surf) + { + NS_RELEASE(surf); // ref. from CreateSurface + rc = NS_OK; + } + + return rc; +} + // Drawing methods --------------------------------------------------------- LONG nsRenderingContextOS2::GetGPIColor (void) @@ -927,36 +940,7 @@ void nsRenderingContextOS2::SetupFillColor (void) } } -void nsRenderingContextOS2::SetupFontAndTextColor (void) -{ - if (!doSetupFontAndTextColor) { - return; - } /* endif */ - if (mFontMetrics != mCurrFontMetrics) - { - // select font - mCurrFontMetrics = mFontMetrics; - if( mCurrFontMetrics) - mSurface->SelectFont( mCurrFontMetrics); - } - - if (mColor != mCurrTextColor) - { - CHARBUNDLE cBundle; - cBundle.lColor = GetGPIColor (); - cBundle.usMixMode = FM_OVERPAINT; - cBundle.usBackMixMode = BM_LEAVEALONE; - - GFX (::GpiSetAttrs (mPS, PRIM_CHAR, - CBB_COLOR | CBB_MIX_MODE | CBB_BACK_MIX_MODE, - 0, &cBundle), - FALSE); - - mCurrTextColor = mColor; - } -} - -nsresult nsRenderingContextOS2::DrawLine( nscoord aX0, nscoord aY0, nscoord aX1, nscoord aY1) +NS_IMETHODIMP nsRenderingContextOS2::DrawLine( nscoord aX0, nscoord aY0, nscoord aX1, nscoord aY1) { mTranMatrix->TransformCoord( &aX0, &aY0); mTranMatrix->TransformCoord( &aX1, &aY1); @@ -983,19 +967,19 @@ nsresult nsRenderingContextOS2::DrawLine( nscoord aX0, nscoord aY0, nscoord aX1, return NS_OK; } -nsresult nsRenderingContextOS2::DrawPolyline(const nsPoint aPoints[], PRInt32 aNumPoints) +NS_IMETHODIMP nsRenderingContextOS2::DrawPolyline(const nsPoint aPoints[], PRInt32 aNumPoints) { PMDrawPoly( aPoints, aNumPoints, PR_FALSE); return NS_OK; } -nsresult nsRenderingContextOS2::DrawPolygon( const nsPoint aPoints[], PRInt32 aNumPoints) +NS_IMETHODIMP nsRenderingContextOS2::DrawPolygon( const nsPoint aPoints[], PRInt32 aNumPoints) { PMDrawPoly( aPoints, aNumPoints, PR_FALSE); return NS_OK; } -nsresult nsRenderingContextOS2::FillPolygon( const nsPoint aPoints[], PRInt32 aNumPoints) +NS_IMETHODIMP nsRenderingContextOS2::FillPolygon( const nsPoint aPoints[], PRInt32 aNumPoints) { PMDrawPoly( aPoints, aNumPoints, PR_TRUE); return NS_OK; @@ -1051,28 +1035,28 @@ void nsRenderingContextOS2::PMDrawPoly( const nsPoint aPoints[], PRInt32 aNumPoi } } -nsresult nsRenderingContextOS2::DrawRect( const nsRect& aRect) +NS_IMETHODIMP nsRenderingContextOS2::DrawRect( const nsRect& aRect) { nsRect tr = aRect; PMDrawRect( tr, FALSE); return NS_OK; } -nsresult nsRenderingContextOS2::DrawRect( nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) +NS_IMETHODIMP nsRenderingContextOS2::DrawRect( nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) { nsRect tr( aX, aY, aWidth, aHeight); PMDrawRect( tr, FALSE); return NS_OK; } -nsresult nsRenderingContextOS2::FillRect( const nsRect& aRect) +NS_IMETHODIMP nsRenderingContextOS2::FillRect( const nsRect& aRect) { nsRect tr = aRect; PMDrawRect( tr, TRUE); return NS_OK; } -nsresult nsRenderingContextOS2::FillRect( nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) +NS_IMETHODIMP nsRenderingContextOS2::FillRect( nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) { nsRect tr( aX, aY, aWidth, aHeight); PMDrawRect( tr, TRUE); @@ -1129,35 +1113,35 @@ void nsRenderingContextOS2::PMDrawRect( nsRect &rect, BOOL fill) } // Arc-drawing methods, all proxy on to PMDrawArc -nsresult nsRenderingContextOS2::DrawEllipse( const nsRect& aRect) +NS_IMETHODIMP nsRenderingContextOS2::DrawEllipse( const nsRect& aRect) { nsRect tRect( aRect); PMDrawArc( tRect, PR_FALSE, PR_TRUE); return NS_OK; } -nsresult nsRenderingContextOS2::DrawEllipse( nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) +NS_IMETHODIMP nsRenderingContextOS2::DrawEllipse( nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) { nsRect tRect( aX, aY, aWidth, aHeight); PMDrawArc( tRect, PR_FALSE, PR_TRUE); return NS_OK; } -nsresult nsRenderingContextOS2::FillEllipse( const nsRect& aRect) +NS_IMETHODIMP nsRenderingContextOS2::FillEllipse( const nsRect& aRect) { nsRect tRect( aRect); PMDrawArc( tRect, PR_TRUE, PR_TRUE); return NS_OK; } -nsresult nsRenderingContextOS2::FillEllipse( nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) +NS_IMETHODIMP nsRenderingContextOS2::FillEllipse( nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) { nsRect tRect( aX, aY, aWidth, aHeight); PMDrawArc( tRect, PR_TRUE, PR_TRUE); return NS_OK; } -nsresult nsRenderingContextOS2::DrawArc( const nsRect& aRect, +NS_IMETHODIMP nsRenderingContextOS2::DrawArc( const nsRect& aRect, float aStartAngle, float aEndAngle) { nsRect tRect( aRect); @@ -1165,7 +1149,7 @@ nsresult nsRenderingContextOS2::DrawArc( const nsRect& aRect, return NS_OK; } -nsresult nsRenderingContextOS2::DrawArc( nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight, +NS_IMETHODIMP nsRenderingContextOS2::DrawArc( nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight, float aStartAngle, float aEndAngle) { nsRect tRect( aX, aY, aWidth, aHeight); @@ -1173,7 +1157,7 @@ nsresult nsRenderingContextOS2::DrawArc( nscoord aX, nscoord aY, nscoord aWidth, return NS_OK; } -nsresult nsRenderingContextOS2::FillArc( const nsRect& aRect, +NS_IMETHODIMP nsRenderingContextOS2::FillArc( const nsRect& aRect, float aStartAngle, float aEndAngle) { nsRect tRect( aRect); @@ -1181,7 +1165,7 @@ nsresult nsRenderingContextOS2::FillArc( const nsRect& aRect, return NS_OK; } -nsresult nsRenderingContextOS2::FillArc( nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight, +NS_IMETHODIMP nsRenderingContextOS2::FillArc( nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight, float aStartAngle, float aEndAngle) { nsRect tRect( aX, aY, aWidth, aHeight); @@ -1250,15 +1234,6 @@ void nsRenderingContextOS2::PMDrawArc( nsRect &rect, PRBool bFilled, PRBool bFul } } -NS_IMETHODIMP nsRenderingContextOS2::GetHints(PRUint32& aResult) -{ - PRUint32 result = 0; - - aResult = result; - - return NS_OK; -} - NS_IMETHODIMP nsRenderingContextOS2 :: GetWidth(char ch, nscoord& aWidth) { char buf[1]; @@ -1641,7 +1616,7 @@ NS_IMETHODIMP nsRenderingContextOS2 :: DrawString(const nsString& aString, // Image drawing: just proxy on to the image object, so no worries yet. -nsresult nsRenderingContextOS2::DrawImage( nsIImage *aImage, nscoord aX, nscoord aY) +NS_IMETHODIMP nsRenderingContextOS2::DrawImage( nsIImage *aImage, nscoord aX, nscoord aY) { nscoord width, height; @@ -1651,7 +1626,7 @@ nsresult nsRenderingContextOS2::DrawImage( nsIImage *aImage, nscoord aX, nscoord return this->DrawImage( aImage, aX, aY, width, height); } -nsresult nsRenderingContextOS2::DrawImage( nsIImage *aImage, nscoord aX, nscoord aY, +NS_IMETHODIMP nsRenderingContextOS2::DrawImage( nsIImage *aImage, nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) { nsRect tr; @@ -1664,7 +1639,7 @@ nsresult nsRenderingContextOS2::DrawImage( nsIImage *aImage, nscoord aX, nscoord return this->DrawImage( aImage, tr); } -nsresult nsRenderingContextOS2::DrawImage( nsIImage *aImage, const nsRect& aSRect, const nsRect& aDRect) +NS_IMETHODIMP nsRenderingContextOS2::DrawImage( nsIImage *aImage, const nsRect& aSRect, const nsRect& aDRect) { nsRect sr,dr; @@ -1680,7 +1655,7 @@ nsresult nsRenderingContextOS2::DrawImage( nsIImage *aImage, const nsRect& aSRec return aImage->Draw( *this, mSurface, sr.x, sr.y, sr.width, sr.height, dr.x, dr.y, dr.width, dr.height); } -nsresult nsRenderingContextOS2::DrawImage( nsIImage *aImage, const nsRect& aRect) +NS_IMETHODIMP nsRenderingContextOS2::DrawImage( nsIImage *aImage, const nsRect& aRect) { nsRect tr( aRect); mTranMatrix->TransformCoord( &tr.x, &tr.y, &tr.width, &tr.height); @@ -1723,7 +1698,7 @@ nsRenderingContextOS2::DrawTile(nsIImage *aImage,nscoord aX0,nscoord aY0,nscoord } -nsresult nsRenderingContextOS2::CopyOffScreenBits( +NS_IMETHODIMP nsRenderingContextOS2::CopyOffScreenBits( nsDrawingSurface aSrcSurf, PRInt32 aSrcX, PRInt32 aSrcY, const nsRect &aDestBounds, PRUint32 aCopyFlags) { @@ -1787,13 +1762,67 @@ nsresult nsRenderingContextOS2::CopyOffScreenBits( return NS_OK; } -nsresult nsRenderingContextOS2::RetrieveCurrentNativeGraphicData(PRUint32* ngd) +NS_IMETHODIMP nsRenderingContextOS2::RetrieveCurrentNativeGraphicData(PRUint32* ngd) { if(ngd != nsnull) *ngd = (PRUint32)mPS; return NS_OK; } +void nsRenderingContextOS2::SetupFontAndTextColor (void) +{ + if (!doSetupFontAndTextColor) { + return; + } /* endif */ + if (mFontMetrics != mCurrFontMetrics) + { + // select font + mCurrFontMetrics = mFontMetrics; + if( mCurrFontMetrics) + mSurface->SelectFont( mCurrFontMetrics); + } + + if (mColor != mCurrTextColor) + { + CHARBUNDLE cBundle; + cBundle.lColor = GetGPIColor (); + cBundle.usMixMode = FM_OVERPAINT; + cBundle.usBackMixMode = BM_LEAVEALONE; + + GFX (::GpiSetAttrs (mPS, PRIM_CHAR, + CBB_COLOR | CBB_MIX_MODE | CBB_BACK_MIX_MODE, + 0, &cBundle), + FALSE); + + mCurrTextColor = mColor; + } +} + +void nsRenderingContextOS2::PushClipState(void) +{ + if (!(mStates->mFlags & FLAG_CLIP_CHANGED)) + { + GraphicsState *tstate = mStates->mNext; + + //we have never set a clip on this state before, so + //remember the current clip state in the next state on the + //stack. kind of wacky, but avoids selecting stuff in the DC + //all the damned time. + + if (nsnull != tstate) + { + tstate->mClipRegion = OS2_CopyClipRegion( mPS ); + + if (tstate->mClipRegion != 0) + tstate->mFlags |= FLAG_CLIP_VALID; + else + tstate->mFlags &= ~FLAG_CLIP_VALID; + } + + mStates->mFlags |= FLAG_CLIP_CHANGED; + } +} + // Clip region helper functions -------------------------------------------- /* hrgnCombine becomes the clip region. Any current clip region is */ diff --git a/gfx/src/os2/nsRenderingContextOS2.h b/gfx/src/os2/nsRenderingContextOS2.h index 1960f32c071d..50d057067524 100644 --- a/gfx/src/os2/nsRenderingContextOS2.h +++ b/gfx/src/os2/nsRenderingContextOS2.h @@ -214,6 +214,7 @@ private: nsresult CommonInit (void); nsresult SetupPS (void); LONG GetGPIColor (void); + void PushClipState(void); // Colour/font setting; call before drawing things.