Bug 1022612. Part 5: BuildDisplayListForExtraPage needs to pass the correct dirty rect in. r=mattwoodrow

When printing, every page has the same origin. So doing this change naively
would result in the first page having all the display items for every page
added to it, and all but the first page's display items being pruned
away by PruneDisplayListForExtraPage. This would making printing long documents
very slow. We avoid that problem with the new check for
NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO, so the only pages other than the
current page we descend into are the ones with placeholders for abs-pos content
on the current page.

--HG--
extra : rebase_source : b9b8c53d5ad5e4eb2d3c5e1f407d605558b3b9d0
This commit is contained in:
Robert O'Callahan 2014-06-09 16:47:58 +12:00
parent 01eb9c6919
commit 2765a46906

View File

@ -414,22 +414,22 @@ PruneDisplayListForExtraPage(nsDisplayListBuilder* aBuilder,
aList->AppendToTop(&newList);
}
static nsresult
static void
BuildDisplayListForExtraPage(nsDisplayListBuilder* aBuilder,
nsPageFrame* aPage, nsIFrame* aExtraPage,
nsDisplayList* aList)
const nsRect& aDirtyRect, nsDisplayList* aList)
{
// The only content in aExtraPage we care about is out-of-flow content whose
// placeholders have occurred in aPage. If
// NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO is not set, then aExtraPage has
// no such content.
if (!aExtraPage->HasAnyStateBits(NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)) {
return;
}
nsDisplayList list;
// Pass an empty dirty rect since we're only interested in finding
// placeholders whose out-of-flows are in the page
// aBuilder->GetReferenceFrame(), and the paths to those placeholders
// have already been marked as NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO.
// Note that we should still do a prune step since we don't want to
// rely on dirty-rect checking for correctness.
aExtraPage->BuildDisplayListForStackingContext(aBuilder, nsRect(), &list);
aExtraPage->BuildDisplayListForStackingContext(aBuilder, aDirtyRect, &list);
PruneDisplayListForExtraPage(aBuilder, aPage, aExtraPage, &list);
aList->AppendToTop(&list);
return NS_OK;
}
static nsIFrame*
@ -506,8 +506,8 @@ nsPageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
clipState.Clear();
clipState.ClipContainingBlockDescendants(clipRect, nullptr);
child->BuildDisplayListForStackingContext(aBuilder,
child->GetVisualOverflowRectRelativeToSelf(), &content);
nsRect dirtyRect = child->GetVisualOverflowRectRelativeToSelf();
child->BuildDisplayListForStackingContext(aBuilder, dirtyRect, &content);
// We may need to paint out-of-flow frames whose placeholders are
// on other pages. Add those pages to our display list. Note that
@ -518,7 +518,8 @@ nsPageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// following placeholders to their out-of-flows) end up on the list.
nsIFrame* page = child;
while ((page = GetNextPage(page)) != nullptr) {
BuildDisplayListForExtraPage(aBuilder, this, page, &content);
BuildDisplayListForExtraPage(aBuilder, this, page,
dirtyRect + child->GetOffsetTo(page), &content);
}
// Add the canvas background color to the bottom of the list. This