Bug 371460: Remove clipping functions from views. r+sr=roc.

This commit is contained in:
sharparrow1%yahoo.com 2007-02-24 15:27:20 +00:00
Родитель 52bb0dd7af
Коммит 88fb576ad6
10 изменённых файлов: 5 добавлений и 338 удалений

Просмотреть файл

@ -507,95 +507,6 @@ SyncFrameViewGeometryDependentProperties(nsPresContext* aPresContext,
}
}
}
// If the frame has visible content that overflows the content area, then we
// need the view marked as having transparent content
// 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:-moz-hidden-unscrollable' which only applies to
// block-level elements and replaced elements. 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 = display->IsAbsolutelyPositioned() && (display->mClipFlags & NS_STYLE_CLIP_RECT);
PRBool hasOverflowClip = isBlockLevel && (display->mOverflowX == NS_STYLE_OVERFLOW_CLIP);
if (hasClip || hasOverflowClip) {
nsSize frameSize = aFrame->GetSize();
nsRect clipRect;
if (hasClip) {
// Start with the 'auto' values and then factor in user specified values
clipRect.SetRect(0, 0, frameSize.width, frameSize.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 = display->mClip.width;
}
if (0 == (NS_STYLE_CLIP_BOTTOM_AUTO & display->mClipFlags)) {
clipRect.height = display->mClip.height;
}
}
}
if (hasOverflowClip) {
// XXX We should be able to replace the next 14 lines with just
// overflowClipRect.Deflate(aFrame->GetUsedBorderAndPadding());
// but unfortunately this function gets called during frame
// construction (why?), and GetUsedBorderAndPadding asserts when
// called on a frame that hasn't been reflowed yet (for good
// reason).
const nsStyleBorder* borderStyle = aStyleContext->GetStyleBorder();
const nsStylePadding* paddingStyle = aStyleContext->GetStylePadding();
nsMargin padding;
nsRect overflowClipRect(0, 0, frameSize.width, frameSize.height);
overflowClipRect.Deflate(borderStyle->GetBorder());
// XXX We need to handle percentage padding
if (paddingStyle->GetPadding(padding)) {
overflowClipRect.Deflate(padding);
}
#ifdef DEBUG
else {
NS_WARNING("Percentage padding and CLIP overflow don't mix");
}
#endif
if (hasClip) {
// If both 'clip' and 'overflow-clip' apply then use the intersection
// of the two
clipRect.IntersectRect(clipRect, overflowClipRect);
} else {
clipRect = overflowClipRect;
}
}
nsRect newSize = aView->GetBounds();
newSize -= aView->GetPosition();
// If part of the view is being clipped out, then mark it transparent
if (clipRect.y > newSize.y
|| clipRect.x > newSize.x
|| clipRect.XMost() < newSize.XMost()
|| clipRect.YMost() < newSize.YMost()) {
viewHasTransparentContent = PR_TRUE;
}
// Set clipping of child views.
nsRegion region(clipRect);
vm->SetViewChildClipRegion(aView, &region);
} else {
// Remove clipping of child views.
vm->SetViewChildClipRegion(aView, nsnull);
}
}
void

Просмотреть файл

