summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@wolfbeast.com>2019-11-03 15:12:34 +0100
committerwolfbeast <mcwerewolf@wolfbeast.com>2019-11-03 15:12:34 +0100
commitdb98e3efff6087b690805358e6f4fda118ec9627 (patch)
tree6c0478110100bdf85f1fa088a86b206905a25f96
parent0de40040f006c493feeff7d688c169b904b8a22e (diff)
downloaduxp-db98e3efff6087b690805358e6f4fda118ec9627.tar.gz
Issue #146 - Part 3: Create nsDisplayTableFixedPosition to avoid display
list collisions when processing the background image of a table.
-rw-r--r--layout/base/nsDisplayList.cpp63
-rw-r--r--layout/base/nsDisplayList.h45
-rw-r--r--layout/tables/nsTableFrame.cpp8
3 files changed, 108 insertions, 8 deletions
diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp
index 744153831d..6b792a779c 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().
@@ -2632,7 +2634,8 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
nsDisplayList* aList,
bool aAllowWillPaintBorderOptimization,
nsStyleContext* aStyleContext,
- const nsRect& aBackgroundOriginRect)
+ const nsRect& aBackgroundOriginRect,
+ nsIFrame* aSecondaryReferenceFrame)
{
nsStyleContext* bgSC = aStyleContext;
const nsStyleBackground* bg = nullptr;
@@ -2752,8 +2755,17 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
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);
}
@@ -5277,6 +5289,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 9431e2cc06..69d13ded99 100644
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -2738,7 +2738,8 @@ public:
nsDisplayList* aList,
bool aAllowWillPaintBorderOptimization = true,
nsStyleContext* aStyleContext = nullptr,
- const nsRect& aBackgroundOriginRect = nsRect());
+ const nsRect& aBackgroundOriginRect = nsRect(),
+ nsIFrame* aSecondaryReferenceFrame = nullptr);
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
@@ -2838,6 +2839,25 @@ 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 the native theme background for a frame.
@@ -3736,7 +3756,7 @@ public:
return mAnimatedGeometryRootForScrollMetadata;
}
-private:
+protected:
// For background-attachment:fixed
nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList, uint32_t aIndex);
@@ -3747,6 +3767,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/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp
index 06a05292fd..890d050fdf 100644
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -1194,13 +1194,14 @@ PaintRowBackground(nsTableRowFrame* aRow,
const nsDisplayListSet& aLists,
const nsPoint& aOffset = nsPoint())
{
- // Compute background rect by iterating all cell frame.
+ // 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());
+ aFrame->GetRectRelativeToSelf(),
+ cell);
}
}
@@ -1232,7 +1233,8 @@ PaintRowGroupBackgroundByColIdx(nsTableRowGroupFrame* aRowGroup,
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, aFrame, cellRect,
aLists.BorderBackground(),
true, nullptr,
- aFrame->GetRectRelativeToSelf());
+ aFrame->GetRectRelativeToSelf(),
+ cell);
}
}
}