diff options
-rw-r--r-- | layout/base/nsDisplayItemTypesList.h | 1 | ||||
-rw-r--r-- | layout/base/nsDisplayList.cpp | 9 | ||||
-rw-r--r-- | layout/base/nsDisplayList.h | 3 | ||||
-rw-r--r-- | layout/tables/nsTableCellFrame.cpp | 103 | ||||
-rw-r--r-- | layout/tables/nsTableColFrame.cpp | 8 | ||||
-rw-r--r-- | layout/tables/nsTableColFrame.h | 5 | ||||
-rw-r--r-- | layout/tables/nsTableColGroupFrame.cpp | 8 | ||||
-rw-r--r-- | layout/tables/nsTableColGroupFrame.h | 5 | ||||
-rw-r--r-- | layout/tables/nsTableFrame.cpp | 268 | ||||
-rw-r--r-- | layout/tables/nsTableFrame.h | 1 | ||||
-rw-r--r-- | layout/tables/nsTableRowFrame.cpp | 16 | ||||
-rw-r--r-- | layout/tables/nsTableRowGroupFrame.cpp | 13 | ||||
-rw-r--r-- | layout/tables/nsTableWrapperFrame.cpp | 6 |
13 files changed, 223 insertions, 223 deletions
diff --git a/layout/base/nsDisplayItemTypesList.h b/layout/base/nsDisplayItemTypesList.h index 9865395a7..d24f6f38f 100644 --- a/layout/base/nsDisplayItemTypesList.h +++ b/layout/base/nsDisplayItemTypesList.h @@ -59,6 +59,7 @@ DECLARE_DISPLAY_ITEM_TYPE(TABLE_CELL_SELECTION) DECLARE_DISPLAY_ITEM_TYPE(TABLE_ROW_BACKGROUND) DECLARE_DISPLAY_ITEM_TYPE(TABLE_ROW_GROUP_BACKGROUND) DECLARE_DISPLAY_ITEM_TYPE(TABLE_BORDER_BACKGROUND) +DECLARE_DISPLAY_ITEM_TYPE(TABLE_BORDER_COLLAPSE) DECLARE_DISPLAY_ITEM_TYPE(TEXT) DECLARE_DISPLAY_ITEM_TYPE(TEXT_OVERFLOW) DECLARE_DISPLAY_ITEM_TYPE_FLAGS(TRANSFORM,TYPE_RENDERS_NO_IMAGES) diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index e22230b41..744153831 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -2631,11 +2631,16 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil const nsRect& aBackgroundRect, nsDisplayList* aList, bool aAllowWillPaintBorderOptimization, - nsStyleContext* aStyleContext) + nsStyleContext* aStyleContext, + const nsRect& aBackgroundOriginRect) { nsStyleContext* bgSC = aStyleContext; const nsStyleBackground* bg = nullptr; nsRect bgRect = aBackgroundRect + aBuilder->ToReferenceFrame(aFrame); + nsRect bgOriginRect = bgRect; + if (!aBackgroundOriginRect.IsEmpty()) { + bgOriginRect = aBackgroundOriginRect + aBuilder->ToReferenceFrame(aFrame); + } nsPresContext* presContext = aFrame->PresContext(); bool isThemed = aFrame->IsThemed(); if (!isThemed) { @@ -2744,7 +2749,7 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil nsDisplayList thisItemList; nsDisplayBackgroundImage* bgItem = - new (aBuilder) nsDisplayBackgroundImage(aBuilder, aFrame, i, bgRect, bg); + new (aBuilder) nsDisplayBackgroundImage(aBuilder, aFrame, i, bgOriginRect, bg); if (bgItem->ShouldFixToViewport(aBuilder)) { thisItemList.AppendNewToTop( diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index c81d34fac..9431e2cc0 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -2737,7 +2737,8 @@ public: const nsRect& aBackgroundRect, nsDisplayList* aList, bool aAllowWillPaintBorderOptimization = true, - nsStyleContext* aStyleContext = nullptr); + nsStyleContext* aStyleContext = nullptr, + const nsRect& aBackgroundOriginRect = nsRect()); virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager, diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp index dea82ea59..bac8d387f 100644 --- a/layout/tables/nsTableCellFrame.cpp +++ b/layout/tables/nsTableCellFrame.cpp @@ -484,70 +484,51 @@ nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists) { DO_GLOBAL_REFLOW_COUNT_DSP("nsTableCellFrame"); - if (IsVisibleInSelection(aBuilder)) { - nsTableFrame* tableFrame = GetTableFrame(); - int32_t emptyCellStyle = GetContentEmpty() && !tableFrame->IsBorderCollapse() ? - StyleTableBorder()->mEmptyCells - : NS_STYLE_TABLE_EMPTY_CELLS_SHOW; - // take account of 'empty-cells' - if (StyleVisibility()->IsVisible() && - (NS_STYLE_TABLE_EMPTY_CELLS_HIDE != emptyCellStyle)) { - // display outset box-shadows if we need to. - bool hasBoxShadow = !!StyleEffects()->mBoxShadow; - if (hasBoxShadow) { - aLists.BorderBackground()->AppendNewToTop( - new (aBuilder) nsDisplayBoxShadowOuter(aBuilder, this)); - } - - // display background if we need to. - if (aBuilder->IsForEventDelivery() || - !StyleBackground()->IsTransparent() || StyleDisplay()->mAppearance) { - if (!tableFrame->IsBorderCollapse()) { - nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, - this, - GetRectRelativeToSelf(), - aLists.BorderBackground()); - } else if (aBuilder->IsAtRootOfPseudoStackingContext() || - aBuilder->IsForEventDelivery()) { - // 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); - aLists.BorderBackground()->AppendNewToTop(item); - item->UpdateForFrameBackground(this); - } else { - // The nsTablePainter will paint our background. Make sure it - // knows if we're background-attachment:fixed. - nsDisplayTableItem* currentItem = aBuilder->GetCurrentTableItem(); - if (currentItem) { - currentItem->UpdateForFrameBackground(this); - } - } - } - - // display inset box-shadows if we need to. - if (hasBoxShadow) { - aLists.BorderBackground()->AppendNewToTop( - new (aBuilder) nsDisplayBoxShadowInner(aBuilder, this)); - } - - // display borders if we need to - ProcessBorders(tableFrame, aBuilder, aLists); - - // and display the selection border if we need to - if (IsSelected()) { - aLists.BorderBackground()->AppendNewToTop(new (aBuilder) - nsDisplayGeneric(aBuilder, this, ::PaintTableCellSelection, - "TableCellSelection", - nsDisplayItem::TYPE_TABLE_CELL_SELECTION)); - } + nsTableFrame* tableFrame = GetTableFrame(); + int32_t emptyCellStyle = GetContentEmpty() && !tableFrame->IsBorderCollapse() ? + StyleTableBorder()->mEmptyCells + : NS_STYLE_TABLE_EMPTY_CELLS_SHOW; + // take account of 'empty-cells' + if (StyleVisibility()->IsVisible() && + (NS_STYLE_TABLE_EMPTY_CELLS_HIDE != emptyCellStyle)) { + // display outset box-shadows if we need to. + bool hasBoxShadow = !!StyleEffects()->mBoxShadow; + if (hasBoxShadow) { + aLists.BorderBackground()->AppendNewToTop( + new (aBuilder) nsDisplayBoxShadowOuter(aBuilder, this)); + } + + // display background if we need to. + if (aBuilder->IsForEventDelivery() || + !StyleBackground()->IsTransparent() || + StyleDisplay()->mAppearance) { + nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, + this, + GetRectRelativeToSelf(), + aLists.BorderBackground()); + } + + // display inset box-shadows if we need to. + if (hasBoxShadow) { + aLists.BorderBackground()->AppendNewToTop( + new (aBuilder) nsDisplayBoxShadowInner(aBuilder, this)); + } + + // display borders if we need to + ProcessBorders(tableFrame, aBuilder, aLists); + + // and display the selection border if we need to + if (IsSelected()) { + aLists.BorderBackground()->AppendNewToTop(new (aBuilder) + nsDisplayGeneric(aBuilder, this, ::PaintTableCellSelection, + "TableCellSelection", + nsDisplayItem::TYPE_TABLE_CELL_SELECTION)); } - - // the 'empty-cells' property has no effect on 'outline' - DisplayOutline(aBuilder, aLists); } + // the 'empty-cells' property has no effect on 'outline' + DisplayOutline(aBuilder, aLists); + // Push a null 'current table item' so that descendant tables can't // accidentally mess with our table nsAutoPushCurrentTableItem pushTableItem; diff --git a/layout/tables/nsTableColFrame.cpp b/layout/tables/nsTableColFrame.cpp index 8f449c3d9..54b03522b 100644 --- a/layout/tables/nsTableColFrame.cpp +++ b/layout/tables/nsTableColFrame.cpp @@ -108,6 +108,14 @@ nsTableColFrame::Reflow(nsPresContext* aPresContext, NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } +void +nsTableColFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists) +{ + nsTableFrame::DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists); +} + int32_t nsTableColFrame::GetSpan() { return StyleTable()->mSpan; diff --git a/layout/tables/nsTableColFrame.h b/layout/tables/nsTableColFrame.h index e95fe76b1..fb989061f 100644 --- a/layout/tables/nsTableColFrame.h +++ b/layout/tables/nsTableColFrame.h @@ -59,12 +59,9 @@ public: const ReflowInput& aReflowInput, nsReflowStatus& aStatus) override; - /** - * Table columns never paint anything, nor receive events. - */ virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) override {} + const nsDisplayListSet& aLists) override; /** * Get the "type" of the frame diff --git a/layout/tables/nsTableColGroupFrame.cpp b/layout/tables/nsTableColGroupFrame.cpp index ff8879a0b..6ee7f0b24 100644 --- a/layout/tables/nsTableColGroupFrame.cpp +++ b/layout/tables/nsTableColGroupFrame.cpp @@ -383,6 +383,14 @@ nsTableColGroupFrame::Reflow(nsPresContext* aPresContext, NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); } +void +nsTableColGroupFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists) +{ + nsTableFrame::DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists); +} + nsTableColFrame * nsTableColGroupFrame::GetFirstColumn() { return GetNextColumn(nullptr); diff --git a/layout/tables/nsTableColGroupFrame.h b/layout/tables/nsTableColGroupFrame.h index 2a25fdc44..b3dfb94e7 100644 --- a/layout/tables/nsTableColGroupFrame.h +++ b/layout/tables/nsTableColGroupFrame.h @@ -43,12 +43,9 @@ public: return static_cast<nsTableFrame*>(parent); } - /** - * ColGroups never paint anything, nor receive events. - */ virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, - const nsDisplayListSet& aLists) override {} + const nsDisplayListSet& aLists) override; /** A colgroup can be caused by three things: * 1) An element with table-column-group display diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index 272a77406..b5cd3b487 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -1131,6 +1131,42 @@ nsDisplayTableItem::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion); } +// A display item that draws all collapsed borders for a table. +class nsDisplayTableBorderCollapse : public nsDisplayTableItem { +public: + nsDisplayTableBorderCollapse(nsDisplayListBuilder* aBuilder, + nsTableFrame* aFrame) + : nsDisplayTableItem(aBuilder, aFrame) { + MOZ_COUNT_CTOR(nsDisplayTableBorderCollapse); + } +#ifdef NS_BUILD_REFCNT_LOGGING + virtual ~nsDisplayTableBorderCollapse() { + MOZ_COUNT_DTOR(nsDisplayTableBorderCollapse); + } +#endif + + virtual void Paint(nsDisplayListBuilder* aBuilder, + nsRenderingContext* aCtx) override; + NS_DISPLAY_DECL_NAME("TableBorderCollapse", TYPE_TABLE_BORDER_COLLAPSE) +}; + +void +nsDisplayTableBorderCollapse::Paint(nsDisplayListBuilder* aBuilder, + nsRenderingContext* aCtx) +{ + nsPoint pt = ToReferenceFrame(); + DrawTarget* drawTarget = aCtx->GetDrawTarget(); + + gfxPoint devPixelOffset = + nsLayoutUtils::PointToGfxPoint(pt, mFrame->PresContext()->AppUnitsPerDevPixel()); + + AutoRestoreTransform autoRestoreTransform(drawTarget); + drawTarget->SetTransform( + drawTarget->GetTransform().PreTranslate(ToPoint(devPixelOffset))); + + static_cast<nsTableFrame*>(mFrame)->PaintBCBorders(*drawTarget, mVisibleRect - pt); +} + class nsDisplayTableBorderBackground : public nsDisplayTableItem { public: nsDisplayTableBorderBackground(nsDisplayListBuilder* aBuilder, @@ -1150,20 +1186,6 @@ public: NS_DISPLAY_DECL_NAME("TableBorderBackground", TYPE_TABLE_BORDER_BACKGROUND) }; -#ifdef DEBUG -static bool -IsFrameAllowedInTable(nsIAtom* aType) -{ - return IS_TABLE_CELL(aType) || - nsGkAtoms::tableRowFrame == aType || - nsGkAtoms::tableRowGroupFrame == aType || - nsGkAtoms::scrollFrame == aType || - nsGkAtoms::tableFrame == aType || - nsGkAtoms::tableColFrame == aType || - nsGkAtoms::tableColGroupFrame == aType; -} -#endif - void nsDisplayTableBorderBackground::Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) @@ -1175,25 +1197,6 @@ nsDisplayTableBorderBackground::Paint(nsDisplayListBuilder* aBuilder, nsDisplayTableItemGeometry::UpdateDrawResult(this, result); } -static int32_t -GetTablePartRank(nsDisplayItem* aItem) -{ - nsIAtom* type = aItem->Frame()->GetType(); - if (type == nsGkAtoms::tableFrame) - return 0; - if (type == nsGkAtoms::tableRowGroupFrame) - return 1; - if (type == nsGkAtoms::tableRowFrame) - return 2; - return 3; -} - -static bool CompareByTablePartRank(nsDisplayItem* aItem1, nsDisplayItem* aItem2, - void* aClosure) -{ - return GetTablePartRank(aItem1) <= GetTablePartRank(aItem2); -} - /* static */ void nsTableFrame::GenericTraversal(nsDisplayListBuilder* aBuilder, nsFrame* aFrame, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) @@ -1206,31 +1209,73 @@ nsTableFrame::GenericTraversal(nsDisplayListBuilder* aBuilder, nsFrame* aFrame, // stacking context, in which case the child won't use its passed-in // BorderBackground list anyway. It does affect cell borders though; this // lets us get cell borders into the nsTableFrame's BorderBackground list. + for (nsIFrame* kid : aFrame->GetChildList(kColGroupList)) { + aFrame->BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); + } + for (nsIFrame* kid : aFrame->PrincipalChildList()) { aFrame->BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); } } +static void +PaintRowBackground(nsTableRowFrame* aRow, + nsIFrame* aFrame, + nsDisplayListBuilder* aBuilder, + const nsDisplayListSet& aLists, + const nsPoint& aOffset = nsPoint()) +{ + // Compute background rect by iterating all cell frame. + for (nsTableCellFrame* cell = aRow->GetFirstCell(); cell; cell = cell->GetNextCell()) { + auto cellRect = cell->GetRectRelativeToSelf() + cell->GetNormalPosition() + aOffset; + nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame, cellRect, + aLists.BorderBackground(), + true, nullptr, + aFrame->GetRectRelativeToSelf()); + } +} + +static void +PaintRowGroupBackground(nsTableRowGroupFrame* aRowGroup, + nsIFrame* aFrame, + nsDisplayListBuilder* aBuilder, + const nsDisplayListSet& aLists) +{ + for (nsTableRowFrame* row = aRowGroup->GetFirstRow(); row; row = row->GetNextRow()) { + PaintRowBackground(row, aFrame, aBuilder, aLists, row->GetNormalPosition()); + } +} + +static void +PaintRowGroupBackgroundByColIdx(nsTableRowGroupFrame* aRowGroup, + nsIFrame* aFrame, + nsDisplayListBuilder* aBuilder, + const nsDisplayListSet& aLists, + const nsTArray<int32_t>& aColIdx, + const nsPoint& aOffset) +{ + for (nsTableRowFrame* row = aRowGroup->GetFirstRow(); row; row = row->GetNextRow()) { + for (nsTableCellFrame* cell = row->GetFirstCell(); cell; cell = cell->GetNextCell()) { + int32_t curColIdx; + cell->GetColIndex(curColIdx); + if (aColIdx.Contains(curColIdx)) { + auto cellRect = cell->GetRectRelativeToSelf() + cell->GetNormalPosition() + row->GetNormalPosition() + aOffset; + nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame, cellRect, + aLists.BorderBackground(), + true, nullptr, + aFrame->GetRectRelativeToSelf()); + } + } + } +} + /* static */ void nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder, nsFrame* aFrame, const nsRect& aDirtyRect, const nsDisplayListSet& aLists, - nsDisplayTableItem* aDisplayItem, DisplayGenericTablePartTraversal aTraversal) { - nsDisplayList eventsBorderBackground; - // If we need to sort the event backgrounds, then we'll put descendants' - // display items into their own set of lists. - bool sortEventBackgrounds = aDisplayItem && aBuilder->IsForEventDelivery(); - nsDisplayListCollection separatedCollection; - const nsDisplayListSet* lists = sortEventBackgrounds ? &separatedCollection : &aLists; - - nsAutoPushCurrentTableItem pushTableItem; - if (aDisplayItem) { - pushTableItem.Push(aBuilder, aDisplayItem); - } - if (aFrame->IsVisibleForPainting(aBuilder)) { nsDisplayTableItem* currentItem = aBuilder->GetCurrentTableItem(); // currentItem may be null, when none of the table parts have a @@ -1242,72 +1287,79 @@ nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder, // Paint the outset box-shadows for the table frames bool hasBoxShadow = aFrame->StyleEffects()->mBoxShadow != nullptr; if (hasBoxShadow) { - lists->BorderBackground()->AppendNewToTop( + aLists.BorderBackground()->AppendNewToTop( new (aBuilder) nsDisplayBoxShadowOuter(aBuilder, aFrame)); } - // Create dedicated background display items per-frame when we're - // handling events. - // XXX how to handle collapsed borders? - if (aBuilder->IsForEventDelivery()) { + if (aFrame->GetType() == nsGkAtoms::tableRowGroupFrame) { + nsTableRowGroupFrame* rowGroup = static_cast<nsTableRowGroupFrame*>(aFrame); + PaintRowGroupBackground(rowGroup, aFrame, aBuilder, aLists); + } else if (aFrame->GetType() == nsGkAtoms::tableRowFrame) { + nsTableRowFrame* row = static_cast<nsTableRowFrame*>(aFrame); + PaintRowBackground(row, aFrame, aBuilder, aLists); + } else if (aFrame->GetType() == nsGkAtoms::tableColGroupFrame) { + // Compute background rect by iterating all cell frame. + nsTableColGroupFrame* colGroup = static_cast<nsTableColGroupFrame*>(aFrame); + // Collecting column index. + AutoTArray<int32_t, 1> colIdx; + for (nsTableColFrame* col = colGroup->GetFirstColumn(); col; col = col->GetNextCol()) { + colIdx.AppendElement(col->GetColIndex()); + } + + nsTableFrame* table = colGroup->GetTableFrame(); + RowGroupArray rowGroups; + table->OrderRowGroups(rowGroups); + for (nsTableRowGroupFrame* rowGroup : rowGroups) { + auto offset = rowGroup->GetNormalPosition() - colGroup->GetNormalPosition(); + PaintRowGroupBackgroundByColIdx(rowGroup, aFrame, aBuilder, aLists, colIdx, offset); + } + } else if (aFrame->GetType() == nsGkAtoms::tableColFrame) { + // Compute background rect by iterating all cell frame. + nsTableColFrame* col = static_cast<nsTableColFrame*>(aFrame); + AutoTArray<int32_t, 1> colIdx; + colIdx.AppendElement(col->GetColIndex()); + + nsTableFrame* table = col->GetTableFrame(); + RowGroupArray rowGroups; + table->OrderRowGroups(rowGroups); + for (nsTableRowGroupFrame* rowGroup : rowGroups) { + auto offset = rowGroup->GetNormalPosition() - + col->GetNormalPosition() - + col->GetTableColGroupFrame()->GetNormalPosition(); + PaintRowGroupBackgroundByColIdx(rowGroup, aFrame, aBuilder, aLists, colIdx, offset); + } + } else { nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame, aFrame->GetRectRelativeToSelf(), - lists->BorderBackground()); + aLists.BorderBackground()); } // Paint the inset box-shadows for the table frames if (hasBoxShadow) { - lists->BorderBackground()->AppendNewToTop( + aLists.BorderBackground()->AppendNewToTop( new (aBuilder) nsDisplayBoxShadowInner(aBuilder, aFrame)); } } - aTraversal(aBuilder, aFrame, aDirtyRect, *lists); + aTraversal(aBuilder, aFrame, aDirtyRect, aLists); - if (sortEventBackgrounds) { - // Ensure that the table frame event background goes before the - // table rowgroups event backgrounds, before the table row event backgrounds, - // before everything else (cells and their blocks) - separatedCollection.BorderBackground()->Sort(CompareByTablePartRank, nullptr); - separatedCollection.MoveTo(aLists); + if (aFrame->IsVisibleForPainting(aBuilder)) { + if (aFrame->GetType() == nsGkAtoms::tableFrame) { + nsTableFrame* table = static_cast<nsTableFrame*>(aFrame); + // In the collapsed border model, overlay all collapsed borders. + if (table->IsBorderCollapse()) { + aLists.BorderBackground()->AppendNewToTop( + new (aBuilder) nsDisplayTableBorderCollapse(aBuilder, table)); + } else { + aLists.BorderBackground()->AppendNewToTop( + new (aBuilder) nsDisplayBorder(aBuilder, table)); + } + } } aFrame->DisplayOutline(aBuilder, aLists); } -static bool -AnyTablePartHasBorderOrBackground(nsIFrame* aStart, nsIFrame* aEnd) -{ - for (nsIFrame* f = aStart; f != aEnd; f = f->GetNextSibling()) { - NS_ASSERTION(IsFrameAllowedInTable(f->GetType()), "unexpected frame type"); - - if (FrameHasBorderOrBackground(f)) - return true; - - nsTableCellFrame *cellFrame = do_QueryFrame(f); - if (cellFrame) - continue; - - if (AnyTablePartHasBorderOrBackground(f->PrincipalChildList().FirstChild(), nullptr)) - return true; - } - - return false; -} - -static void -UpdateItemForColGroupBackgrounds(nsDisplayTableItem* item, - const nsFrameList& aFrames) { - for (nsFrameList::Enumerator e(aFrames); !e.AtEnd(); e.Next()) { - nsTableColGroupFrame* cg = static_cast<nsTableColGroupFrame*>(e.get()); - item->UpdateForFrameBackground(cg); - for (nsTableColFrame* colFrame = cg->GetFirstColumn(); colFrame; - colFrame = colFrame->GetNextCol()) { - item->UpdateForFrameBackground(colFrame); - } - } -} - // table paint code is concerned primarily with borders and bg color // SEC: TODO: adjust the rect for captions void @@ -1317,35 +1369,7 @@ nsTableFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, { DO_GLOBAL_REFLOW_COUNT_DSP_COLOR("nsTableFrame", NS_RGB(255,128,255)); - nsDisplayTableItem* item = nullptr; - if (IsVisibleInSelection(aBuilder)) { - nsMargin deflate = GetDeflationForBackground(PresContext()); - if (StyleVisibility()->IsVisible()) { - // 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)) { - DisplayBackgroundUnconditional(aBuilder, aLists, false); - } - } - - // 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(), nullptr)) { - item = new (aBuilder) nsDisplayTableBorderBackground(aBuilder, this, - deflate != nsMargin(0, 0, 0, 0)); - aLists.BorderBackground()->AppendNewToTop(item); - } - } - DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists, item); - if (item) { - UpdateItemForColGroupBackgrounds(item, mColGroups); - } + DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists); } nsMargin diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h index c7b92d387..d4b6d88a7 100644 --- a/layout/tables/nsTableFrame.h +++ b/layout/tables/nsTableFrame.h @@ -250,7 +250,6 @@ public: nsFrame* aFrame, const nsRect& aDirtyRect, const nsDisplayListSet& aLists, - nsDisplayTableItem* aDisplayItem, DisplayGenericTablePartTraversal aTraversal = GenericTraversal); // Return the closest sibling of aPriorChildFrame (including aPriroChildFrame) diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp index 1b6051ef2..dc053c991 100644 --- a/layout/tables/nsTableRowFrame.cpp +++ b/layout/tables/nsTableRowFrame.cpp @@ -605,21 +605,7 @@ nsTableRowFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsDisplayTableItem* item = nullptr; - 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); - aLists.BorderBackground()->AppendNewToTop(item); - } - } - nsTableFrame::DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists, item); + nsTableFrame::DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists); } nsIFrame::LogicalSides diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 8f014b204..943bdf50b 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -249,19 +249,8 @@ nsTableRowGroupFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { - nsDisplayTableItem* item = nullptr; - 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); - aLists.BorderBackground()->AppendNewToTop(item); - } - } nsTableFrame::DisplayGenericTablePart(aBuilder, this, aDirtyRect, - aLists, item, DisplayRows); + aLists, DisplayRows); } nsIFrame::LogicalSides diff --git a/layout/tables/nsTableWrapperFrame.cpp b/layout/tables/nsTableWrapperFrame.cpp index f0b6d1512..da71375d5 100644 --- a/layout/tables/nsTableWrapperFrame.cpp +++ b/layout/tables/nsTableWrapperFrame.cpp @@ -190,7 +190,11 @@ nsTableWrapperFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, // Now we have to sort everything by content order, since the caption // may be somewhere inside the table - set.SortAllByContentOrder(GetContent()); + set.BlockBorderBackgrounds()->SortByContentOrder(GetContent()); + set.Floats()->SortByContentOrder(GetContent()); + set.Content()->SortByContentOrder(GetContent()); + set.PositionedDescendants()->SortByContentOrder(GetContent()); + set.Outlines()->SortByContentOrder(GetContent()); set.MoveTo(aLists); } |