From 885fa92ef4ef4b87d29980a4b5b5b7ef889c3944 Mon Sep 17 00:00:00 2001 From: Mats Palmgren <matspal@gmail.com> Date: Tue, 3 Apr 2012 02:30:45 +0200 Subject: [PATCH] Bug 736915 - Print Selection prints a blank page when the selection is inside a table. r=bz When rendering just the current Selection (Print - Selection) then don't create display items for table-related frames unless the frame itself is part of the selection, and always ask descendant frames to build display lists [in case they are selected]. --- layout/tables/nsTableCellFrame.cpp | 133 ++++++++++++------------- layout/tables/nsTableFrame.cpp | 48 +++++---- layout/tables/nsTableOuterFrame.cpp | 2 - layout/tables/nsTableRowFrame.cpp | 28 +++--- layout/tables/nsTableRowGroupFrame.cpp | 24 ++--- 5 files changed, 113 insertions(+), 122 deletions(-) diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index 803247c85f1f3..cb57b71f566bd 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -434,78 +434,77 @@ nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - if (!IsVisibleInSelection(aBuilder)) - return NS_OK; - DO_GLOBAL_REFLOW_COUNT_DSP("nsTableCellFrame"); - nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this); - PRInt32 emptyCellStyle = GetContentEmpty() && !tableFrame->IsBorderCollapse() ? - GetStyleTableBorder()->mEmptyCells - : NS_STYLE_TABLE_EMPTY_CELLS_SHOW; - // take account of 'empty-cells' - if (GetStyleVisibility()->IsVisible() && - (NS_STYLE_TABLE_EMPTY_CELLS_HIDE != emptyCellStyle)) { - - - bool isRoot = aBuilder->IsAtRootOfPseudoStackingContext(); - if (!isRoot) { - nsDisplayTableItem* currentItem = aBuilder->GetCurrentTableItem(); - if (currentItem) { - currentItem->UpdateForFrameBackground(this); + if (IsVisibleInSelection(aBuilder)) { + nsTableFrame* tableFrame = nsTableFrame::GetTableFrame(this); + PRInt32 emptyCellStyle = GetContentEmpty() && !tableFrame->IsBorderCollapse() ? + GetStyleTableBorder()->mEmptyCells + : NS_STYLE_TABLE_EMPTY_CELLS_SHOW; + // take account of 'empty-cells' + if (GetStyleVisibility()->IsVisible() && + (NS_STYLE_TABLE_EMPTY_CELLS_HIDE != emptyCellStyle)) { + + + bool isRoot = aBuilder->IsAtRootOfPseudoStackingContext(); + if (!isRoot) { + nsDisplayTableItem* currentItem = aBuilder->GetCurrentTableItem(); + if (currentItem) { + currentItem->UpdateForFrameBackground(this); + } + } + + // display outset box-shadows if we need to. + bool hasBoxShadow = !!(GetStyleBorder()->mBoxShadow); + if (hasBoxShadow) { + nsresult rv = aLists.BorderBackground()->AppendNewToTop( + new (aBuilder) nsDisplayBoxShadowOuter(aBuilder, this)); + NS_ENSURE_SUCCESS(rv, rv); + } + + // display background if we need to. + if (aBuilder->IsForEventDelivery() || + (((!tableFrame->IsBorderCollapse() || isRoot) && + (!GetStyleBackground()->IsTransparent() || GetStyleDisplay()->mAppearance)))) { + // The cell background was not painted by the nsTablePainter, + // so we need to do it. We have special background processing here + // so we need to duplicate some code from nsFrame::DisplayBorderBackgroundOutline + nsDisplayTableItem* item = + new (aBuilder) nsDisplayTableCellBackground(aBuilder, this); + nsresult rv = aLists.BorderBackground()->AppendNewToTop(item); + NS_ENSURE_SUCCESS(rv, rv); + item->UpdateForFrameBackground(this); + } + + // display inset box-shadows if we need to. + if (hasBoxShadow) { + nsresult rv = aLists.BorderBackground()->AppendNewToTop( + new (aBuilder) nsDisplayBoxShadowInner(aBuilder, this)); + NS_ENSURE_SUCCESS(rv, rv); + } + + // display borders if we need to + if (!tableFrame->IsBorderCollapse() && HasBorder() && + emptyCellStyle == NS_STYLE_TABLE_EMPTY_CELLS_SHOW) { + nsresult rv = aLists.BorderBackground()->AppendNewToTop(new (aBuilder) + nsDisplayBorder(aBuilder, this)); + NS_ENSURE_SUCCESS(rv, rv); + } + + // and display the selection border if we need to + if (IsSelected()) { + nsresult rv = aLists.BorderBackground()->AppendNewToTop(new (aBuilder) + nsDisplayGeneric(aBuilder, this, ::PaintTableCellSelection, + "TableCellSelection", + nsDisplayItem::TYPE_TABLE_CELL_SELECTION)); + NS_ENSURE_SUCCESS(rv, rv); } } - - // display outset box-shadows if we need to. - bool hasBoxShadow = !!(GetStyleBorder()->mBoxShadow); - if (hasBoxShadow) { - nsresult rv = aLists.BorderBackground()->AppendNewToTop( - new (aBuilder) nsDisplayBoxShadowOuter(aBuilder, this)); - NS_ENSURE_SUCCESS(rv, rv); - } - - // display background if we need to. - if (aBuilder->IsForEventDelivery() || - (((!tableFrame->IsBorderCollapse() || isRoot) && - (!GetStyleBackground()->IsTransparent() || GetStyleDisplay()->mAppearance)))) { - // The cell background was not painted by the nsTablePainter, - // so we need to do it. We have special background processing here - // so we need to duplicate some code from nsFrame::DisplayBorderBackgroundOutline - nsDisplayTableItem* item = - new (aBuilder) nsDisplayTableCellBackground(aBuilder, this); - nsresult rv = aLists.BorderBackground()->AppendNewToTop(item); - NS_ENSURE_SUCCESS(rv, rv); - item->UpdateForFrameBackground(this); - } - - // display inset box-shadows if we need to. - if (hasBoxShadow) { - nsresult rv = aLists.BorderBackground()->AppendNewToTop( - new (aBuilder) nsDisplayBoxShadowInner(aBuilder, this)); - NS_ENSURE_SUCCESS(rv, rv); - } - - // display borders if we need to - if (!tableFrame->IsBorderCollapse() && HasBorder() && - emptyCellStyle == NS_STYLE_TABLE_EMPTY_CELLS_SHOW) { - nsresult rv = aLists.BorderBackground()->AppendNewToTop(new (aBuilder) - nsDisplayBorder(aBuilder, this)); - NS_ENSURE_SUCCESS(rv, rv); - } - - // and display the selection border if we need to - if (IsSelected()) { - nsresult rv = aLists.BorderBackground()->AppendNewToTop(new (aBuilder) - nsDisplayGeneric(aBuilder, this, ::PaintTableCellSelection, - "TableCellSelection", - nsDisplayItem::TYPE_TABLE_CELL_SELECTION)); - NS_ENSURE_SUCCESS(rv, rv); - } + + // the 'empty-cells' property has no effect on 'outline' + nsresult rv = DisplayOutline(aBuilder, aLists); + NS_ENSURE_SUCCESS(rv, rv); } - // the 'empty-cells' property has no effect on 'outline' - nsresult rv = DisplayOutline(aBuilder, aLists); - NS_ENSURE_SUCCESS(rv, rv); - // Push a null 'current table item' so that descendant tables can't // accidentally mess with our table nsAutoPushCurrentTableItem pushTableItem; diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 90c37ce9a51b3..96d6faa95df70 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -1270,36 +1270,34 @@ nsTableFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - if (!IsVisibleInSelection(aBuilder)) - return NS_OK; - DO_GLOBAL_REFLOW_COUNT_DSP_COLOR("nsTableFrame", NS_RGB(255,128,255)); - if (GetStyleVisibility()->IsVisible()) { - nsMargin deflate = GetDeflationForBackground(PresContext()); - // If 'deflate' is (0,0,0,0) then we can paint the table background - // in its own display item, so do that to take advantage of - // opacity and visibility optimizations - if (deflate == nsMargin(0, 0, 0, 0)) { - nsresult rv = DisplayBackgroundUnconditional(aBuilder, aLists, false); + nsDisplayTableItem* item = nsnull; + if (IsVisibleInSelection(aBuilder)) { + if (GetStyleVisibility()->IsVisible()) { + nsMargin deflate = GetDeflationForBackground(PresContext()); + // If 'deflate' is (0,0,0,0) then we can paint the table background + // in its own display item, so do that to take advantage of + // opacity and visibility optimizations + if (deflate == nsMargin(0, 0, 0, 0)) { + nsresult rv = DisplayBackgroundUnconditional(aBuilder, aLists, false); + NS_ENSURE_SUCCESS(rv, rv); + } + } + + // This background is created if any of the table parts are visible, + // or if we're doing event handling (since DisplayGenericTablePart + // needs the item for the |sortEventBackgrounds|-dependent code). + // Specific visibility decisions are delegated to the table background + // painter, which handles borders and backgrounds for the table. + if (aBuilder->IsForEventDelivery() || + AnyTablePartHasBorderOrBackground(this, GetNextSibling()) || + AnyTablePartHasBorderOrBackground(mColGroups.FirstChild(), nsnull)) { + item = new (aBuilder) nsDisplayTableBorderBackground(aBuilder, this); + nsresult rv = aLists.BorderBackground()->AppendNewToTop(item); NS_ENSURE_SUCCESS(rv, rv); } } - - nsDisplayTableItem* item = nsnull; - // This background is created if any of the table parts are visible, - // or if we're doing event handling (since DisplayGenericTablePart - // needs the item for the |sortEventBackgrounds|-dependent code). - // Specific visibility decisions are delegated to the table background - // painter, which handles borders and backgrounds for the table. - if (aBuilder->IsForEventDelivery() || - AnyTablePartHasBorderOrBackground(this, GetNextSibling()) || - AnyTablePartHasBorderOrBackground(mColGroups.FirstChild(), nsnull)) { - item = new (aBuilder) nsDisplayTableBorderBackground(aBuilder, this); - nsresult rv = aLists.BorderBackground()->AppendNewToTop(item); - NS_ENSURE_SUCCESS(rv, rv); - } - return DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists, item); } diff --git a/layout/tables/nsTableOuterFrame.cpp b/layout/tables/nsTableOuterFrame.cpp index 49206de5e3c6a..c8f98af363e02 100644 --- a/layout/tables/nsTableOuterFrame.cpp +++ b/layout/tables/nsTableOuterFrame.cpp @@ -338,8 +338,6 @@ nsTableOuterFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, { // No border, background or outline are painted because they all belong // to the inner table. - if (!IsVisibleInSelection(aBuilder)) - return NS_OK; // If there's no caption, take a short cut to avoid having to create // the special display list set and then sort it. diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index d185e326f49c2..b63cdb3072356 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -589,23 +589,21 @@ nsTableRowFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - if (!IsVisibleInSelection(aBuilder)) - return NS_OK; - - bool isRoot = aBuilder->IsAtRootOfPseudoStackingContext(); nsDisplayTableItem* item = nsnull; - if (isRoot) { - // This background is created regardless of whether this frame is - // visible or not. Visibility decisions are delegated to the - // table background painter. - // We would use nsDisplayGeneric for this rare case except that we - // need the background to be larger than the row frame in some - // cases. - item = new (aBuilder) nsDisplayTableRowBackground(aBuilder, this); - nsresult rv = aLists.BorderBackground()->AppendNewToTop(item); - NS_ENSURE_SUCCESS(rv, rv); + if (IsVisibleInSelection(aBuilder)) { + bool isRoot = aBuilder->IsAtRootOfPseudoStackingContext(); + if (isRoot) { + // This background is created regardless of whether this frame is + // visible or not. Visibility decisions are delegated to the + // table background painter. + // We would use nsDisplayGeneric for this rare case except that we + // need the background to be larger than the row frame in some + // cases. + item = new (aBuilder) nsDisplayTableRowBackground(aBuilder, this); + nsresult rv = aLists.BorderBackground()->AppendNewToTop(item); + NS_ENSURE_SUCCESS(rv, rv); + } } - return nsTableFrame::DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists, item); } diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 1d7a55d04dd3d..4f22b6c6f63ff 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -248,20 +248,18 @@ nsTableRowGroupFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - if (!IsVisibleInSelection(aBuilder)) - return NS_OK; - - bool isRoot = aBuilder->IsAtRootOfPseudoStackingContext(); nsDisplayTableItem* item = nsnull; - if (isRoot) { - // This background is created regardless of whether this frame is - // visible or not. Visibility decisions are delegated to the - // table background painter. - item = new (aBuilder) nsDisplayTableRowGroupBackground(aBuilder, this); - nsresult rv = aLists.BorderBackground()->AppendNewToTop(item); - NS_ENSURE_SUCCESS(rv, rv); - } - + if (IsVisibleInSelection(aBuilder)) { + bool isRoot = aBuilder->IsAtRootOfPseudoStackingContext(); + if (isRoot) { + // This background is created regardless of whether this frame is + // visible or not. Visibility decisions are delegated to the + // table background painter. + item = new (aBuilder) nsDisplayTableRowGroupBackground(aBuilder, this); + nsresult rv = aLists.BorderBackground()->AppendNewToTop(item); + NS_ENSURE_SUCCESS(rv, rv); + } + } return nsTableFrame::DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists, item, DisplayRows); } -- GitLab