diff --git a/mozilla/gfx/src/motif/nsRegionUnix.cpp b/mozilla/gfx/src/motif/nsRegionUnix.cpp new file mode 100644 index 00000000000..681ebce5cf1 --- /dev/null +++ b/mozilla/gfx/src/motif/nsRegionUnix.cpp @@ -0,0 +1,96 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "nsRegionUnix.h" + +static NS_DEFINE_IID(kRegionIID, NS_IREGION_IID); + +nsRegionUnix :: nsRegionUnix() +{ + NS_INIT_REFCNT(); +} + +nsRegionUnix :: ~nsRegionUnix() +{ +} + +NS_IMPL_QUERY_INTERFACE(nsRegionUnix, kRegionIID) +NS_IMPL_ADDREF(nsRegionUnix) +NS_IMPL_RELEASE(nsRegionUnix) + +nsresult nsRegionUnix :: Init(void) +{ + return NS_OK; +} + +void nsRegionUnix :: SetTo(const nsIRegion &aRegion) +{ +} + +void nsRegionUnix :: SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) +{ +} + +void nsRegionUnix :: Intersect(const nsIRegion &aRegion) +{ +} + +void nsRegionUnix :: Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) +{ +} + +void nsRegionUnix :: Union(const nsIRegion &aRegion) +{ +} + +void nsRegionUnix :: Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) +{ +} + +void nsRegionUnix :: Subtract(const nsIRegion &aRegion) +{ +} + +PRBool nsRegionUnix :: IsEmpty(void) +{ + return PR_FALSE; +} + +PRBool nsRegionUnix :: IsEqual(const nsIRegion &aRegion) +{ + return PR_FALSE; +} + +void nsRegionUnix :: GetBoundingBox(PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight) +{ + *aX = *aY = *aWidth = *aHeight = 0; +} + +void nsRegionUnix :: Offset(PRInt32 aXOffset, PRInt32 aYOffset) +{ +} + +PRBool nsRegionUnix :: ContainsRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) +{ + return PR_TRUE; +} + +PRBool nsRegionUnix :: ForEachRect(nsRectInRegionFunc *func, void *closure) +{ + return PR_FALSE; +} diff --git a/mozilla/gfx/src/motif/nsRegionUnix.h b/mozilla/gfx/src/motif/nsRegionUnix.h new file mode 100644 index 00000000000..08b101e37f5 --- /dev/null +++ b/mozilla/gfx/src/motif/nsRegionUnix.h @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsRegionUnix_h___ +#define nsRegionUnix_h___ + +#include "nsIRegion.h" + +class nsRegionUnix : public nsIRegion +{ +public: + nsRegionUnix(); + + NS_DECL_ISUPPORTS + + virtual nsresult Init(); + + virtual void SetTo(const nsIRegion &aRegion); + virtual void SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight); + virtual void Intersect(const nsIRegion &aRegion); + virtual void Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight); + virtual void Union(const nsIRegion &aRegion); + virtual void Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight); + virtual void Subtract(const nsIRegion &aRegion); + virtual PRBool IsEmpty(void); + virtual PRBool IsEqual(const nsIRegion &aRegion); + virtual void GetBoundingBox(PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight); + virtual void Offset(PRInt32 aXOffset, PRInt32 aYOffset); + virtual PRBool ContainsRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight); + virtual PRBool ForEachRect(nsRectInRegionFunc *func, void *closure); + +private: + ~nsRegionUnix(); +}; + +#endif // nsRegionUnix_h___ diff --git a/mozilla/gfx/src/motif/nsRenderingContextUnix.cpp b/mozilla/gfx/src/motif/nsRenderingContextUnix.cpp index 0acd7359514..f785160b87e 100644 --- a/mozilla/gfx/src/motif/nsRenderingContextUnix.cpp +++ b/mozilla/gfx/src/motif/nsRenderingContextUnix.cpp @@ -93,11 +93,11 @@ nsIDeviceContext * nsRenderingContextUnix :: GetDeviceContext(void) return mContext; } -void nsRenderingContextUnix :: PushState() +void nsRenderingContextUnix :: PushState(void) { } -void nsRenderingContextUnix :: PopState() +void nsRenderingContextUnix :: PopState(void) { } @@ -106,16 +106,42 @@ PRBool nsRenderingContextUnix :: IsVisibleRect(const nsRect& aRect) return PR_TRUE; } -void nsRenderingContextUnix :: SetClipRect(const nsRect& aRect, PRBool aIntersect) +void nsRenderingContextUnix :: SetClipRect(const nsRect& aRect, nsClipCombine aCombine) { + nsRect trect = aRect; + + mTMatrix->TransformCoord(&trect.x, &trect.y, + &trect.width, &trect.height); + + //how we combine the new rect with the previous? + + if (aCombine == nsClipCombine_kIntersect) + { + } + else if (aCombine == nsClipCombine_kUnion) + { + } + else if (aCombine == nsClipCombine_kSubtract) + { + } + else if (aCombine == nsClipCombine_kReplace) + { + } + else + NS_ASSERTION(FALSE, "illegal clip combination"); } PRBool nsRenderingContextUnix :: GetClipRect(nsRect &aRect) { - return PR_TRUE; + return PR_FALSE; } -void nsRenderingContextUnix :: SetClipRegion(const nsIRegion& aRegion, PRBool aIntersect) +void nsRenderingContextUnix :: SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine) +{ + //XXX wow, needs to do something. +} + +void nsRenderingContextUnix :: GetClipRegion(nsIRegion **aRegion) { //XXX wow, needs to do something. } diff --git a/mozilla/gfx/src/motif/nsRenderingContextUnix.h b/mozilla/gfx/src/motif/nsRenderingContextUnix.h index 4df5604f90a..15021673de3 100644 --- a/mozilla/gfx/src/motif/nsRenderingContextUnix.h +++ b/mozilla/gfx/src/motif/nsRenderingContextUnix.h @@ -34,6 +34,7 @@ #include "nsImageUnix.h" #include "nsIDeviceContext.h" #include "nsVoidArray.h" +#include "nsIRegion.h" #include "Xm/Xm.h" @@ -62,15 +63,15 @@ public: virtual nsresult SelectOffScreenDrawingSurface(nsDrawingSurface aSurface); - virtual void PushState(); - virtual void PopState(); + virtual void PushState(void); + virtual void PopState(void); virtual PRBool IsVisibleRect(const nsRect& aRect); - virtual void SetClipRect(const nsRect& aRect, PRBool aIntersect); + virtual void SetClipRect(const nsRect& aRect, nsClipCombine aCombine); virtual PRBool GetClipRect(nsRect &aRect); - virtual void SetClipRegion(const nsIRegion& aRegion, PRBool aIntersect); - + virtual void SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine); + virtual void GetClipRegion(nsIRegion **aRegion); virtual void SetColor(nscolor aColor); virtual nscolor GetColor() const; diff --git a/mozilla/gfx/src/nsIRenderingContext.h b/mozilla/gfx/src/nsIRenderingContext.h index 6e1e466f791..a4269fc7c4b 100644 --- a/mozilla/gfx/src/nsIRenderingContext.h +++ b/mozilla/gfx/src/nsIRenderingContext.h @@ -37,6 +37,16 @@ struct nsFont; struct nsPoint; struct nsRect; +//cliprect/region combination methods + +typedef enum +{ + nsClipCombine_kIntersect = 0, + nsClipCombine_kUnion = 1, + nsClipCombine_kSubtract = 2, + nsClipCombine_kReplace = 3 +} nsClipCombine; + // IID for the nsIRenderingContext interface #define NS_IRENDERING_CONTEXT_IID \ { 0x7fd8c0f0, 0xa265, 0x11d1, \ @@ -90,12 +100,12 @@ public: /** * Save a graphical state onto a stack. */ - virtual void PushState() = 0; + virtual void PushState(void) = 0; /** * Get and and set RenderingContext to this graphical state */ - virtual void PopState() = 0; + virtual void PopState(void) = 0; /** * Tells if a given rectangle is visible within the rendering context @@ -107,26 +117,35 @@ public: /** * Sets the clipping for the RenderingContext to the passed in rectangle * @param aRect The rectangle to set the clipping rectangle to - * @param aIntersect A boolean, if true will cause aRect to be - * intersected with existing clip area + * @param aCombine how to combine this rect with the current clip region. + * see the bottom of nsIRenderingContext.h */ - virtual void SetClipRect(const nsRect& aRect, PRBool aIntersect) = 0; + virtual void SetClipRect(const nsRect& aRect, nsClipCombine aCombine) = 0; /** - * Gets the clipping rectangle of the RenderingContext - * @param aRect out parameter to containt the clipping rectangle + * Gets the bounds of the clip region of the RenderingContext + * @param aRect out parameter to contain the clip region bounds * for the RenderingContext * @return PR_TRUE if the rendering context has a cliprect set + * (i.e. this is the exact clip rect, not a clip region bounds) */ virtual PRBool GetClipRect(nsRect &aRect) = 0; /** * Sets the clipping for the RenderingContext to the passed in region * @param aRegion The region to set the clipping area to - * @param aIntersect A boolean, if true will cause aRegion to be - * intersected with existing clip area + * @param aCombine how to combine this region with the current clip region. + * see the bottom of nsIRenderingContext.h */ - virtual void SetClipRegion(const nsIRegion& aRegion, PRBool aIntersect) = 0; + virtual void SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine) = 0; + + /** + * Gets the current clipping region for the RenderingContext + * @param aRegion out parameter representing the clip region. + * if SetClipRegion() is called, do not assume that GetClipRegion() + * will return the same object. + */ + virtual void GetClipRegion(nsIRegion **aRegion) = 0; /** * Sets the forground color for the RenderingContext diff --git a/mozilla/gfx/src/windows/nsRenderingContextWin.cpp b/mozilla/gfx/src/windows/nsRenderingContextWin.cpp index 14950749551..4a8e6ca44d9 100644 --- a/mozilla/gfx/src/windows/nsRenderingContextWin.cpp +++ b/mozilla/gfx/src/windows/nsRenderingContextWin.cpp @@ -19,6 +19,9 @@ #include "nsRenderingContextWin.h" #include +#define FLAG_CLIP_VALID 0x0001 +#define FLAG_CLIP_CHANGED 0x0002 + class GraphicsState { public: @@ -29,7 +32,6 @@ public: GraphicsState *mNext; nsTransform2D mMatrix; nsRect mLocalClip; - nsRect mGlobalClip; HRGN mClipRegion; nscolor mBrushColor; HBRUSH mSolidBrush; @@ -37,6 +39,7 @@ public: HFONT mFont; nscolor mPenColor; HPEN mSolidPen; + PRUint32 mFlags; }; GraphicsState :: GraphicsState() @@ -44,7 +47,6 @@ GraphicsState :: GraphicsState() mNext = nsnull; mMatrix.SetToIdentity(); mLocalClip.x = mLocalClip.y = mLocalClip.width = mLocalClip.height = 0; - mGlobalClip = mLocalClip; mClipRegion = NULL; mBrushColor = NS_RGB(0, 0, 0); mSolidBrush = NULL; @@ -52,12 +54,12 @@ GraphicsState :: GraphicsState() mFont = NULL; mPenColor = NS_RGB(0, 0, 0); mSolidPen = NULL; + mFlags = 0; } GraphicsState :: GraphicsState(GraphicsState &aState) : mMatrix(&aState.mMatrix), - mLocalClip(aState.mLocalClip), - mGlobalClip(aState.mGlobalClip) + mLocalClip(aState.mLocalClip) { mNext = &aState; mClipRegion = NULL; @@ -67,6 +69,7 @@ GraphicsState :: GraphicsState(GraphicsState &aState) : mFont = NULL; mPenColor = aState.mPenColor; mSolidPen = NULL; + mFlags = 0; } GraphicsState :: ~GraphicsState() @@ -309,7 +312,7 @@ nsIDeviceContext * nsRenderingContextWin :: GetDeviceContext(void) return mContext; } -void nsRenderingContextWin :: PushState() +void nsRenderingContextWin :: PushState(void) { PRInt32 cnt = mStateCache->Count(); @@ -331,14 +334,14 @@ void nsRenderingContextWin :: PushState() state->mMatrix = mStates->mMatrix; state->mLocalClip = mStates->mLocalClip; - state->mGlobalClip = mStates->mGlobalClip; - state->mClipRegion = nsnull; + state->mClipRegion = NULL; state->mBrushColor = mStates->mBrushColor; - state->mSolidBrush = nsnull; + state->mSolidBrush = NULL; state->mFontMetrics = mStates->mFontMetrics; - state->mFont = nsnull; + state->mFont = NULL; state->mPenColor = mStates->mPenColor; - state->mSolidPen = nsnull; + state->mSolidPen = NULL; + state->mFlags = 0; mStates = state; } @@ -346,7 +349,7 @@ void nsRenderingContextWin :: PushState() mTMatrix = &mStates->mMatrix; } -void nsRenderingContextWin :: PopState() +void nsRenderingContextWin :: PopState(void) { if (nsnull == mStates) { @@ -366,27 +369,21 @@ void nsRenderingContextWin :: PopState() GraphicsState *pstate; - if (NULL != oldstate->mClipRegion) + if (oldstate->mFlags & FLAG_CLIP_CHANGED) { pstate = mStates; //the clip rect has changed from state to state, so //install the previous clip rect - while ((nsnull != pstate) && (NULL == pstate->mClipRegion)) + while ((nsnull != pstate) && !(pstate->mFlags & FLAG_CLIP_VALID)) pstate = pstate->mNext; - if ((nsnull != pstate) && (pstate->mGlobalClip != oldstate->mGlobalClip)) + if (nsnull != pstate) ::SelectClipRgn(mDC, pstate->mClipRegion); - else - ::SelectClipRgn(mDC, NULL); - - //kill the clip region we are popping off the stack - - ::DeleteObject(oldstate->mClipRegion); - oldstate->mClipRegion = NULL; } + oldstate->mFlags &= ~(FLAG_CLIP_VALID | FLAG_CLIP_CHANGED); oldstate->mSolidBrush = NULL; oldstate->mFont = NULL; oldstate->mSolidPen = NULL; @@ -401,7 +398,7 @@ PRBool nsRenderingContextWin :: IsVisibleRect(const nsRect& aRect) return PR_TRUE; } -void nsRenderingContextWin :: SetClipRect(const nsRect& aRect, PRBool aIntersect) +void nsRenderingContextWin :: SetClipRect(const nsRect& aRect, nsClipCombine aCombine) { nsRect trect = aRect; @@ -410,26 +407,51 @@ void nsRenderingContextWin :: SetClipRect(const nsRect& aRect, PRBool aIntersect mTMatrix->TransformCoord(&trect.x, &trect.y, &trect.width, &trect.height); - //should we combine the new rect with the previous? + //how we combine the new rect with the previous? - if (aIntersect == PR_TRUE) + if (aCombine == nsClipCombine_kIntersect) { - if (PR_FALSE == mStates->mGlobalClip.IntersectRect(mStates->mGlobalClip, trect)) - { - mStates->mGlobalClip.x = mStates->mGlobalClip.y = mStates->mGlobalClip.width = mStates->mGlobalClip.height = 0; - } + PushClipState(); + + ::IntersectClipRect(mDC, trect.x, + trect.y, + trect.XMost(), + trect.YMost()); + } + else if (aCombine == nsClipCombine_kUnion) + { + PushClipState(); + + HRGN tregion = ::CreateRectRgn(trect.x, + trect.y, + trect.XMost(), + trect.YMost()); + + ::ExtSelectClipRgn(mDC, tregion, RGN_OR); + ::DeleteObject(tregion); + } + else if (aCombine == nsClipCombine_kSubtract) + { + PushClipState(); + + ::ExcludeClipRect(mDC, trect.x, + trect.y, + trect.XMost(), + trect.YMost()); + } + else if (aCombine == nsClipCombine_kReplace) + { + PushClipState(); + + HRGN tregion = ::CreateRectRgn(trect.x, + trect.y, + trect.XMost(), + trect.YMost()); + ::SelectClipRgn(mDC, tregion); + ::DeleteObject(tregion); } else - mStates->mGlobalClip = trect; - - if (NULL != mStates->mClipRegion) - ::DeleteObject(mStates->mClipRegion); - - mStates->mClipRegion = ::CreateRectRgn(mStates->mGlobalClip.x, - mStates->mGlobalClip.y, - mStates->mGlobalClip.XMost(), - mStates->mGlobalClip.YMost()); - ::SelectClipRgn(mDC, mStates->mClipRegion); + NS_ASSERTION(FALSE, "illegal clip combination"); } PRBool nsRenderingContextWin :: GetClipRect(nsRect &aRect) @@ -439,7 +461,12 @@ PRBool nsRenderingContextWin :: GetClipRect(nsRect &aRect) return PR_TRUE; } -void nsRenderingContextWin :: SetClipRegion(const nsIRegion& aRegion, PRBool aIntersect) +void nsRenderingContextWin :: SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine) +{ + //XXX wow, needs to do something. +} + +void nsRenderingContextWin :: GetClipRegion(nsIRegion **aRegion) { //XXX wow, needs to do something. } @@ -877,17 +904,28 @@ nsresult nsRenderingContextWin :: CopyOffScreenBits(nsRect &aBounds) { if ((nsnull != mDC) && (nsnull != mMainDC)) { + HRGN tregion = ::CreateRectRgn(0, 0, 0, 0); + + if (::GetClipRgn(mDC, tregion) == 1) + ::SelectClipRgn(mMainDC, tregion); +// else +// ::SelectClipRgn(mMainDC, NULL); + + ::DeleteObject(tregion); + +#if 0 GraphicsState *pstate = mStates; //look for a cliprect somewhere in the stack... - while ((nsnull != pstate) && (NULL == pstate->mClipRegion)) + while ((nsnull != pstate) && !(pstate->mFlags & FLAG_CLIP_VALID)) pstate = pstate->mNext; if (nsnull != pstate) ::SelectClipRgn(mMainDC, pstate->mClipRegion); else ::SelectClipRgn(mMainDC, NULL); +#endif ::BitBlt(mMainDC, 0, 0, aBounds.width, aBounds.height, mDC, 0, 0, SRCCOPY); } @@ -952,3 +990,29 @@ HPEN nsRenderingContextWin :: SetupSolidPen(void) return mCurrPen; } + +void nsRenderingContextWin :: 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) + { + if (NULL == tstate->mClipRegion) + tstate->mClipRegion = ::CreateRectRgn(0, 0, 0, 0); + + if (::GetClipRgn(mDC, tstate->mClipRegion) == 1) + tstate->mFlags |= FLAG_CLIP_VALID; + else + tstate->mFlags &= ~FLAG_CLIP_VALID; + } + + mStates->mFlags |= FLAG_CLIP_CHANGED; + } +} diff --git a/mozilla/gfx/src/windows/nsRenderingContextWin.h b/mozilla/gfx/src/windows/nsRenderingContextWin.h index 93196a21ef6..99ac23e15fc 100644 --- a/mozilla/gfx/src/windows/nsRenderingContextWin.h +++ b/mozilla/gfx/src/windows/nsRenderingContextWin.h @@ -60,14 +60,15 @@ public: virtual nsresult SelectOffScreenDrawingSurface(nsDrawingSurface aSurface); - virtual void PushState(); - virtual void PopState(); + virtual void PushState(void); + virtual void PopState(void); virtual PRBool IsVisibleRect(const nsRect& aRect); - virtual void SetClipRect(const nsRect& aRect, PRBool aIntersect); + virtual void SetClipRect(const nsRect& aRect, nsClipCombine aCombine); virtual PRBool GetClipRect(nsRect &aRect); - virtual void SetClipRegion(const nsIRegion& aRegion, PRBool aIntersect); + virtual void SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine); + virtual void GetClipRegion(nsIRegion **aRegion); virtual void SetColor(nscolor aColor); virtual nscolor GetColor() const; @@ -129,6 +130,7 @@ private: HBRUSH SetupSolidBrush(void); HPEN SetupSolidPen(void); void SetupFont(void); + void PushClipState(void); protected: nscolor mCurrentColor; @@ -142,6 +144,7 @@ protected: nsIDeviceContext *mContext; float mP2T; HDC mMainDC; + HRGN mClipRegion; //default objects HBRUSH mOrigSolidBrush; HBRUSH mBlackBrush; diff --git a/mozilla/layout/base/nsCSSRendering.cpp b/mozilla/layout/base/nsCSSRendering.cpp index 790b8dd7ba2..2445b5d4936 100644 --- a/mozilla/layout/base/nsCSSRendering.cpp +++ b/mozilla/layout/base/nsCSSRendering.cpp @@ -851,7 +851,7 @@ void nsCSSRendering::PaintBackground(nsIPresContext& aPresContext, PRIntn yPos = aColor.mBackgroundXPosition; #endif aRenderingContext.PushState(); - aRenderingContext.SetClipRect(aDirtyRect, PR_TRUE); + aRenderingContext.SetClipRect(aDirtyRect, nsClipCombine_kIntersect); PRIntn x, y; for (y = 0; y <= ycount; ++y, ypos += tileHeight) { for (x = 0, xpos = xpos0; x <= xcount; ++x, xpos += tileWidth) { diff --git a/mozilla/layout/base/src/nsContainerFrame.cpp b/mozilla/layout/base/src/nsContainerFrame.cpp index 39788aac9e1..9c81a2e5a38 100644 --- a/mozilla/layout/base/src/nsContainerFrame.cpp +++ b/mozilla/layout/base/src/nsContainerFrame.cpp @@ -232,7 +232,7 @@ void nsContainerFrame::PaintChildren(nsIPresContext& aPresContext, if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { aRenderingContext.PushState(); aRenderingContext.SetClipRect(nsRect(0, 0, mRect.width, mRect.height), - PR_TRUE); + nsClipCombine_kIntersect); hidden = PR_TRUE; } diff --git a/mozilla/layout/base/src/nsFrame.cpp b/mozilla/layout/base/src/nsFrame.cpp index d9e641b0599..ac5b7d5bdf1 100644 --- a/mozilla/layout/base/src/nsFrame.cpp +++ b/mozilla/layout/base/src/nsFrame.cpp @@ -372,17 +372,17 @@ NS_METHOD nsFrame::MoveTo(nscoord aX, nscoord aY) if ((aX != mRect.x) || (aY != mRect.y)) { mRect.x = aX; mRect.y = aY; + } - // Let the view know - if (nsnull != mView) { - // Position view relative to it's parent, not relative to our - // parent frame (our parent frame may not have a view). - nsIView* parentWithView; - nsPoint origin; - GetOffsetFromView(origin, parentWithView); - mView->SetPosition(origin.x, origin.y); - NS_IF_RELEASE(parentWithView); - } + // Let the view know + if (nsnull != mView) { + // Position view relative to it's parent, not relative to our + // parent frame (our parent frame may not have a view). + nsIView* parentWithView; + nsPoint origin; + GetOffsetFromView(origin, parentWithView); + mView->SetPosition(origin.x, origin.y); + NS_IF_RELEASE(parentWithView); } return NS_OK; @@ -998,6 +998,7 @@ nsFrame::DidReflow(nsIPresContext& aPresContext, { NS_FRAME_TRACE_MSG(("nsFrame::DidReflow: aStatus=%d", aStatus)); if (NS_FRAME_REFLOW_FINISHED == aStatus) { +// MoveTo(mRect.x, mRect.y); //added and killed per kipp's instructions... MMP mState &= ~NS_FRAME_IN_REFLOW; } return NS_OK; diff --git a/mozilla/layout/html/base/src/nsHTMLImage.cpp b/mozilla/layout/html/base/src/nsHTMLImage.cpp index d4d5f5a865e..2c27d38068f 100644 --- a/mozilla/layout/html/base/src/nsHTMLImage.cpp +++ b/mozilla/layout/html/base/src/nsHTMLImage.cpp @@ -37,6 +37,9 @@ #include "nsILinkHandler.h" #include "nsIURL.h" #include "nsCSSLayout.h" +#include "nsViewsCID.h" +#include "nsIView.h" +#include "nsIViewManager.h" #define BROKEN_IMAGE_URL "resource:/html/broken-image.gif" @@ -292,6 +295,45 @@ nsHTMLImageLoader::GetDesiredSize(nsIPresContext* aPresContext, ImageFrame::ImageFrame(nsIContent* aContent, nsIFrame* aParentFrame) : nsLeafFrame(aContent, aParentFrame) { +#if 0 + //lifted from nsRootPart.cpp. if we do this very much, factor it somehow. MMP + // Create a view + nsIFrame* parent; + nsIView* view; + + GetParentWithView(parent); + NS_ASSERTION(parent, "GetParentWithView failed"); + nsIView* parView; + + parent->GetView(parView); + NS_ASSERTION(parView, "no parent with view"); + + // Create a view + static NS_DEFINE_IID(kViewCID, NS_VIEW_CID); + static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID); + + nsresult result = NSRepository::CreateInstance(kViewCID, + nsnull, + kIViewIID, + (void **)&view); + if (NS_OK == result) { + nsIView* rootView = parView; + nsIViewManager* viewManager = rootView->GetViewManager(); + + // Initialize the view + NS_ASSERTION(nsnull != viewManager, "null view manager"); + + view->Init(viewManager, mRect, rootView); + viewManager->InsertChild(rootView, view, 0); + + NS_RELEASE(viewManager); + + // Remember our view + SetView(view); + NS_RELEASE(view); + } + NS_RELEASE(parView); +#endif } ImageFrame::~ImageFrame() diff --git a/mozilla/layout/html/forms/src/nsInputFrame.cpp b/mozilla/layout/html/forms/src/nsInputFrame.cpp index ff30e2a0cfd..84a21516e62 100644 --- a/mozilla/layout/html/forms/src/nsInputFrame.cpp +++ b/mozilla/layout/html/forms/src/nsInputFrame.cpp @@ -62,6 +62,7 @@ nsInputFrame::nsInputFrame(nsIContent* aContent, nsIFrame* aParentFrame) : nsInputFrameSuper(aContent, aParentFrame) { mLastMouseState = eMouseNone; + mDidInit = PR_FALSE; } nsInputFrame::~nsInputFrame() @@ -138,16 +139,21 @@ nsInputFrame::Paint(nsIPresContext& aPresContext, nsIView* view = nsnull; GetView(view); if (nsnull != view) { - SetViewVisiblity(&aPresContext, PR_TRUE); + if (PR_FALSE == mDidInit) { + ((nsInput*)mContent)->GetFormManager()->Init(PR_FALSE); + PostCreateWidget(&aPresContext, view); + mDidInit = PR_TRUE; + } +// SetViewVisiblity(&aPresContext, PR_TRUE); NS_RELEASE(view); } - // Point borders/padding if any return nsInputFrameSuper::Paint(aPresContext, aRenderingContext, aDirtyRect); } return NS_OK; } +//don't call this. MMP void nsInputFrame::SetViewVisiblity(nsIPresContext* aPresContext, PRBool aShow) { @@ -261,7 +267,7 @@ nsInputFrame::Reflow(nsIPresContext* aPresContext, // initialize the view as hidden since we don't know the (x,y) until Paint result = view->Init(viewMan, boundBox, parView, &id, initData, nsnull, 0, nsnull, - 1.0f, nsViewVisibility_kHide); + 1.0f, nsViewVisibility_kShow); if (nsnull != initData) { delete(initData); } @@ -297,7 +303,7 @@ nsInputFrame::Reflow(nsIPresContext* aPresContext, // If we are being reflowed and have a view, hide the view until // we are told to paint (which is when our location will have // stabilized). - SetViewVisiblity(aPresContext, PR_FALSE); +// SetViewVisiblity(aPresContext, PR_FALSE); } aDesiredSize.ascent = aDesiredSize.height; diff --git a/mozilla/layout/html/forms/src/nsInputFrame.h b/mozilla/layout/html/forms/src/nsInputFrame.h index 1d2cb5a76ac..9f3178c82ac 100644 --- a/mozilla/layout/html/forms/src/nsInputFrame.h +++ b/mozilla/layout/html/forms/src/nsInputFrame.h @@ -212,6 +212,7 @@ protected: nsMouseState mLastMouseState; nsSize mWidgetSize; + PRBool mDidInit; }; #endif diff --git a/mozilla/layout/html/style/src/nsCSSRendering.cpp b/mozilla/layout/html/style/src/nsCSSRendering.cpp index 790b8dd7ba2..2445b5d4936 100644 --- a/mozilla/layout/html/style/src/nsCSSRendering.cpp +++ b/mozilla/layout/html/style/src/nsCSSRendering.cpp @@ -851,7 +851,7 @@ void nsCSSRendering::PaintBackground(nsIPresContext& aPresContext, PRIntn yPos = aColor.mBackgroundXPosition; #endif aRenderingContext.PushState(); - aRenderingContext.SetClipRect(aDirtyRect, PR_TRUE); + aRenderingContext.SetClipRect(aDirtyRect, nsClipCombine_kIntersect); PRIntn x, y; for (y = 0; y <= ycount; ++y, ypos += tileHeight) { for (x = 0, xpos = xpos0; x <= xcount; ++x, xpos += tileWidth) { diff --git a/mozilla/view/public/nsIView.h b/mozilla/view/public/nsIView.h index 8fcbbf7e79c..663694e4ee6 100644 --- a/mozilla/view/public/nsIView.h +++ b/mozilla/view/public/nsIView.h @@ -123,8 +123,12 @@ public: * @param rc rendering context to paint into * @param rect damage area * @param aPaintFlags see nsIView.h for flag definitions + * @param aBackstop if we will need to do back to front + * painting, this is the view that, once rendered + * ends the back to front pass. */ - virtual void Paint(nsIRenderingContext& rc, const nsRect& rect, PRUint32 aPaintFlags) = 0; + virtual void Paint(nsIRenderingContext& rc, const nsRect& rect, + PRUint32 aPaintFlags, nsIView *aBackstop = nsnull) = 0; /** * Called to indicate that the specified region of the view @@ -367,10 +371,15 @@ public: //visibility state is set to inherit #define NS_VIEW_FLAG_PARENT_HIDDEN 0x0001 +//when painting, if we have determined that we need to do a combination +//of front to back and back to front painting, this flag will be set +//while in the back to front pass +#define NS_VIEW_FLAG_BACK_TO_FRONT 0x0002 + //during event propagation, see if parent views can handle the event -#define NS_VIEW_FLAG_CHECK_PARENT 0x0002 +#define NS_VIEW_FLAG_CHECK_PARENT 0x0004 //during event propagation, see if child views can handle the event -#define NS_VIEW_FLAG_CHECK_CHILDREN 0x0004 +#define NS_VIEW_FLAG_CHECK_CHILDREN 0x0008 #endif diff --git a/mozilla/view/src/nsView.cpp b/mozilla/view/src/nsView.cpp index 3e9cd4caaf2..51f54c30ab0 100644 --- a/mozilla/view/src/nsView.cpp +++ b/mozilla/view/src/nsView.cpp @@ -365,41 +365,28 @@ nsIWidget * nsView :: GetWidget() return mWindow; } -void nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect, PRUint32 aPaintFlags) +void nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect, + PRUint32 aPaintFlags, nsIView *aBackstop) { + nsIView *pRoot = mViewManager->GetRootView(); + rc.PushState(); if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom)) { - rc.Translate(mBounds.x, mBounds.y); - nsRect crect; - crect.x = mClip.mLeft; - crect.y = mClip.mTop; + crect.x = mClip.mLeft + mBounds.x; + crect.y = mClip.mTop + mBounds.y; crect.width = mClip.mRight - mClip.mLeft; crect.height = mClip.mBottom - mClip.mTop; - rc.SetClipRect(crect, PR_TRUE); + rc.SetClipRect(crect, nsClipCombine_kIntersect); } - else - { - nsIView *pRoot = mViewManager->GetRootView(); + else if (this != pRoot) + rc.SetClipRect(mBounds, nsClipCombine_kIntersect); - if (this != pRoot) - rc.SetClipRect(mBounds, PR_TRUE); - - NS_RELEASE(pRoot); - - rc.Translate(mBounds.x, mBounds.y); - } - - if (nsnull != mFrame) - { - nsIPresContext *cx = mViewManager->GetPresContext(); - mFrame->Paint(*cx, rc, rect); - NS_RELEASE(cx); - } + rc.Translate(mBounds.x, mBounds.y); //XXX maybe we should set this before we set the clip? MMP @@ -432,7 +419,39 @@ void nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect, PRUint32 aPain } } + if ((mVis == nsViewVisibility_kShow) && (nsnull != mFrame)) + { + nsIPresContext *cx = mViewManager->GetPresContext(); + rc.PushState(); + mFrame->Paint(*cx, rc, rect); + rc.PopState(); + NS_RELEASE(cx); + } + rc.PopState(); + + //now we need to exclude this view from the rest of the + //paint process. only do this if this view is actually + //visible and if there is no widget (like a scrollbar) here. + + if ((mVis == nsViewVisibility_kShow) && (nsnull == mWindow)) + { + if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom)) + { + nsRect crect; + + crect.x = mClip.mLeft + mBounds.x; + crect.y = mClip.mTop + mBounds.y; + crect.width = mClip.mRight - mClip.mLeft; + crect.height = mClip.mBottom - mClip.mTop; + + rc.SetClipRect(crect, nsClipCombine_kSubtract); + } + else if (this != pRoot) + rc.SetClipRect(mBounds, nsClipCombine_kSubtract); + } + + NS_RELEASE(pRoot); } void nsView :: Paint(nsIRenderingContext& rc, const nsIRegion& region, PRUint32 aPaintFlags) @@ -854,7 +873,7 @@ void nsView :: List(FILE* out, PRInt32 aIndent) const for (PRInt32 i = aIndent; --i >= 0; ) fputs(" ", out); fprintf(out, "%p win=%p ", this, mWindow); out << mBounds; - fputs("<\n", out); + fprintf(out, " z=%d vis=%d opc=%1.3f <\n", mZindex, mVis, mOpacity); nsIView* kid = mFirstChild; while (nsnull != kid) { kid->List(out, aIndent + 1); diff --git a/mozilla/view/src/nsView.h b/mozilla/view/src/nsView.h index 4fa19da617b..505ac5d529c 100644 --- a/mozilla/view/src/nsView.h +++ b/mozilla/view/src/nsView.h @@ -56,7 +56,8 @@ public: virtual void Destroy(); virtual nsIViewManager * GetViewManager(); virtual nsIWidget * GetWidget(); - virtual void Paint(nsIRenderingContext& rc, const nsRect& rect, PRUint32 aPaintFlags); + virtual void Paint(nsIRenderingContext& rc, const nsRect& rect, + PRUint32 aPaintFlags, nsIView *aBackstop = nsnull); virtual void Paint(nsIRenderingContext& rc, const nsIRegion& region, PRUint32 aPaintFlags); virtual nsEventStatus HandleEvent(nsGUIEvent *event, PRUint32 aEventFlags); virtual void SetPosition(nscoord x, nscoord y); diff --git a/mozilla/view/src/nsViewManager.cpp b/mozilla/view/src/nsViewManager.cpp index 4d3f5051afd..55b66874d6a 100644 --- a/mozilla/view/src/nsViewManager.cpp +++ b/mozilla/view/src/nsViewManager.cpp @@ -300,7 +300,7 @@ void nsViewManager :: Refresh(nsIView *aView, nsIRenderingContext *aContext, nsR } if (aUpdateFlags & NS_VMREFRESH_SCREEN_RECT) - localcx->SetClipRect(*rect, PR_FALSE); + localcx->SetClipRect(*rect, nsClipCombine_kReplace); GetWindowOffsets(&xoff, &yoff); @@ -311,9 +311,11 @@ void nsViewManager :: Refresh(nsIView *aView, nsIRenderingContext *aContext, nsR if (aUpdateFlags & NS_VMREFRESH_SCREEN_RECT) trect.MoveBy(xoff, yoff); else - localcx->SetClipRect(trect, PR_FALSE); + localcx->SetClipRect(trect, nsClipCombine_kReplace); + localcx->PushState(); aView->Paint(*localcx, trect, 0); + localcx->PopState(); if (aUpdateFlags & NS_VMREFRESH_DOUBLE_BUFFER) localcx->CopyOffScreenBits(wrect);