summaryrefslogtreecommitdiffstats
path: root/layout
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@wolfbeast.com>2019-11-04 08:41:04 +0100
committerwolfbeast <mcwerewolf@wolfbeast.com>2019-11-04 08:41:48 +0100
commitbbc2206a0fda053a6f5071b457bd209dab9ed268 (patch)
tree8dae72f2c725e512dfcfca5ba4f4062dd98d1cdd /layout
parent22b410f31b0fc61a0a99522fe2aea1a31823bd99 (diff)
parentee8c5d3878456b4e194dc3724616d194907ed466 (diff)
downloadUXP-bbc2206a0fda053a6f5071b457bd209dab9ed268.tar
UXP-bbc2206a0fda053a6f5071b457bd209dab9ed268.tar.gz
UXP-bbc2206a0fda053a6f5071b457bd209dab9ed268.tar.lz
UXP-bbc2206a0fda053a6f5071b457bd209dab9ed268.tar.xz
UXP-bbc2206a0fda053a6f5071b457bd209dab9ed268.zip
Merge branch 'table-sticky-work'
This resolves #146.
Diffstat (limited to 'layout')
-rw-r--r--layout/base/RestyleManagerBase.cpp9
-rw-r--r--layout/base/nsDisplayItemTypesList.h4
-rw-r--r--layout/base/nsDisplayList.cpp113
-rw-r--r--layout/base/nsDisplayList.h83
-rw-r--r--layout/generic/StickyScrollContainer.cpp10
-rw-r--r--layout/generic/nsFrame.cpp8
-rw-r--r--layout/reftests/position-sticky/inner-table-1-ref.html26
-rw-r--r--layout/reftests/position-sticky/inner-table-1.html35
-rw-r--r--layout/reftests/position-sticky/reftest.list1
-rw-r--r--layout/reftests/table-background/reftest.list6
-rw-r--r--layout/reftests/table-bordercollapse/bc_borderradius-ref.html17
-rw-r--r--layout/reftests/table-bordercollapse/bc_borderradius.html18
-rw-r--r--layout/reftests/table-bordercollapse/reftest.list4
-rw-r--r--layout/tables/moz.build1
-rw-r--r--layout/tables/nsTableCellFrame.cpp117
-rw-r--r--layout/tables/nsTableCellFrame.h5
-rw-r--r--layout/tables/nsTableColFrame.cpp8
-rw-r--r--layout/tables/nsTableColFrame.h5
-rw-r--r--layout/tables/nsTableColGroupFrame.cpp8
-rw-r--r--layout/tables/nsTableColGroupFrame.h5
-rw-r--r--layout/tables/nsTableFrame.cpp322
-rw-r--r--layout/tables/nsTableFrame.h11
-rw-r--r--layout/tables/nsTablePainter.cpp696
-rw-r--r--layout/tables/nsTablePainter.h268
-rw-r--r--layout/tables/nsTableRowFrame.cpp66
-rw-r--r--layout/tables/nsTableRowFrame.h1
-rw-r--r--layout/tables/nsTableRowGroupFrame.cpp53
-rw-r--r--layout/tables/nsTableRowGroupFrame.h1
-rw-r--r--layout/tables/nsTableWrapperFrame.cpp6
29 files changed, 443 insertions, 1464 deletions
diff --git a/layout/base/RestyleManagerBase.cpp b/layout/base/RestyleManagerBase.cpp
index 6770f9464..6ef048a19 100644
--- a/layout/base/RestyleManagerBase.cpp
+++ b/layout/base/RestyleManagerBase.cpp
@@ -474,15 +474,6 @@ RecomputePosition(nsIFrame* aFrame)
if (display->IsRelativelyPositionedStyle()) {
// Move the frame
if (display->mPosition == NS_STYLE_POSITION_STICKY) {
- if (display->IsInnerTableStyle()) {
- // We don't currently support sticky positioning of inner table
- // elements (bug 975644). Bail.
- //
- // When this is fixed, remove the null-check for the computed
- // offsets in nsTableRowFrame::ReflowChildren.
- return true;
- }
-
// Update sticky positioning for an entire element at once, starting with
// the first continuation or ib-split sibling.
// It's rare that the frame we already have isn't already the first
diff --git a/layout/base/nsDisplayItemTypesList.h b/layout/base/nsDisplayItemTypesList.h
index 9865395a7..cf809817f 100644
--- a/layout/base/nsDisplayItemTypesList.h
+++ b/layout/base/nsDisplayItemTypesList.h
@@ -56,9 +56,7 @@ DECLARE_DISPLAY_ITEM_TYPE(SVG_PATH_GEOMETRY)
DECLARE_DISPLAY_ITEM_TYPE(SVG_TEXT)
DECLARE_DISPLAY_ITEM_TYPE(TABLE_CELL_BACKGROUND)
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..1579e6970 100644
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -80,6 +80,8 @@
#include "nsPluginFrame.h"
#include "DisplayItemScrollClip.h"
#include "nsSVGMaskFrame.h"
+#include "nsTableCellFrame.h"
+#include "nsTableColFrame.h"
// GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
// GetTickCount().
@@ -2631,11 +2633,17 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
const nsRect& aBackgroundRect,
nsDisplayList* aList,
bool aAllowWillPaintBorderOptimization,
- nsStyleContext* aStyleContext)
+ nsStyleContext* aStyleContext,
+ const nsRect& aBackgroundOriginRect,
+ nsIFrame* aSecondaryReferenceFrame)
{
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) {
@@ -2743,12 +2751,31 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
}
nsDisplayList thisItemList;
- nsDisplayBackgroundImage* bgItem =
- new (aBuilder) nsDisplayBackgroundImage(aBuilder, aFrame, i, bgRect, bg);
-
+ nsDisplayBackgroundImage* bgItem;
+ if (aSecondaryReferenceFrame) {
+ bgItem =
+ new (aBuilder) nsDisplayTableBackgroundImage(aBuilder,
+ aFrame,
+ i,
+ bgOriginRect,
+ bg,
+ aSecondaryReferenceFrame);
+ } else {
+ bgItem =
+ new (aBuilder) nsDisplayBackgroundImage(aBuilder, aFrame, i, bgOriginRect, bg);
+ }
if (bgItem->ShouldFixToViewport(aBuilder)) {
- thisItemList.AppendNewToTop(
- nsDisplayFixedPosition::CreateForFixedBackground(aBuilder, aFrame, bgItem, i));
+ if (aSecondaryReferenceFrame) {
+ thisItemList.AppendNewToTop(
+ nsDisplayTableFixedPosition::CreateForFixedBackground(aBuilder,
+ aSecondaryReferenceFrame,
+ bgItem,
+ i,
+ aFrame));
+ } else {
+ thisItemList.AppendNewToTop(
+ nsDisplayFixedPosition::CreateForFixedBackground(aBuilder, aFrame, bgItem, i));
+ }
} else {
thisItemList.AppendNewToTop(bgItem);
}
@@ -2889,7 +2916,7 @@ nsDisplayBackgroundImage::ImageLayerization
nsDisplayBackgroundImage::ShouldCreateOwnLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager)
{
- nsIFrame* backgroundStyleFrame = nsCSSRendering::FindBackgroundStyleFrame(mFrame);
+ nsIFrame* backgroundStyleFrame = nsCSSRendering::FindBackgroundStyleFrame(StyleFrame());
if (ActiveLayerTracker::IsBackgroundPositionAnimated(aBuilder,
backgroundStyleFrame)) {
return WHENEVER_POSSIBLE;
@@ -3144,16 +3171,16 @@ nsDisplayBackgroundImage::PaintInternal(nsDisplayListBuilder* aBuilder,
StyleGeometryBox clip = mBackgroundStyle->mImage.mLayers[mLayer].mClip;
if (clip == StyleGeometryBox::Text) {
- if (!GenerateAndPushTextMask(mFrame, aCtx, mBackgroundRect, aBuilder)) {
+ if (!GenerateAndPushTextMask(StyleFrame(), aCtx, mBackgroundRect, aBuilder)) {
return;
}
}
nsCSSRendering::PaintBGParams params =
- nsCSSRendering::PaintBGParams::ForSingleLayer(*mFrame->PresContext(),
+ nsCSSRendering::PaintBGParams::ForSingleLayer(*StyleFrame()->PresContext(),
*aCtx,
aBounds, mBackgroundRect,
- mFrame, flags, mLayer,
+ StyleFrame(), flags, mLayer,
CompositionOp::OP_OVER);
params.bgClipRect = aClipRect;
image::DrawResult result =
@@ -3255,6 +3282,27 @@ nsDisplayBackgroundImage::GetPerFrameKey()
nsDisplayItem::GetPerFrameKey();
}
+nsDisplayTableBackgroundImage::nsDisplayTableBackgroundImage(nsDisplayListBuilder* aBuilder,
+ nsIFrame* aFrame,
+ uint32_t aLayer,
+ const nsRect& aBackgroundRect,
+ const nsStyleBackground* aBackgroundStyle,
+ nsIFrame* aCellFrame)
+ : nsDisplayBackgroundImage(aBuilder, aFrame, aLayer, aBackgroundRect, aBackgroundStyle)
+ , mStyleFrame(aFrame)
+ , mTableType(GetTableTypeFromFrame(mStyleFrame))
+{
+ mFrame = aCellFrame;
+}
+
+bool
+nsDisplayTableBackgroundImage::IsInvalid(nsRect& aRect)
+{
+ bool result = mStyleFrame ? mStyleFrame->IsInvalid(aRect) : false;
+ aRect += ToReferenceFrame();
+ return result;
+}
+
nsDisplayThemedBackground::nsDisplayThemedBackground(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
const nsRect& aBackgroundRect)
@@ -5272,6 +5320,51 @@ bool nsDisplayFixedPosition::TryMerge(nsDisplayItem* aItem) {
return true;
}
+TableType
+GetTableTypeFromFrame(nsIFrame* aFrame)
+{
+ nsIAtom* type = aFrame->GetType();
+ if (type == nsGkAtoms::tableFrame) {
+ return TableType::TABLE;
+ } else if (type == nsGkAtoms::tableColFrame) {
+ return TableType::TABLE_COL;
+ } else if (type == nsGkAtoms::tableColGroupFrame) {
+ return TableType::TABLE_COL_GROUP;
+ } else if (type == nsGkAtoms::tableRowFrame) {
+ return TableType::TABLE_ROW;
+ } else if (type == nsGkAtoms::tableRowGroupFrame) {
+ return TableType::TABLE_ROW_GROUP;
+ } else if (type == nsGkAtoms::tableCellFrame) {
+ return TableType::TABLE_CELL;
+ } else {
+ MOZ_ASSERT_UNREACHABLE("Invalid frame.");
+ return TableType::TABLE;
+ }
+}
+
+nsDisplayTableFixedPosition::nsDisplayTableFixedPosition(nsDisplayListBuilder* aBuilder,
+ nsIFrame* aFrame,
+ nsDisplayList* aList,
+ uint32_t aIndex,
+ nsIFrame* aAncestorFrame)
+ : nsDisplayFixedPosition(aBuilder, aFrame, aList, aIndex)
+ , mTableType(GetTableTypeFromFrame(aAncestorFrame))
+{
+}
+
+/* static */ nsDisplayTableFixedPosition*
+nsDisplayTableFixedPosition::CreateForFixedBackground(nsDisplayListBuilder* aBuilder,
+ nsIFrame* aFrame,
+ nsDisplayBackgroundImage* aImage,
+ uint32_t aIndex,
+ nsIFrame* aAncestorFrame)
+{
+ nsDisplayList temp;
+ temp.AppendToTop(aImage);
+
+ return new (aBuilder) nsDisplayTableFixedPosition(aBuilder, aFrame, &temp, aIndex + 1, aAncestorFrame);
+}
+
nsDisplayStickyPosition::nsDisplayStickyPosition(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
nsDisplayList* aList)
diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h
index c81d34fac..e9047b113 100644
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -2737,7 +2737,9 @@ public:
const nsRect& aBackgroundRect,
nsDisplayList* aList,
bool aAllowWillPaintBorderOptimization = true,
- nsStyleContext* aStyleContext = nullptr);
+ nsStyleContext* aStyleContext = nullptr,
+ const nsRect& aBackgroundOriginRect = nsRect(),
+ nsIFrame* aSecondaryReferenceFrame = nullptr);
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
@@ -2812,6 +2814,8 @@ protected:
void PaintInternal(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
const nsRect& aBounds, nsRect* aClipRect);
+ virtual nsIFrame* StyleFrame() { return mFrame; }
+
// Determine whether we want to be separated into our own layer, independent
// of whether this item can actually be layerized.
enum ImageLayerization {
@@ -2837,6 +2841,60 @@ protected:
bool mShouldTreatAsFixed;
};
+enum class TableType : uint8_t {
+ TABLE,
+ TABLE_COL,
+ TABLE_COL_GROUP,
+ TABLE_ROW,
+ TABLE_ROW_GROUP,
+ TABLE_CELL,
+
+ TABLE_TYPE_MAX
+};
+
+enum class TableTypeBits : uint8_t {
+ COUNT = 3
+};
+
+static_assert(
+ static_cast<uint8_t>(TableType::TABLE_TYPE_MAX) < (1 << (static_cast<uint8_t>(TableTypeBits::COUNT) + 1)),
+ "TableType cannot fit with TableTypeBits::COUNT");
+TableType GetTableTypeFromFrame(nsIFrame* aFrame);
+
+/**
+ * A display item to paint background image for table. For table parts, such
+ * as row, row group, col, col group, when drawing its background, we'll
+ * create separate background image display item for its containning cell.
+ * Those background image display items will reference to same DisplayItemData
+ * if we keep the mFrame point to cell's ancestor frame. We don't want to this
+ * happened bacause share same DisplatItemData will cause many bugs. So that
+ * we let mFrame point to cell frame and store the table type of the ancestor
+ * frame. And use mFrame and table type as key to generate DisplayItemData to
+ * avoid sharing DisplayItemData.
+ *
+ * Also store ancestor frame as mStyleFrame for all rendering informations.
+ */
+class nsDisplayTableBackgroundImage : public nsDisplayBackgroundImage {
+public:
+ nsDisplayTableBackgroundImage(nsDisplayListBuilder* aBuilder,
+ nsIFrame* aFrame,
+ uint32_t aLayer,
+ const nsRect& aBackgroundRect,
+ const nsStyleBackground* aBackgroundStyle,
+ nsIFrame* aCellFrame);
+
+ virtual uint32_t GetPerFrameKey() override {
+ return (static_cast<uint8_t>(mTableType) << nsDisplayItem::TYPE_BITS) |
+ nsDisplayItem::GetPerFrameKey();
+ }
+
+ virtual bool IsInvalid(nsRect& aRect) override;
+protected:
+ virtual nsIFrame* StyleFrame() override { return mStyleFrame; }
+
+ nsIFrame* mStyleFrame;
+ TableType mTableType;
+};
/**
* A display item to paint the native theme background for a frame.
@@ -3735,7 +3793,7 @@ public:
return mAnimatedGeometryRootForScrollMetadata;
}
-private:
+protected:
// For background-attachment:fixed
nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList, uint32_t aIndex);
@@ -3746,6 +3804,27 @@ private:
bool mIsFixedBackground;
};
+class nsDisplayTableFixedPosition : public nsDisplayFixedPosition
+{
+public:
+ static nsDisplayTableFixedPosition* CreateForFixedBackground(nsDisplayListBuilder* aBuilder,
+ nsIFrame* aFrame,
+ nsDisplayBackgroundImage* aImage,
+ uint32_t aIndex,
+ nsIFrame* aAncestorFrame);
+
+ virtual uint32_t GetPerFrameKey() override {
+ return (mIndex << (nsDisplayItem::TYPE_BITS + static_cast<uint8_t>(TableTypeBits::COUNT))) |
+ (static_cast<uint8_t>(mTableType) << nsDisplayItem::TYPE_BITS) |
+ nsDisplayItem::GetPerFrameKey();
+ }
+protected:
+ nsDisplayTableFixedPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
+ nsDisplayList* aList, uint32_t aIndex, nsIFrame* aAncestorFrame);
+
+ TableType mTableType;
+};
+
/**
* This creates an empty scrollable layer. It has no child layers.
* It is used to record the existence of a scrollable frame in the layer
diff --git a/layout/generic/StickyScrollContainer.cpp b/layout/generic/StickyScrollContainer.cpp
index ca68992c3..c5ed44e92 100644
--- a/layout/generic/StickyScrollContainer.cpp
+++ b/layout/generic/StickyScrollContainer.cpp
@@ -45,7 +45,7 @@ StickyScrollContainer::GetStickyScrollContainerForFrame(nsIFrame* aFrame)
// <html style="position: fixed">
return nullptr;
}
- auto frame = static_cast<nsIFrame*>(do_QueryFrame(scrollFrame));
+ nsIFrame* frame = do_QueryFrame(scrollFrame);
StickyScrollContainer* s =
frame->GetProperty(StickyScrollContainerProperty());
if (!s) {
@@ -176,6 +176,14 @@ StickyScrollContainer::ComputeStickyLimits(nsIFrame* aFrame, nsRect* aStick,
nsRect rect =
nsLayoutUtils::GetAllInFlowRectsUnion(aFrame, aFrame->GetParent());
+ // Note: Table row groups aren't supposed to be containing blocks, but we treat
+ // them as such anyway.
+ // Not having this basically disables position:sticky on table cells, which
+ // would be really unfortunate, and doesn't match what other browsers do.
+ if (cbFrame != scrolledFrame && cbFrame->GetType() == nsGkAtoms::tableRowGroupFrame) {
+ cbFrame = cbFrame->GetContainingBlock();
+ }
+
// Containing block limits for the position of aFrame relative to its parent.
// The margin box of the sticky element stays within the content box of the
// contaning-block element.
diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp
index a531dea07..bbbb5c332 100644
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -562,15 +562,12 @@ nsFrame::Init(nsIContent* aContent,
}
if (disp->mPosition == NS_STYLE_POSITION_STICKY &&
!aPrevInFlow &&
- !(mState & NS_FRAME_IS_NONDISPLAY) &&
- !disp->IsInnerTableStyle()) {
+ !(mState & NS_FRAME_IS_NONDISPLAY)) {
// Note that we only add first continuations, but we really only
// want to add first continuation-or-ib-split-siblings. But since we
// don't yet know if we're a later part of a block-in-inline split,
// we'll just add later members of a block-in-inline split here, and
// then StickyScrollContainer will remove them later.
- // We don't currently support relative positioning of inner table
- // elements (bug 35168), so exclude them from sticky positioning too.
StickyScrollContainer* ssc =
StickyScrollContainer::GetStickyScrollContainerForFrame(this);
if (ssc) {
@@ -6629,6 +6626,9 @@ GetNearestBlockContainer(nsIFrame* frame)
// Since the parent of such a block is either a normal block or
// another such pseudo, this shouldn't cause anything bad to happen.
// Also the anonymous blocks inside table cells are not containing blocks.
+ //
+ // If we ever start skipping table row groups from being containing blocks,
+ // we need to remove the containing block assignment in StickyScrollContainer .
while (frame->IsFrameOfType(nsIFrame::eLineParticipant) ||
frame->IsBlockWrapper() ||
// Table rows are not containing blocks either
diff --git a/layout/reftests/position-sticky/inner-table-1-ref.html b/layout/reftests/position-sticky/inner-table-1-ref.html
deleted file mode 100644
index 379841fae..000000000
--- a/layout/reftests/position-sticky/inner-table-1-ref.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html>
-<!-- Any copyright is dedicated to the Public Domain.
- - http://creativecommons.org/publicdomain/zero/1.0/ -->
-<html>
- <head>
- <link rel="author" title="Corey Ford" href="mailto:corey@coreyford.name">
- </head>
- <body>
- <table>
- <thead>
- <tr>
- <td>a</td>
- </tr>
- </thead>
- <tr>
- <td>b</td>
- </tr>
- <tr>
- <td>c</td>
- </tr>
- <tr>
- <td>d</td>
- </tr>
- </table>
- </body>
-</html>
diff --git a/layout/reftests/position-sticky/inner-table-1.html b/layout/reftests/position-sticky/inner-table-1.html
deleted file mode 100644
index 212e658fd..000000000
--- a/layout/reftests/position-sticky/inner-table-1.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE html>
-<!-- Any copyright is dedicated to the Public Domain.
- - http://creativecommons.org/publicdomain/zero/1.0/ -->
-<html>
- <head>
- <title>CSS Test: Sticky Positioning - inner table elements</title>
- <link rel="author" title="Corey Ford" href="mailto:corey@coreyford.name">
- <link rel="match" href="inner-table-1-ref.html">
- <meta name="assert" content="Sticky positioning on inner table elements should have no effect (until bug 35168 is fixed)">
- <style>
- .sticky {
- position: sticky;
- top: 1000px;
- }
- </style>
- </head>
- <body>
- <table>
- <thead class="sticky">
- <tr>
- <td>a</td>
- </tr>
- </thead>
- <tr class="sticky">
- <td>b</td>
- </tr>
- <tr>
- <td class="sticky">c</td>
- </tr>
- <tr>
- <td>d</td>
- </tr>
- </table>
- </body>
-</html>
diff --git a/layout/reftests/position-sticky/reftest.list b/layout/reftests/position-sticky/reftest.list
index 2705d08fd..01e7b1638 100644
--- a/layout/reftests/position-sticky/reftest.list
+++ b/layout/reftests/position-sticky/reftest.list
@@ -48,4 +48,3 @@ fails == column-contain-1a.html column-contain-1-ref.html
fuzzy-if(skiaContent,1,22) fuzzy-if(winWidget&&!layersGPUAccelerated,116,1320) fuzzy-if(Android,8,1533) == block-in-inline-2.html block-in-inline-2-ref.html
fuzzy-if(Android,8,630) fuzzy-if(OSX>=1008,1,11) fuzzy-if(skiaContent,1,220) fuzzy-if(winWidget&&!layersGPUAccelerated,116,1320) == block-in-inline-3.html block-in-inline-3-ref.html
== block-in-inline-continuations.html block-in-inline-continuations-ref.html
-fuzzy-if(winWidget&&!layersGPUAccelerated,140,140) == inner-table-1.html inner-table-1-ref.html
diff --git a/layout/reftests/table-background/reftest.list b/layout/reftests/table-background/reftest.list
index eb2817ca0..68dc43e95 100644
--- a/layout/reftests/table-background/reftest.list
+++ b/layout/reftests/table-background/reftest.list
@@ -44,11 +44,11 @@ fuzzy-if(d2d,1,1083) fuzzy-if(skiaContent,1,2200) == border-collapse-opacity-tab
fails == border-collapse-opacity-table-column-group.html border-collapse-opacity-table-column-group-ref.html # bug 424274
fails == border-collapse-opacity-table-column.html border-collapse-opacity-table-column-ref.html # bug 424274
fuzzy-if(d2d,1,16359) fuzzy-if(skiaContent,1,17000) == border-collapse-opacity-table-row-group.html border-collapse-opacity-table-row-group-ref.html
-fuzzy-if(d2d,1,5453) fuzzy-if(skiaContent,1,11000) == border-collapse-opacity-table-row.html border-collapse-opacity-table-row-ref.html
+fuzzy-if(d2d,1,11000) fuzzy-if(skiaContent,1,11000) == border-collapse-opacity-table-row.html border-collapse-opacity-table-row-ref.html
fuzzy-if(d2d||skiaContent,1,60000) == border-collapse-opacity-table.html border-collapse-opacity-table-ref.html
fuzzy-if(d2d,1,2478) fuzzy-if(skiaContent,1,2500) == border-separate-opacity-table-cell.html border-separate-opacity-table-cell-ref.html
-fails == border-separate-opacity-table-column-group.html border-separate-opacity-table-column-group-ref.html # bug 424274
-fails == border-separate-opacity-table-column.html border-separate-opacity-table-column-ref.html # bug 424274
+fuzzy-if(d2d,1,38000) == border-separate-opacity-table-column-group.html border-separate-opacity-table-column-group-ref.html # bug 424274
+fuzzy-if(d2d,1,13000) == border-separate-opacity-table-column.html border-separate-opacity-table-column-ref.html # bug 424274
fuzzy-if(d2d,1,37170) fuzzy-if(skiaContent,1,38000) == border-separate-opacity-table-row-group.html border-separate-opacity-table-row-group-ref.html
fuzzy-if(d2d,1,12390) fuzzy-if(skiaContent,1,13000) == border-separate-opacity-table-row.html border-separate-opacity-table-row-ref.html
fuzzy-if(d2d||skiaContent,1,95000) == border-separate-opacity-table.html border-separate-opacity-table-ref.html
diff --git a/layout/reftests/table-bordercollapse/bc_borderradius-ref.html b/layout/reftests/table-bordercollapse/bc_borderradius-ref.html
new file mode 100644
index 000000000..c7b041f79
--- /dev/null
+++ b/layout/reftests/table-bordercollapse/bc_borderradius-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<style>
+ table {
+ border-collapse: collapse;
+ }
+ td {
+ background-color: rgb(0, 255, 0);
+ margin-bottom: 10px;
+ height: 100px;
+ width:100px;
+ }
+</style>
+<table>
+ <tr>
+ <td></td>
+ </tr>
+</table>
diff --git a/layout/reftests/table-bordercollapse/bc_borderradius.html b/layout/reftests/table-bordercollapse/bc_borderradius.html
new file mode 100644
index 000000000..3ae2a89d8
--- /dev/null
+++ b/layout/reftests/table-bordercollapse/bc_borderradius.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<style>
+ table {
+ border-collapse: collapse;
+ }
+ td {
+ background-color: rgb(0, 255, 0);
+ margin-bottom: 10px;
+ height: 100px;
+ width:100px;
+ border-radius: 50px;
+ }
+</style>
+<table>
+ <tr>
+ <td></td>
+ </tr>
+</table>
diff --git a/layout/reftests/table-bordercollapse/reftest.list b/layout/reftests/table-bordercollapse/reftest.list
index 8356dc54b..5ca6f305a 100644
--- a/layout/reftests/table-bordercollapse/reftest.list
+++ b/layout/reftests/table-bordercollapse/reftest.list
@@ -20,6 +20,7 @@
== bc_dyn_table3.html bc_dyn_table3_ref.html
== bc_borderoffset1.html bc_borderoffset1_ref.html
== bc_borderoffset2.html bc_borderoffset2_ref.html
+== bc_borderradius.html bc_borderradius-ref.html
== frame_above_rules_all.html frame_above_rules_all_ref.html
== frame_above_rules_cols.html frame_above_rules_cols_ref.html
== frame_above_rules_groups.html frame_above_rules_groups_ref.html
@@ -104,4 +105,5 @@ fuzzy(255,40) == border-style-outset-becomes-groove.html border-style-outset-bec
# So get 40 pixels of fuzz, 20 at each beveled corner (because the border width
# is 20px).
fuzzy(255,40) == border-style-inset-becomes-ridge.html border-style-inset-becomes-ridge-ref.html
-fuzzy(2,8301) == 1324524.html 1324524-ref.html
+fuzzy(2,11000) == 1324524.html 1324524-ref.html
+
diff --git a/layout/tables/moz.build b/layout/tables/moz.build
index b77776320..e28e21ee0 100644
--- a/layout/tables/moz.build
+++ b/layout/tables/moz.build
@@ -21,7 +21,6 @@ UNIFIED_SOURCES += [
'nsTableColFrame.cpp',
'nsTableColGroupFrame.cpp',
'nsTableFrame.cpp',
- 'nsTablePainter.cpp',
'nsTableRowFrame.cpp',
'nsTableRowGroupFrame.cpp',
'nsTableWrapperFrame.cpp',
diff --git a/layout/tables/nsTableCellFrame.cpp b/layout/tables/nsTableCellFrame.cpp
index dea82ea59..ec9458f76 100644
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -12,7 +12,6 @@
#include "nsTableColFrame.h"
#include "nsTableRowFrame.h"
#include "nsTableRowGroupFrame.h"
-#include "nsTablePainter.h"
#include "nsStyleContext.h"
#include "nsStyleConsts.h"
#include "nsPresContext.h"
@@ -380,19 +379,6 @@ nsTableCellFrame::PaintBackground(nsRenderingContext& aRenderingContext,
return nsCSSRendering::PaintBackground(params);
}
-// Called by nsTablePainter
-DrawResult
-nsTableCellFrame::PaintCellBackground(nsRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect, nsPoint aPt,
- uint32_t aFlags)
-{
- if (!StyleVisibility()->IsVisible()) {
- return DrawResult::SUCCESS;
- }
-
- return PaintBackground(aRenderingContext, aDirtyRect, aPt, aFlags);
-}
-
nsresult
nsTableCellFrame::ProcessBorders(nsTableFrame* aFrame,
nsDisplayListBuilder* aBuilder,
@@ -484,70 +470,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/nsTableCellFrame.h b/layout/tables/nsTableCellFrame.h
index 240809850..5f87c5f6d 100644
--- a/layout/tables/nsTableCellFrame.h
+++ b/layout/tables/nsTableCellFrame.h
@@ -107,11 +107,6 @@ public:
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists) override;
- DrawResult PaintCellBackground(nsRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect, nsPoint aPt,
- uint32_t aFlags);
-
-
virtual nsresult ProcessBorders(nsTableFrame* aFrame,
nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists);
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..890d050fd 100644
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -23,7 +23,6 @@
#include "nsTableRowFrame.h"
#include "nsTableRowGroupFrame.h"
#include "nsTableWrapperFrame.h"
-#include "nsTablePainter.h"
#include "BasicTableLayoutStrategy.h"
#include "FixedTableLayoutStrategy.h"
@@ -1131,67 +1130,40 @@ nsDisplayTableItem::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
}
-class nsDisplayTableBorderBackground : public nsDisplayTableItem {
+// A display item that draws all collapsed borders for a table.
+class nsDisplayTableBorderCollapse : public nsDisplayTableItem {
public:
- nsDisplayTableBorderBackground(nsDisplayListBuilder* aBuilder,
- nsTableFrame* aFrame,
- bool aDrawsBackground) :
- nsDisplayTableItem(aBuilder, aFrame, aDrawsBackground) {
- MOZ_COUNT_CTOR(nsDisplayTableBorderBackground);
- }
+ nsDisplayTableBorderCollapse(nsDisplayListBuilder* aBuilder,
+ nsTableFrame* aFrame)
+ : nsDisplayTableItem(aBuilder, aFrame) {
+ MOZ_COUNT_CTOR(nsDisplayTableBorderCollapse);
+ }
#ifdef NS_BUILD_REFCNT_LOGGING
- virtual ~nsDisplayTableBorderBackground() {
- MOZ_COUNT_DTOR(nsDisplayTableBorderBackground);
+ virtual ~nsDisplayTableBorderCollapse() {
+ MOZ_COUNT_DTOR(nsDisplayTableBorderCollapse);
}
#endif
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx) override;
- NS_DISPLAY_DECL_NAME("TableBorderBackground", TYPE_TABLE_BORDER_BACKGROUND)
+ NS_DISPLAY_DECL_NAME("TableBorderCollapse", TYPE_TABLE_BORDER_COLLAPSE)
};
-#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)
+nsDisplayTableBorderCollapse::Paint(nsDisplayListBuilder* aBuilder,
+ nsRenderingContext* aCtx)
{
- DrawResult result = static_cast<nsTableFrame*>(mFrame)->
- PaintTableBorderBackground(aBuilder, *aCtx, mVisibleRect,
- ToReferenceFrame());
+ nsPoint pt = ToReferenceFrame();
+ DrawTarget* drawTarget = aCtx->GetDrawTarget();
- nsDisplayTableItemGeometry::UpdateDrawResult(this, result);
-}
+ gfxPoint devPixelOffset =
+ nsLayoutUtils::PointToGfxPoint(pt, mFrame->PresContext()->AppUnitsPerDevPixel());
-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;
-}
+ AutoRestoreTransform autoRestoreTransform(drawTarget);
+ drawTarget->SetTransform(
+ drawTarget->GetTransform().PreTranslate(ToPoint(devPixelOffset)));
-static bool CompareByTablePartRank(nsDisplayItem* aItem1, nsDisplayItem* aItem2,
- void* aClosure)
-{
- return GetTablePartRank(aItem1) <= GetTablePartRank(aItem2);
+ static_cast<nsTableFrame*>(mFrame)->PaintBCBorders(*drawTarget, mVisibleRect - pt);
}
/* static */ void
@@ -1206,31 +1178,75 @@ 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 over all cell frames.
+ 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(),
+ cell);
+ }
+}
+
+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(),
+ cell);
+ }
+ }
+ }
+}
+
/* 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 +1258,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 +1340,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
@@ -1359,59 +1354,6 @@ nsTableFrame::GetDeflationForBackground(nsPresContext* aPresContext) const
return GetOuterBCBorder(wm).GetPhysicalMargin(wm);
}
-// XXX We don't put the borders and backgrounds in tree order like we should.
-// That requires some major surgery which we aren't going to do right now.
-DrawResult
-nsTableFrame::PaintTableBorderBackground(nsDisplayListBuilder* aBuilder,
- nsRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- nsPoint aPt)
-{
- nsPresContext* presContext = PresContext();
-
- uint32_t bgFlags = aBuilder->GetBackgroundPaintFlags();
- PaintBorderFlags borderFlags = aBuilder->ShouldSyncDecodeImages()
- ? PaintBorderFlags::SYNC_DECODE_IMAGES
- : PaintBorderFlags();
-
- TableBackgroundPainter painter(this, TableBackgroundPainter::eOrigin_Table,
- presContext, aRenderingContext,
- aDirtyRect, aPt, bgFlags);
- nsMargin deflate = GetDeflationForBackground(presContext);
- // If 'deflate' is (0,0,0,0) then we'll paint the table background
- // in a separate display item, so don't do it here.
- DrawResult result =
- painter.PaintTable(this, deflate, deflate != nsMargin(0, 0, 0, 0));
-
- if (StyleVisibility()->IsVisible()) {
- if (!IsBorderCollapse()) {
- Sides skipSides = GetSkipSides();
- nsRect rect(aPt, mRect.Size());
-
- result &=
- nsCSSRendering::PaintBorder(presContext, aRenderingContext, this,
- aDirtyRect, rect, mStyleContext,
- borderFlags, skipSides);
- } else {
- DrawTarget* drawTarget = aRenderingContext.GetDrawTarget();
-
- gfxPoint devPixelOffset =
- nsLayoutUtils::PointToGfxPoint(aPt,
- 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)));
-
- PaintBCBorders(*drawTarget, aDirtyRect - aPt);
- }
- }
-
- return result;
-}
-
nsIFrame::LogicalSides
nsTableFrame::GetLogicalSkipSides(const ReflowInput* aReflowInput) const
{
diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h
index c7b92d387..a6b786402 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)
@@ -272,16 +271,6 @@ public:
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists) override;
- /**
- * Paint the background of the table and its parts (column groups,
- * columns, row groups, rows, and cells), and the table border, and all
- * internal borders if border-collapse is on.
- */
- DrawResult PaintTableBorderBackground(nsDisplayListBuilder* aBuilder,
- nsRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- nsPoint aPt);
-
/** Get the outer half (i.e., the part outside the height and width of
* the table) of the largest segment (?) of border-collapsed border on
* the table on each side, or 0 for non border-collapsed tables.
diff --git a/layout/tables/nsTablePainter.cpp b/layout/tables/nsTablePainter.cpp
deleted file mode 100644
index bfe2a7d42..000000000
--- a/layout/tables/nsTablePainter.cpp
+++ /dev/null
@@ -1,696 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsTableFrame.h"
-#include "nsTableRowGroupFrame.h"
-#include "nsTableRowFrame.h"
-#include "nsTableColGroupFrame.h"
-#include "nsTableColFrame.h"
-#include "nsTableCellFrame.h"
-#include "nsTablePainter.h"
-#include "nsCSSRendering.h"
-#include "nsDisplayList.h"
-#include "mozilla/WritingModes.h"
-
-/* ~*~ Table Background Painting ~*~
-
- Mozilla's Table Background painting follows CSS2.1:17.5.1
- That section does not, however, describe the effect of
- borders on background image positioning. What we do is:
-
- - in separate borders, the borders are passed in so that
- their width figures in image positioning, even for rows/cols, which
- don't have visible borders. This is done to allow authors
- to position row backgrounds by, for example, aligning the
- top left corner with the top left padding corner of the
- top left table cell in the row in cases where all cells
- have consistent border widths. If we didn't honor these
- invisible borders, there would be no way to align
- backgrounds with the padding edges, and designs would be
- lost underneath the border.
-
- - in collapsing borders, because the borders collapse, we
- use the -continuous border- width to synthesize a border
- style and pass that in instead of using the element's
- assigned style directly.
-
- The continuous border on a given edge of an element is
- the collapse of all borders guaranteed to be continuous
- along that edge. Cell borders are ignored (because, for
- example, setting a thick border on the leftmost cell
- should not shift the row background over; this way a
- striped background set on <tr> will line up across rows
- even if the cells are assigned arbitrary border widths.
-
- For example, the continuous border on the top edge of a
- row group is the collapse of any row group, row, and
- table borders involved. (The first row group's top would
- be [table-top + row group top + first row top]. It's bottom
- would be [row group bottom + last row bottom + next row
- top + next row group top].)
- The top edge of a column group likewise includes the
- table top, row group top, and first row top borders. However,
- it *also* includes its own top border, since that is guaranteed
- to be continuous. It does not include column borders because
- those are not guaranteed to be continuous: there may be two
- columns with different borders in a single column group.
-
- An alternative would be to define the continuous border as
- [table? + row group + row] for horizontal
- [table? + col group + col] for vertical
- This makes it easier to line up backgrounds across elements
- despite varying border widths, but it does not give much
- flexibility in aligning /to/ those border widths.
-*/
-
-
-/* ~*~ TableBackgroundPainter ~*~
-
- The TableBackgroundPainter is created and destroyed in one painting call.
- Its principal function is PaintTable, which paints all table element
- backgrounds. The initial code in that method sets up an array of column
- data that caches the background styles and the border sizes for the
- columns and colgroups in TableBackgroundData structs in mCols. Data for
- BC borders are calculated and stashed in a synthesized border style struct
- in the data struct since collapsed borders aren't the same width as style-
- assigned borders. The data struct optimizes by only doing this if there's
- an image background; otherwise we don't care. //XXX should also check background-origin
- The class then loops through the row groups, rows, and cells. At the cell
- level, it paints the backgrounds, one over the other, inside the cell rect.
-
- The exception to this pattern is when a table element creates a (pseudo)
- stacking context. Elements with stacking contexts (e.g., 'opacity' applied)
- are <dfn>passed through</dfn>, which means their data (and their
- descendants' data) are not cached. The full loop is still executed, however,
- so that underlying layers can get painted at the cell level.
-
- The TableBackgroundPainter is then destroyed.
-
- Elements with stacking contexts set up their own painter to finish the
- painting process, since they were skipped. They call the appropriate
- sub-part of the loop (e.g. PaintRow) which will paint the frame and
- descendants.
-
- XXX views are going
- */
-
-using namespace mozilla;
-using namespace mozilla::image;
-
-TableBackgroundPainter::TableBackgroundData::TableBackgroundData()
- : mFrame(nullptr)
- , mVisible(false)
- , mUsesSynthBorder(false)
-{
-}
-
-TableBackgroundPainter::TableBackgroundData::TableBackgroundData(nsIFrame* aFrame)
- : mFrame(aFrame)
- , mRect(aFrame->GetRect())
- , mVisible(mFrame->IsVisibleForPainting())
- , mUsesSynthBorder(false)
-{
-}
-
-inline bool
-TableBackgroundPainter::TableBackgroundData::ShouldSetBCBorder() const
-{
- /* we only need accurate border data when positioning background images*/
- if (!mVisible) {
- return false;
- }
-
- const nsStyleImageLayers& layers = mFrame->StyleBackground()->mImage;
- NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, layers) {
- if (!layers.mLayers[i].mImage.IsEmpty())
- return true;
- }
- return false;
-}
-
-void
-TableBackgroundPainter::TableBackgroundData::SetBCBorder(const nsMargin& aBorder)
-{
- mUsesSynthBorder = true;
- mSynthBorderWidths = aBorder;
-}
-
-nsStyleBorder
-TableBackgroundPainter::TableBackgroundData::StyleBorder(const nsStyleBorder& aZeroBorder) const
-{
- MOZ_ASSERT(mVisible, "Don't call StyleBorder on an invisible TableBackgroundData");
-
- if (mUsesSynthBorder) {
- nsStyleBorder result = aZeroBorder;
- NS_FOR_CSS_SIDES(side) {
- result.SetBorderWidth(side, mSynthBorderWidths.Side(side));
- }
- return result;
- }
-
- MOZ_ASSERT(mFrame);
-
- return *mFrame->StyleBorder();
-}
-
-TableBackgroundPainter::TableBackgroundPainter(nsTableFrame* aTableFrame,
- Origin aOrigin,
- nsPresContext* aPresContext,
- nsRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- const nsPoint& aRenderPt,
- uint32_t aBGPaintFlags)
- : mPresContext(aPresContext),
- mRenderingContext(aRenderingContext),
- mRenderPt(aRenderPt),
- mDirtyRect(aDirtyRect),
- mOrigin(aOrigin),
- mZeroBorder(aPresContext),
- mBGPaintFlags(aBGPaintFlags)
-{
- MOZ_COUNT_CTOR(TableBackgroundPainter);
-
- NS_FOR_CSS_SIDES(side) {
- mZeroBorder.SetBorderStyle(side, NS_STYLE_BORDER_STYLE_SOLID);
- mZeroBorder.SetBorderWidth(side, 0);
- }
-
- mIsBorderCollapse = aTableFrame->IsBorderCollapse();
-#ifdef DEBUG
- mCompatMode = mPresContext->CompatibilityMode();
-#endif
- mNumCols = aTableFrame->GetColCount();
-}
-
-TableBackgroundPainter::~TableBackgroundPainter()
-{
- MOZ_COUNT_DTOR(TableBackgroundPainter);
-}
-
-DrawResult
-TableBackgroundPainter::PaintTableFrame(nsTableFrame* aTableFrame,
- nsTableRowGroupFrame* aFirstRowGroup,
- nsTableRowGroupFrame* aLastRowGroup,
- const nsMargin& aDeflate)
-{
- MOZ_ASSERT(aTableFrame, "null frame");
- TableBackgroundData tableData(aTableFrame);
- tableData.mRect.MoveTo(0,0); //using table's coords
- tableData.mRect.Deflate(aDeflate);
- WritingMode wm = aTableFrame->GetWritingMode();
- if (mIsBorderCollapse && tableData.ShouldSetBCBorder()) {
- if (aFirstRowGroup && aLastRowGroup && mNumCols > 0) {
- //only handle non-degenerate tables; we need a more robust BC model
- //to make degenerate tables' borders reasonable to deal with
- LogicalMargin border(wm);
- LogicalMargin tempBorder(wm);
- nsTableColFrame* colFrame = aTableFrame->GetColFrame(mNumCols - 1);
- if (colFrame) {
- colFrame->GetContinuousBCBorderWidth(wm, tempBorder);
- }
- border.IEnd(wm) = tempBorder.IEnd(wm);
-
- aLastRowGroup->GetContinuousBCBorderWidth(wm, tempBorder);
- border.BEnd(wm) = tempBorder.BEnd(wm);
-
- nsTableRowFrame* rowFrame = aFirstRowGroup->GetFirstRow();
- if (rowFrame) {
- rowFrame->GetContinuousBCBorderWidth(wm, tempBorder);
- border.BStart(wm) = tempBorder.BStart(wm);
- }
-
- border.IStart(wm) = aTableFrame->GetContinuousIStartBCBorderWidth();
-
- tableData.SetBCBorder(border.GetPhysicalMargin(wm));
- }
- }
-
- DrawResult result = DrawResult::SUCCESS;
-
- if (tableData.IsVisible()) {
- nsCSSRendering::PaintBGParams params =
- nsCSSRendering::PaintBGParams::ForAllLayers(*mPresContext,
- mRenderingContext,
- mDirtyRect,
- tableData.mRect + mRenderPt,
- tableData.mFrame,
- mBGPaintFlags);
-
- result &=
- nsCSSRendering::PaintBackgroundWithSC(params,
- tableData.mFrame->StyleContext(),
- tableData.StyleBorder(mZeroBorder));
- }
-
- return result;
-}
-
-void
-TableBackgroundPainter::TranslateContext(nscoord aDX,
- nscoord aDY)
-{
- mRenderPt += nsPoint(aDX, aDY);
- for (auto& col : mCols) {
- col.mCol.mRect.MoveBy(-aDX, -aDY);
- }
- for (auto& colGroup : mColGroups) {
- colGroup.mRect.MoveBy(-aDX, -aDY);
- }
-}
-
-TableBackgroundPainter::ColData::ColData(nsIFrame* aFrame, TableBackgroundData& aColGroupBGData)
- : mCol(aFrame)
- , mColGroup(aColGroupBGData)
-{
-}
-
-DrawResult
-TableBackgroundPainter::PaintTable(nsTableFrame* aTableFrame,
- const nsMargin& aDeflate,
- bool aPaintTableBackground)
-{
- NS_PRECONDITION(aTableFrame, "null table frame");
-
- nsTableFrame::RowGroupArray rowGroups;
- aTableFrame->OrderRowGroups(rowGroups);
- WritingMode wm = aTableFrame->GetWritingMode();
-
- DrawResult result = DrawResult::SUCCESS;
-
- if (rowGroups.Length() < 1) { //degenerate case
- if (aPaintTableBackground) {
- result &= PaintTableFrame(aTableFrame, nullptr, nullptr, nsMargin(0,0,0,0));
- }
- /* No cells; nothing else to paint */
- return result;
- }
-
- if (aPaintTableBackground) {
- result &=
- PaintTableFrame(aTableFrame, rowGroups[0], rowGroups[rowGroups.Length() - 1],
- aDeflate);
- }
-
- /*Set up column background/border data*/
- if (mNumCols > 0) {
- nsFrameList& colGroupList = aTableFrame->GetColGroups();
- NS_ASSERTION(colGroupList.FirstChild(), "table should have at least one colgroup");
-
- // Collect all col group frames first so that we know how many there are.
- nsTArray<nsTableColGroupFrame*> colGroupFrames;
- for (nsTableColGroupFrame* cgFrame = static_cast<nsTableColGroupFrame*>(colGroupList.FirstChild());
- cgFrame; cgFrame = static_cast<nsTableColGroupFrame*>(cgFrame->GetNextSibling())) {
-
- if (cgFrame->GetColCount() < 1) {
- //No columns, no cells, so no need for data
- continue;
- }
- colGroupFrames.AppendElement(cgFrame);
- }
-
- // Ensure that mColGroups won't reallocate during the loop below, because
- // we grab references to its contents and need those to stay valid until
- // mColGroups is destroyed as part of TablePainter destruction.
- mColGroups.SetCapacity(colGroupFrames.Length());
-
- LogicalMargin border(wm);
- /* BC iStart borders aren't stored on cols, but the previous column's
- iEnd border is the next one's iStart border.*/
- //Start with table's iStart border.
- nscoord lastIStartBorder = aTableFrame->GetContinuousIStartBCBorderWidth();
-
- for (nsTableColGroupFrame* cgFrame : colGroupFrames) {
- /*Create data struct for column group*/
- TableBackgroundData& cgData = *mColGroups.AppendElement(TableBackgroundData(cgFrame));
- if (mIsBorderCollapse && cgData.ShouldSetBCBorder()) {
- border.IStart(wm) = lastIStartBorder;
- cgFrame->GetContinuousBCBorderWidth(wm, border);
- cgData.SetBCBorder(border.GetPhysicalMargin(wm));
- }
-
- /*Loop over columns in this colgroup*/
- for (nsTableColFrame* col = cgFrame->GetFirstColumn(); col;
- col = static_cast<nsTableColFrame*>(col->GetNextSibling())) {
- MOZ_ASSERT(size_t(col->GetColIndex()) == mCols.Length());
- // Store a reference to the colGroup in the ColData element.
- ColData& colData = *mCols.AppendElement(ColData(col, cgData));
- //Bring column mRect into table's coord system
- colData.mCol.mRect.MoveBy(cgData.mRect.x, cgData.mRect.y);
- if (mIsBorderCollapse) {
- border.IStart(wm) = lastIStartBorder;
- lastIStartBorder = col->GetContinuousBCBorderWidth(wm, border);
- if (colData.mCol.ShouldSetBCBorder()) {
- colData.mCol.SetBCBorder(border.GetPhysicalMargin(wm));
- }
- }
- }
- }
- }
-
- for (uint32_t i = 0; i < rowGroups.Length(); i++) {
- nsTableRowGroupFrame* rg = rowGroups[i];
- TableBackgroundData rowGroupBGData(rg);
- // Need to compute the right rect via GetOffsetTo, since the row
- // group may not be a child of the table.
- rowGroupBGData.mRect.MoveTo(rg->GetOffsetTo(aTableFrame));
-
- // We have to draw backgrounds not only within the overflow region of this
- // row group, but also possibly (in the case of column / column group
- // backgrounds) at its pre-relative-positioning location.
- nsRect rgVisualOverflow = rg->GetVisualOverflowRectRelativeToSelf();
- nsRect rgOverflowRect = rgVisualOverflow + rg->GetPosition();
- nsRect rgNormalRect = rgVisualOverflow + rg->GetNormalPosition();
-
- if (rgOverflowRect.Union(rgNormalRect).Intersects(mDirtyRect - mRenderPt)) {
- result &=
- PaintRowGroup(rg, rowGroupBGData, rg->IsPseudoStackingContextFromStyle());
- }
- }
-
- return result;
-}
-
-DrawResult
-TableBackgroundPainter::PaintRowGroup(nsTableRowGroupFrame* aFrame)
-{
- return PaintRowGroup(aFrame, TableBackgroundData(aFrame), false);
-}
-
-DrawResult
-TableBackgroundPainter::PaintRowGroup(nsTableRowGroupFrame* aFrame,
- TableBackgroundData aRowGroupBGData,
- bool aPassThrough)
-{
- MOZ_ASSERT(aFrame, "null frame");
-
- nsTableRowFrame* firstRow = aFrame->GetFirstRow();
- WritingMode wm = aFrame->GetWritingMode();
-
- /* Load row group data */
- if (aPassThrough) {
- aRowGroupBGData.MakeInvisible();
- } else {
- if (mIsBorderCollapse && aRowGroupBGData.ShouldSetBCBorder()) {
- LogicalMargin border(wm);
- if (firstRow) {
- //pick up first row's bstart border (= rg bstart border)
- firstRow->GetContinuousBCBorderWidth(wm, border);
- /* (row group doesn't store its bstart border) */
- }
- //overwrite sides+bottom borders with rg's own
- aFrame->GetContinuousBCBorderWidth(wm, border);
- aRowGroupBGData.SetBCBorder(border.GetPhysicalMargin(wm));
- }
- aPassThrough = !aRowGroupBGData.IsVisible();
- }
-
- /* translate everything into row group coord system*/
- if (eOrigin_TableRowGroup != mOrigin) {
- TranslateContext(aRowGroupBGData.mRect.x, aRowGroupBGData.mRect.y);
- }
- nsRect rgRect = aRowGroupBGData.mRect;
- aRowGroupBGData.mRect.MoveTo(0, 0);
-
- /* Find the right row to start with */
-
- // Note that mDirtyRect - mRenderPt is guaranteed to be in the row
- // group's coordinate system here, so passing its .y to
- // GetFirstRowContaining is ok.
- nscoord overflowAbove;
- nsIFrame* cursor = aFrame->GetFirstRowContaining(mDirtyRect.y - mRenderPt.y, &overflowAbove);
-
- // Sadly, it seems like there may be non-row frames in there... or something?
- // There are certainly null-checks in GetFirstRow() and GetNextRow(). :(
- while (cursor && cursor->GetType() != nsGkAtoms::tableRowFrame) {
- cursor = cursor->GetNextSibling();
- }
-
- // It's OK if cursor is null here.
- nsTableRowFrame* row = static_cast<nsTableRowFrame*>(cursor);
- if (!row) {
- // No useful cursor; just start at the top. Don't bother to set up a
- // cursor; if we've gotten this far then we've already built the display
- // list for the rowgroup, so not having a cursor means that there's some
- // good reason we don't have a cursor and we shouldn't create one here.
- row = firstRow;
- }
-
- DrawResult result = DrawResult::SUCCESS;
-
- /* Finally paint */
- for (; row; row = row->GetNextRow()) {
- TableBackgroundData rowBackgroundData(row);
-
- // Be sure to consider our positions both pre- and post-relative
- // positioning, since we potentially need to paint at both places.
- nscoord rowY = std::min(rowBackgroundData.mRect.y, row->GetNormalPosition().y);
-
- // Intersect wouldn't handle rowspans.
- if (cursor &&
- (mDirtyRect.YMost() - mRenderPt.y) <= (rowY - overflowAbove)) {
- // All done; cells originating in later rows can't intersect mDirtyRect.
- break;
- }
-
- result &=
- PaintRow(row, aRowGroupBGData, rowBackgroundData,
- aPassThrough || row->IsPseudoStackingContextFromStyle());
- }
-
- /* translate back into table coord system */
- if (eOrigin_TableRowGroup != mOrigin) {
- TranslateContext(-rgRect.x, -rgRect.y);
- }
-
- return result;
-}
-
-DrawResult
-TableBackgroundPainter::PaintRow(nsTableRowFrame* aFrame)
-{
- return PaintRow(aFrame, TableBackgroundData(), TableBackgroundData(aFrame), false);
-}
-
-DrawResult
-TableBackgroundPainter::PaintRow(nsTableRowFrame* aFrame,
- const TableBackgroundData& aRowGroupBGData,
- TableBackgroundData aRowBGData,
- bool aPassThrough)
-{
- MOZ_ASSERT(aFrame, "null frame");
-
- /* Load row data */
- WritingMode wm = aFrame->GetWritingMode();
- if (aPassThrough) {
- aRowBGData.MakeInvisible();
- } else {
- if (mIsBorderCollapse && aRowBGData.ShouldSetBCBorder()) {
- LogicalMargin border(wm);
- nsTableRowFrame* nextRow = aFrame->GetNextRow();
- if (nextRow) { //outer bStart after us is inner bEnd for us
- border.BEnd(wm) = nextRow->GetOuterBStartContBCBorderWidth();
- }
- else { //acquire rg's bEnd border
- nsTableRowGroupFrame* rowGroup = static_cast<nsTableRowGroupFrame*>(aFrame->GetParent());
- rowGroup->GetContinuousBCBorderWidth(wm, border);
- }
- //get the rest of the borders; will overwrite all but bEnd
- aFrame->GetContinuousBCBorderWidth(wm, border);
-
- aRowBGData.SetBCBorder(border.GetPhysicalMargin(wm));
- }
- aPassThrough = !aRowBGData.IsVisible();
- }
-
- /* Translate */
- if (eOrigin_TableRow == mOrigin) {
- /* If we originate from the row, then make the row the origin. */
- aRowBGData.mRect.MoveTo(0, 0);
- }
- //else: Use row group's coord system -> no translation necessary
-
- DrawResult result = DrawResult::SUCCESS;
-
- for (nsTableCellFrame* cell = aFrame->GetFirstCell(); cell; cell = cell->GetNextCell()) {
- nsRect cellBGRect, rowBGRect, rowGroupBGRect, colBGRect;
- ComputeCellBackgrounds(cell, aRowGroupBGData, aRowBGData,
- cellBGRect, rowBGRect,
- rowGroupBGRect, colBGRect);
-
- // Find the union of all the cell background layers.
- nsRect combinedRect(cellBGRect);
- combinedRect.UnionRect(combinedRect, rowBGRect);
- combinedRect.UnionRect(combinedRect, rowGroupBGRect);
- combinedRect.UnionRect(combinedRect, colBGRect);
-
- if (combinedRect.Intersects(mDirtyRect)) {
- bool passCell = aPassThrough || cell->IsPseudoStackingContextFromStyle();
- result &=
- PaintCell(cell, aRowGroupBGData, aRowBGData, cellBGRect, rowBGRect,
- rowGroupBGRect, colBGRect, passCell);
- }
- }
-
- return result;
-}
-
-DrawResult
-TableBackgroundPainter::PaintCell(nsTableCellFrame* aCell,
- const TableBackgroundData& aRowGroupBGData,
- const TableBackgroundData& aRowBGData,
- nsRect& aCellBGRect,
- nsRect& aRowBGRect,
- nsRect& aRowGroupBGRect,
- nsRect& aColBGRect,
- bool aPassSelf)
-{
- MOZ_ASSERT(aCell, "null frame");
-
- const nsStyleTableBorder* cellTableStyle;
- cellTableStyle = aCell->StyleTableBorder();
- if (NS_STYLE_TABLE_EMPTY_CELLS_SHOW != cellTableStyle->mEmptyCells &&
- aCell->GetContentEmpty() && !mIsBorderCollapse) {
- return DrawResult::SUCCESS;
- }
-
- int32_t colIndex;
- aCell->GetColIndex(colIndex);
- // We're checking mNumCols instead of mCols.Length() here because mCols can
- // be empty even if mNumCols > 0.
- NS_ASSERTION(size_t(colIndex) < mNumCols, "out-of-bounds column index");
- if (size_t(colIndex) >= mNumCols) {
- return DrawResult::SUCCESS;
- }
-
- // If callers call PaintRowGroup or PaintRow directly, we haven't processed
- // our columns. Ignore column / col group backgrounds in that case.
- bool haveColumns = !mCols.IsEmpty();
-
- DrawResult result = DrawResult::SUCCESS;
-
- //Paint column group background
- if (haveColumns && mCols[colIndex].mColGroup.IsVisible()) {
- nsCSSRendering::PaintBGParams params =
- nsCSSRendering::PaintBGParams::ForAllLayers(*mPresContext, mRenderingContext,
- mDirtyRect,
- mCols[colIndex].mColGroup.mRect + mRenderPt,
- mCols[colIndex].mColGroup.mFrame,
- mBGPaintFlags);
- params.bgClipRect = &aColBGRect;
- result &=
- nsCSSRendering::PaintBackgroundWithSC(params,
- mCols[colIndex].mColGroup.mFrame->StyleContext(),
- mCols[colIndex].mColGroup.StyleBorder(mZeroBorder));
- }
-
- //Paint column background
- if (haveColumns && mCols[colIndex].mCol.IsVisible()) {
- nsCSSRendering::PaintBGParams params =
- nsCSSRendering::PaintBGParams::ForAllLayers(*mPresContext, mRenderingContext,
- mDirtyRect,
- mCols[colIndex].mCol.mRect + mRenderPt,
- mCols[colIndex].mCol.mFrame,
- mBGPaintFlags);
- params.bgClipRect = &aColBGRect;
- result &=
- nsCSSRendering::PaintBackgroundWithSC(params,
- mCols[colIndex].mCol.mFrame->StyleContext(),
- mCols[colIndex].mCol.StyleBorder(mZeroBorder));
- }
-
- //Paint row group background
- if (aRowGroupBGData.IsVisible()) {
- nsCSSRendering::PaintBGParams params =
- nsCSSRendering::PaintBGParams::ForAllLayers(*mPresContext, mRenderingContext,
- mDirtyRect,
- aRowGroupBGData.mRect + mRenderPt,
- aRowGroupBGData.mFrame, mBGPaintFlags);
- params.bgClipRect = &aRowGroupBGRect;
- result &=
- nsCSSRendering::PaintBackgroundWithSC(params,
- aRowGroupBGData.mFrame->StyleContext(),
- aRowGroupBGData.StyleBorder(mZeroBorder));
- }
-
- //Paint row background
- if (aRowBGData.IsVisible()) {
- nsCSSRendering::PaintBGParams params =
- nsCSSRendering::PaintBGParams::ForAllLayers(*mPresContext, mRenderingContext,
- mDirtyRect,
- aRowBGData.mRect + mRenderPt,
- aRowBGData.mFrame, mBGPaintFlags);
- params.bgClipRect = &aRowBGRect;
- result &=
- nsCSSRendering::PaintBackgroundWithSC(params,
- aRowBGData.mFrame->StyleContext(),
- aRowBGData.StyleBorder(mZeroBorder));
- }
-
- //Paint cell background in border-collapse unless we're just passing
- if (mIsBorderCollapse && !aPassSelf) {
- result &=
- aCell->PaintCellBackground(mRenderingContext, mDirtyRect,
- aCellBGRect.TopLeft(), mBGPaintFlags);
- }
-
- return result;
-}
-
-void
-TableBackgroundPainter::ComputeCellBackgrounds(nsTableCellFrame* aCell,
- const TableBackgroundData& aRowGroupBGData,
- const TableBackgroundData& aRowBGData,
- nsRect& aCellBGRect,
- nsRect& aRowBGRect,
- nsRect& aRowGroupBGRect,
- nsRect& aColBGRect)
-{
- // We need to compute table background layer rects for this cell space,
- // adjusted for possible relative positioning. This behavior is not specified
- // at the time of this writing, but the approach below should be web
- // compatible.
- //
- // Our goal is that relative positioning of a table part should leave
- // backgrounds *under* that part unchanged. ("Under" being defined by CSS 2.1
- // Section 17.5.1.) If a cell is positioned, we do not expect the row
- // background to move. On the other hand, the backgrounds of layers *above*
- // the positioned part are taken along for the ride -- for example,
- // positioning a row group will also cause the row background to be drawn in
- // the new location, unless it has further positioning applied.
- //
- // Each table part layer has its position stored in the coordinate space of
- // the layer below (which is to say, its geometric parent), and the stored
- // position is the post-relative-positioning one. The position of each
- // background layer rect is thus determined by peeling off successive table
- // part layers, removing the contribution of each layer's positioning one by
- // one. Every rect we generate will be the same size, the size of the cell
- // space.
-
- // We cannot rely on the row group background data to be available, since some
- // callers enter through PaintRow.
- nsIFrame* rowGroupFrame =
- aRowGroupBGData.mFrame ? aRowGroupBGData.mFrame : aRowBGData.mFrame->GetParent();
-
- // The cell background goes at the cell's position, translated to use the same
- // coordinate system as aRowBGData.
- aCellBGRect = aCell->GetRect() + aRowBGData.mRect.TopLeft() + mRenderPt;
-
- // The row background goes at the normal position of the cell, which is to say
- // the position without relative positioning applied.
- aRowBGRect = aCellBGRect + (aCell->GetNormalPosition() - aCell->GetPosition());
-
- // The row group background goes at the position we'd find the cell if neither
- // the cell's relative positioning nor the row's were applied.
- aRowGroupBGRect = aRowBGRect +
- (aRowBGData.mFrame->GetNormalPosition() - aRowBGData.mFrame->GetPosition());
-
- // The column and column group backgrounds (they're always at the same
- // location, since relative positioning doesn't apply to columns or column
- // groups) are drawn at the position we'd find the cell if none of the cell's,
- // row's, or row group's relative positioning were applied.
- aColBGRect = aRowGroupBGRect +
- (rowGroupFrame->GetNormalPosition() - rowGroupFrame->GetPosition());
-
-}
diff --git a/layout/tables/nsTablePainter.h b/layout/tables/nsTablePainter.h
deleted file mode 100644
index dfba42156..000000000
--- a/layout/tables/nsTablePainter.h
+++ /dev/null
@@ -1,268 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef nsTablePainter_h__
-#define nsTablePainter_h__
-
-#include "imgIContainer.h"
-
-#include "celldata.h"
-
-// flags for Paint, PaintChild, PaintChildren are currently only used by tables.
-//Table-based paint call; not a direct call as with views
-#define NS_PAINT_FLAG_TABLE_BG_PAINT 0x00000001
-//Cells should paint their backgrounds only, no children
-#define NS_PAINT_FLAG_TABLE_CELL_BG_PASS 0x00000002
-
-class nsIFrame;
-class nsTableFrame;
-class nsTableRowGroupFrame;
-class nsTableRowFrame;
-class nsTableCellFrame;
-
-class TableBackgroundPainter
-{
- /*
- * Helper class for painting table backgrounds
- *
- */
-
- typedef mozilla::image::DrawResult DrawResult;
-
- public:
-
- enum Origin { eOrigin_Table, eOrigin_TableRowGroup, eOrigin_TableRow };
-
- /** Public constructor
- * @param aTableFrame - the table's table frame
- * @param aOrigin - what type of table frame is creating this instance
- * @param aPresContext - the presentation context
- * @param aRenderingContext - the rendering context
- * @param aDirtyRect - the area that needs to be painted,
- * relative to aRenderingContext
- * @param aPt - offset of the table frame relative to
- * aRenderingContext
- * @param aBGPaintFlags - Flags of the nsCSSRendering::PAINTBG_* variety
- */
- TableBackgroundPainter(nsTableFrame* aTableFrame,
- Origin aOrigin,
- nsPresContext* aPresContext,
- nsRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- const nsPoint& aPt,
- uint32_t aBGPaintFlags);
-
- /** Destructor */
- ~TableBackgroundPainter();
-
- /* ~*~ The Border Collapse Painting Issue ~*~
-
- In border-collapse, the *table* paints the cells' borders,
- so we need to make sure the backgrounds get painted first
- (underneath) by doing a cell-background-only painting pass.
- */
-
- /* ~*~ Using nsTablePainter Background Painting ~*~
-
- A call to PaintTable will normally paint all of the table's
- elements (except for the table background, if aPaintTableBackground
- is false).
- Elements with views however, will be skipped and must create their
- own painter to call the appropriate paint function in their ::Paint
- method (e.g. painter.PaintRow in nsTableRow::Paint)
- */
-
- /** Paint background for the table frame (if requested) and its children
- * down through cells.
- * (Cells themselves will only be painted in border collapse)
- * Table must do a flagged TABLE_BG_PAINT ::Paint call on its
- * children afterwards
- * @param aTableFrame - the table frame
- * @param aDeflate - deflation needed to bring table's mRect
- * to the outer grid lines in border-collapse
- * @param aPaintTableBackground - if true, the table background
- * is included, otherwise it isn't
- * @returns DrawResult::SUCCESS if all painting was successful. If some
- * painting failed or an improved result could be achieved by sync
- * decoding images, returns another value.
- */
- DrawResult PaintTable(nsTableFrame* aTableFrame, const nsMargin& aDeflate,
- bool aPaintTableBackground);
-
- /** Paint background for the row group and its children down through cells
- * (Cells themselves will only be painted in border collapse)
- * Standards mode only
- * Table Row Group must do a flagged TABLE_BG_PAINT ::Paint call on its
- * children afterwards
- * @param aFrame - the table row group frame
- * @returns DrawResult::SUCCESS if all painting was successful. If some
- * painting failed or an improved result could be achieved by sync
- * decoding images, returns another value.
- */
- DrawResult PaintRowGroup(nsTableRowGroupFrame* aFrame);
-
- /** Paint background for the row and its children down through cells
- * (Cells themselves will only be painted in border collapse)
- * Standards mode only
- * Table Row must do a flagged TABLE_BG_PAINT ::Paint call on its
- * children afterwards
- * @param aFrame - the table row frame
- * @returns DrawResult::SUCCESS if all painting was successful. If some
- * painting failed or an improved result could be achieved by sync
- * decoding images, returns another value.
- */
- DrawResult PaintRow(nsTableRowFrame* aFrame);
-
- private:
- struct TableBackgroundData;
-
- /** Paint table frame's background
- * @param aTableFrame - the table frame
- * @param aFirstRowGroup - the first (in layout order) row group
- * may be null
- * @param aLastRowGroup - the last (in layout order) row group
- * may be null
- * @param aDeflate - adjustment to frame's rect (used for quirks BC)
- * may be null
- */
- DrawResult PaintTableFrame(nsTableFrame* aTableFrame,
- nsTableRowGroupFrame* aFirstRowGroup,
- nsTableRowGroupFrame* aLastRowGroup,
- const nsMargin& aDeflate);
-
- /* aPassThrough params indicate whether to paint the element or to just
- * pass through and paint underlying layers only.
- * aRowGroupBGData is not a const reference because the function modifies
- * its copy. Same for aRowBGData in PaintRow.
- * See Public versions for function descriptions
- */
- DrawResult PaintRowGroup(nsTableRowGroupFrame* aFrame,
- TableBackgroundData aRowGroupBGData,
- bool aPassThrough);
-
- DrawResult PaintRow(nsTableRowFrame* aFrame,
- const TableBackgroundData& aRowGroupBGData,
- TableBackgroundData aRowBGData,
- bool aPassThrough);
-
- /** Paint table background layers for this cell space
- * Also paints cell's own background in border-collapse mode
- * @param aCell - the cell
- * @param aRowGroupBGData - background drawing info for the row group
- * @param aRowBGData - background drawing info for the row
- * @param aCellBGRect - background rect for the cell
- * @param aRowBGRect - background rect for the row
- * @param aRowGroupBGRect - background rect for the row group
- * @param aColBGRect - background rect for the column and column group
- * @param aPassSelf - pass this cell; i.e. paint only underlying layers
- */
- DrawResult PaintCell(nsTableCellFrame* aCell,
- const TableBackgroundData& aRowGroupBGData,
- const TableBackgroundData& aRowBGData,
- nsRect& aCellBGRect,
- nsRect& aRowBGRect,
- nsRect& aRowGroupBGRect,
- nsRect& aColBGRect,
- bool aPassSelf);
-
- /** Compute table background layer positions for this cell space
- * @param aCell - the cell
- * @param aRowGroupBGData - background drawing info for the row group
- * @param aRowBGData - background drawing info for the row
- * @param aCellBGRectOut - outparam: background rect for the cell
- * @param aRowBGRectOut - outparam: background rect for the row
- * @param aRowGroupBGRectOut - outparam: background rect for the row group
- * @param aColBGRectOut - outparam: background rect for the column
- and column group
- */
- void ComputeCellBackgrounds(nsTableCellFrame* aCell,
- const TableBackgroundData& aRowGroupBGData,
- const TableBackgroundData& aRowBGData,
- nsRect& aCellBGRect,
- nsRect& aRowBGRect,
- nsRect& aRowGroupBGRect,
- nsRect& aColBGRect);
-
- /** Translate mRenderingContext, mDirtyRect, and mCols' column and
- * colgroup coords
- * @param aDX - origin's x-coord change
- * @param aDY - origin's y-coord change
- */
- void TranslateContext(nscoord aDX,
- nscoord aDY);
-
- struct TableBackgroundData {
- public:
- /**
- * Construct an empty TableBackgroundData instance, which is invisible.
- */
- TableBackgroundData();
-
- /**
- * Construct a TableBackgroundData instance for a frame. Visibility will
- * be derived from the frame and can be overridden using MakeInvisible().
- */
- explicit TableBackgroundData(nsIFrame* aFrame);
-
- /** Destructor */
- ~TableBackgroundData() {}
-
- /** Data is valid & frame is visible */
- bool IsVisible() const { return mVisible; }
-
- /** Override visibility of the frame, force it to be invisible */
- void MakeInvisible() { mVisible = false; }
-
- /** True if need to set border-collapse border; must call SetFull beforehand */
- bool ShouldSetBCBorder() const;
-
- /** Set border-collapse border with aBorderWidth as widths */
- void SetBCBorder(const nsMargin& aBorderWidth);
-
- /**
- * @param aZeroBorder An nsStyleBorder instance that has been initialized
- * for the right nsPresContext, with all border widths
- * set to zero and border styles set to solid.
- * @return The nsStyleBorder that should be used for rendering
- * this background.
- */
- nsStyleBorder StyleBorder(const nsStyleBorder& aZeroBorder) const;
-
- nsIFrame* const mFrame;
-
- /** mRect is the rect of mFrame in the current coordinate system */
- nsRect mRect;
-
- private:
- nsMargin mSynthBorderWidths;
- bool mVisible;
- bool mUsesSynthBorder;
- };
-
- struct ColData {
- ColData(nsIFrame* aFrame, TableBackgroundData& aColGroupBGData);
- TableBackgroundData mCol;
- TableBackgroundData& mColGroup; // reference to col's parent colgroup's data, owned by TablePainter in mColGroups
- };
-
- nsPresContext* mPresContext;
- nsRenderingContext& mRenderingContext;
- nsPoint mRenderPt;
- nsRect mDirtyRect;
-#ifdef DEBUG
- nsCompatibility mCompatMode;
-#endif
- bool mIsBorderCollapse;
- Origin mOrigin; //user's table frame type
-
- nsTArray<TableBackgroundData> mColGroups;
- nsTArray<ColData> mCols;
- size_t mNumCols;
-
- nsStyleBorder mZeroBorder; //cached zero-width border
- uint32_t mBGPaintFlags;
-};
-
-#endif
diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp
index 1b6051ef2..ea2477b73 100644
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -561,65 +561,12 @@ nsTableRowFrame::CalcBSize(const ReflowInput& aReflowInput)
return GetInitialBSize();
}
-/**
- * We need a custom display item for table row backgrounds. This is only used
- * when the table row is the root of a stacking context (e.g., has 'opacity').
- * Table row backgrounds can extend beyond the row frame bounds, when
- * the row contains row-spanning cells.
- */
-class nsDisplayTableRowBackground : public nsDisplayTableItem {
-public:
- nsDisplayTableRowBackground(nsDisplayListBuilder* aBuilder,
- nsTableRowFrame* aFrame) :
- nsDisplayTableItem(aBuilder, aFrame) {
- MOZ_COUNT_CTOR(nsDisplayTableRowBackground);
- }
-#ifdef NS_BUILD_REFCNT_LOGGING
- virtual ~nsDisplayTableRowBackground() {
- MOZ_COUNT_DTOR(nsDisplayTableRowBackground);
- }
-#endif
-
- virtual void Paint(nsDisplayListBuilder* aBuilder,
- nsRenderingContext* aCtx) override;
- NS_DISPLAY_DECL_NAME("TableRowBackground", TYPE_TABLE_ROW_BACKGROUND)
-};
-
-void
-nsDisplayTableRowBackground::Paint(nsDisplayListBuilder* aBuilder,
- nsRenderingContext* aCtx)
-{
- auto rowFrame = static_cast<nsTableRowFrame*>(mFrame);
- TableBackgroundPainter painter(rowFrame->GetTableFrame(),
- TableBackgroundPainter::eOrigin_TableRow,
- mFrame->PresContext(), *aCtx,
- mVisibleRect, ToReferenceFrame(),
- aBuilder->GetBackgroundPaintFlags());
-
- DrawResult result = painter.PaintRow(rowFrame);
- nsDisplayTableItemGeometry::UpdateDrawResult(this, result);
-}
-
void
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
@@ -979,12 +926,11 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext,
// be merged into the else below if we can.)
nsMargin* computedOffsetProp =
kidFrame->GetProperty(nsIFrame::ComputedOffsetProperty());
- // Bug 975644: a position:sticky kid can end up with a null
- // property value here.
- LogicalMargin computedOffsets(wm, computedOffsetProp ?
- *computedOffsetProp : nsMargin());
- ReflowInput::ApplyRelativePositioning(kidFrame, wm, computedOffsets,
- &kidPosition, containerSize);
+
+ // On our fist reflow sticky children may not have the property yet (we
+ // need to reflow the children first to size the scroll frame).
+ LogicalMargin computedOffsets(wm, computedOffsetProp ? *computedOffsetProp : nsMargin());
+ ReflowInput::ApplyRelativePositioning(kidFrame, wm, computedOffsets, &kidPosition, containerSize);
}
// In vertical-rl mode, we are likely to have containerSize.width = 0
diff --git a/layout/tables/nsTableRowFrame.h b/layout/tables/nsTableRowFrame.h
index a6aba81e7..9e15d851f 100644
--- a/layout/tables/nsTableRowFrame.h
+++ b/layout/tables/nsTableRowFrame.h
@@ -8,7 +8,6 @@
#include "mozilla/Attributes.h"
#include "nscore.h"
#include "nsContainerFrame.h"
-#include "nsTablePainter.h"
#include "nsTableRowGroupFrame.h"
#include "mozilla/WritingModes.h"
diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp
index 8f014b204..3e4f60f62 100644
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -154,46 +154,6 @@ nsTableRowGroupFrame::InitRepeatedFrame(nsTableRowGroupFrame* aHeaderFooterFrame
return NS_OK;
}
-/**
- * We need a custom display item for table row backgrounds. This is only used
- * when the table row is the root of a stacking context (e.g., has 'opacity').
- * Table row backgrounds can extend beyond the row frame bounds, when
- * the row contains row-spanning cells.
- */
-class nsDisplayTableRowGroupBackground : public nsDisplayTableItem {
-public:
- nsDisplayTableRowGroupBackground(nsDisplayListBuilder* aBuilder,
- nsTableRowGroupFrame* aFrame) :
- nsDisplayTableItem(aBuilder, aFrame) {
- MOZ_COUNT_CTOR(nsDisplayTableRowGroupBackground);
- }
-#ifdef NS_BUILD_REFCNT_LOGGING
- virtual ~nsDisplayTableRowGroupBackground() {
- MOZ_COUNT_DTOR(nsDisplayTableRowGroupBackground);
- }
-#endif
-
- virtual void Paint(nsDisplayListBuilder* aBuilder,
- nsRenderingContext* aCtx) override;
-
- NS_DISPLAY_DECL_NAME("TableRowGroupBackground", TYPE_TABLE_ROW_GROUP_BACKGROUND)
-};
-
-void
-nsDisplayTableRowGroupBackground::Paint(nsDisplayListBuilder* aBuilder,
- nsRenderingContext* aCtx)
-{
- auto rgFrame = static_cast<nsTableRowGroupFrame*>(mFrame);
- TableBackgroundPainter painter(rgFrame->GetTableFrame(),
- TableBackgroundPainter::eOrigin_TableRowGroup,
- mFrame->PresContext(), *aCtx,
- mVisibleRect, ToReferenceFrame(),
- aBuilder->GetBackgroundPaintFlags());
-
- DrawResult result = painter.PaintRowGroup(rgFrame);
- nsDisplayTableItemGeometry::UpdateDrawResult(this, result);
-}
-
// Handle the child-traversal part of DisplayGenericTablePart
static void
DisplayRows(nsDisplayListBuilder* aBuilder, nsFrame* aFrame,
@@ -249,19 +209,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/nsTableRowGroupFrame.h b/layout/tables/nsTableRowGroupFrame.h
index 7abdd4b74..721d91046 100644
--- a/layout/tables/nsTableRowGroupFrame.h
+++ b/layout/tables/nsTableRowGroupFrame.h
@@ -10,7 +10,6 @@
#include "nsContainerFrame.h"
#include "nsIAtom.h"
#include "nsILineIterator.h"
-#include "nsTablePainter.h"
#include "nsTArray.h"
#include "nsTableFrame.h"
#include "mozilla/WritingModes.h"
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);
}