--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -1243,33 +1243,73 @@ nsDisplayTableItem::ComputeInvalidationR
geometry->ShouldInvalidateToSyncDecodeImages())) {
bool snap;
aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap));
}
nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
}
-class nsDisplayTableBorderBackground : public nsDisplayTableItem {
+// A display item that draws all collapsed borders for a table.
+// At some point, we may want to find a nicer partitioning for dividing
+// border-collapse segments into their own display items.
+class nsDisplayTableBorderCollapse : public nsDisplayTableItem {
public:
- 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)
+};
+
+void
+nsDisplayTableBorderCollapse::Paint(nsDisplayListBuilder* aBuilder,
+ nsRenderingContext* aCtx)
+{
+ nsPoint pt = ToReferenceFrame();
+ DrawTarget* drawTarget = aCtx->GetDrawTarget();
+
+ gfxPoint devPixelOffset =
+ nsLayoutUtils::PointToGfxPoint(pt, mFrame->PresContext()->AppUnitsPerDevPixel());
+
+ // XXX we should probably get rid of this translation at some stage
+ // But that would mean modifying PaintBCBorders, ugh
+ AutoRestoreTransform autoRestoreTransform(drawTarget);
+ drawTarget->SetTransform(
+ drawTarget->GetTransform().PreTranslate(ToPoint(devPixelOffset)));
+
+ static_cast<nsTableFrame*>(mFrame)->PaintBCBorders(*drawTarget, mVisibleRect - pt);
+}
+
+class nsDisplayTableBackground : public nsDisplayTableItem {
+public:
+ nsDisplayTableBackground(nsDisplayListBuilder* aBuilder,
+ nsTableFrame* aFrame,
+ bool aDrawsBackground) :
+ nsDisplayTableItem(aBuilder, aFrame, aDrawsBackground) {
+ MOZ_COUNT_CTOR(nsDisplayTableBackground);
+ }
+#ifdef NS_BUILD_REFCNT_LOGGING
+ virtual ~nsDisplayTableBackground() {
+ MOZ_COUNT_DTOR(nsDisplayTableBackground);
+ }
+#endif
+
+ virtual void Paint(nsDisplayListBuilder* aBuilder,
+ nsRenderingContext* aCtx) override;
+ NS_DISPLAY_DECL_NAME("TableBorderBackground", TYPE_TABLE_BACKGROUND)
};
#ifdef DEBUG
static bool
IsFrameAllowedInTable(nsIAtom* aType)
{
return IS_TABLE_CELL(aType) ||
nsGkAtoms::tableRowFrame == aType ||
@@ -1277,21 +1317,21 @@ IsFrameAllowedInTable(nsIAtom* aType)
nsGkAtoms::scrollFrame == aType ||
nsGkAtoms::tableFrame == aType ||
nsGkAtoms::tableColFrame == aType ||
nsGkAtoms::tableColGroupFrame == aType;
}
#endif
void
-nsDisplayTableBorderBackground::Paint(nsDisplayListBuilder* aBuilder,
+nsDisplayTableBackground::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx)
{
DrawResult result = static_cast<nsTableFrame*>(mFrame)->
- PaintTableBorderBackground(aBuilder, *aCtx, mVisibleRect,
+ PaintTableBackground(aBuilder, *aCtx, mVisibleRect,
ToReferenceFrame());
nsDisplayTableItemGeometry::UpdateDrawResult(this, result);
}
static int32_t
GetTablePartRank(nsDisplayItem* aItem)
{
@@ -1475,19 +1515,27 @@ nsTableFrame::BuildDisplayList(nsDisplay
// This background is created if any of the table parts are visible,
// or if we're doing event handling (since DisplayGenericTablePart
// needs the item for the |sortEventBackgrounds|-dependent code).
// Specific visibility decisions are delegated to the table background
// painter, which handles borders and backgrounds for the table.
if (aBuilder->IsForEventDelivery() ||
AnyTablePartHasBorderOrBackground(this, this, GetNextSibling()) ||
AnyTablePartHasBorderOrBackground(this, mColGroups.FirstChild(), nullptr)) {
- item = new (aBuilder) nsDisplayTableBorderBackground(aBuilder, this,
+ item = new (aBuilder) nsDisplayTableBackground(aBuilder, this,
deflate != nsMargin(0, 0, 0, 0));
aLists.BorderBackground()->AppendNewToTop(item);
+
+ if (IsBorderCollapse()) {
+ aLists.BorderBackground()->AppendNewToTop(
+ new (aBuilder) nsDisplayTableBorderCollapse(aBuilder, this));
+ } else {
+ aLists.BorderBackground()->AppendNewToTop(
+ new (aBuilder) nsDisplayBorder(aBuilder, this));
+ }
}
}
DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists, item);
if (item) {
UpdateItemForColGroupBackgrounds(item, mColGroups);
}
}
@@ -1500,63 +1548,34 @@ nsTableFrame::GetDeflationForBackground(
WritingMode wm = GetWritingMode();
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)
+nsTableFrame::PaintTableBackground(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
{
if (MOZ_UNLIKELY(StyleBorder()->mBoxDecorationBreak ==
StyleBoxDecorationBreak::Clone)) {
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -262,23 +262,22 @@ public:
virtual void GetChildLists(nsTArray<ChildList>* aLists) const override;
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
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.
+ * columns, row groups, rows, and cells)
*/
- DrawResult PaintTableBorderBackground(nsDisplayListBuilder* aBuilder,
- nsRenderingContext& aRenderingContext,
- const nsRect& aDirtyRect,
- nsPoint aPt);
+ DrawResult PaintTableBackground(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.
*/
LogicalMargin GetOuterBCBorder(const WritingMode aWM) const;
/** Same as above, but only if it's included from the border-box width