From 8b0eb04e0831b90fce0564b0189c8d16a4712aae Mon Sep 17 00:00:00 2001 From: "troy%netscape.com" Date: Tue, 25 Apr 2000 04:43:11 +0000 Subject: [PATCH] Reinstated clipping code which had been backed out because it caused a problem for XUL layout. I added a workaround for the XUL problem --- content/base/src/nsStyleContext.cpp | 2 +- content/html/style/src/nsCSSStyleRule.cpp | 30 ++--- layout/base/nsPresShell.cpp | 55 ++++++++ layout/base/public/nsIStyleContext.h | 11 ++ layout/base/src/nsStyleContext.cpp | 2 +- layout/forms/nsImageControlFrame.cpp | 2 +- layout/generic/nsBlockFrame.cpp | 15 +-- layout/generic/nsBlockReflowState.cpp | 15 +-- layout/generic/nsBlockReflowState.h | 15 +-- layout/generic/nsContainerFrame.cpp | 119 +++++++++++------- layout/generic/nsFrame.cpp | 41 +++--- layout/generic/nsFrame.h | 9 +- layout/generic/nsFrameSetFrame.cpp | 2 +- layout/generic/nsHTMLContainerFrame.cpp | 68 +++++++--- layout/generic/nsImageFrame.cpp | 10 -- layout/generic/nsObjectFrame.cpp | 3 +- layout/html/base/src/nsBlockFrame.cpp | 15 +-- layout/html/base/src/nsBlockReflowState.cpp | 15 +-- layout/html/base/src/nsBlockReflowState.h | 15 +-- layout/html/base/src/nsContainerFrame.cpp | 119 +++++++++++------- layout/html/base/src/nsFrame.cpp | 41 +++--- layout/html/base/src/nsFrame.h | 9 +- layout/html/base/src/nsHTMLContainerFrame.cpp | 68 +++++++--- layout/html/base/src/nsImageFrame.cpp | 10 -- layout/html/base/src/nsObjectFrame.cpp | 3 +- layout/html/base/src/nsPresShell.cpp | 55 ++++++++ layout/html/base/src/nsScrollFrame.cpp | 2 +- layout/html/base/src/nsScrollPortFrame.cpp | 2 +- layout/html/document/src/nsFrameSetFrame.cpp | 2 +- layout/html/forms/src/nsImageControlFrame.cpp | 2 +- layout/html/forms/src/nsLabelFrame.cpp | 2 +- layout/html/style/src/nsCSSStyleRule.cpp | 30 ++--- layout/style/nsCSSStyleRule.cpp | 30 ++--- layout/style/nsStyleContext.cpp | 2 +- view/public/nsIView.h | 2 - view/src/nsScrollPortView.cpp | 3 +- view/src/nsScrollPortView.h | 1 - view/src/nsScrollingView.cpp | 6 +- view/src/nsScrollingView.h | 1 - view/src/nsView.cpp | 67 +++------- view/src/nsView.h | 3 +- 41 files changed, 542 insertions(+), 362 deletions(-) diff --git a/content/base/src/nsStyleContext.cpp b/content/base/src/nsStyleContext.cpp index 1f04a34d318..0f7073218db 100644 --- a/content/base/src/nsStyleContext.cpp +++ b/content/base/src/nsStyleContext.cpp @@ -1031,7 +1031,7 @@ void StyleDisplayImpl::ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* mBreakAfter = PR_FALSE; mOverflow = NS_STYLE_OVERFLOW_VISIBLE; mClipFlags = NS_STYLE_CLIP_AUTO; - mClip.SizeTo(0,0,0,0); + mClip.SetRect(0,0,0,0); } void StyleDisplayImpl::SetFrom(const nsStyleDisplay& aSource) diff --git a/content/html/style/src/nsCSSStyleRule.cpp b/content/html/style/src/nsCSSStyleRule.cpp index 26f3079c7d5..ed786e08f85 100644 --- a/content/html/style/src/nsCSSStyleRule.cpp +++ b/content/html/style/src/nsCSSStyleRule.cpp @@ -1912,35 +1912,37 @@ MapDeclarationDisplayInto(nsICSSDeclaration* aDeclaration, display->mClipFlags = 0; // clear it if (eCSSUnit_Auto == ourDisplay->mClip->mTop.GetUnit()) { - display->mClip.top = 0; + display->mClip.y = 0; display->mClipFlags |= NS_STYLE_CLIP_TOP_AUTO; } else if (ourDisplay->mClip->mTop.IsLengthUnit()) { - display->mClip.top = CalcLength(ourDisplay->mClip->mTop, aFont->mFont, aPresContext); - fullAuto = PR_FALSE; - } - if (eCSSUnit_Auto == ourDisplay->mClip->mRight.GetUnit()) { - display->mClip.right = 0; - display->mClipFlags |= NS_STYLE_CLIP_RIGHT_AUTO; - } - else if (ourDisplay->mClip->mRight.IsLengthUnit()) { - display->mClip.right = CalcLength(ourDisplay->mClip->mRight, aFont->mFont, aPresContext); + display->mClip.y = CalcLength(ourDisplay->mClip->mTop, aFont->mFont, aPresContext); fullAuto = PR_FALSE; } if (eCSSUnit_Auto == ourDisplay->mClip->mBottom.GetUnit()) { - display->mClip.bottom = 0; + display->mClip.height = 0; display->mClipFlags |= NS_STYLE_CLIP_BOTTOM_AUTO; } else if (ourDisplay->mClip->mBottom.IsLengthUnit()) { - display->mClip.bottom = CalcLength(ourDisplay->mClip->mBottom, aFont->mFont, aPresContext); + display->mClip.height = CalcLength(ourDisplay->mClip->mBottom, aFont->mFont, aPresContext) - + display->mClip.y; fullAuto = PR_FALSE; } if (eCSSUnit_Auto == ourDisplay->mClip->mLeft.GetUnit()) { - display->mClip.left = 0; + display->mClip.x = 0; display->mClipFlags |= NS_STYLE_CLIP_LEFT_AUTO; } else if (ourDisplay->mClip->mLeft.IsLengthUnit()) { - display->mClip.left = CalcLength(ourDisplay->mClip->mLeft, aFont->mFont, aPresContext); + display->mClip.x = CalcLength(ourDisplay->mClip->mLeft, aFont->mFont, aPresContext); + fullAuto = PR_FALSE; + } + if (eCSSUnit_Auto == ourDisplay->mClip->mRight.GetUnit()) { + display->mClip.width = 0; + display->mClipFlags |= NS_STYLE_CLIP_RIGHT_AUTO; + } + else if (ourDisplay->mClip->mRight.IsLengthUnit()) { + display->mClip.width = CalcLength(ourDisplay->mClip->mRight, aFont->mFont, aPresContext) - + display->mClip.x; fullAuto = PR_FALSE; } display->mClipFlags &= ~NS_STYLE_CLIP_TYPE_MASK; diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index e4fb3850b97..d7fafc58c51 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -3072,6 +3072,53 @@ PresShell::GetPlaceholderFrameFor(nsIFrame* aFrame, //nsIViewObserver +// If the element is absolutely positioned and has a specified clip rect +// then it pushes the current rendering context and sets the clip rect. +// Returns PR_TRUE if the clip rect is set and PR_FALSE otherwise +static PRBool +SetClipRect(nsIRenderingContext& aRenderingContext, nsIFrame* aFrame) +{ + PRBool clipState; + const nsStyleDisplay* display; + aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display); + const nsStylePosition* position; + aFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&) position); + + // 'clip' only applies to absolutely positioned elements, and is + // relative to the element's border edge. 'clip' applies to the entire + // element: border, padding, and content areas, and even scrollbars if + // there are any. + if (position->IsAbsolutelyPositioned() && (display->mClipFlags & NS_STYLE_CLIP_RECT)) { + nsSize size; + + // Start with the 'auto' values and then factor in user specified values + aFrame->GetSize(size); + nsRect clipRect(0, 0, size.width, size.height); + + if (display->mClipFlags & NS_STYLE_CLIP_RECT) { + if (0 == (NS_STYLE_CLIP_TOP_AUTO & display->mClipFlags)) { + clipRect.y = display->mClip.y; + } + if (0 == (NS_STYLE_CLIP_LEFT_AUTO & display->mClipFlags)) { + clipRect.x = display->mClip.x; + } + if (0 == (NS_STYLE_CLIP_RIGHT_AUTO & display->mClipFlags)) { + clipRect.width = clipRect.x + display->mClip.width; + } + if (0 == (NS_STYLE_CLIP_BOTTOM_AUTO & display->mClipFlags)) { + clipRect.height = clipRect.y + display->mClip.height; + } + } + + // Set updated clip-rect into the rendering context + aRenderingContext.PushState(); + aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect, clipState); + return PR_TRUE; + } + + return PR_FALSE; +} + NS_IMETHODIMP PresShell::Paint(nsIView *aView, nsIRenderingContext& aRenderingContext, @@ -3090,6 +3137,10 @@ PresShell::Paint(nsIView *aView, { StCaretHider caretHider(this); // stack-based class hides caret until dtor. + // If the frame is absolutely positioned, then the 'clip' property + // applies + PRBool setClipRect = SetClipRect(aRenderingContext, frame); + rv = frame->Paint(mPresContext, aRenderingContext, aDirtyRect, NS_FRAME_PAINT_LAYER_BACKGROUND); rv = frame->Paint(mPresContext, aRenderingContext, aDirtyRect, @@ -3097,6 +3148,10 @@ PresShell::Paint(nsIView *aView, rv = frame->Paint(mPresContext, aRenderingContext, aDirtyRect, NS_FRAME_PAINT_LAYER_FOREGROUND); + if (setClipRect) { + PRBool clipState; + aRenderingContext.PopState(clipState); + } #ifdef NS_DEBUG // Draw a border around the frame diff --git a/layout/base/public/nsIStyleContext.h b/layout/base/public/nsIStyleContext.h index 5511672f3f3..1fd7a81cf0d 100644 --- a/layout/base/public/nsIStyleContext.h +++ b/layout/base/public/nsIStyleContext.h @@ -27,6 +27,7 @@ #include "nsColor.h" #include "nsCoord.h" #include "nsMargin.h" +#include "nsRect.h" #include "nsFont.h" #include "nsVoidArray.h" #include "nsStyleCoord.h" @@ -163,6 +164,9 @@ struct nsStylePosition : public nsStyleStruct { PRBool IsAbsolutelyPositioned() const {return (NS_STYLE_POSITION_ABSOLUTE == mPosition) || (NS_STYLE_POSITION_FIXED == mPosition);} + + PRBool IsPositioned() const {return IsAbsolutelyPositioned() || + (NS_STYLE_POSITION_RELATIVE == mPosition);} }; struct nsStyleText : public nsStyleStruct { @@ -197,7 +201,14 @@ struct nsStyleDisplay : public nsStyleStruct { PRUint8 mOverflow; // [reset] see nsStyleConsts.h PRUint8 mClipFlags; // [reset] see nsStyleConsts.h +#if 0 + // XXX This is how it is defined in the CSS2 spec, but the errata + // changed it to be consistent with the positioning draft and how + // Nav and IE implement it nsMargin mClip; // [reset] offsets from respective edge +#else + nsRect mClip; // [reset] offsets from upper-left border edge +#endif PRBool IsBlockLevel() const {return (NS_STYLE_DISPLAY_BLOCK == mDisplay) || (NS_STYLE_DISPLAY_LIST_ITEM == mDisplay) || diff --git a/layout/base/src/nsStyleContext.cpp b/layout/base/src/nsStyleContext.cpp index 1f04a34d318..0f7073218db 100644 --- a/layout/base/src/nsStyleContext.cpp +++ b/layout/base/src/nsStyleContext.cpp @@ -1031,7 +1031,7 @@ void StyleDisplayImpl::ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* mBreakAfter = PR_FALSE; mOverflow = NS_STYLE_OVERFLOW_VISIBLE; mClipFlags = NS_STYLE_CLIP_AUTO; - mClip.SizeTo(0,0,0,0); + mClip.SetRect(0,0,0,0); } void StyleDisplayImpl::SetFrom(const nsStyleDisplay& aSource) diff --git a/layout/forms/nsImageControlFrame.cpp b/layout/forms/nsImageControlFrame.cpp index 77423257fe1..0245c9dcf2a 100644 --- a/layout/forms/nsImageControlFrame.cpp +++ b/layout/forms/nsImageControlFrame.cpp @@ -240,7 +240,7 @@ nsImageControlFrame::Init(nsIPresContext* aPresContext, parWithView->GetView(aPresContext, &parView); // the view's size is not know yet, but its size will be kept in synch with our frame. nsRect boundBox(0, 0, 0, 0); - result = view->Init(viewMan, boundBox, parView, nsnull); + result = view->Init(viewMan, boundBox, parView); view->SetContentTransparency(PR_TRUE); viewMan->InsertChild(parView, view, 0); SetView(aPresContext, view); diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index dfca9ab439e..855486d5c02 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -5929,13 +5929,6 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, const nsStyleDisplay* disp = (const nsStyleDisplay*) mStyleContext->GetStyleData(eStyleStruct_Display); - // If overflow is hidden then set the clip rect so that children - // don't leak out of us - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - aRenderingContext.PushState(); - SetClipRect(aRenderingContext); - } - // Only paint the border and background if we're visible if (disp->IsVisible() && (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) && (0 != mRect.width) && (0 != mRect.height)) { @@ -5956,6 +5949,14 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, aDirtyRect, rect, *spacing, mStyleContext, 0); } + // If overflow is hidden then set the clip rect so that children don't + // leak out of us. Note that because overflow'-clip' only applies to + // the content area we do this after painting the border and background + if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { + aRenderingContext.PushState(); + SetOverflowClipRect(aRenderingContext); + } + // Child elements have the opportunity to override the visibility // property and display even if the parent is hidden if (NS_FRAME_PAINT_LAYER_FLOATERS == aWhichLayer) { diff --git a/layout/generic/nsBlockReflowState.cpp b/layout/generic/nsBlockReflowState.cpp index dfca9ab439e..855486d5c02 100644 --- a/layout/generic/nsBlockReflowState.cpp +++ b/layout/generic/nsBlockReflowState.cpp @@ -5929,13 +5929,6 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, const nsStyleDisplay* disp = (const nsStyleDisplay*) mStyleContext->GetStyleData(eStyleStruct_Display); - // If overflow is hidden then set the clip rect so that children - // don't leak out of us - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - aRenderingContext.PushState(); - SetClipRect(aRenderingContext); - } - // Only paint the border and background if we're visible if (disp->IsVisible() && (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) && (0 != mRect.width) && (0 != mRect.height)) { @@ -5956,6 +5949,14 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, aDirtyRect, rect, *spacing, mStyleContext, 0); } + // If overflow is hidden then set the clip rect so that children don't + // leak out of us. Note that because overflow'-clip' only applies to + // the content area we do this after painting the border and background + if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { + aRenderingContext.PushState(); + SetOverflowClipRect(aRenderingContext); + } + // Child elements have the opportunity to override the visibility // property and display even if the parent is hidden if (NS_FRAME_PAINT_LAYER_FLOATERS == aWhichLayer) { diff --git a/layout/generic/nsBlockReflowState.h b/layout/generic/nsBlockReflowState.h index dfca9ab439e..855486d5c02 100644 --- a/layout/generic/nsBlockReflowState.h +++ b/layout/generic/nsBlockReflowState.h @@ -5929,13 +5929,6 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, const nsStyleDisplay* disp = (const nsStyleDisplay*) mStyleContext->GetStyleData(eStyleStruct_Display); - // If overflow is hidden then set the clip rect so that children - // don't leak out of us - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - aRenderingContext.PushState(); - SetClipRect(aRenderingContext); - } - // Only paint the border and background if we're visible if (disp->IsVisible() && (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) && (0 != mRect.width) && (0 != mRect.height)) { @@ -5956,6 +5949,14 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, aDirtyRect, rect, *spacing, mStyleContext, 0); } + // If overflow is hidden then set the clip rect so that children don't + // leak out of us. Note that because overflow'-clip' only applies to + // the content area we do this after painting the border and background + if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { + aRenderingContext.PushState(); + SetOverflowClipRect(aRenderingContext); + } + // Child elements have the opportunity to override the visibility // property and display even if the parent is hidden if (NS_FRAME_PAINT_LAYER_FLOATERS == aWhichLayer) { diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index 0ab2aef3e57..74167d95d02 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -149,27 +149,11 @@ nsContainerFrame::PaintChildren(nsIPresContext* aPresContext, const nsStyleDisplay* disp = (const nsStyleDisplay*) mStyleContext->GetStyleData(eStyleStruct_Display); - // Child elements have the opportunity to override the visibility property - // of their parent and display even if the parent is hidden - PRBool clipState; - - // If overflow is hidden then set the clip rect so that children - // don't leak out of us - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - aRenderingContext.PushState(); - aRenderingContext.SetClipRect(nsRect(0, 0, mRect.width, mRect.height), - nsClipCombine_kIntersect, clipState); - } - nsIFrame* kid = mFrames.FirstChild(); while (nsnull != kid) { PaintChild(aPresContext, aRenderingContext, aDirtyRect, kid, aWhichLayer); kid->GetNextSibling(&kid); } - - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - aRenderingContext.PopState(clipState); - } } // Paint one child frame @@ -527,41 +511,82 @@ nsContainerFrame::SyncFrameViewAfterReflow(nsIPresContext* aPresContext, vm->SetViewZIndex(aView, zIndex); vm->SetViewAutoZIndex(aView, autoZIndex); - // Clip applies to block-level and replaced elements with overflow - // set to other than 'visible' - if (display->IsBlockLevel()) { - if (display->mOverflow == NS_STYLE_OVERFLOW_HIDDEN) { - nscoord left, top, right, bottom; + // There are two types of clipping: + // - 'clip' which only applies to absolutely positioned elements, and is + // relative to the element's border edge. 'clip' applies to the entire + // element + // - 'overflow-clip' which only applies to block-level elements and replaced + // elements that have 'overflow' set to 'hidden'. 'overflow-clip' is relative + // to the content area and applies to content only (not border or background). + // Note that out-of-flow frames like floated or absolutely positioned frames + // are block-level, but we can't rely on the 'display' value being set correctly + // in the style context... + PRBool hasClip, hasOverflowClip; + PRBool isBlockLevel = display->IsBlockLevel() || (0 != (kidState & NS_FRAME_OUT_OF_FLOW)); + hasClip = position->IsAbsolutelyPositioned() && (display->mClipFlags & NS_STYLE_CLIP_RECT); + hasOverflowClip = isBlockLevel && (display->mOverflow == NS_STYLE_OVERFLOW_HIDDEN); + if (hasClip || hasOverflowClip) { + nsRect clipRect, overflowClipRect; - // Start with the 'auto' values and then factor in user - // specified values - left = top = 0; - right = frameSize.width; - bottom = frameSize.height; + if (hasClip) { + // Start with the 'auto' values and then factor in user specified values + clipRect.SetRect(0, 0, frameSize.width, frameSize.height); - if (0 == (NS_STYLE_CLIP_TOP_AUTO & display->mClipFlags)) { - top += display->mClip.top; + if (display->mClipFlags & NS_STYLE_CLIP_RECT) { + if (0 == (NS_STYLE_CLIP_TOP_AUTO & display->mClipFlags)) { + clipRect.y = display->mClip.y; + } + if (0 == (NS_STYLE_CLIP_LEFT_AUTO & display->mClipFlags)) { + clipRect.x = display->mClip.x; + } + if (0 == (NS_STYLE_CLIP_RIGHT_AUTO & display->mClipFlags)) { + clipRect.width = clipRect.x + display->mClip.width; + } + if (0 == (NS_STYLE_CLIP_BOTTOM_AUTO & display->mClipFlags)) { + clipRect.height = clipRect.y + display->mClip.height; + } } - if (0 == (NS_STYLE_CLIP_RIGHT_AUTO & display->mClipFlags)) { - right -= display->mClip.right; - } - if (0 == (NS_STYLE_CLIP_BOTTOM_AUTO & display->mClipFlags)) { - bottom -= display->mClip.bottom; - } - if (0 == (NS_STYLE_CLIP_LEFT_AUTO & display->mClipFlags)) { - left += display->mClip.left; - } - // Set clipping of child views. - aView->SetChildClip(left, top, right, bottom); - PRUint32 vflags; - aView->GetViewFlags(&vflags); - aView->SetViewFlags(vflags | NS_VIEW_PUBLIC_FLAG_CLIPCHILDREN); - } else { - // Remove clipping of child views. - PRUint32 vflags; - aView->GetViewFlags(&vflags); - aView->SetViewFlags(vflags & ~NS_VIEW_PUBLIC_FLAG_CLIPCHILDREN); } + + if (hasOverflowClip) { + const nsStyleSpacing* spacing; + nsMargin border, padding; + + aFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)spacing); + + // XXX We don't support the 'overflow-clip' property yet so just use the + // content area (which is the default value) as the clip shape + overflowClipRect.SetRect(0, 0, frameSize.width, frameSize.height); + spacing->GetBorder(border); + overflowClipRect.Deflate(border); + // XXX We need to handle percentage padding + if (spacing->GetPadding(padding)) { + overflowClipRect.Deflate(padding); + } + } + + // If both 'clip' and 'overflow-clip' apply then use the intersection + // of the two + if (hasClip && hasOverflowClip) { + clipRect.IntersectRect(clipRect, overflowClipRect); + } + + // Set clipping of child views. + if (hasClip) { + aView->SetChildClip(clipRect.x, clipRect.y, clipRect.XMost(), clipRect.YMost()); + } else { + aView->SetChildClip(overflowClipRect.x, overflowClipRect.y, + overflowClipRect.XMost(), overflowClipRect.YMost()); + } + PRUint32 vflags; + aView->GetViewFlags(&vflags); + aView->SetViewFlags(vflags | NS_VIEW_PUBLIC_FLAG_CLIPCHILDREN); + + } else { + // Remove clipping of child views. + PRUint32 vflags; + aView->GetViewFlags(&vflags); + aView->SetViewFlags(vflags & ~NS_VIEW_PUBLIC_FLAG_CLIPCHILDREN); } NS_RELEASE(vm); diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 80e42cd76cf..33292094a2f 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -615,33 +615,30 @@ nsFrame::DisplaySelection(nsIPresContext* aPresContext, PRBool isOkToTurnOn) } void -nsFrame::SetClipRect(nsIRenderingContext& aRenderingContext) +nsFrame::SetOverflowClipRect(nsIRenderingContext& aRenderingContext) { - PRBool clipState; - const nsStyleDisplay* display; - GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display); + // 'overflow-clip' only applies to block-level elements and replaced + // elements that have 'overflow' set to 'hidden', and it is relative + // to the content area and applies to content only (not border or background) + const nsStyleSpacing* spacing; + GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)spacing); + + // Start with the 'auto' values and then factor in user specified values + nsRect clipRect(0, 0, mRect.width, mRect.height); - // Start with the auto version of the clip rect. Then overlay on top - // of it specific offsets. - nscoord top = 0; - nscoord right = mRect.width; - nscoord bottom = mRect.height; - nscoord left = 0; - if (0 == (NS_STYLE_CLIP_TOP_AUTO & display->mClipFlags)) { - top += display->mClip.top; - } - if (0 == (NS_STYLE_CLIP_RIGHT_AUTO & display->mClipFlags)) { - right -= display->mClip.right; - } - if (0 == (NS_STYLE_CLIP_BOTTOM_AUTO & display->mClipFlags)) { - bottom -= display->mClip.bottom; - } - if (0 == (NS_STYLE_CLIP_LEFT_AUTO & display->mClipFlags)) { - left += display->mClip.left; + // XXX We don't support the 'overflow-clip' property yet, so just use the + // content area (which is the default value) as the clip shape + nsMargin border, padding; + + spacing->GetBorder(border); + clipRect.Deflate(border); + // XXX We need to handle percentage padding + if (spacing->GetPadding(padding)) { + clipRect.Deflate(padding); } // Set updated clip-rect into the rendering context - nsRect clipRect(left, top, right - left, bottom - top); + PRBool clipState; aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect, clipState); } diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h index 3014e71796a..0bb9549fedd 100644 --- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -423,10 +423,11 @@ protected: virtual PRBool ParentDisablesSelection() const; - // Set the clip rect into the rendering-context after applying CSS's - // clip property. This method assumes that the caller has checked - // that the clip property applies to its situation. - void SetClipRect(nsIRenderingContext& aRenderingContext); + // Set the overflow clip rect into the rendering-context. Used for block-level + // elements and replaced elements that have 'overflow' set to 'hidden'. This + // member function assumes that the caller has checked that the clip property + // applies to its situation. + void SetOverflowClipRect(nsIRenderingContext& aRenderingContext); nsRect mRect; nsIContent* mContent; diff --git a/layout/generic/nsFrameSetFrame.cpp b/layout/generic/nsFrameSetFrame.cpp index d8e1e176db0..96ec6f1b73b 100644 --- a/layout/generic/nsFrameSetFrame.cpp +++ b/layout/generic/nsFrameSetFrame.cpp @@ -275,7 +275,7 @@ nsHTMLFramesetFrame::Init(nsIPresContext* aPresContext, GetParentWithView(aPresContext, &parWithView); parWithView->GetView(aPresContext, &parView); nsRect boundBox(0, 0, 0, 0); - result = view->Init(viewMan, boundBox, parView, nsnull); + result = view->Init(viewMan, boundBox, parView); viewMan->InsertChild(parView, view, 0); SetView(aPresContext, view); diff --git a/layout/generic/nsHTMLContainerFrame.cpp b/layout/generic/nsHTMLContainerFrame.cpp index 58de574e25b..57783b30aa2 100644 --- a/layout/generic/nsHTMLContainerFrame.cpp +++ b/layout/generic/nsHTMLContainerFrame.cpp @@ -377,6 +377,21 @@ nsHTMLContainerFrame::ReparentFrameViewList(nsIPresContext* aPresContext, return NS_OK; } +static PRBool +IsContainerContent(nsIFrame* aFrame) +{ + nsIContent* content; + PRBool result = PR_FALSE; + + aFrame->GetContent(&content); + if (content) { + content->CanContainChildren(result); + NS_RELEASE(content); + } + + return result; +} + nsresult nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext* aPresContext, nsIFrame* aFrame, @@ -458,6 +473,33 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext* aPresContext, NS_IF_RELEASE(pseudoTag); } + // See if the frame is block-level and has 'overflow' set to 'hidden'. If + // so and it can have child frames, then we need to give it a view so clipping + // of any child views works correctly. Note that if it's floated it is also + // block-level, but we can't trust that the style context 'display' value is + // set correctly + if (!aForce) { + if ((display->IsBlockLevel() || display->IsFloating()) && + (display->mOverflow == NS_STYLE_OVERFLOW_HIDDEN)) { + + // The reason for the check of whether it can contain children is just + // to avoid giving it a view unnecessarily + if (::IsContainerContent(aFrame)) { + // XXX Check for the frame being a block frame and only force a view + // in that case, because adding a view for box frames seems to cause + // problems for XUL... + nsIAtom* frameType; + + aFrame->GetFrameType(&frameType); + if ((frameType == nsLayoutAtoms::blockFrame) || + (frameType == nsLayoutAtoms::areaFrame)) { + aForce = PR_TRUE; + } + NS_IF_RELEASE(frameType); + } + } + } + if (aForce) { // Create a view nsIFrame* parent; @@ -528,26 +570,18 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext* aPresContext, // If it's a container element, then leave the view visible, but // mark it as having transparent content. The reason we need to // do this is that child elements can override their parent's - // hidden visibility and be visible anyway - nsIContent* content; - + // hidden visibility and be visible anyway. + // // Because this function is called before processing the content // object's child elements, we can't tell if it's a leaf by looking // at whether the frame has any child frames - aFrame->GetContent(&content); - if (content) { - PRBool isContainer; - - content->CanContainChildren(isContainer); - if (isContainer) { - // The view needs to be visible, but marked as having transparent - // content - viewHasTransparentContent = PR_TRUE; - } else { - // Go ahead and hide the view - viewIsVisible = PR_FALSE; - } - NS_RELEASE(content); + if (::IsContainerContent(aFrame)) { + // The view needs to be visible, but marked as having transparent + // content + viewHasTransparentContent = PR_TRUE; + } else { + // Go ahead and hide the view + viewIsVisible = PR_FALSE; } } } diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index 85ee628c48d..806cf2cce0a 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -559,11 +559,6 @@ nsImageFrame::Paint(nsIPresContext* aPresContext, const nsStyleDisplay* disp = (const nsStyleDisplay*) mStyleContext->GetStyleData(eStyleStruct_Display); if (disp->IsVisible() && mRect.width && mRect.height) { - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - aRenderingContext.PushState(); - SetClipRect(aRenderingContext); - } - // First paint background and borders nsLeafFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); @@ -639,11 +634,6 @@ nsImageFrame::Paint(nsIPresContext* aPresContext, NS_IF_RELEASE(lowImage); NS_IF_RELEASE(image); - - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - PRBool clipState; - aRenderingContext.PopState(clipState); - } } return nsFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsObjectFrame.cpp index f03aa601d13..758436c8b6b 100644 --- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -377,8 +377,7 @@ nsObjectFrame::CreateWidget(nsIPresContext* aPresContext, { // nsWidgetInitData* initData = GetWidgetInitData(aPresContext); // needs to be deleted // initialize the view as hidden since we don't know the (x,y) until Paint - result = view->Init(viewMan, boundBox, parView, nsnull, - nsViewVisibility_kHide); + result = view->Init(viewMan, boundBox, parView, nsViewVisibility_kHide); // if (nsnull != initData) { // delete(initData); // } diff --git a/layout/html/base/src/nsBlockFrame.cpp b/layout/html/base/src/nsBlockFrame.cpp index dfca9ab439e..855486d5c02 100644 --- a/layout/html/base/src/nsBlockFrame.cpp +++ b/layout/html/base/src/nsBlockFrame.cpp @@ -5929,13 +5929,6 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, const nsStyleDisplay* disp = (const nsStyleDisplay*) mStyleContext->GetStyleData(eStyleStruct_Display); - // If overflow is hidden then set the clip rect so that children - // don't leak out of us - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - aRenderingContext.PushState(); - SetClipRect(aRenderingContext); - } - // Only paint the border and background if we're visible if (disp->IsVisible() && (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) && (0 != mRect.width) && (0 != mRect.height)) { @@ -5956,6 +5949,14 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, aDirtyRect, rect, *spacing, mStyleContext, 0); } + // If overflow is hidden then set the clip rect so that children don't + // leak out of us. Note that because overflow'-clip' only applies to + // the content area we do this after painting the border and background + if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { + aRenderingContext.PushState(); + SetOverflowClipRect(aRenderingContext); + } + // Child elements have the opportunity to override the visibility // property and display even if the parent is hidden if (NS_FRAME_PAINT_LAYER_FLOATERS == aWhichLayer) { diff --git a/layout/html/base/src/nsBlockReflowState.cpp b/layout/html/base/src/nsBlockReflowState.cpp index dfca9ab439e..855486d5c02 100644 --- a/layout/html/base/src/nsBlockReflowState.cpp +++ b/layout/html/base/src/nsBlockReflowState.cpp @@ -5929,13 +5929,6 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, const nsStyleDisplay* disp = (const nsStyleDisplay*) mStyleContext->GetStyleData(eStyleStruct_Display); - // If overflow is hidden then set the clip rect so that children - // don't leak out of us - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - aRenderingContext.PushState(); - SetClipRect(aRenderingContext); - } - // Only paint the border and background if we're visible if (disp->IsVisible() && (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) && (0 != mRect.width) && (0 != mRect.height)) { @@ -5956,6 +5949,14 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, aDirtyRect, rect, *spacing, mStyleContext, 0); } + // If overflow is hidden then set the clip rect so that children don't + // leak out of us. Note that because overflow'-clip' only applies to + // the content area we do this after painting the border and background + if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { + aRenderingContext.PushState(); + SetOverflowClipRect(aRenderingContext); + } + // Child elements have the opportunity to override the visibility // property and display even if the parent is hidden if (NS_FRAME_PAINT_LAYER_FLOATERS == aWhichLayer) { diff --git a/layout/html/base/src/nsBlockReflowState.h b/layout/html/base/src/nsBlockReflowState.h index dfca9ab439e..855486d5c02 100644 --- a/layout/html/base/src/nsBlockReflowState.h +++ b/layout/html/base/src/nsBlockReflowState.h @@ -5929,13 +5929,6 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, const nsStyleDisplay* disp = (const nsStyleDisplay*) mStyleContext->GetStyleData(eStyleStruct_Display); - // If overflow is hidden then set the clip rect so that children - // don't leak out of us - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - aRenderingContext.PushState(); - SetClipRect(aRenderingContext); - } - // Only paint the border and background if we're visible if (disp->IsVisible() && (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) && (0 != mRect.width) && (0 != mRect.height)) { @@ -5956,6 +5949,14 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, aDirtyRect, rect, *spacing, mStyleContext, 0); } + // If overflow is hidden then set the clip rect so that children don't + // leak out of us. Note that because overflow'-clip' only applies to + // the content area we do this after painting the border and background + if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { + aRenderingContext.PushState(); + SetOverflowClipRect(aRenderingContext); + } + // Child elements have the opportunity to override the visibility // property and display even if the parent is hidden if (NS_FRAME_PAINT_LAYER_FLOATERS == aWhichLayer) { diff --git a/layout/html/base/src/nsContainerFrame.cpp b/layout/html/base/src/nsContainerFrame.cpp index 0ab2aef3e57..74167d95d02 100644 --- a/layout/html/base/src/nsContainerFrame.cpp +++ b/layout/html/base/src/nsContainerFrame.cpp @@ -149,27 +149,11 @@ nsContainerFrame::PaintChildren(nsIPresContext* aPresContext, const nsStyleDisplay* disp = (const nsStyleDisplay*) mStyleContext->GetStyleData(eStyleStruct_Display); - // Child elements have the opportunity to override the visibility property - // of their parent and display even if the parent is hidden - PRBool clipState; - - // If overflow is hidden then set the clip rect so that children - // don't leak out of us - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - aRenderingContext.PushState(); - aRenderingContext.SetClipRect(nsRect(0, 0, mRect.width, mRect.height), - nsClipCombine_kIntersect, clipState); - } - nsIFrame* kid = mFrames.FirstChild(); while (nsnull != kid) { PaintChild(aPresContext, aRenderingContext, aDirtyRect, kid, aWhichLayer); kid->GetNextSibling(&kid); } - - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - aRenderingContext.PopState(clipState); - } } // Paint one child frame @@ -527,41 +511,82 @@ nsContainerFrame::SyncFrameViewAfterReflow(nsIPresContext* aPresContext, vm->SetViewZIndex(aView, zIndex); vm->SetViewAutoZIndex(aView, autoZIndex); - // Clip applies to block-level and replaced elements with overflow - // set to other than 'visible' - if (display->IsBlockLevel()) { - if (display->mOverflow == NS_STYLE_OVERFLOW_HIDDEN) { - nscoord left, top, right, bottom; + // There are two types of clipping: + // - 'clip' which only applies to absolutely positioned elements, and is + // relative to the element's border edge. 'clip' applies to the entire + // element + // - 'overflow-clip' which only applies to block-level elements and replaced + // elements that have 'overflow' set to 'hidden'. 'overflow-clip' is relative + // to the content area and applies to content only (not border or background). + // Note that out-of-flow frames like floated or absolutely positioned frames + // are block-level, but we can't rely on the 'display' value being set correctly + // in the style context... + PRBool hasClip, hasOverflowClip; + PRBool isBlockLevel = display->IsBlockLevel() || (0 != (kidState & NS_FRAME_OUT_OF_FLOW)); + hasClip = position->IsAbsolutelyPositioned() && (display->mClipFlags & NS_STYLE_CLIP_RECT); + hasOverflowClip = isBlockLevel && (display->mOverflow == NS_STYLE_OVERFLOW_HIDDEN); + if (hasClip || hasOverflowClip) { + nsRect clipRect, overflowClipRect; - // Start with the 'auto' values and then factor in user - // specified values - left = top = 0; - right = frameSize.width; - bottom = frameSize.height; + if (hasClip) { + // Start with the 'auto' values and then factor in user specified values + clipRect.SetRect(0, 0, frameSize.width, frameSize.height); - if (0 == (NS_STYLE_CLIP_TOP_AUTO & display->mClipFlags)) { - top += display->mClip.top; + if (display->mClipFlags & NS_STYLE_CLIP_RECT) { + if (0 == (NS_STYLE_CLIP_TOP_AUTO & display->mClipFlags)) { + clipRect.y = display->mClip.y; + } + if (0 == (NS_STYLE_CLIP_LEFT_AUTO & display->mClipFlags)) { + clipRect.x = display->mClip.x; + } + if (0 == (NS_STYLE_CLIP_RIGHT_AUTO & display->mClipFlags)) { + clipRect.width = clipRect.x + display->mClip.width; + } + if (0 == (NS_STYLE_CLIP_BOTTOM_AUTO & display->mClipFlags)) { + clipRect.height = clipRect.y + display->mClip.height; + } } - if (0 == (NS_STYLE_CLIP_RIGHT_AUTO & display->mClipFlags)) { - right -= display->mClip.right; - } - if (0 == (NS_STYLE_CLIP_BOTTOM_AUTO & display->mClipFlags)) { - bottom -= display->mClip.bottom; - } - if (0 == (NS_STYLE_CLIP_LEFT_AUTO & display->mClipFlags)) { - left += display->mClip.left; - } - // Set clipping of child views. - aView->SetChildClip(left, top, right, bottom); - PRUint32 vflags; - aView->GetViewFlags(&vflags); - aView->SetViewFlags(vflags | NS_VIEW_PUBLIC_FLAG_CLIPCHILDREN); - } else { - // Remove clipping of child views. - PRUint32 vflags; - aView->GetViewFlags(&vflags); - aView->SetViewFlags(vflags & ~NS_VIEW_PUBLIC_FLAG_CLIPCHILDREN); } + + if (hasOverflowClip) { + const nsStyleSpacing* spacing; + nsMargin border, padding; + + aFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)spacing); + + // XXX We don't support the 'overflow-clip' property yet so just use the + // content area (which is the default value) as the clip shape + overflowClipRect.SetRect(0, 0, frameSize.width, frameSize.height); + spacing->GetBorder(border); + overflowClipRect.Deflate(border); + // XXX We need to handle percentage padding + if (spacing->GetPadding(padding)) { + overflowClipRect.Deflate(padding); + } + } + + // If both 'clip' and 'overflow-clip' apply then use the intersection + // of the two + if (hasClip && hasOverflowClip) { + clipRect.IntersectRect(clipRect, overflowClipRect); + } + + // Set clipping of child views. + if (hasClip) { + aView->SetChildClip(clipRect.x, clipRect.y, clipRect.XMost(), clipRect.YMost()); + } else { + aView->SetChildClip(overflowClipRect.x, overflowClipRect.y, + overflowClipRect.XMost(), overflowClipRect.YMost()); + } + PRUint32 vflags; + aView->GetViewFlags(&vflags); + aView->SetViewFlags(vflags | NS_VIEW_PUBLIC_FLAG_CLIPCHILDREN); + + } else { + // Remove clipping of child views. + PRUint32 vflags; + aView->GetViewFlags(&vflags); + aView->SetViewFlags(vflags & ~NS_VIEW_PUBLIC_FLAG_CLIPCHILDREN); } NS_RELEASE(vm); diff --git a/layout/html/base/src/nsFrame.cpp b/layout/html/base/src/nsFrame.cpp index 80e42cd76cf..33292094a2f 100644 --- a/layout/html/base/src/nsFrame.cpp +++ b/layout/html/base/src/nsFrame.cpp @@ -615,33 +615,30 @@ nsFrame::DisplaySelection(nsIPresContext* aPresContext, PRBool isOkToTurnOn) } void -nsFrame::SetClipRect(nsIRenderingContext& aRenderingContext) +nsFrame::SetOverflowClipRect(nsIRenderingContext& aRenderingContext) { - PRBool clipState; - const nsStyleDisplay* display; - GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display); + // 'overflow-clip' only applies to block-level elements and replaced + // elements that have 'overflow' set to 'hidden', and it is relative + // to the content area and applies to content only (not border or background) + const nsStyleSpacing* spacing; + GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)spacing); + + // Start with the 'auto' values and then factor in user specified values + nsRect clipRect(0, 0, mRect.width, mRect.height); - // Start with the auto version of the clip rect. Then overlay on top - // of it specific offsets. - nscoord top = 0; - nscoord right = mRect.width; - nscoord bottom = mRect.height; - nscoord left = 0; - if (0 == (NS_STYLE_CLIP_TOP_AUTO & display->mClipFlags)) { - top += display->mClip.top; - } - if (0 == (NS_STYLE_CLIP_RIGHT_AUTO & display->mClipFlags)) { - right -= display->mClip.right; - } - if (0 == (NS_STYLE_CLIP_BOTTOM_AUTO & display->mClipFlags)) { - bottom -= display->mClip.bottom; - } - if (0 == (NS_STYLE_CLIP_LEFT_AUTO & display->mClipFlags)) { - left += display->mClip.left; + // XXX We don't support the 'overflow-clip' property yet, so just use the + // content area (which is the default value) as the clip shape + nsMargin border, padding; + + spacing->GetBorder(border); + clipRect.Deflate(border); + // XXX We need to handle percentage padding + if (spacing->GetPadding(padding)) { + clipRect.Deflate(padding); } // Set updated clip-rect into the rendering context - nsRect clipRect(left, top, right - left, bottom - top); + PRBool clipState; aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect, clipState); } diff --git a/layout/html/base/src/nsFrame.h b/layout/html/base/src/nsFrame.h index 3014e71796a..0bb9549fedd 100644 --- a/layout/html/base/src/nsFrame.h +++ b/layout/html/base/src/nsFrame.h @@ -423,10 +423,11 @@ protected: virtual PRBool ParentDisablesSelection() const; - // Set the clip rect into the rendering-context after applying CSS's - // clip property. This method assumes that the caller has checked - // that the clip property applies to its situation. - void SetClipRect(nsIRenderingContext& aRenderingContext); + // Set the overflow clip rect into the rendering-context. Used for block-level + // elements and replaced elements that have 'overflow' set to 'hidden'. This + // member function assumes that the caller has checked that the clip property + // applies to its situation. + void SetOverflowClipRect(nsIRenderingContext& aRenderingContext); nsRect mRect; nsIContent* mContent; diff --git a/layout/html/base/src/nsHTMLContainerFrame.cpp b/layout/html/base/src/nsHTMLContainerFrame.cpp index 58de574e25b..57783b30aa2 100644 --- a/layout/html/base/src/nsHTMLContainerFrame.cpp +++ b/layout/html/base/src/nsHTMLContainerFrame.cpp @@ -377,6 +377,21 @@ nsHTMLContainerFrame::ReparentFrameViewList(nsIPresContext* aPresContext, return NS_OK; } +static PRBool +IsContainerContent(nsIFrame* aFrame) +{ + nsIContent* content; + PRBool result = PR_FALSE; + + aFrame->GetContent(&content); + if (content) { + content->CanContainChildren(result); + NS_RELEASE(content); + } + + return result; +} + nsresult nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext* aPresContext, nsIFrame* aFrame, @@ -458,6 +473,33 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext* aPresContext, NS_IF_RELEASE(pseudoTag); } + // See if the frame is block-level and has 'overflow' set to 'hidden'. If + // so and it can have child frames, then we need to give it a view so clipping + // of any child views works correctly. Note that if it's floated it is also + // block-level, but we can't trust that the style context 'display' value is + // set correctly + if (!aForce) { + if ((display->IsBlockLevel() || display->IsFloating()) && + (display->mOverflow == NS_STYLE_OVERFLOW_HIDDEN)) { + + // The reason for the check of whether it can contain children is just + // to avoid giving it a view unnecessarily + if (::IsContainerContent(aFrame)) { + // XXX Check for the frame being a block frame and only force a view + // in that case, because adding a view for box frames seems to cause + // problems for XUL... + nsIAtom* frameType; + + aFrame->GetFrameType(&frameType); + if ((frameType == nsLayoutAtoms::blockFrame) || + (frameType == nsLayoutAtoms::areaFrame)) { + aForce = PR_TRUE; + } + NS_IF_RELEASE(frameType); + } + } + } + if (aForce) { // Create a view nsIFrame* parent; @@ -528,26 +570,18 @@ nsHTMLContainerFrame::CreateViewForFrame(nsIPresContext* aPresContext, // If it's a container element, then leave the view visible, but // mark it as having transparent content. The reason we need to // do this is that child elements can override their parent's - // hidden visibility and be visible anyway - nsIContent* content; - + // hidden visibility and be visible anyway. + // // Because this function is called before processing the content // object's child elements, we can't tell if it's a leaf by looking // at whether the frame has any child frames - aFrame->GetContent(&content); - if (content) { - PRBool isContainer; - - content->CanContainChildren(isContainer); - if (isContainer) { - // The view needs to be visible, but marked as having transparent - // content - viewHasTransparentContent = PR_TRUE; - } else { - // Go ahead and hide the view - viewIsVisible = PR_FALSE; - } - NS_RELEASE(content); + if (::IsContainerContent(aFrame)) { + // The view needs to be visible, but marked as having transparent + // content + viewHasTransparentContent = PR_TRUE; + } else { + // Go ahead and hide the view + viewIsVisible = PR_FALSE; } } } diff --git a/layout/html/base/src/nsImageFrame.cpp b/layout/html/base/src/nsImageFrame.cpp index 85ee628c48d..806cf2cce0a 100644 --- a/layout/html/base/src/nsImageFrame.cpp +++ b/layout/html/base/src/nsImageFrame.cpp @@ -559,11 +559,6 @@ nsImageFrame::Paint(nsIPresContext* aPresContext, const nsStyleDisplay* disp = (const nsStyleDisplay*) mStyleContext->GetStyleData(eStyleStruct_Display); if (disp->IsVisible() && mRect.width && mRect.height) { - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - aRenderingContext.PushState(); - SetClipRect(aRenderingContext); - } - // First paint background and borders nsLeafFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); @@ -639,11 +634,6 @@ nsImageFrame::Paint(nsIPresContext* aPresContext, NS_IF_RELEASE(lowImage); NS_IF_RELEASE(image); - - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - PRBool clipState; - aRenderingContext.PopState(clipState); - } } return nsFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); diff --git a/layout/html/base/src/nsObjectFrame.cpp b/layout/html/base/src/nsObjectFrame.cpp index f03aa601d13..758436c8b6b 100644 --- a/layout/html/base/src/nsObjectFrame.cpp +++ b/layout/html/base/src/nsObjectFrame.cpp @@ -377,8 +377,7 @@ nsObjectFrame::CreateWidget(nsIPresContext* aPresContext, { // nsWidgetInitData* initData = GetWidgetInitData(aPresContext); // needs to be deleted // initialize the view as hidden since we don't know the (x,y) until Paint - result = view->Init(viewMan, boundBox, parView, nsnull, - nsViewVisibility_kHide); + result = view->Init(viewMan, boundBox, parView, nsViewVisibility_kHide); // if (nsnull != initData) { // delete(initData); // } diff --git a/layout/html/base/src/nsPresShell.cpp b/layout/html/base/src/nsPresShell.cpp index e4fb3850b97..d7fafc58c51 100644 --- a/layout/html/base/src/nsPresShell.cpp +++ b/layout/html/base/src/nsPresShell.cpp @@ -3072,6 +3072,53 @@ PresShell::GetPlaceholderFrameFor(nsIFrame* aFrame, //nsIViewObserver +// If the element is absolutely positioned and has a specified clip rect +// then it pushes the current rendering context and sets the clip rect. +// Returns PR_TRUE if the clip rect is set and PR_FALSE otherwise +static PRBool +SetClipRect(nsIRenderingContext& aRenderingContext, nsIFrame* aFrame) +{ + PRBool clipState; + const nsStyleDisplay* display; + aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display); + const nsStylePosition* position; + aFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&) position); + + // 'clip' only applies to absolutely positioned elements, and is + // relative to the element's border edge. 'clip' applies to the entire + // element: border, padding, and content areas, and even scrollbars if + // there are any. + if (position->IsAbsolutelyPositioned() && (display->mClipFlags & NS_STYLE_CLIP_RECT)) { + nsSize size; + + // Start with the 'auto' values and then factor in user specified values + aFrame->GetSize(size); + nsRect clipRect(0, 0, size.width, size.height); + + if (display->mClipFlags & NS_STYLE_CLIP_RECT) { + if (0 == (NS_STYLE_CLIP_TOP_AUTO & display->mClipFlags)) { + clipRect.y = display->mClip.y; + } + if (0 == (NS_STYLE_CLIP_LEFT_AUTO & display->mClipFlags)) { + clipRect.x = display->mClip.x; + } + if (0 == (NS_STYLE_CLIP_RIGHT_AUTO & display->mClipFlags)) { + clipRect.width = clipRect.x + display->mClip.width; + } + if (0 == (NS_STYLE_CLIP_BOTTOM_AUTO & display->mClipFlags)) { + clipRect.height = clipRect.y + display->mClip.height; + } + } + + // Set updated clip-rect into the rendering context + aRenderingContext.PushState(); + aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect, clipState); + return PR_TRUE; + } + + return PR_FALSE; +} + NS_IMETHODIMP PresShell::Paint(nsIView *aView, nsIRenderingContext& aRenderingContext, @@ -3090,6 +3137,10 @@ PresShell::Paint(nsIView *aView, { StCaretHider caretHider(this); // stack-based class hides caret until dtor. + // If the frame is absolutely positioned, then the 'clip' property + // applies + PRBool setClipRect = SetClipRect(aRenderingContext, frame); + rv = frame->Paint(mPresContext, aRenderingContext, aDirtyRect, NS_FRAME_PAINT_LAYER_BACKGROUND); rv = frame->Paint(mPresContext, aRenderingContext, aDirtyRect, @@ -3097,6 +3148,10 @@ PresShell::Paint(nsIView *aView, rv = frame->Paint(mPresContext, aRenderingContext, aDirtyRect, NS_FRAME_PAINT_LAYER_FOREGROUND); + if (setClipRect) { + PRBool clipState; + aRenderingContext.PopState(clipState); + } #ifdef NS_DEBUG // Draw a border around the frame diff --git a/layout/html/base/src/nsScrollFrame.cpp b/layout/html/base/src/nsScrollFrame.cpp index 4e01367bb1b..8b42831eb20 100644 --- a/layout/html/base/src/nsScrollFrame.cpp +++ b/layout/html/base/src/nsScrollFrame.cpp @@ -329,7 +329,7 @@ nsScrollFrame::CreateScrollingView(nsIPresContext* aPresContext) } // Initialize the scrolling view - view->Init(viewManager, mRect, parentView, nsnull, display->IsVisible()? + view->Init(viewManager, mRect, parentView, display->IsVisible()? nsViewVisibility_kShow : nsViewVisibility_kHide); // Insert the view into the view hierarchy diff --git a/layout/html/base/src/nsScrollPortFrame.cpp b/layout/html/base/src/nsScrollPortFrame.cpp index 46f26bee117..0f68eb06ec9 100644 --- a/layout/html/base/src/nsScrollPortFrame.cpp +++ b/layout/html/base/src/nsScrollPortFrame.cpp @@ -232,7 +232,7 @@ nsScrollPortFrame::CreateScrollingView(nsIPresContext* aPresContext) } // Initialize the scrolling view - view->Init(viewManager, mRect, parentView, nsnull, display->IsVisibleOrCollapsed() ? + view->Init(viewManager, mRect, parentView, display->IsVisibleOrCollapsed() ? nsViewVisibility_kShow : nsViewVisibility_kHide); // Insert the view into the view hierarchy diff --git a/layout/html/document/src/nsFrameSetFrame.cpp b/layout/html/document/src/nsFrameSetFrame.cpp index d8e1e176db0..96ec6f1b73b 100644 --- a/layout/html/document/src/nsFrameSetFrame.cpp +++ b/layout/html/document/src/nsFrameSetFrame.cpp @@ -275,7 +275,7 @@ nsHTMLFramesetFrame::Init(nsIPresContext* aPresContext, GetParentWithView(aPresContext, &parWithView); parWithView->GetView(aPresContext, &parView); nsRect boundBox(0, 0, 0, 0); - result = view->Init(viewMan, boundBox, parView, nsnull); + result = view->Init(viewMan, boundBox, parView); viewMan->InsertChild(parView, view, 0); SetView(aPresContext, view); diff --git a/layout/html/forms/src/nsImageControlFrame.cpp b/layout/html/forms/src/nsImageControlFrame.cpp index 77423257fe1..0245c9dcf2a 100644 --- a/layout/html/forms/src/nsImageControlFrame.cpp +++ b/layout/html/forms/src/nsImageControlFrame.cpp @@ -240,7 +240,7 @@ nsImageControlFrame::Init(nsIPresContext* aPresContext, parWithView->GetView(aPresContext, &parView); // the view's size is not know yet, but its size will be kept in synch with our frame. nsRect boundBox(0, 0, 0, 0); - result = view->Init(viewMan, boundBox, parView, nsnull); + result = view->Init(viewMan, boundBox, parView); view->SetContentTransparency(PR_TRUE); viewMan->InsertChild(parView, view, 0); SetView(aPresContext, view); diff --git a/layout/html/forms/src/nsLabelFrame.cpp b/layout/html/forms/src/nsLabelFrame.cpp index 9aadd699488..3922f84944d 100644 --- a/layout/html/forms/src/nsLabelFrame.cpp +++ b/layout/html/forms/src/nsLabelFrame.cpp @@ -518,7 +518,7 @@ nsLabelFrame::Init(nsIPresContext* aPresContext, parWithView->GetView(aPresContext, &parView); // the view's size is not know yet, but its size will be kept in synch with our frame. nsRect boundBox(0, 0, 0, 0); - result = view->Init(viewMan, boundBox, parView, nsnull); + result = view->Init(viewMan, boundBox, parView); view->SetContentTransparency(PR_TRUE); viewMan->InsertChild(parView, view, 0); SetView(aPresContext, view); diff --git a/layout/html/style/src/nsCSSStyleRule.cpp b/layout/html/style/src/nsCSSStyleRule.cpp index 26f3079c7d5..ed786e08f85 100644 --- a/layout/html/style/src/nsCSSStyleRule.cpp +++ b/layout/html/style/src/nsCSSStyleRule.cpp @@ -1912,35 +1912,37 @@ MapDeclarationDisplayInto(nsICSSDeclaration* aDeclaration, display->mClipFlags = 0; // clear it if (eCSSUnit_Auto == ourDisplay->mClip->mTop.GetUnit()) { - display->mClip.top = 0; + display->mClip.y = 0; display->mClipFlags |= NS_STYLE_CLIP_TOP_AUTO; } else if (ourDisplay->mClip->mTop.IsLengthUnit()) { - display->mClip.top = CalcLength(ourDisplay->mClip->mTop, aFont->mFont, aPresContext); - fullAuto = PR_FALSE; - } - if (eCSSUnit_Auto == ourDisplay->mClip->mRight.GetUnit()) { - display->mClip.right = 0; - display->mClipFlags |= NS_STYLE_CLIP_RIGHT_AUTO; - } - else if (ourDisplay->mClip->mRight.IsLengthUnit()) { - display->mClip.right = CalcLength(ourDisplay->mClip->mRight, aFont->mFont, aPresContext); + display->mClip.y = CalcLength(ourDisplay->mClip->mTop, aFont->mFont, aPresContext); fullAuto = PR_FALSE; } if (eCSSUnit_Auto == ourDisplay->mClip->mBottom.GetUnit()) { - display->mClip.bottom = 0; + display->mClip.height = 0; display->mClipFlags |= NS_STYLE_CLIP_BOTTOM_AUTO; } else if (ourDisplay->mClip->mBottom.IsLengthUnit()) { - display->mClip.bottom = CalcLength(ourDisplay->mClip->mBottom, aFont->mFont, aPresContext); + display->mClip.height = CalcLength(ourDisplay->mClip->mBottom, aFont->mFont, aPresContext) - + display->mClip.y; fullAuto = PR_FALSE; } if (eCSSUnit_Auto == ourDisplay->mClip->mLeft.GetUnit()) { - display->mClip.left = 0; + display->mClip.x = 0; display->mClipFlags |= NS_STYLE_CLIP_LEFT_AUTO; } else if (ourDisplay->mClip->mLeft.IsLengthUnit()) { - display->mClip.left = CalcLength(ourDisplay->mClip->mLeft, aFont->mFont, aPresContext); + display->mClip.x = CalcLength(ourDisplay->mClip->mLeft, aFont->mFont, aPresContext); + fullAuto = PR_FALSE; + } + if (eCSSUnit_Auto == ourDisplay->mClip->mRight.GetUnit()) { + display->mClip.width = 0; + display->mClipFlags |= NS_STYLE_CLIP_RIGHT_AUTO; + } + else if (ourDisplay->mClip->mRight.IsLengthUnit()) { + display->mClip.width = CalcLength(ourDisplay->mClip->mRight, aFont->mFont, aPresContext) - + display->mClip.x; fullAuto = PR_FALSE; } display->mClipFlags &= ~NS_STYLE_CLIP_TYPE_MASK; diff --git a/layout/style/nsCSSStyleRule.cpp b/layout/style/nsCSSStyleRule.cpp index 26f3079c7d5..ed786e08f85 100644 --- a/layout/style/nsCSSStyleRule.cpp +++ b/layout/style/nsCSSStyleRule.cpp @@ -1912,35 +1912,37 @@ MapDeclarationDisplayInto(nsICSSDeclaration* aDeclaration, display->mClipFlags = 0; // clear it if (eCSSUnit_Auto == ourDisplay->mClip->mTop.GetUnit()) { - display->mClip.top = 0; + display->mClip.y = 0; display->mClipFlags |= NS_STYLE_CLIP_TOP_AUTO; } else if (ourDisplay->mClip->mTop.IsLengthUnit()) { - display->mClip.top = CalcLength(ourDisplay->mClip->mTop, aFont->mFont, aPresContext); - fullAuto = PR_FALSE; - } - if (eCSSUnit_Auto == ourDisplay->mClip->mRight.GetUnit()) { - display->mClip.right = 0; - display->mClipFlags |= NS_STYLE_CLIP_RIGHT_AUTO; - } - else if (ourDisplay->mClip->mRight.IsLengthUnit()) { - display->mClip.right = CalcLength(ourDisplay->mClip->mRight, aFont->mFont, aPresContext); + display->mClip.y = CalcLength(ourDisplay->mClip->mTop, aFont->mFont, aPresContext); fullAuto = PR_FALSE; } if (eCSSUnit_Auto == ourDisplay->mClip->mBottom.GetUnit()) { - display->mClip.bottom = 0; + display->mClip.height = 0; display->mClipFlags |= NS_STYLE_CLIP_BOTTOM_AUTO; } else if (ourDisplay->mClip->mBottom.IsLengthUnit()) { - display->mClip.bottom = CalcLength(ourDisplay->mClip->mBottom, aFont->mFont, aPresContext); + display->mClip.height = CalcLength(ourDisplay->mClip->mBottom, aFont->mFont, aPresContext) - + display->mClip.y; fullAuto = PR_FALSE; } if (eCSSUnit_Auto == ourDisplay->mClip->mLeft.GetUnit()) { - display->mClip.left = 0; + display->mClip.x = 0; display->mClipFlags |= NS_STYLE_CLIP_LEFT_AUTO; } else if (ourDisplay->mClip->mLeft.IsLengthUnit()) { - display->mClip.left = CalcLength(ourDisplay->mClip->mLeft, aFont->mFont, aPresContext); + display->mClip.x = CalcLength(ourDisplay->mClip->mLeft, aFont->mFont, aPresContext); + fullAuto = PR_FALSE; + } + if (eCSSUnit_Auto == ourDisplay->mClip->mRight.GetUnit()) { + display->mClip.width = 0; + display->mClipFlags |= NS_STYLE_CLIP_RIGHT_AUTO; + } + else if (ourDisplay->mClip->mRight.IsLengthUnit()) { + display->mClip.width = CalcLength(ourDisplay->mClip->mRight, aFont->mFont, aPresContext) - + display->mClip.x; fullAuto = PR_FALSE; } display->mClipFlags &= ~NS_STYLE_CLIP_TYPE_MASK; diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp index 1f04a34d318..0f7073218db 100644 --- a/layout/style/nsStyleContext.cpp +++ b/layout/style/nsStyleContext.cpp @@ -1031,7 +1031,7 @@ void StyleDisplayImpl::ResetFrom(const nsStyleDisplay* aParent, nsIPresContext* mBreakAfter = PR_FALSE; mOverflow = NS_STYLE_OVERFLOW_VISIBLE; mClipFlags = NS_STYLE_CLIP_AUTO; - mClip.SizeTo(0,0,0,0); + mClip.SetRect(0,0,0,0); } void StyleDisplayImpl::SetFrom(const nsStyleDisplay& aSource) diff --git a/view/public/nsIView.h b/view/public/nsIView.h index 3425d684b22..18138c9e6b2 100644 --- a/view/public/nsIView.h +++ b/view/public/nsIView.h @@ -88,14 +88,12 @@ public: * @param aParent intended parent for view. this is not actually set in the * nsIView through this method. it is only used by the initialization * code to walk up the view tree, if necessary, to find resources. - * @param aCilpRect initial clip rect of view * @param aVisibilityFlag initial visibility state of view * @result The result of the initialization, NS_OK if no errors */ NS_IMETHOD Init(nsIViewManager* aManager, const nsRect &aBounds, const nsIView *aParent, - const nsViewClip *aClip = nsnull, nsViewVisibility aVisibilityFlag = nsViewVisibility_kShow) = 0; /** diff --git a/view/src/nsScrollPortView.cpp b/view/src/nsScrollPortView.cpp index cbe2672f3ed..e5de244e887 100644 --- a/view/src/nsScrollPortView.cpp +++ b/view/src/nsScrollPortView.cpp @@ -103,10 +103,9 @@ nsrefcnt nsScrollPortView::Release() NS_IMETHODIMP nsScrollPortView::Init(nsIViewManager* aManager, const nsRect &aBounds, const nsIView *aParent, - const nsViewClip *aClip, nsViewVisibility aVisibilityFlag) { - return nsView::Init(aManager, aBounds, aParent, aClip, aVisibilityFlag); + return nsView::Init(aManager, aBounds, aParent, aVisibilityFlag); } NS_IMETHODIMP nsScrollPortView::SetDimensions(nscoord width, nscoord height, PRBool aPaint) diff --git a/view/src/nsScrollPortView.h b/view/src/nsScrollPortView.h index fc5d0d87dc4..0cb065208eb 100644 --- a/view/src/nsScrollPortView.h +++ b/view/src/nsScrollPortView.h @@ -43,7 +43,6 @@ public: NS_IMETHOD Init(nsIViewManager* aManager, const nsRect &aBounds, const nsIView *aParent, - const nsViewClip *aClip = nsnull, nsViewVisibility aVisibilityFlag = nsViewVisibility_kShow); NS_IMETHOD SetDimensions(nscoord width, nscoord height, PRBool aPaint = PR_TRUE); NS_IMETHOD SetPosition(nscoord aX, nscoord aY); diff --git a/view/src/nsScrollingView.cpp b/view/src/nsScrollingView.cpp index 6e36d43e23d..832d922cb4f 100644 --- a/view/src/nsScrollingView.cpp +++ b/view/src/nsScrollingView.cpp @@ -444,7 +444,6 @@ nsrefcnt nsScrollingView::Release() NS_IMETHODIMP nsScrollingView::Init(nsIViewManager* aManager, const nsRect &aBounds, const nsIView *aParent, - const nsViewClip *aClip, nsViewVisibility aVisibilityFlag) { nsIDeviceContext *dx = nsnull; @@ -463,7 +462,7 @@ NS_IMETHODIMP nsScrollingView::Init(nsIViewManager* aManager, NS_RELEASE(dx); } - return nsView::Init(aManager, aBounds, aParent, aClip, aVisibilityFlag); + return nsView::Init(aManager, aBounds, aParent, aVisibilityFlag); } NS_IMETHODIMP nsScrollingView::SetDimensions(nscoord width, nscoord height, PRBool aPaint) @@ -840,8 +839,7 @@ NS_IMETHODIMP nsScrollingView::CreateScrollControls(nsNativeWidget aNative) trect.height = NSToCoordRound(sbHeight); trect.y = mBounds.y + mBounds.YMost() - trect.height; - rv = mCornerView->Init(mViewManager, trect, this, - nsnull, nsViewVisibility_kHide); + rv = mCornerView->Init(mViewManager, trect, this, nsViewVisibility_kHide); mViewManager->InsertChild(this, mCornerView, mZindex); mCornerView->CreateWidget(kWidgetCID, &initData, mWindow ? nsnull : aNative); diff --git a/view/src/nsScrollingView.h b/view/src/nsScrollingView.h index eae4342d927..dda60157e66 100644 --- a/view/src/nsScrollingView.h +++ b/view/src/nsScrollingView.h @@ -45,7 +45,6 @@ public: NS_IMETHOD Init(nsIViewManager* aManager, const nsRect &aBounds, const nsIView *aParent, - const nsViewClip *aClip = nsnull, nsViewVisibility aVisibilityFlag = nsViewVisibility_kShow); NS_IMETHOD SetDimensions(nscoord width, nscoord height, PRBool aPaint = PR_TRUE); NS_IMETHOD SetPosition(nscoord aX, nscoord aY); diff --git a/view/src/nsView.cpp b/view/src/nsView.cpp index feb8f4489d1..9e0bce21237 100644 --- a/view/src/nsView.cpp +++ b/view/src/nsView.cpp @@ -210,7 +210,6 @@ nsIView* nsView::GetViewFor(nsIWidget* aWidget) NS_IMETHODIMP nsView :: Init(nsIViewManager* aManager, const nsRect &aBounds, const nsIView *aParent, - const nsViewClip *aClip, nsViewVisibility aVisibilityFlag) { //printf(" \n callback=%d data=%d", aWidgetCreateCallback, aCallbackData); @@ -224,15 +223,10 @@ NS_IMETHODIMP nsView :: Init(nsIViewManager* aManager, // we don't hold a reference to the view manager mViewManager = aManager; - if (aClip != nsnull) - mClip = *aClip; - else - { - mClip.mLeft = 0; - mClip.mRight = 0; - mClip.mTop = 0; - mClip.mBottom = 0; - } + mChildClip.mLeft = 0; + mChildClip.mRight = 0; + mChildClip.mTop = 0; + mChildClip.mBottom = 0; SetBounds(aBounds); @@ -273,18 +267,7 @@ NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect, if (nsnull != mClientData) { nsCOMPtr observer; if (NS_OK == mViewManager->GetViewObserver(*getter_AddRefs(observer))) { - if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom)) { - nsRect crect; - crect.x = mClip.mLeft; - crect.y = mClip.mTop; - crect.width = mClip.mRight - mClip.mLeft; - crect.height = mClip.mBottom - mClip.mTop; - rc.SetClipRect(crect, nsClipCombine_kIntersect, aResult); - if (!aResult) - observer->Paint((nsIView *)this, rc, rect); - } else { - observer->Paint((nsIView *)this, rc, rect); - } + observer->Paint((nsIView *)this, rc, rect); } } } else { @@ -308,11 +291,7 @@ NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect, { nsRect brect; GetBounds(brect); - - // what does this test mean? - if ((mClip.mLeft == mClip.mRight) || (mClip.mTop == mClip.mBottom) && (this != pRoot)) { - rc.SetClipRect(brect, nsClipCombine_kIntersect, clipres); - } + rc.SetClipRect(brect, nsClipCombine_kIntersect, clipres); } } @@ -580,12 +559,6 @@ NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect, if (nsnull != mClientData) { nsCOMPtr observer; if (NS_OK == mViewManager->GetViewObserver(*getter_AddRefs(observer))) { - if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom)) { - nsRect crect(mClip.mLeft, mClip.mTop, - mClip.mRight - mClip.mLeft, - mClip.mBottom - mClip.mTop); - localcx->SetClipRect(crect, nsClipCombine_kIntersect, clipres); - } observer->Paint((nsIView *)this, *localcx, rect); } } @@ -696,17 +669,7 @@ NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect, nsRect brect; GetBounds(brect); - if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom)) - { - nsRect crect; - - crect.x = mClip.mLeft + brect.x; - crect.y = mClip.mTop + brect.y; - crect.width = mClip.mRight - mClip.mLeft; - crect.height = mClip.mBottom - mClip.mTop; - - rc.SetClipRect(crect, nsClipCombine_kSubtract, clipres); - } else if (this != pRoot) + if (this != pRoot) rc.SetClipRect(brect, nsClipCombine_kSubtract, clipres); } @@ -1049,20 +1012,20 @@ NS_IMETHODIMP nsView :: GetBounds(nsRect &aBounds) const NS_IMETHODIMP nsView :: SetChildClip(nscoord aLeft, nscoord aTop, nscoord aRight, nscoord aBottom) { NS_PRECONDITION(aLeft <= aRight && aTop <= aBottom, "bad clip values"); - mClip.mLeft = aLeft; - mClip.mTop = aTop; - mClip.mRight = aRight; - mClip.mBottom = aBottom; + mChildClip.mLeft = aLeft; + mChildClip.mTop = aTop; + mChildClip.mRight = aRight; + mChildClip.mBottom = aBottom; return NS_OK; } NS_IMETHODIMP nsView :: GetChildClip(nscoord *aLeft, nscoord *aTop, nscoord *aRight, nscoord *aBottom) const { - *aLeft = mClip.mLeft; - *aTop = mClip.mTop; - *aRight = mClip.mRight; - *aBottom = mClip.mBottom; + *aLeft = mChildClip.mLeft; + *aTop = mChildClip.mTop; + *aRight = mChildClip.mRight; + *aBottom = mChildClip.mBottom; return NS_OK; } diff --git a/view/src/nsView.h b/view/src/nsView.h index ee94de7c960..f848d38d2c0 100644 --- a/view/src/nsView.h +++ b/view/src/nsView.h @@ -49,7 +49,6 @@ public: NS_IMETHOD Init(nsIViewManager* aManager, const nsRect &aBounds, const nsIView *aParent, - const nsViewClip *aClip = nsnull, nsViewVisibility aVisibilityFlag = nsViewVisibility_kShow); NS_IMETHOD Destroy(); @@ -145,7 +144,7 @@ protected: nsViewVisibility mVis; PRInt32 mNumKids; nsRect mBounds; - nsViewClip mClip; + nsViewClip mChildClip; nsTransform2D *mXForm; float mOpacity; PRUint32 mVFlags;