Bug 296838. Allow drawWindow to draw fixed-position elements. rubberstamp r+sr=dbaron,a=chofmann

This commit is contained in:
roc+%cs.cmu.edu 2005-06-21 04:07:04 +00:00
parent 941fb250ab
commit 53259eb945
5 changed files with 100 additions and 36 deletions

View File

@ -1792,14 +1792,9 @@ nsCanvasRenderingContext2D::DrawWindow(nsIDOMWindow* aWindow, PRInt32 aX, PRInt3
// Dig down past the viewport scroll stuff
nsIViewManager* vm = presContext->GetViewManager();
nsIScrollableView* scrollableView;
vm->GetRootScrollableView(&scrollableView);
nsIView* view;
if (scrollableView) {
scrollableView->GetScrolledView(view);
} else {
vm->GetRootView(view);
}
vm->GetRootView(view);
NS_ASSERTION(view, "Must have root view!");
nscolor bgColor;
nsresult rv = mCSSParser->ParseColorString(PromiseFlatString(aBGColor),
@ -1811,7 +1806,7 @@ nsCanvasRenderingContext2D::DrawWindow(nsIDOMWindow* aWindow, PRInt32 aX, PRInt3
r.ScaleRoundOut(p2t);
nsCOMPtr<nsIRenderingContext> blackCtx;
rv = vm->RenderOffscreen(view, r, PR_FALSE,
rv = vm->RenderOffscreen(view, r, PR_FALSE, PR_TRUE,
NS_ComposeColors(NS_RGB(0, 0, 0), bgColor),
getter_AddRefs(blackCtx));
NS_ENSURE_SUCCESS(rv, rv);
@ -1834,7 +1829,7 @@ nsCanvasRenderingContext2D::DrawWindow(nsIDOMWindow* aWindow, PRInt32 aX, PRInt3
// But we need to compose our given background color onto black/white
// to get the real background to use.
nsCOMPtr<nsIRenderingContext> whiteCtx;
rv = vm->RenderOffscreen(view, r, PR_FALSE,
rv = vm->RenderOffscreen(view, r, PR_FALSE, PR_TRUE,
NS_ComposeColors(NS_RGB(255, 255, 255), bgColor),
getter_AddRefs(whiteCtx));
if (NS_SUCCEEDED(rv)) {

View File

@ -888,7 +888,8 @@ DocumentViewerImpl::DumpContentToPPM(const char* aFileName)
} else {
nsCOMPtr<nsIRenderingContext> context;
nsresult rv = mViewManager->RenderOffscreen(view, r,
PR_FALSE, NS_RGB(255, 255, 255),
PR_FALSE, PR_TRUE,
NS_RGB(255, 255, 255),
getter_AddRefs(context));
if (NS_FAILED(rv)) {

View File

@ -452,15 +452,14 @@ public:
/**
* Dump the specified view into a new offscreen rendering context.
* The view is treated as the display root and is not clipped by
* ancestor views, nor is ancestor or sibling content displayed even
* if it overlaps the view.
* @param aRect is the region to capture into the offscreen buffer, in the view's
* coordinate system
* @param aUntrusted set to PR_TRUE if the contents may be passed to malicious
* agents. E.g. we might choose not to paint the contents of sensitive widgets
* such as the file name in a file upload widget, and we might choose not
* to paint themes.
* @param aIgnoreViewportScrolling ignore clipping/scrolling/scrollbar painting
* due to scrolling in the viewport
* @param aBackgroundColor a background color to render onto
* @param aRenderedContext gets set to a rendering context whose offscreen
* buffer can be locked to get the data. The buffer's size will be aRect's size.
@ -468,6 +467,7 @@ public:
* cx->DestroyDrawingSurface(cx->GetDrawingSurface()).
*/
NS_IMETHOD RenderOffscreen(nsIView* aView, nsRect aRect, PRBool aUntrusted,
PRBool aIgnoreViewportScrolling,
nscolor aBackgroundColor,
nsIRenderingContext** aRenderedContext) = 0;

View File

@ -869,7 +869,7 @@ void nsViewManager::Refresh(nsView *aView, nsIRenderingContext *aContext,
PL_INIT_ARENA_POOL(&displayArena, "displayArena", 1024);
PRBool anyTransparentPixels
= BuildRenderingDisplayList(aView, damageRegion, &displayList, displayArena,
PR_FALSE, PR_FALSE);
PR_FALSE, PR_FALSE, nsnull);
PRBool needBlending = PR_FALSE;
for (PRInt32 i = 0; i < displayList.Count(); i++) {
DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, displayList.ElementAt(i));
@ -1276,10 +1276,12 @@ void nsViewManager::AddCoveringWidgetsToOpaqueRegion(nsRegion &aRgn, nsIDeviceCo
PRBool nsViewManager::BuildRenderingDisplayList(nsIView* aRootView,
const nsRegion& aRegion, nsVoidArray* aDisplayList, PLArenaPool &aPool,
PRBool aIgnoreCoveringWidgets, PRBool aIgnoreOutsideClipping)
PRBool aIgnoreCoveringWidgets, PRBool aIgnoreOutsideClipping,
nsIView* aSuppressScrolling)
{
BuildDisplayList(NS_STATIC_CAST(nsView*, aRootView),
aRegion.GetBounds(), PR_FALSE, aIgnoreOutsideClipping,
aSuppressScrolling,
aDisplayList, aPool);
nsRegion opaqueRgn;
@ -2333,6 +2335,30 @@ static PRBool ComputePlaceholderContainment(nsView* aView) {
return containsPlaceholder;
}
/**
* Returns PR_TRUE if this view is (or is part of) a viewport scrollbar/scrollcorner
*/
static PRBool IsViewportScrollApparatus(nsView* aView, nsIView* aRootScroll) {
if (!aRootScroll)
return PR_FALSE;
// aView is NOT part of the scrolling apparatus if and only if it is a descendant
// of aRootScroll, OR it is a fixed position view or descendant
nsIView* aRootScrollframeView = aRootScroll->GetParent();
while (aView) {
if (aView == aRootScroll) {
// We're part of the scrolled document.
return PR_FALSE;
}
if (aView == aRootScrollframeView) {
return PR_TRUE;
}
aView = aView->GetParent();
}
// We're the root view or perhaps the view for a position:fixed element
return PR_FALSE;
}
/*
Fills aDisplayList with DisplayListElement2* pointers. The caller is responsible
for freeing these structs. The display list elements are ordered by z-order so
@ -2342,15 +2368,17 @@ static PRBool ComputePlaceholderContainment(nsView* aView) {
This should be changed so that the display list array is passed in as a parameter. There
is no need to have the display list as a member of nsViewManager.
aRect is the area in aView which we want to build a display list for.
Set aEventProcesing when the list is required for event processing.
Set aCaptured if the event or painting is being captured by the given view so
only views that are descended from the given view are considered.
@param aRect the area in aView which we want to build a display list for
@param aEventProcesing PR_TRUE when the list is required for event processing
@param aCaptured PR_TRUE if the event or painting is being captured by the
given view so only views that are descended from the given view are considered
@param aSuppressScrolling if non-null, scrollbars associated with this scrollable
view are not drawn, and clipping this view and its ancestors is suppressed
*/
void nsViewManager::BuildDisplayList(nsView* aView, const nsRect& aRect,
PRBool aEventProcessing,
PRBool aCaptured, nsVoidArray* aDisplayList,
PLArenaPool &aPool)
PRBool aCaptured, nsIView* aSuppressScrolling,
nsVoidArray* aDisplayList, PLArenaPool &aPool)
{
// compute this view's origin
nsPoint origin = ComputeViewOffset(aView);
@ -2393,7 +2421,9 @@ void nsViewManager::BuildDisplayList(nsView* aView, const nsRect& aRect,
CreateDisplayList(displayRoot, zTree, origin.x, origin.y,
aView, &aRect, displayRoot,
displayRootOrigin.x, displayRootOrigin.y,
paintFloats, aEventProcessing, PlaceholderHash, aPool);
paintFloats, aEventProcessing,
aSuppressScrolling ? aSuppressScrolling->GetFirstChild() : nsnull,
PlaceholderHash, aPool);
// Reparent any views that need reparenting in the Z-order tree
if(zTree) {
@ -2407,6 +2437,18 @@ void nsViewManager::BuildDisplayList(nsView* aView, const nsRect& aRect,
SortByZOrder(zTree, *aDisplayList, mergeTmp, PR_TRUE, aPool);
}
if (aSuppressScrolling) {
// Don't render viewport scrollbars
for (PRInt32 i = 0; i < aDisplayList->Count(); i++) {
DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*,
aDisplayList->ElementAt(i));
if ((element->mFlags & VIEW_RENDERED)
&& IsViewportScrollApparatus(element->mView, aSuppressScrolling)) {
element->mFlags &= ~VIEW_RENDERED;
}
}
}
}
void nsViewManager::BuildEventTargetList(nsVoidArray &aTargets, nsView* aView, nsGUIEvent* aEvent,
@ -2420,7 +2462,7 @@ void nsViewManager::BuildEventTargetList(nsVoidArray &aTargets, nsView* aView, n
nsRect eventRect(aEvent->point.x, aEvent->point.y, 1, 1);
nsAutoVoidArray displayList;
BuildDisplayList(aView, eventRect, PR_TRUE, aCaptured, &displayList, aPool);
BuildDisplayList(aView, eventRect, PR_TRUE, aCaptured, nsnull, &displayList, aPool);
#ifdef DEBUG_roc
if (getenv("MOZ_SHOW_DISPLAY_LIST")) ShowDisplayList(&displayList);
@ -2904,7 +2946,7 @@ NS_IMETHODIMP nsViewManager::SetViewChildClipRegion(nsIView *aView, const nsRegi
/*
Returns PR_TRUE if and only if aView is a (possibly indirect) child of aAncestor.
*/
static PRBool IsAncestorOf(const nsView* aAncestor, const nsView* aView)
static PRBool IsAncestorOf(const nsIView* aAncestor, const nsIView* aView)
{
while (nsnull != aView) {
aView = aView->GetParent();
@ -2991,7 +3033,7 @@ PRBool nsViewManager::CanScrollWithBitBlt(nsView* aView)
nsAutoVoidArray displayList;
PLArenaPool displayArena;
PL_INIT_ARENA_POOL(&displayArena, "displayArena", 1024);
BuildDisplayList(aView, r, PR_FALSE, PR_FALSE, &displayList, displayArena);
BuildDisplayList(aView, r, PR_FALSE, PR_FALSE, nsnull, &displayList, displayArena);
PRInt32 i;
for (i = 0; i < displayList.Count(); i++) {
@ -3451,6 +3493,7 @@ NS_IMETHODIMP nsViewManager::GetRootScrollableView(nsIScrollableView **aScrollab
NS_IMETHODIMP nsViewManager::RenderOffscreen(nsIView* aView, nsRect aRect,
PRBool aUntrusted,
PRBool aIgnoreViewportScrolling,
nscolor aBackgroundColor,
nsIRenderingContext** aRenderedContext)
{
@ -3487,11 +3530,23 @@ NS_IMETHODIMP nsViewManager::RenderOffscreen(nsIView* aView, nsRect aRect,
localcx->SetColor(aBackgroundColor);
localcx->FillRect(aRect);
nsRect r = aRect;
nsIView* suppressScrolling = nsnull;
if (aIgnoreViewportScrolling && mRootScrollable) {
// Suppress clipping/scrolling/scrollbar painting due to our
// viewport scrollable view
nscoord x, y;
mRootScrollable->GetScrollPosition(x, y);
localcx->Translate(x, y);
r.MoveBy(-x, -y);
suppressScrolling = mRootScrollable->View();
}
nsAutoVoidArray displayList;
PLArenaPool displayArena;
PL_INIT_ARENA_POOL(&displayArena, "displayArena", 1024);
BuildRenderingDisplayList(view, nsRegion(aRect), &displayList, displayArena,
PR_TRUE, PR_TRUE);
BuildRenderingDisplayList(view, nsRegion(r), &displayList, displayArena,
PR_TRUE, PR_TRUE, suppressScrolling);
RenderViews(view, *localcx, nsRegion(aRect), surface, displayList);
PL_FreeArenaPool(&displayArena);
PL_FinishArenaPool(&displayArena);
@ -3534,7 +3589,7 @@ NS_IMETHODIMP nsViewManager::Display(nsIView* aView, nscoord aX, nscoord aY, con
PLArenaPool displayArena;
PL_INIT_ARENA_POOL(&displayArena, "displayArena", 1024);
BuildRenderingDisplayList(view, nsRegion(trect), &displayList, displayArena,
PR_FALSE, PR_FALSE);
PR_FALSE, PR_FALSE, nsnull);
RenderViews(view, *localcx, nsRegion(trect), PR_FALSE, displayList);
PL_FreeArenaPool(&displayArena);
PL_FinishArenaPool(&displayArena);
@ -3615,6 +3670,8 @@ static nsresult EnsureZTreeNodeCreated(nsView* aView, DisplayZTreeNode* &aNode,
* if we should avoid descending into any floating views
* @param aEventProcessing PR_TRUE if we intend to do event processing with
* this display list
* @param aSuppressClip if non-null, any clipping from this view and its ancestors
* should not be applied
* @param aPool the arena to allocate the aResults elements from
*/
PRBool nsViewManager::CreateDisplayList(nsView *aView,
@ -3623,6 +3680,7 @@ PRBool nsViewManager::CreateDisplayList(nsView *aView,
const nsRect *aDamageRect, nsView *aTopView,
nscoord aX, nscoord aY, PRBool aPaintFloats,
PRBool aEventProcessing,
nsIView* aSuppressClip,
nsHashtable &aMapPlaceholderViewToZTreeNode,
PLArenaPool &aPool)
{
@ -3650,6 +3708,10 @@ PRBool nsViewManager::CreateDisplayList(nsView *aView,
(aView->GetClipChildrenToBounds(PR_FALSE)
&& !(aView->GetViewFlags() & NS_VIEW_FLAG_CONTAINS_PLACEHOLDER))
|| aView->GetClipChildrenToBounds(PR_TRUE);
if (isClipView && aSuppressClip && IsAncestorOf(aView, aSuppressClip)) {
isClipView = PR_FALSE;
}
PRBool overlap;
nsRect irect;
@ -3715,7 +3777,7 @@ PRBool nsViewManager::CreateDisplayList(nsView *aView,
// Add POP first because the z-tree is in reverse order
retval = AddToDisplayList(aView, aResult, bounds, bounds,
POP_FILTER, aX - aOriginX, aY - aOriginY, PR_TRUE, aPool,
aTopView);
aSuppressClip);
if (retval)
return retval;
@ -3733,7 +3795,7 @@ PRBool nsViewManager::CreateDisplayList(nsView *aView,
// Add POP first because the z-tree is in reverse order
retval = AddToDisplayList(aView, aResult, bounds, bounds,
POP_CLIP, aX - aOriginX, aY - aOriginY, PR_TRUE, aPool,
aTopView);
aSuppressClip);
if (retval)
return retval;
@ -3752,6 +3814,7 @@ PRBool nsViewManager::CreateDisplayList(nsView *aView,
retval = CreateDisplayList(childView, createdNode,
aOriginX, aOriginY, aRealView, aDamageRect, aTopView,
pos.x, pos.y, aPaintFloats, aEventProcessing,
aSuppressClip,
aMapPlaceholderViewToZTreeNode, aPool);
if (createdNode != nsnull) {
EnsureZTreeNodeCreated(aView, aResult, aPool);
@ -3777,7 +3840,7 @@ PRBool nsViewManager::CreateDisplayList(nsView *aView,
retval = AddToDisplayList(aView, aResult, bounds, irect, flags,
aX - aOriginX, aY - aOriginY,
aEventProcessing && aTopView == aView, aPool,
aTopView);
aSuppressClip);
// We're forcing AddToDisplayList to pick up the view only
// during event processing, and only when aView is back at the
// root of the tree of acceptable views (note that when event
@ -3803,7 +3866,7 @@ PRBool nsViewManager::CreateDisplayList(nsView *aView,
if (AddToDisplayList(aView, aResult, bounds, bounds, PUSH_CLIP,
aX - aOriginX, aY - aOriginY, PR_TRUE, aPool,
aTopView)) {
aSuppressClip)) {
retval = PR_TRUE;
}
@ -3819,7 +3882,7 @@ PRBool nsViewManager::CreateDisplayList(nsView *aView,
retval = AddToDisplayList(aView, aResult, bounds, bounds,
PUSH_FILTER, aX - aOriginX, aY - aOriginY, PR_TRUE, aPool,
aTopView);
aSuppressClip);
if (retval)
return retval;

View File

@ -230,6 +230,7 @@ public:
NS_IMETHOD Display(nsIView *aView, nscoord aX, nscoord aY, const nsRect& aClipRect);
NS_IMETHOD RenderOffscreen(nsIView* aView, nsRect aRect, PRBool aUntrusted,
PRBool aIgnoreViewportScrolling,
nscolor aBackgroundColor,
nsIRenderingContext** aRenderedContext);
@ -292,7 +293,8 @@ private:
void DefaultRefresh(nsView* aView, const nsRect* aRect);
PRBool BuildRenderingDisplayList(nsIView* aRootView,
const nsRegion& aRegion, nsVoidArray* aDisplayList, PLArenaPool &aPool,
PRBool aIgnoreCoveringWidgets, PRBool aIgnoreOutsideClipping);
PRBool aIgnoreCoveringWidgets, PRBool aIgnoreOutsideClipping,
nsIView* aSuppressScrolling);
void RenderViews(nsView *aRootView, nsIRenderingContext& aRC,
const nsRegion& aRegion, nsIDrawingSurface* aRCSurface,
const nsVoidArray& aDisplayList);
@ -313,8 +315,10 @@ private:
void ReparentViews(DisplayZTreeNode* aNode, nsHashtable &);
void BuildDisplayList(nsView* aView, const nsRect& aRect, PRBool aEventProcessing,
PRBool aCaptured, nsVoidArray* aDisplayList, PLArenaPool &aPool);
void BuildEventTargetList(nsVoidArray &aTargets, nsView* aView, nsGUIEvent* aEvent, PRBool aCaptured, PLArenaPool &aPool);
PRBool aCaptured, nsIView* aSuppressScrolling,
nsVoidArray* aDisplayList, PLArenaPool &aPool);
void BuildEventTargetList(nsVoidArray &aTargets, nsView* aView,
nsGUIEvent* aEvent, PRBool aCaptured, PLArenaPool &aPool);
PRBool CreateDisplayList(nsView *aView,
DisplayZTreeNode* &aResult,
@ -322,6 +326,7 @@ private:
nsView *aRealView, const nsRect *aDamageRect,
nsView *aTopView, nscoord aX, nscoord aY,
PRBool aPaintFloats, PRBool aEventProcessing,
nsIView* aSuppressClip,
nsHashtable&, PLArenaPool &aPool);
PRBool AddToDisplayList(nsView *aView,
DisplayZTreeNode* &aParent, nsRect &aClipRect,