@ -553,8 +553,6 @@ nsSimplePageSequenceFrame::StartPrint(nsPresContext* aPresContext,
// sure the child views don't get asked to print
// but my guess is that there won't be any
vm->SetViewVisibility(view, nsViewVisibility_kHide);
nsRegion emptyRegion;
vm->SetViewChildClipRegion(view, &emptyRegion);
} else {
nsRect rect = page->GetRect();
rect.y = y;

Просмотреть файл

@ -48,7 +48,6 @@
#include "nsIDocShellTreeItem.h"
#include "nsIWebNavigation.h"
#include "nsIPresShell.h"
#include "nsIViewManager.h"
#include "nsIWidget.h"
#include "nsPresContext.h"

Просмотреть файл

@ -46,8 +46,6 @@
#include "nsScrollbarButtonFrame.h"
#include "nsGkAtoms.h"
#include "nsIScrollableFrame.h"
#include "nsIView.h"
#include "nsIViewManager.h"
#include "nsIScrollbarMediator.h"
//

Просмотреть файл

@ -62,10 +62,10 @@ enum nsRectVisibility {
nsRectVisibility_kZeroAreaRect
};
// 88946f17-d4a7-410f-bb42-cc71dcd0a330
// 38439490-51d4-416a-a12f-20535d9d8119
#define NS_IVIEWMANAGER_IID \
{ 0x88946f17, 0xd4a7, 0x410f, \
{ 0xbb, 0x42, 0xcc, 0x71, 0xdc, 0xd0, 0xa3, 0x30 } }
{ 0x38439490, 0x51d4, 0x416a, \
{ 0xa1, 0x2f, 0x20, 0x53, 0x5d, 0x9d, 0x81, 0x19 } }
class nsIViewManager : public nsISupports
{
@ -264,28 +264,6 @@ public:
NS_IMETHOD ResizeView(nsIView *aView, const nsRect &aRect,
PRBool aRepaintExposedAreaOnly = PR_FALSE) = 0;
/**
* Set the region to which a view's descendants are clipped. The view
* itself is not clipped to this region; this allows for effects
* where part of the view is drawn outside the clip region (e.g.,
* its borders and background). The view manager generates the
* appropriate dirty regions.
*
* @param aView view to set clipping for
* @param aRegion
* if null then no clipping is required. In this case all descendant
* views (but not descendants through placeholder edges) must have their
* bounds inside the bounds of this view
* if non-null, then we will clip this view's descendant views
* --- including descendants through placeholder edges ---
* to the region. The region's bounds must be within the bounds of
* this view. The descendant views' bounds need not be inside the bounds
* of this view (because we're going to clip them anyway).
*
* XXX Currently we only support regions consisting of a single rectangle.
*/
NS_IMETHOD SetViewChildClipRegion(nsIView *aView, const nsRegion *aRegion) = 0;
/**
* Set the visibility of a view.
* The view manager generates the appropriate dirty regions.

Просмотреть файл

@ -88,8 +88,6 @@ nsScrollPortView::nsScrollPortView(nsViewManager* aViewManager)
mListeners = nsnull;
mSmoothScroll = nsnull;
SetClipChildrenToBounds(PR_TRUE);
}
nsScrollPortView::~nsScrollPortView()

Просмотреть файл

@ -868,101 +868,3 @@ PRBool nsIView::ExternalIsRoot() const
{
return nsIView::IsRoot();
}
/**
* @param aStopAtView clipping from ancestors of this view will not be applied
* @return PR_TRUE iff we found a placeholder parent edge on the way up the view tree
* from aView to aStopAtView
*/
static PRBool ApplyClipRect(const nsView* aView, nsRect* aRect, PRBool aFollowPlaceholders,
nsIView* aStopAtView)
{
// this records the offset from the origin of the current aView
// to the origin of the initial aView
nsPoint offset(0, 0);
PRBool lastViewIsFloating = aView->GetFloating();
PRBool foundPlaceholders = PR_FALSE;
while (NS_STATIC_CAST(const nsIView*, aView) != aStopAtView) {
const nsView* parentView = aView->GetParent();
nsPoint offsetFromParent = aView->GetPosition();
const nsView* zParent = aView->GetZParent();
if (zParent) {
foundPlaceholders = PR_TRUE;
if (aFollowPlaceholders) {
// correct offsetFromParent to account for the fact that we're
// switching parentView to ZParent
// Note that the common case is that parentView is an ancestor of
// ZParent.
const nsView* zParentChain;
for (zParentChain = zParent;
zParentChain != parentView && zParentChain;
zParentChain = zParentChain->GetParent()) {
offsetFromParent -= zParentChain->GetPosition();
}
if (!zParentChain) {
// uh oh. As we walked up the tree, we missed zParent. This can
// happen because of odd (but legal) containing block hierarchies.
// Just compute the required offset from scratch; this is slow,
// but hopefully rarely executed.
offsetFromParent = nsViewManager::ComputeViewOffset(aView)
- nsViewManager::ComputeViewOffset(zParent);
}
parentView = zParent;
}
}
if (!parentView) {
break;
}
PRBool parentIsFloating = parentView->GetFloating();
if (lastViewIsFloating && !parentIsFloating) {
break;
}
// now make offset be the offset from parentView's origin to the initial
// aView's origin
offset += offsetFromParent;
if (parentView->GetClipChildrenToBounds(aFollowPlaceholders)) {
// Get the parent's clip rect (which is just the dimensions in this
// case) into the initial aView's coordinates
nsRect clipRect = parentView->GetDimensions();
clipRect -= offset;
PRBool overlap = aRect->IntersectRect(clipRect, *aRect);
if (!overlap) {
break;
}
}
// The child-clipping rect is applied to all *content* children.
// So we apply it if we're in the placeholder-following pass, or
// if we're in the first pass and we haven't detected any
// placeholders yet, in which case this geometric ancestor is also
// a content ancestor.
const nsRect* r = parentView->GetClipChildrenToRect();
if (r && (!foundPlaceholders || aFollowPlaceholders)) {
// Get the parent's clip rect into the initial aView's coordinates
nsRect clipRect = *r;
clipRect -= offset;
PRBool overlap = aRect->IntersectRect(clipRect, *aRect);
if (!overlap) {
break;
}
}
aView = parentView;
lastViewIsFloating = parentIsFloating;
}
return foundPlaceholders;
}
nsRect nsView::GetClippedRect(nsIView* aStopAtView)
{
nsRect clip = GetDimensions();
PRBool foundPlaceholders = ApplyClipRect(this, &clip, PR_FALSE, aStopAtView);
if (foundPlaceholders && !clip.IsEmpty()) {
ApplyClipRect(this, &clip, PR_TRUE, aStopAtView);
}
return clip;
}

Просмотреть файл

@ -110,41 +110,6 @@ public:
*/
virtual PRBool IsZPlaceholderView() const { return PR_FALSE; }
/**
* Called to set the clip of the children of this view.
* The clip is relative to the origin of the view.
* All of the children of this view will be clipped using
* the specified rectangle
*/
void SetClipChildrenToRect(const nsRect* aRect) {
if (!aRect) {
delete mClipRect;
mClipRect = nsnull;
} else {
if (mClipRect) {
*mClipRect = *aRect;
} else {
mClipRect = new nsRect(*aRect);
}
}
}
void SetClipChildrenToBounds(PRBool aDoClip) {
mVFlags = (mVFlags & ~NS_VIEW_FLAG_CLIP_CHILDREN_TO_BOUNDS)
| (aDoClip ? NS_VIEW_FLAG_CLIP_CHILDREN_TO_BOUNDS : 0);
}
void SetClipPlaceholdersToBounds(PRBool aDoClip) {
mVFlags = (mVFlags & ~NS_VIEW_FLAG_CLIP_PLACEHOLDERS_TO_BOUNDS)
| (aDoClip ? NS_VIEW_FLAG_CLIP_PLACEHOLDERS_TO_BOUNDS : 0);
}
/**
* Called to get the dimensions and position of the clip for the children of this view.
*/
const nsRect* GetClipChildrenToRect() const
{ return mClipRect; }
PRBool GetClipChildrenToBounds(PRBool aPlaceholders) const
{ return (mVFlags & (aPlaceholders ? NS_VIEW_FLAG_CLIP_PLACEHOLDERS_TO_BOUNDS : NS_VIEW_FLAG_CLIP_CHILDREN_TO_BOUNDS)) != 0; }
/**
* Called to indicate that the visibility of a view has been
* changed.
@ -183,14 +148,6 @@ public:
*/
NS_IMETHOD SetWidget(nsIWidget *aWidget);
/**
* @return the view's dimensions after clipping by ancestors is applied
* (the rect is relative to the view's origin)
* @param aStopAtView do not consider clipping imposed by views above this view
* on the ancestor chain
*/
nsRect GetClippedRect(nsIView* aStopAtView = nsnull);
// Helper function to get the view that's associated with a widget
static nsView* GetViewFor(nsIWidget* aWidget) {
return NS_STATIC_CAST(nsView*, nsIView::GetViewFor(aWidget));

Просмотреть файл

@ -1023,8 +1023,7 @@ AccumulateIntersectionsIntoDirtyRegion(nsView* aTargetView,
// commonly we have dirty rects on the root view.
nsPoint offset = aTargetView->GetOffsetTo(aSourceView);
nsRegion intersection;
intersection.And(*aSourceView->GetDirtyRegion(),
aTargetView->GetClippedRect() + offset);
intersection = *aSourceView->GetDirtyRegion();
if (!intersection.IsEmpty()) {
nsRegion* targetRegion = aTargetView->GetDirtyRegion();
if (targetRegion) {
@ -1073,22 +1072,7 @@ nsViewManager::UpdateViewAfterScroll(nsView *aView, const nsRegion& aUpdateRegio
{
NS_ASSERTION(RootViewManager()->mScrollCnt > 0,
"Someone forgot to call WillBitBlit()");
// Look at the view's clipped rect. It may be that part of the view is clipped out
// in which case we don't need to worry about invalidating the clipped-out part.
nsRect damageRect = aView->GetClippedRect();
if (damageRect.IsEmpty()) {
return;
}
nsPoint offset = ComputeViewOffset(aView);
damageRect.MoveBy(offset);
// if this is a floating view, it isn't covered by any widgets other than
// its children, which are handled by the widget scroller.
if (aView->GetFloating()) {
return;
}
UpdateWidgetArea(RootViewManager()->GetRootView(), nsRegion(damageRect), aView);
if (!aUpdateRegion.IsEmpty()) {
// XXX We should update the region, not the bounds rect, but that requires
// a little more work. Fix this when we reshuffle this code.
@ -1209,14 +1193,7 @@ NS_IMETHODIMP nsViewManager::UpdateView(nsIView *aView, const nsRect &aRect, PRU
nsView* view = NS_STATIC_CAST(nsView*, aView);
// Only Update the rectangle region of the rect that intersects the view's non clipped rectangle
nsRect clippedRect = view->GetClippedRect();
if (clippedRect.IsEmpty()) {
return NS_OK;
}
nsRect damagedRect;
damagedRect.IntersectRect(aRect, clippedRect);
nsRect damagedRect(aRect);
// If the rectangle is not visible then abort
// without invalidating. This is a performance
@ -1968,47 +1945,6 @@ NS_IMETHODIMP nsViewManager::ResizeView(nsIView *aView, const nsRect &aRect, PRB
return NS_OK;
}
NS_IMETHODIMP nsViewManager::SetViewChildClipRegion(nsIView *aView, const nsRegion *aRegion)
{
nsView* view = NS_STATIC_CAST(nsView*, aView);
NS_ASSERTION(!(nsnull == view), "no view");
const nsRect* oldClipRect = view->GetClipChildrenToRect();
nsRect newClipRectStorage = view->GetDimensions();
nsRect* newClipRect = nsnull;
if (aRegion) {
newClipRectStorage = aRegion->GetBounds();
newClipRect = &newClipRectStorage;
}
if ((oldClipRect != nsnull) == (newClipRect != nsnull)
&& (!newClipRect || *newClipRect == *oldClipRect)) {
return NS_OK;
}
nsRect oldClipRectStorage =
oldClipRect ? *oldClipRect : view->GetDimensions();
// Update the view properties
view->SetClipChildrenToRect(newClipRect);
if (IsViewInserted(view)) {
// Invalidate changed areas
// Paint (new - old) in the current view
InvalidateRectDifference(view, newClipRectStorage, oldClipRectStorage, NS_VMREFRESH_NO_SYNC);
// Paint (old - new) in the parent view, since it'll be clipped out of the current view
nsView* parent = view->GetParent();
if (parent) {
oldClipRectStorage += view->GetPosition();
newClipRectStorage += view->GetPosition();
InvalidateRectDifference(parent, oldClipRectStorage, newClipRectStorage, NS_VMREFRESH_NO_SYNC);
}
}
return NS_OK;
}
PRBool nsViewManager::CanScrollWithBitBlt(nsView* aView, nsPoint aDelta,
nsRegion* aUpdateRegion)
{
@ -2351,15 +2287,7 @@ NS_IMETHODIMP nsViewManager::EndUpdateViewBatch(PRUint32 aUpdateFlags)
NS_IMETHODIMP nsViewManager::SetRootScrollableView(nsIScrollableView *aScrollable)
{
if (mRootScrollable) {
NS_STATIC_CAST(nsScrollPortView*, mRootScrollable)->
SetClipPlaceholdersToBounds(PR_FALSE);
}
mRootScrollable = aScrollable;
if (mRootScrollable) {
NS_STATIC_CAST(nsScrollPortView*, mRootScrollable)->
SetClipPlaceholdersToBounds(PR_TRUE);
}
return NS_OK;
}

Просмотреть файл

@ -200,8 +200,6 @@ public:
NS_IMETHOD ResizeView(nsIView *aView, const nsRect &aRect, PRBool aRepaintExposedAreaOnly = PR_FALSE);
NS_IMETHOD SetViewChildClipRegion(nsIView *aView, const nsRegion *aRegion);
NS_IMETHOD SetViewCheckChildEvents(nsIView *aView, PRBool aEnable);
NS_IMETHOD SetViewFloating(nsIView *aView, PRBool aFloating);