mirror of
https://github.com/roytam1/basilisk55.git
synced 2026-05-29 07:17:05 +00:00
import from UXP:
- Issue #1378 - Align the drawing of table cell backgrounds with the spec. (598fe2fa) - Issue #1378 - Follow-up: make sure background items remain table-aligned. (ec8e49b6)
This commit is contained in:
@@ -449,19 +449,40 @@ PaintTableCellSelection(nsIFrame* aFrame, DrawTarget* aDrawTarget,
|
||||
aPt);
|
||||
}
|
||||
|
||||
bool
|
||||
nsTableCellFrame::ShouldPaintBordersAndBackgrounds() const
|
||||
{
|
||||
// If we're not visible, we don't paint.
|
||||
if (!StyleVisibility()->IsVisible()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Consider 'empty-cells', but only in separated borders mode.
|
||||
if (!GetContentEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsTableFrame* tableFrame = GetTableFrame();
|
||||
if (tableFrame->IsBorderCollapse()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return StyleTableBorder()->mEmptyCells == NS_STYLE_TABLE_EMPTY_CELLS_SHOW;
|
||||
}
|
||||
|
||||
bool
|
||||
nsTableCellFrame::ShouldPaintBackground(nsDisplayListBuilder* aBuilder)
|
||||
{
|
||||
return ShouldPaintBordersAndBackgrounds() && IsVisibleInSelection(aBuilder);
|
||||
}
|
||||
|
||||
void
|
||||
nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsRect& aDirtyRect,
|
||||
const nsDisplayListSet& aLists)
|
||||
{
|
||||
DO_GLOBAL_REFLOW_COUNT_DSP("nsTableCellFrame");
|
||||
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)) {
|
||||
if (ShouldPaintBordersAndBackgrounds()) {
|
||||
// display outset box-shadows if we need to.
|
||||
bool hasBoxShadow = !!StyleEffects()->mBoxShadow;
|
||||
if (hasBoxShadow) {
|
||||
@@ -486,7 +507,7 @@ nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
|
||||
// display borders if we need to
|
||||
ProcessBorders(tableFrame, aBuilder, aLists);
|
||||
ProcessBorders(GetTableFrame(), aBuilder, aLists);
|
||||
|
||||
// and display the selection border if we need to
|
||||
if (IsSelected()) {
|
||||
|
||||
@@ -209,7 +209,7 @@ public:
|
||||
/** set the desired size returned by this frame during its last reflow */
|
||||
inline void SetDesiredSize(const ReflowOutput & aDesiredSize);
|
||||
|
||||
bool GetContentEmpty();
|
||||
bool GetContentEmpty() const;
|
||||
void SetContentEmpty(bool aContentEmpty);
|
||||
|
||||
bool HasPctOverBSize();
|
||||
@@ -246,6 +246,10 @@ public:
|
||||
virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) override;
|
||||
virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) override;
|
||||
virtual void InvalidateFrameForRemoval() override { InvalidateFrameSubtree(); }
|
||||
|
||||
bool ShouldPaintBordersAndBackgrounds() const;
|
||||
|
||||
bool ShouldPaintBackground(nsDisplayListBuilder* aBuilder);
|
||||
|
||||
protected:
|
||||
virtual LogicalSides
|
||||
@@ -283,7 +287,7 @@ inline void nsTableCellFrame::SetDesiredSize(const ReflowOutput & aDesiredSize)
|
||||
mDesiredSize = aDesiredSize.Size(wm).ConvertTo(GetWritingMode(), wm);
|
||||
}
|
||||
|
||||
inline bool nsTableCellFrame::GetContentEmpty()
|
||||
inline bool nsTableCellFrame::GetContentEmpty() const
|
||||
{
|
||||
return HasAnyStateBits(NS_TABLE_CELL_CONTENT_EMPTY);
|
||||
}
|
||||
|
||||
@@ -1204,6 +1204,10 @@ PaintRowBackground(nsTableRowFrame* aRow,
|
||||
{
|
||||
// Compute background rect by iterating over all cell frames.
|
||||
for (nsTableCellFrame* cell = aRow->GetFirstCell(); cell; cell = cell->GetNextCell()) {
|
||||
if (!cell->ShouldPaintBackground(aBuilder)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto cellRect = cell->GetRectRelativeToSelf() + cell->GetNormalPosition() + aOffset;
|
||||
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame, cellRect,
|
||||
aLists.BorderBackground(),
|
||||
@@ -1234,6 +1238,10 @@ PaintRowGroupBackgroundByColIdx(nsTableRowGroupFrame* aRowGroup,
|
||||
{
|
||||
for (nsTableRowFrame* row = aRowGroup->GetFirstRow(); row; row = row->GetNextRow()) {
|
||||
for (nsTableCellFrame* cell = row->GetFirstCell(); cell; cell = cell->GetNextCell()) {
|
||||
if (!cell->ShouldPaintBackground(aBuilder)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t curColIdx;
|
||||
cell->GetColIndex(curColIdx);
|
||||
if (aColIdx.Contains(curColIdx)) {
|
||||
@@ -1255,66 +1263,83 @@ nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayListSet& aLists,
|
||||
DisplayGenericTablePartTraversal aTraversal)
|
||||
{
|
||||
if (aFrame->IsVisibleForPainting(aBuilder)) {
|
||||
bool isVisible = aFrame->IsVisibleForPainting(aBuilder);
|
||||
bool isTable = (aFrame->GetType() == nsGkAtoms::tableFrame);
|
||||
|
||||
if (isVisible || !isTable) {
|
||||
nsDisplayTableItem* currentItem = aBuilder->GetCurrentTableItem();
|
||||
// currentItem may be null, when none of the table parts have a
|
||||
// background or border
|
||||
if (currentItem) {
|
||||
currentItem->UpdateForFrameBackground(aFrame);
|
||||
}
|
||||
}
|
||||
|
||||
if (isVisible) {
|
||||
// XXX: should box-shadow for rows/rowgroups/columns/colgroups get painted
|
||||
// just because we're visible? Or should it depend on the cell visibility
|
||||
// when we're not the whole table?
|
||||
|
||||
// Paint the outset box-shadows for the table frames
|
||||
bool hasBoxShadow = aFrame->StyleEffects()->mBoxShadow != nullptr;
|
||||
if (hasBoxShadow) {
|
||||
if (aFrame->StyleEffects()->mBoxShadow) {
|
||||
aLists.BorderBackground()->AppendNewToTop(
|
||||
new (aBuilder) nsDisplayBoxShadowOuter(aBuilder, aFrame));
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
// Background visibility for rows, rowgroups, columns, colgroups depends on
|
||||
// the visibility of the _cell_, not of the row/col(group).
|
||||
// See spec at https://drafts.csswg.org/css-tables-3/#drawing-cell-backgrounds
|
||||
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 = 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(),
|
||||
aLists.BorderBackground());
|
||||
}
|
||||
|
||||
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 if (isVisible) {
|
||||
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame,
|
||||
aFrame->GetRectRelativeToSelf(),
|
||||
aLists.BorderBackground());
|
||||
}
|
||||
|
||||
if (isVisible) {
|
||||
// XXX: should box-shadow for rows/rowgroups/columns/colgroups get painted
|
||||
// just because we're visible? Or should it depend on the cell visibility
|
||||
// when we're not the whole table?
|
||||
|
||||
// Paint the inset box-shadows for the table frames
|
||||
if (hasBoxShadow) {
|
||||
if (aFrame->StyleEffects()->mBoxShadow) {
|
||||
aLists.BorderBackground()->AppendNewToTop(
|
||||
new (aBuilder) nsDisplayBoxShadowInner(aBuilder, aFrame));
|
||||
}
|
||||
@@ -1322,8 +1347,8 @@ nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
aTraversal(aBuilder, aFrame, aDirtyRect, aLists);
|
||||
|
||||
if (aFrame->IsVisibleForPainting(aBuilder)) {
|
||||
if (aFrame->GetType() == nsGkAtoms::tableFrame) {
|
||||
if (isVisible) {
|
||||
if (isTable) {
|
||||
nsTableFrame* table = static_cast<nsTableFrame*>(aFrame);
|
||||
// In the collapsed border model, overlay all collapsed borders.
|
||||
if (table->IsBorderCollapse()) {
|
||||
|
||||
Reference in New Issue
Block a user