Backed out changeset 93acd240b578 (bug 929484) for reftest failures in border-separate-opacity-table-column-group.html

This commit is contained in:
Carsten "Tomcat" Book
2017-05-04 17:00:20 +02:00
parent 4f8774de65
commit 075b27fbe3
13 changed files with 228 additions and 227 deletions

View File

@@ -59,7 +59,6 @@ DECLARE_DISPLAY_ITEM_TYPE(TABLE_CELL_SELECTION)
DECLARE_DISPLAY_ITEM_TYPE(TABLE_ROW_BACKGROUND) DECLARE_DISPLAY_ITEM_TYPE(TABLE_ROW_BACKGROUND)
DECLARE_DISPLAY_ITEM_TYPE(TABLE_ROW_GROUP_BACKGROUND) DECLARE_DISPLAY_ITEM_TYPE(TABLE_ROW_GROUP_BACKGROUND)
DECLARE_DISPLAY_ITEM_TYPE(TABLE_BORDER_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)
DECLARE_DISPLAY_ITEM_TYPE(TEXT_OVERFLOW) DECLARE_DISPLAY_ITEM_TYPE(TEXT_OVERFLOW)
DECLARE_DISPLAY_ITEM_TYPE_FLAGS(TRANSFORM,TYPE_RENDERS_NO_IMAGES) DECLARE_DISPLAY_ITEM_TYPE_FLAGS(TRANSFORM,TYPE_RENDERS_NO_IMAGES)

View File

@@ -3062,16 +3062,11 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
const nsRect& aBackgroundRect, const nsRect& aBackgroundRect,
nsDisplayList* aList, nsDisplayList* aList,
bool aAllowWillPaintBorderOptimization, bool aAllowWillPaintBorderOptimization,
nsStyleContext* aStyleContext, nsStyleContext* aStyleContext)
const nsRect& aBackgroundOriginRect)
{ {
nsStyleContext* bgSC = aStyleContext; nsStyleContext* bgSC = aStyleContext;
const nsStyleBackground* bg = nullptr; const nsStyleBackground* bg = nullptr;
nsRect bgRect = aBackgroundRect + aBuilder->ToReferenceFrame(aFrame); nsRect bgRect = aBackgroundRect + aBuilder->ToReferenceFrame(aFrame);
nsRect bgOriginRect = bgRect;
if (!aBackgroundOriginRect.IsEmpty()) {
bgOriginRect = aBackgroundOriginRect + aBuilder->ToReferenceFrame(aFrame);
}
nsPresContext* presContext = aFrame->PresContext(); nsPresContext* presContext = aFrame->PresContext();
bool isThemed = aFrame->IsThemed(); bool isThemed = aFrame->IsThemed();
if (!isThemed) { if (!isThemed) {
@@ -3180,7 +3175,7 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
nsDisplayList thisItemList; nsDisplayList thisItemList;
nsDisplayBackgroundImage::InitData bgData = nsDisplayBackgroundImage::InitData bgData =
nsDisplayBackgroundImage::GetInitData(aBuilder, aFrame, i, bgOriginRect, bg, nsDisplayBackgroundImage::GetInitData(aBuilder, aFrame, i, bgRect, bg,
LayerizeFixed::DO_NOT_LAYERIZE_FIXED_BACKGROUND_IF_AVOIDING_COMPONENT_ALPHA_LAYERS); LayerizeFixed::DO_NOT_LAYERIZE_FIXED_BACKGROUND_IF_AVOIDING_COMPONENT_ALPHA_LAYERS);
if (bgData.shouldFixToViewport) { if (bgData.shouldFixToViewport) {

View File

@@ -3071,8 +3071,7 @@ public:
const nsRect& aBackgroundRect, const nsRect& aBackgroundRect,
nsDisplayList* aList, nsDisplayList* aList,
bool aAllowWillPaintBorderOptimization = true, bool aAllowWillPaintBorderOptimization = true,
nsStyleContext* aStyleContext = nullptr, nsStyleContext* aStyleContext = nullptr);
const nsRect& aBackgroundOriginRect = nsRect());
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager, LayerManager* aManager,

View File

@@ -490,51 +490,71 @@ nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists) const nsDisplayListSet& aLists)
{ {
DO_GLOBAL_REFLOW_COUNT_DSP("nsTableCellFrame"); DO_GLOBAL_REFLOW_COUNT_DSP("nsTableCellFrame");
nsTableFrame* tableFrame = GetTableFrame(); if (IsVisibleInSelection(aBuilder)) {
int32_t emptyCellStyle = GetContentEmpty() && !tableFrame->IsBorderCollapse() ? nsTableFrame* tableFrame = GetTableFrame();
StyleTableBorder()->mEmptyCells int32_t emptyCellStyle = GetContentEmpty() && !tableFrame->IsBorderCollapse() ?
: NS_STYLE_TABLE_EMPTY_CELLS_SHOW; StyleTableBorder()->mEmptyCells
// take account of 'empty-cells' : NS_STYLE_TABLE_EMPTY_CELLS_SHOW;
if (StyleVisibility()->IsVisible() && // take account of 'empty-cells'
(NS_STYLE_TABLE_EMPTY_CELLS_HIDE != emptyCellStyle)) { if (StyleVisibility()->IsVisible() &&
// display outset box-shadows if we need to. (NS_STYLE_TABLE_EMPTY_CELLS_HIDE != emptyCellStyle)) {
bool hasBoxShadow = !!StyleEffects()->mBoxShadow; // display outset box-shadows if we need to.
if (hasBoxShadow) { bool hasBoxShadow = !!StyleEffects()->mBoxShadow;
aLists.BorderBackground()->AppendNewToTop( if (hasBoxShadow) {
new (aBuilder) nsDisplayBoxShadowOuter(aBuilder, this)); aLists.BorderBackground()->AppendNewToTop(
} new (aBuilder) nsDisplayBoxShadowOuter(aBuilder, this));
}
// display background if we need to.
if (aBuilder->IsForEventDelivery() || // display background if we need to.
!StyleBackground()->IsTransparent(this) || if (aBuilder->IsForEventDelivery() ||
StyleDisplay()->UsedAppearance()) { !StyleBackground()->IsTransparent(this) ||
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, StyleDisplay()->UsedAppearance()) {
this, if (!tableFrame->IsBorderCollapse()) {
GetRectRelativeToSelf(), nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder,
aLists.BorderBackground()); this,
} GetRectRelativeToSelf(),
aLists.BorderBackground());
// display inset box-shadows if we need to. } else if (aBuilder->IsAtRootOfPseudoStackingContext() ||
if (hasBoxShadow) { aBuilder->IsForEventDelivery()) {
aLists.BorderBackground()->AppendNewToTop( // The cell background was not painted by the nsTablePainter,
new (aBuilder) nsDisplayBoxShadowInner(aBuilder, this)); // so we need to do it. We have special background processing here
} // so we need to duplicate some code from nsFrame::DisplayBorderBackgroundOutline
nsDisplayTableItem* item =
// display borders if we need to new (aBuilder) nsDisplayTableCellBackground(aBuilder, this);
ProcessBorders(tableFrame, aBuilder, aLists); aLists.BorderBackground()->AppendNewToTop(item);
item->UpdateForFrameBackground(this);
// and display the selection border if we need to } else {
if (IsSelected()) { // The nsTablePainter will paint our background. Make sure it
aLists.BorderBackground()->AppendNewToTop(new (aBuilder) // knows if we're background-attachment:fixed.
nsDisplayGeneric(aBuilder, this, ::PaintTableCellSelection, nsDisplayTableItem* currentItem = aBuilder->GetCurrentTableItem();
"TableCellSelection", if (currentItem) {
nsDisplayItem::TYPE_TABLE_CELL_SELECTION)); 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));
}
} }
// 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 // Push a null 'current table item' so that descendant tables can't
// accidentally mess with our table // accidentally mess with our table
nsAutoPushCurrentTableItem pushTableItem; nsAutoPushCurrentTableItem pushTableItem;

View File

@@ -122,14 +122,6 @@ nsTableColFrame::Reflow(nsPresContext* aPresContext,
NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); 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() int32_t nsTableColFrame::GetSpan()
{ {
return StyleTable()->mSpan; return StyleTable()->mSpan;

View File

@@ -53,9 +53,12 @@ public:
const ReflowInput& aReflowInput, const ReflowInput& aReflowInput,
nsReflowStatus& aStatus) override; nsReflowStatus& aStatus) override;
/**
* Table columns never paint anything, nor receive events.
*/
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect, const nsRect& aDirtyRect,
const nsDisplayListSet& aLists) override; const nsDisplayListSet& aLists) override {}
#ifdef DEBUG_FRAME_DUMP #ifdef DEBUG_FRAME_DUMP
virtual nsresult GetFrameName(nsAString& aResult) const override; virtual nsresult GetFrameName(nsAString& aResult) const override;

View File

@@ -386,14 +386,6 @@ nsTableColGroupFrame::Reflow(nsPresContext* aPresContext,
NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize); 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() nsTableColFrame * nsTableColGroupFrame::GetFirstColumn()
{ {
return GetNextColumn(nullptr); return GetNextColumn(nullptr);

View File

@@ -50,9 +50,12 @@ public:
return static_cast<nsTableFrame*>(parent); return static_cast<nsTableFrame*>(parent);
} }
/**
* ColGroups never paint anything, nor receive events.
*/
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect, const nsRect& aDirtyRect,
const nsDisplayListSet& aLists) override; const nsDisplayListSet& aLists) override {}
/** A colgroup can be caused by three things: /** A colgroup can be caused by three things:
* 1) An element with table-column-group display * 1) An element with table-column-group display

View File

@@ -1238,46 +1238,6 @@ nsDisplayTableItem::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion); nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
} }
// A display item that draws all collapsed borders for a table.
// At some point, we may want to find a nicer partitioning for dividing
// border-collapse segments into their own display items.
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());
// XXX we should probably get rid of this translation at some stage
// But that would mean modifying PaintBCBorders, ugh
AutoRestoreTransform autoRestoreTransform(drawTarget);
drawTarget->SetTransform(
drawTarget->GetTransform().PreTranslate(ToPoint(devPixelOffset)));
static_cast<nsTableFrame*>(mFrame)->PaintBCBorders(*drawTarget, mVisibleRect - pt);
}
class nsDisplayTableBorderBackground : public nsDisplayTableItem { class nsDisplayTableBorderBackground : public nsDisplayTableItem {
public: public:
nsDisplayTableBorderBackground(nsDisplayListBuilder* aBuilder, nsDisplayTableBorderBackground(nsDisplayListBuilder* aBuilder,
@@ -1297,6 +1257,20 @@ public:
NS_DISPLAY_DECL_NAME("TableBorderBackground", TYPE_TABLE_BORDER_BACKGROUND) NS_DISPLAY_DECL_NAME("TableBorderBackground", TYPE_TABLE_BORDER_BACKGROUND)
}; };
#ifdef DEBUG
static bool
IsFrameAllowedInTable(LayoutFrameType aType)
{
return IS_TABLE_CELL(aType) ||
LayoutFrameType::TableRow == aType ||
LayoutFrameType::TableRowGroup == aType ||
LayoutFrameType::Scroll == aType ||
LayoutFrameType::Table == aType ||
LayoutFrameType::TableCol == aType ||
LayoutFrameType::TableColGroup == aType;
}
#endif
void void
nsDisplayTableBorderBackground::Paint(nsDisplayListBuilder* aBuilder, nsDisplayTableBorderBackground::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx) nsRenderingContext* aCtx)
@@ -1308,6 +1282,25 @@ nsDisplayTableBorderBackground::Paint(nsDisplayListBuilder* aBuilder,
nsDisplayTableItemGeometry::UpdateDrawResult(this, result); nsDisplayTableItemGeometry::UpdateDrawResult(this, result);
} }
static int32_t
GetTablePartRank(nsDisplayItem* aItem)
{
LayoutFrameType type = aItem->Frame()->Type();
if (type == LayoutFrameType::Table)
return 0;
if (type == LayoutFrameType::TableRowGroup)
return 1;
if (type == LayoutFrameType::TableRow)
return 2;
return 3;
}
struct TablePartRankComparator {
bool operator()(nsDisplayItem* aItem1, nsDisplayItem* aItem2) const {
return GetTablePartRank(aItem1) < GetTablePartRank(aItem2);
}
};
/* static */ void /* static */ void
nsTableFrame::GenericTraversal(nsDisplayListBuilder* aBuilder, nsFrame* aFrame, nsTableFrame::GenericTraversal(nsDisplayListBuilder* aBuilder, nsFrame* aFrame,
const nsRect& aDirtyRect, const nsDisplayListSet& aLists) const nsRect& aDirtyRect, const nsDisplayListSet& aLists)
@@ -1320,73 +1313,31 @@ nsTableFrame::GenericTraversal(nsDisplayListBuilder* aBuilder, nsFrame* aFrame,
// stacking context, in which case the child won't use its passed-in // stacking context, in which case the child won't use its passed-in
// BorderBackground list anyway. It does affect cell borders though; this // BorderBackground list anyway. It does affect cell borders though; this
// lets us get cell borders into the nsTableFrame's BorderBackground list. // 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()) { for (nsIFrame* kid : aFrame->PrincipalChildList()) {
aFrame->BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists); 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 /* static */ void
nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder, nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
nsFrame* aFrame, nsFrame* aFrame,
const nsRect& aDirtyRect, const nsRect& aDirtyRect,
const nsDisplayListSet& aLists, const nsDisplayListSet& aLists,
nsDisplayTableItem* aDisplayItem,
DisplayGenericTablePartTraversal aTraversal) 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)) { if (aFrame->IsVisibleForPainting(aBuilder)) {
nsDisplayTableItem* currentItem = aBuilder->GetCurrentTableItem(); nsDisplayTableItem* currentItem = aBuilder->GetCurrentTableItem();
// currentItem may be null, when none of the table parts have a // currentItem may be null, when none of the table parts have a
@@ -1398,74 +1349,34 @@ nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
// Paint the outset box-shadows for the table frames // Paint the outset box-shadows for the table frames
bool hasBoxShadow = aFrame->StyleEffects()->mBoxShadow != nullptr; bool hasBoxShadow = aFrame->StyleEffects()->mBoxShadow != nullptr;
if (hasBoxShadow) { if (hasBoxShadow) {
aLists.BorderBackground()->AppendNewToTop( lists->BorderBackground()->AppendNewToTop(
new (aBuilder) nsDisplayBoxShadowOuter(aBuilder, aFrame)); new (aBuilder) nsDisplayBoxShadowOuter(aBuilder, aFrame));
} }
if (aFrame->IsTableRowGroupFrame()) { // Create dedicated background display items per-frame when we're
nsTableRowGroupFrame* rowGroup = static_cast<nsTableRowGroupFrame*>(aFrame); // handling events.
PaintRowGroupBackground(rowGroup, aFrame, aBuilder, aLists); // XXX how to handle collapsed borders?
} else if (aFrame->IsTableRowFrame()) { if (aBuilder->IsForEventDelivery()) {
nsTableRowFrame* row = static_cast<nsTableRowFrame*>(aFrame);
PaintRowBackground(row, aFrame, aBuilder, aLists);
} else if (aFrame->IsTableColGroupFrame()) {
// 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->IsTableColFrame()) {
// 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, nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame,
aFrame->GetRectRelativeToSelf(), aFrame->GetRectRelativeToSelf(),
aLists.BorderBackground()); lists->BorderBackground());
} }
// Paint the inset box-shadows for the table frames // Paint the inset box-shadows for the table frames
if (hasBoxShadow) { if (hasBoxShadow) {
aLists.BorderBackground()->AppendNewToTop( lists->BorderBackground()->AppendNewToTop(
new (aBuilder) nsDisplayBoxShadowInner(aBuilder, aFrame)); new (aBuilder) nsDisplayBoxShadowInner(aBuilder, aFrame));
} }
} }
aTraversal(aBuilder, aFrame, aDirtyRect, aLists); aTraversal(aBuilder, aFrame, aDirtyRect, *lists);
if (aFrame->IsVisibleForPainting(aBuilder)) { if (sortEventBackgrounds) {
if (aFrame->IsTableFrame()) { // Ensure that the table frame event background goes before the
nsTableFrame* table = static_cast<nsTableFrame*>(aFrame); // table rowgroups event backgrounds, before the table row event backgrounds,
// In the collapsed border model, overlay all collapsed borders. // before everything else (cells and their blocks)
if (table->IsBorderCollapse()) { separatedCollection.BorderBackground()->Sort<nsDisplayItem*>(TablePartRankComparator());
aLists.BorderBackground()->AppendNewToTop( separatedCollection.MoveTo(aLists);
new (aBuilder) nsDisplayTableBorderCollapse(aBuilder, table));
} else {
aLists.BorderBackground()->AppendNewToTop(
new (aBuilder) nsDisplayBorder(aBuilder, table));
}
}
} }
aFrame->DisplayOutline(aBuilder, aLists); aFrame->DisplayOutline(aBuilder, aLists);
@@ -1493,6 +1404,43 @@ static inline bool FrameHasBorderOrBackground(nsTableFrame* tableFrame, nsIFrame
return false; return false;
} }
static bool
AnyTablePartHasBorderOrBackground(nsTableFrame* aTableFrame,
nsIFrame* aStart,
nsIFrame* aEnd)
{
for (nsIFrame* f = aStart; f != aEnd; f = f->GetNextSibling()) {
NS_ASSERTION(IsFrameAllowedInTable(f->Type()), "unexpected frame type");
if (FrameHasBorderOrBackground(aTableFrame, f))
return true;
nsTableCellFrame *cellFrame = do_QueryFrame(f);
if (cellFrame)
continue;
if (AnyTablePartHasBorderOrBackground(aTableFrame,
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 // table paint code is concerned primarily with borders and bg color
// SEC: TODO: adjust the rect for captions // SEC: TODO: adjust the rect for captions
void void
@@ -1502,7 +1450,35 @@ nsTableFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
{ {
DO_GLOBAL_REFLOW_COUNT_DSP_COLOR("nsTableFrame", NS_RGB(255,128,255)); DO_GLOBAL_REFLOW_COUNT_DSP_COLOR("nsTableFrame", NS_RGB(255,128,255));
DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists); 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, this, GetNextSibling()) ||
AnyTablePartHasBorderOrBackground(this, 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);
}
} }
nsMargin nsMargin

View File

@@ -245,6 +245,7 @@ public:
nsFrame* aFrame, nsFrame* aFrame,
const nsRect& aDirtyRect, const nsRect& aDirtyRect,
const nsDisplayListSet& aLists, const nsDisplayListSet& aLists,
nsDisplayTableItem* aDisplayItem,
DisplayGenericTablePartTraversal aTraversal = GenericTraversal); DisplayGenericTablePartTraversal aTraversal = GenericTraversal);
// Return the closest sibling of aPriorChildFrame (including aPriroChildFrame) // Return the closest sibling of aPriorChildFrame (including aPriroChildFrame)

View File

@@ -621,7 +621,21 @@ nsTableRowFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect, const nsRect& aDirtyRect,
const nsDisplayListSet& aLists) const nsDisplayListSet& aLists)
{ {
nsTableFrame::DisplayGenericTablePart(aBuilder, this, aDirtyRect, 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);
} }
nsIFrame::LogicalSides nsIFrame::LogicalSides

View File

@@ -293,8 +293,19 @@ nsTableRowGroupFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect, const nsRect& aDirtyRect,
const nsDisplayListSet& aLists) 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, nsTableFrame::DisplayGenericTablePart(aBuilder, this, aDirtyRect,
aLists, DisplayRows); aLists, item, DisplayRows);
} }
nsIFrame::LogicalSides nsIFrame::LogicalSides

View File

@@ -190,11 +190,7 @@ nsTableWrapperFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// Now we have to sort everything by content order, since the caption // Now we have to sort everything by content order, since the caption
// may be somewhere inside the table // may be somewhere inside the table
set.BlockBorderBackgrounds()->SortByContentOrder(GetContent()); set.SortAllByContentOrder(GetContent());
set.Floats()->SortByContentOrder(GetContent());
set.Content()->SortByContentOrder(GetContent());
set.PositionedDescendants()->SortByContentOrder(GetContent());
set.Outlines()->SortByContentOrder(GetContent());
set.MoveTo(aLists); set.MoveTo(aLists);
} }