diff options
Diffstat (limited to 'layout/tables/nsTableFrame.cpp')
-rw-r--r-- | layout/tables/nsTableFrame.cpp | 381 |
1 files changed, 248 insertions, 133 deletions
diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index e7fd7340bf..a2f8b2b625 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -1235,10 +1235,10 @@ LogicalSides nsTableFrame::GetLogicalSkipSides() const { // frame attribute was accounted for in nsHTMLTableElement::MapTableBorderInto // account for pagination if (GetPrevInFlow()) { - skip |= eLogicalSideBitsBStart; + skip += LogicalSide::BStart; } if (GetNextInFlow()) { - skip |= eLogicalSideBitsBEnd; + skip += LogicalSide::BEnd; } return skip; } @@ -1615,7 +1615,6 @@ void nsTableFrame::Reflow(nsPresContext* aPresContext, nsReflowStatus& aStatus) { MarkInReflow(); DO_GLOBAL_REFLOW_COUNT("nsTableFrame"); - DISPLAY_REFLOW(aPresContext, this, aReflowInput, aDesiredSize, aStatus); MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); MOZ_ASSERT(!HasAnyStateBits(NS_FRAME_OUT_OF_FLOW), "The nsTableWrapperFrame should be the out-of-flow if needed"); @@ -2393,8 +2392,11 @@ nsMargin nsTableFrame::GetUsedMargin() const { return nsMargin(0, 0, 0, 0); } -// TODO(TYLin): Should this property only be set on the first-in-flow of -// nsTableFrame? +// TODO(TYLin, dshin): This ideally should be set only in first-in-flow. +// However, the current implementation of border-collapsed table does not +// handle continuation gracefully. One concrete issue is shown in bug 1881157 +// comment 3. It is also unclear if the damage area, current included in this +// property, should be stored separately per-continuation. NS_DECLARE_FRAME_PROPERTY_DELETABLE(TableBCDataProperty, TableBCData) TableBCData* nsTableFrame::GetTableBCData() const { @@ -3800,24 +3802,29 @@ class BCMapCellIterator; /***************************************************************** * BCMapCellInfo - * This structure stores information about the cellmap and all involved - * table related frames that are used during the computation of winning borders - * in CalcBCBorders so that they do need to be looked up again and again when - * iterating over the cells. + * This structure stores information during the computation of winning borders + * in CalcBCBorders, so that they don't need to be looked up repeatedly. ****************************************************************/ -struct BCMapCellInfo { +struct BCMapCellInfo final { explicit BCMapCellInfo(nsTableFrame* aTableFrame); void ResetCellInfo(); void SetInfo(nsTableRowFrame* aNewRow, int32_t aColIndex, BCCellData* aCellData, BCMapCellIterator* aIter, nsCellMap* aCellMap = nullptr); - // functions to set the border widths on the table related frames, where the - // knowledge about the current position in the table is used. - void SetTableBStartBorderWidth(BCPixelSize aWidth); - void SetTableIStartBorderWidth(int32_t aRowB, BCPixelSize aWidth); - void SetTableIEndBorderWidth(int32_t aRowB, BCPixelSize aWidth); - void SetTableBEndBorderWidth(BCPixelSize aWidth); + // Functions to (re)set the border widths on the table related cell frames, + // where the knowledge about the current position in the table is used. + // For most "normal" cells that have row/colspan of 1, these functions + // are called once at most during the reflow, setting the value as given + // (Discarding the value from the previous reflow, which is now irrelevant). + // However, for cells spanning multiple rows/coluns, the maximum border + // width seen is stored. This is controlled by calling the reset functions + // before the cell's border is computed the first time. + void ResetIStartBorderWidths(); + void ResetIEndBorderWidths(); + void ResetBStartBorderWidths(); + void ResetBEndBorderWidths(); + void SetIStartBorderWidths(BCPixelSize aWidth); void SetIEndBorderWidths(BCPixelSize aWidth); void SetBStartBorderWidths(BCPixelSize aWidth); @@ -3845,12 +3852,12 @@ struct BCMapCellInfo { int32_t GetCellEndRowIndex() const; int32_t GetCellEndColIndex() const; - // storage of table information + // Storage of table information required to compute individual cell + // information. nsTableFrame* mTableFrame; nsTableFrame* mTableFirstInFlow; int32_t mNumTableRows; int32_t mNumTableCols; - TableBCData* mTableBCData; WritingMode mTableWM; // a cell can only belong to one rowgroup @@ -3893,7 +3900,6 @@ BCMapCellInfo::BCMapCellInfo(nsTableFrame* aTableFrame) mTableFirstInFlow(static_cast<nsTableFrame*>(aTableFrame->FirstInFlow())), mNumTableRows(aTableFrame->GetRowCount()), mNumTableCols(aTableFrame->GetColCount()), - mTableBCData(mTableFirstInFlow->GetTableBCData()), mTableWM(aTableFrame->Style()), mCurrentRowFrame(nullptr), mCurrentColGroupFrame(nullptr), @@ -3922,6 +3928,36 @@ inline int32_t BCMapCellInfo::GetCellEndColIndex() const { return mColIndex + mColSpan - 1; } +static TableBCData* GetTableBCData(nsTableFrame* aTableFrame) { + auto* firstInFlow = static_cast<nsTableFrame*>(aTableFrame->FirstInFlow()); + return firstInFlow->GetTableBCData(); +} + +/***************************************************************** + * BCMapTableInfo + * This structure stores controls border information global to the + * table computed during the border-collapsed border calcuation. + ****************************************************************/ +struct BCMapTableInfo final { + explicit BCMapTableInfo(nsTableFrame* aTableFrame) + : mTableBCData{GetTableBCData(aTableFrame)} {} + + void ResetTableIStartBorderWidth() { mTableBCData->mIStartBorderWidth = 0; } + + void ResetTableIEndBorderWidth() { mTableBCData->mIEndBorderWidth = 0; } + + void ResetTableBStartBorderWidth() { mTableBCData->mBStartBorderWidth = 0; } + + void ResetTableBEndBorderWidth() { mTableBCData->mBEndBorderWidth = 0; } + + void SetTableIStartBorderWidth(int32_t aRowB, BCPixelSize aWidth); + void SetTableIEndBorderWidth(int32_t aRowB, BCPixelSize aWidth); + void SetTableBStartBorderWidth(BCPixelSize aWidth); + void SetTableBEndBorderWidth(BCPixelSize aWidth); + + TableBCData* mTableBCData; +}; + class BCMapCellIterator { public: BCMapCellIterator(nsTableFrame* aTableFrame, const TableArea& aDamageArea); @@ -4537,7 +4573,7 @@ struct BCCornerInfo { ownerColor = 0; ownerWidth = subWidth = ownerElem = subSide = subElem = hasDashDot = numSegs = bevel = 0; - ownerSide = eLogicalSideBStart; + ownerSide = static_cast<uint16_t>(LogicalSide::BStart); ownerStyle = BORDER_STYLE_UNSET; subStyle = StyleBorderStyle::Solid; } @@ -4552,7 +4588,7 @@ struct BCCornerInfo { // border perpendicular to ownerSide StyleBorderStyle subStyle; // border style of subElem StyleBorderStyle ownerStyle; // border style of ownerElem - uint16_t ownerSide : 2; // LogicalSide (e.g eLogicalSideBStart, etc) of the + uint16_t ownerSide : 2; // LogicalSide (e.g LogicalSide::BStart, etc) of the // border owning the corner relative to the corner uint16_t ownerElem : 4; // elem type (e.g. eTable, eGroup, etc) owning the corner @@ -4575,7 +4611,7 @@ void BCCornerInfo::Set(mozilla::LogicalSide aSide, BCCellBorder aBorder) { ownerStyle = aBorder.style; ownerWidth = aBorder.width; ownerColor = aBorder.color; - ownerSide = aSide; + ownerSide = static_cast<uint16_t>(aSide); hasDashDot = 0; numSegs = 0; if (aBorder.width > 0) { @@ -4586,7 +4622,8 @@ void BCCornerInfo::Set(mozilla::LogicalSide aSide, BCCellBorder aBorder) { bevel = 0; subWidth = 0; // the following will get set later - subSide = IsInline(aSide) ? eLogicalSideBStart : eLogicalSideIStart; + subSide = static_cast<uint16_t>(IsInline(aSide) ? LogicalSide::BStart + : LogicalSide::IStart); subElem = eTableOwner; subStyle = StyleBorderStyle::Solid; } @@ -4631,16 +4668,16 @@ void BCCornerInfo::Update(mozilla::LogicalSide aSide, BCCellBorder aBorder) { subStyle = tempBorder.style; subWidth = tempBorder.width; if (!firstWins) { - subSide = aSide; + subSide = static_cast<uint16_t>(aSide); } } } else { // input args are dominant - ownerSide = aSide; + ownerSide = static_cast<uint16_t>(aSide); if (::Perpendicular(oldSide, LogicalSide(ownerSide))) { subElem = oldBorder.owner; subStyle = oldBorder.style; subWidth = oldBorder.width; - subSide = oldSide; + subSide = static_cast<uint16_t>(oldSide); } } if (aBorder.width > 0) { @@ -4858,13 +4895,8 @@ void nsTableFrame::ExpandBCDamageArea(TableArea& aArea) const { #define ADJACENT true #define INLINE_DIR true -void BCMapCellInfo::SetTableBStartBorderWidth(BCPixelSize aWidth) { - mTableBCData->mBStartBorderWidth = - std::max(mTableBCData->mBStartBorderWidth, aWidth); -} - -void BCMapCellInfo::SetTableIStartBorderWidth(int32_t aRowB, - BCPixelSize aWidth) { +void BCMapTableInfo::SetTableIStartBorderWidth(int32_t aRowB, + BCPixelSize aWidth) { // update the iStart first cell border if (aRowB == 0) { mTableBCData->mIStartCellBorderWidth = aWidth; @@ -4873,7 +4905,8 @@ void BCMapCellInfo::SetTableIStartBorderWidth(int32_t aRowB, std::max(mTableBCData->mIStartBorderWidth, aWidth); } -void BCMapCellInfo::SetTableIEndBorderWidth(int32_t aRowB, BCPixelSize aWidth) { +void BCMapTableInfo::SetTableIEndBorderWidth(int32_t aRowB, + BCPixelSize aWidth) { // update the iEnd first cell border if (aRowB == 0) { mTableBCData->mIEndCellBorderWidth = aWidth; @@ -4882,38 +4915,83 @@ void BCMapCellInfo::SetTableIEndBorderWidth(int32_t aRowB, BCPixelSize aWidth) { std::max(mTableBCData->mIEndBorderWidth, aWidth); } -void BCMapCellInfo::SetIEndBorderWidths(BCPixelSize aWidth) { - // update the borders of the cells and cols affected +void BCMapTableInfo::SetTableBStartBorderWidth(BCPixelSize aWidth) { + mTableBCData->mBStartBorderWidth = + std::max(mTableBCData->mBStartBorderWidth, aWidth); +} + +void BCMapTableInfo::SetTableBEndBorderWidth(BCPixelSize aWidth) { + mTableBCData->mBEndBorderWidth = + std::max(mTableBCData->mBEndBorderWidth, aWidth); +} + +void BCMapCellInfo::ResetIStartBorderWidths() { if (mCell) { - mCell->SetBorderWidth( - eLogicalSideIEnd, - std::max(aWidth, mCell->GetBorderWidth(eLogicalSideIEnd))); + mCell->SetBorderWidth(LogicalSide::IStart, 0); + } + if (mStartCol) { + mStartCol->SetIStartBorderWidth(0); + } +} + +void BCMapCellInfo::ResetIEndBorderWidths() { + if (mCell) { + mCell->SetBorderWidth(LogicalSide::IEnd, 0); } if (mEndCol) { - BCPixelSize half = BC_BORDER_START_HALF(aWidth); - mEndCol->SetIEndBorderWidth(std::max(half, mEndCol->GetIEndBorderWidth())); + mEndCol->SetIEndBorderWidth(0); } } -void BCMapCellInfo::SetBEndBorderWidths(BCPixelSize aWidth) { - // update the borders of the affected cells and rows +void BCMapCellInfo::ResetBStartBorderWidths() { if (mCell) { - mCell->SetBorderWidth( - eLogicalSideBEnd, - std::max(aWidth, mCell->GetBorderWidth(eLogicalSideBEnd))); + mCell->SetBorderWidth(LogicalSide::BStart, 0); + } + if (mStartRow) { + mStartRow->SetBStartBCBorderWidth(0); + } +} + +void BCMapCellInfo::ResetBEndBorderWidths() { + if (mCell) { + mCell->SetBorderWidth(LogicalSide::BEnd, 0); } if (mEndRow) { + mEndRow->SetBEndBCBorderWidth(0); + } +} + +void BCMapCellInfo::SetIStartBorderWidths(BCPixelSize aWidth) { + if (mCell) { + mCell->SetBorderWidth( + LogicalSide::IStart, + std::max(aWidth, mCell->GetBorderWidth(LogicalSide::IStart))); + } + if (mStartCol) { + BCPixelSize half = BC_BORDER_END_HALF(aWidth); + mStartCol->SetIStartBorderWidth( + std::max(half, mStartCol->GetIStartBorderWidth())); + } +} + +void BCMapCellInfo::SetIEndBorderWidths(BCPixelSize aWidth) { + // update the borders of the cells and cols affected + if (mCell) { + mCell->SetBorderWidth( + LogicalSide::IEnd, + std::max(aWidth, mCell->GetBorderWidth(LogicalSide::IEnd))); + } + if (mEndCol) { BCPixelSize half = BC_BORDER_START_HALF(aWidth); - mEndRow->SetBEndBCBorderWidth( - std::max(half, mEndRow->GetBEndBCBorderWidth())); + mEndCol->SetIEndBorderWidth(std::max(half, mEndCol->GetIEndBorderWidth())); } } void BCMapCellInfo::SetBStartBorderWidths(BCPixelSize aWidth) { if (mCell) { mCell->SetBorderWidth( - eLogicalSideBStart, - std::max(aWidth, mCell->GetBorderWidth(eLogicalSideBStart))); + LogicalSide::BStart, + std::max(aWidth, mCell->GetBorderWidth(LogicalSide::BStart))); } if (mStartRow) { BCPixelSize half = BC_BORDER_END_HALF(aWidth); @@ -4922,24 +5000,20 @@ void BCMapCellInfo::SetBStartBorderWidths(BCPixelSize aWidth) { } } -void BCMapCellInfo::SetIStartBorderWidths(BCPixelSize aWidth) { +void BCMapCellInfo::SetBEndBorderWidths(BCPixelSize aWidth) { + // update the borders of the affected cells and rows if (mCell) { mCell->SetBorderWidth( - eLogicalSideIStart, - std::max(aWidth, mCell->GetBorderWidth(eLogicalSideIStart))); + LogicalSide::BEnd, + std::max(aWidth, mCell->GetBorderWidth(LogicalSide::BEnd))); } - if (mStartCol) { - BCPixelSize half = BC_BORDER_END_HALF(aWidth); - mStartCol->SetIStartBorderWidth( - std::max(half, mStartCol->GetIStartBorderWidth())); + if (mEndRow) { + BCPixelSize half = BC_BORDER_START_HALF(aWidth); + mEndRow->SetBEndBCBorderWidth( + std::max(half, mEndRow->GetBEndBCBorderWidth())); } } -void BCMapCellInfo::SetTableBEndBorderWidth(BCPixelSize aWidth) { - mTableBCData->mBEndBorderWidth = - std::max(mTableBCData->mBEndBorderWidth, aWidth); -} - void BCMapCellInfo::SetColumn(int32_t aColX) { mCurrentColFrame = mTableFirstInFlow->GetColFrame(aColX); mCurrentColGroupFrame = @@ -4957,46 +5031,46 @@ void BCMapCellInfo::IncrementRow(bool aResetToBStartRowOfCell) { BCCellBorder BCMapCellInfo::GetBStartEdgeBorder() { return CompareBorders(mTableFrame, mCurrentColGroupFrame, mCurrentColFrame, mRowGroup, mStartRow, mCell, mTableWM, - eLogicalSideBStart, !ADJACENT); + LogicalSide::BStart, !ADJACENT); } BCCellBorder BCMapCellInfo::GetBEndEdgeBorder() { return CompareBorders(mTableFrame, mCurrentColGroupFrame, mCurrentColFrame, - mRowGroup, mEndRow, mCell, mTableWM, eLogicalSideBEnd, + mRowGroup, mEndRow, mCell, mTableWM, LogicalSide::BEnd, ADJACENT); } BCCellBorder BCMapCellInfo::GetIStartEdgeBorder() { return CompareBorders(mTableFrame, mColGroup, mStartCol, mRowGroup, - mCurrentRowFrame, mCell, mTableWM, eLogicalSideIStart, + mCurrentRowFrame, mCell, mTableWM, LogicalSide::IStart, !ADJACENT); } BCCellBorder BCMapCellInfo::GetIEndEdgeBorder() { return CompareBorders(mTableFrame, mColGroup, mEndCol, mRowGroup, - mCurrentRowFrame, mCell, mTableWM, eLogicalSideIEnd, + mCurrentRowFrame, mCell, mTableWM, LogicalSide::IEnd, ADJACENT); } BCCellBorder BCMapCellInfo::GetIEndInternalBorder() { const nsIFrame* cg = mCgAtEnd ? mColGroup : nullptr; return CompareBorders(nullptr, cg, mEndCol, nullptr, nullptr, mCell, mTableWM, - eLogicalSideIEnd, ADJACENT); + LogicalSide::IEnd, ADJACENT); } BCCellBorder BCMapCellInfo::GetIStartInternalBorder() { const nsIFrame* cg = mCgAtStart ? mColGroup : nullptr; return CompareBorders(nullptr, cg, mStartCol, nullptr, nullptr, mCell, - mTableWM, eLogicalSideIStart, !ADJACENT); + mTableWM, LogicalSide::IStart, !ADJACENT); } BCCellBorder BCMapCellInfo::GetBEndInternalBorder() { const nsIFrame* rg = mRgAtEnd ? mRowGroup : nullptr; return CompareBorders(nullptr, nullptr, nullptr, rg, mEndRow, mCell, mTableWM, - eLogicalSideBEnd, ADJACENT); + LogicalSide::BEnd, ADJACENT); } BCCellBorder BCMapCellInfo::GetBStartInternalBorder() { const nsIFrame* rg = mRgAtStart ? mRowGroup : nullptr; return CompareBorders(nullptr, nullptr, nullptr, rg, mStartRow, mCell, - mTableWM, eLogicalSideBStart, !ADJACENT); + mTableWM, LogicalSide::BStart, !ADJACENT); } // Calculate border information for border-collapsed tables. @@ -5115,6 +5189,10 @@ void nsTableFrame::CalcBCBorders() { if (!lastBEndBorders.borders) ABORT0(); BCMapCellInfo info(this); + // TODO(dshin): This is basically propData, except it uses first-in-flow's + // data. Consult the definition of `TableBCDataProperty` regarding + // using the first-in-flow only. + BCMapTableInfo tableInfo(this); // Block-start corners of the cell being traversed, indexed by columns. BCCorners bStartCorners(damageArea.ColCount() + 1, damageArea.StartCol()); @@ -5164,10 +5242,12 @@ void nsTableFrame::CalcBCBorders() { // table, row group, row if the border is at the bStart of the table, // otherwise it was processed in a previous row if (0 == info.mRowIndex) { - if (!tableBorderReset[eLogicalSideBStart]) { - propData->mBStartBorderWidth = 0; - tableBorderReset[eLogicalSideBStart] = true; + uint8_t idxBStart = static_cast<uint8_t>(LogicalSide::BStart); + if (!tableBorderReset[idxBStart]) { + tableInfo.ResetTableBStartBorderWidth(); + tableBorderReset[idxBStart] = true; } + bool reset = false; for (int32_t colIdx = info.mColIndex; colIdx <= info.GetCellEndColIndex(); colIdx++) { info.SetColumn(colIdx); @@ -5175,9 +5255,9 @@ void nsTableFrame::CalcBCBorders() { BCCornerInfo& bStartIStartCorner = bStartCorners[colIdx]; // Mark inline-end direction border from this corner. if (0 == colIdx) { - bStartIStartCorner.Set(eLogicalSideIEnd, currentBorder); + bStartIStartCorner.Set(LogicalSide::IEnd, currentBorder); } else { - bStartIStartCorner.Update(eLogicalSideIEnd, currentBorder); + bStartIStartCorner.Update(LogicalSide::IEnd, currentBorder); tableCellMap->SetBCBorderCorner( LogicalCorner::BStartIStart, *iter.mCellMap, 0, 0, colIdx, LogicalSide(bStartIStartCorner.ownerSide), @@ -5186,7 +5266,7 @@ void nsTableFrame::CalcBCBorders() { // Above, we set the corner `colIndex` column as having a border towards // inline-end, heading towards the next column. Vice versa is also true, // where the next column has a border heading towards this column. - bStartCorners[colIdx + 1].Set(eLogicalSideIStart, currentBorder); + bStartCorners[colIdx + 1].Set(LogicalSide::IStart, currentBorder); MOZ_ASSERT(firstRowBStartEdgeBorder, "Inline start border tracking not set?"); // update firstRowBStartEdgeBorder and see if a new segment starts @@ -5196,13 +5276,17 @@ void nsTableFrame::CalcBCBorders() { firstRowBStartEdgeBorder.ref()) : true; // store the border segment in the cell map - tableCellMap->SetBCBorderEdge(eLogicalSideBStart, *iter.mCellMap, 0, 0, + tableCellMap->SetBCBorderEdge(LogicalSide::BStart, *iter.mCellMap, 0, 0, colIdx, 1, currentBorder.owner, currentBorder.width, startSeg); // Set border width at block-start (table-wide and for the cell), but // only if it's the largest we've encountered. - info.SetTableBStartBorderWidth(currentBorder.width); + tableInfo.SetTableBStartBorderWidth(currentBorder.width); + if (!reset) { + info.ResetBStartBorderWidths(); + reset = true; + } info.SetBStartBorderWidths(currentBorder.width); } } else { @@ -5225,34 +5309,40 @@ void nsTableFrame::CalcBCBorders() { // table, col group, col if the border is at the iStart of the table, // otherwise it was processed in a previous col if (0 == info.mColIndex) { - if (!tableBorderReset[eLogicalSideIStart]) { - propData->mIStartBorderWidth = 0; - tableBorderReset[eLogicalSideIStart] = true; + uint8_t idxIStart = static_cast<uint8_t>(LogicalSide::IStart); + if (!tableBorderReset[idxIStart]) { + tableInfo.ResetTableIStartBorderWidth(); + tableBorderReset[idxIStart] = true; } info.mCurrentRowFrame = nullptr; + bool reset = false; for (int32_t rowB = info.mRowIndex; rowB <= info.GetCellEndRowIndex(); rowB++) { info.IncrementRow(rowB == info.mRowIndex); BCCellBorder currentBorder = info.GetIStartEdgeBorder(); BCCornerInfo& bStartIStartCorner = (0 == rowB) ? bStartCorners[0] : bEndCorners[0]; - bStartIStartCorner.Update(eLogicalSideBEnd, currentBorder); + bStartIStartCorner.Update(LogicalSide::BEnd, currentBorder); tableCellMap->SetBCBorderCorner( LogicalCorner::BStartIStart, *iter.mCellMap, iter.mRowGroupStart, rowB, 0, LogicalSide(bStartIStartCorner.ownerSide), bStartIStartCorner.subWidth, bStartIStartCorner.bevel); - bEndCorners[0].Set(eLogicalSideBStart, currentBorder); + bEndCorners[0].Set(LogicalSide::BStart, currentBorder); // update lastBlockDirBorders and see if a new segment starts bool startSeg = SetBorder(currentBorder, lastBlockDirBorders[0]); // store the border segment in the cell map - tableCellMap->SetBCBorderEdge(eLogicalSideIStart, *iter.mCellMap, + tableCellMap->SetBCBorderEdge(LogicalSide::IStart, *iter.mCellMap, iter.mRowGroupStart, rowB, info.mColIndex, 1, currentBorder.owner, currentBorder.width, startSeg); // Set border width at inline-start (table-wide and for the cell), but // only if it's the largest we've encountered. - info.SetTableIStartBorderWidth(rowB, currentBorder.width); + tableInfo.SetTableIStartBorderWidth(rowB, currentBorder.width); + if (!reset) { + info.ResetIStartBorderWidths(); + reset = true; + } info.SetIStartBorderWidths(currentBorder.width); } } @@ -5261,11 +5351,13 @@ void nsTableFrame::CalcBCBorders() { // cells and the table, row group, row if (info.mNumTableCols == info.GetCellEndColIndex() + 1) { // touches iEnd edge of table - if (!tableBorderReset[eLogicalSideIEnd]) { - propData->mIEndBorderWidth = 0; - tableBorderReset[eLogicalSideIEnd] = true; + uint8_t idxIEnd = static_cast<uint8_t>(LogicalSide::IEnd); + if (!tableBorderReset[idxIEnd]) { + tableInfo.ResetTableIEndBorderWidth(); + tableBorderReset[idxIEnd] = true; } info.mCurrentRowFrame = nullptr; + bool reset = false; for (int32_t rowB = info.mRowIndex; rowB <= info.GetCellEndRowIndex(); rowB++) { info.IncrementRow(rowB == info.mRowIndex); @@ -5275,7 +5367,7 @@ void nsTableFrame::CalcBCBorders() { BCCornerInfo& bStartIEndCorner = (0 == rowB) ? bStartCorners[info.GetCellEndColIndex() + 1] : bEndCorners[info.GetCellEndColIndex() + 1]; - bStartIEndCorner.Update(eLogicalSideBEnd, currentBorder); + bStartIEndCorner.Update(LogicalSide::BEnd, currentBorder); tableCellMap->SetBCBorderCorner( LogicalCorner::BStartIEnd, *iter.mCellMap, iter.mRowGroupStart, rowB, info.GetCellEndColIndex(), @@ -5283,7 +5375,7 @@ void nsTableFrame::CalcBCBorders() { bStartIEndCorner.bevel); BCCornerInfo& bEndIEndCorner = bEndCorners[info.GetCellEndColIndex() + 1]; - bEndIEndCorner.Set(eLogicalSideBStart, currentBorder); + bEndIEndCorner.Set(LogicalSide::BStart, currentBorder); tableCellMap->SetBCBorderCorner( LogicalCorner::BEndIEnd, *iter.mCellMap, iter.mRowGroupStart, rowB, info.GetCellEndColIndex(), LogicalSide(bEndIEndCorner.ownerSide), @@ -5293,12 +5385,16 @@ void nsTableFrame::CalcBCBorders() { currentBorder, lastBlockDirBorders[info.GetCellEndColIndex() + 1]); // store the border segment in the cell map and update cellBorders tableCellMap->SetBCBorderEdge( - eLogicalSideIEnd, *iter.mCellMap, iter.mRowGroupStart, rowB, + LogicalSide::IEnd, *iter.mCellMap, iter.mRowGroupStart, rowB, info.GetCellEndColIndex(), 1, currentBorder.owner, currentBorder.width, startSeg); // Set border width at inline-end (table-wide and for the cell), but // only if it's the largest we've encountered. - info.SetTableIEndBorderWidth(rowB, currentBorder.width); + tableInfo.SetTableIEndBorderWidth(rowB, currentBorder.width); + if (!reset) { + info.ResetIEndBorderWidths(); + reset = true; + } info.SetIEndBorderWidths(currentBorder.width); } } else { @@ -5306,6 +5402,7 @@ void nsTableFrame::CalcBCBorders() { int32_t segLength = 0; BCMapCellInfo ajaInfo(this); BCMapCellInfo priorAjaInfo(this); + bool reset = false; for (int32_t rowB = info.mRowIndex; rowB <= info.GetCellEndRowIndex(); rowB += segLength) { // Grab the cell adjacent to our inline-end. @@ -5325,9 +5422,14 @@ void nsTableFrame::CalcBCBorders() { if (info.GetCellEndColIndex() < damageArea.EndCol() && rowB >= damageArea.StartRow() && rowB < damageArea.EndRow()) { tableCellMap->SetBCBorderEdge( - eLogicalSideIEnd, *iter.mCellMap, iter.mRowGroupStart, rowB, + LogicalSide::IEnd, *iter.mCellMap, iter.mRowGroupStart, rowB, info.GetCellEndColIndex(), segLength, currentBorder.owner, currentBorder.width, startSeg); + if (!reset) { + info.ResetIEndBorderWidths(); + ajaInfo.ResetIStartBorderWidths(); + reset = true; + } info.SetIEndBorderWidths(currentBorder.width); ajaInfo.SetIStartBorderWidths(currentBorder.width); } @@ -5346,7 +5448,7 @@ void nsTableFrame::CalcBCBorders() { ? &bStartCorners[info.GetCellEndColIndex() + 1] : &bEndCorners[info.GetCellEndColIndex() + 1]; // From previous row. - bStartIEndCorner->Update(eLogicalSideBEnd, currentBorder); + bStartIEndCorner->Update(LogicalSide::BEnd, currentBorder); // If this is a rowspan, need to consider if this "corner" is generating // an inline segment for the adjacent cell. e.g. // @@ -5360,7 +5462,7 @@ void nsTableFrame::CalcBCBorders() { BCCellBorder adjacentBorder = ajaInfo.GetBStartInternalBorder(); currentBorder = CompareBorders(!CELL_CORNER, currentBorder, adjacentBorder, INLINE_DIR); - bStartIEndCorner->Update(eLogicalSideIEnd, currentBorder); + bStartIEndCorner->Update(LogicalSide::IEnd, currentBorder); } // Check that the spanned area is inside of the invalidation area if (info.GetCellEndColIndex() < damageArea.EndCol() && @@ -5387,7 +5489,7 @@ void nsTableFrame::CalcBCBorders() { BCCornerInfo& bEndIEndCorner = (hitsSpanOnIEnd) ? bStartCorners[info.GetCellEndColIndex() + 1] : bEndCorners[info.GetCellEndColIndex() + 1]; - bEndIEndCorner.Set(eLogicalSideBStart, currentBorder); + bEndIEndCorner.Set(LogicalSide::BStart, currentBorder); priorAjaInfo = ajaInfo; } } @@ -5400,23 +5502,25 @@ void nsTableFrame::CalcBCBorders() { // cells and the table, row group, row if (info.mNumTableRows == info.GetCellEndRowIndex() + 1) { // touches bEnd edge of table - if (!tableBorderReset[eLogicalSideBEnd]) { - propData->mBEndBorderWidth = 0; - tableBorderReset[eLogicalSideBEnd] = true; + uint8_t idxBEnd = static_cast<uint8_t>(LogicalSide::BEnd); + if (!tableBorderReset[idxBEnd]) { + tableInfo.ResetTableBEndBorderWidth(); + tableBorderReset[idxBEnd] = true; } + bool reset = false; for (int32_t colIdx = info.mColIndex; colIdx <= info.GetCellEndColIndex(); colIdx++) { info.SetColumn(colIdx); BCCellBorder currentBorder = info.GetBEndEdgeBorder(); BCCornerInfo& bEndIStartCorner = bEndCorners[colIdx]; - bEndIStartCorner.Update(eLogicalSideIEnd, currentBorder); + bEndIStartCorner.Update(LogicalSide::IEnd, currentBorder); tableCellMap->SetBCBorderCorner( LogicalCorner::BEndIStart, *iter.mCellMap, iter.mRowGroupStart, info.GetCellEndRowIndex(), colIdx, LogicalSide(bEndIStartCorner.ownerSide), bEndIStartCorner.subWidth, bEndIStartCorner.bevel); BCCornerInfo& bEndIEndCorner = bEndCorners[colIdx + 1]; - bEndIEndCorner.Update(eLogicalSideIStart, currentBorder); + bEndIEndCorner.Update(LogicalSide::IStart, currentBorder); // Store the block-end inline-end corner if it also is the block-end // inline-end of the overall table. if (info.mNumTableCols == colIdx + 1) { @@ -5439,7 +5543,7 @@ void nsTableFrame::CalcBCBorders() { } // store the border segment in the cell map and update cellBorders tableCellMap->SetBCBorderEdge( - eLogicalSideBEnd, *iter.mCellMap, iter.mRowGroupStart, + LogicalSide::BEnd, *iter.mCellMap, iter.mRowGroupStart, info.GetCellEndRowIndex(), colIdx, 1, currentBorder.owner, currentBorder.width, startSeg); // update lastBEndBorders @@ -5449,12 +5553,17 @@ void nsTableFrame::CalcBCBorders() { // Set border width at block-end (table-wide and for the cell), but // only if it's the largest we've encountered. + if (!reset) { + info.ResetBEndBorderWidths(); + reset = true; + } info.SetBEndBorderWidths(currentBorder.width); - info.SetTableBEndBorderWidth(currentBorder.width); + tableInfo.SetTableBEndBorderWidth(currentBorder.width); } } else { int32_t segLength = 0; BCMapCellInfo ajaInfo(this); + bool reset = false; for (int32_t colIdx = info.mColIndex; colIdx <= info.GetCellEndColIndex(); colIdx += segLength) { // Grab the cell adjacent to our block-end. @@ -5486,12 +5595,12 @@ void nsTableFrame::CalcBCBorders() { } else if (prevRowIndex < info.GetCellEndRowIndex() + 1) { // spans below the cell to the iStart side bStartCorners[colIdx] = bEndIStartCorner; - bEndIStartCorner.Set(eLogicalSideIEnd, currentBorder); + bEndIStartCorner.Set(LogicalSide::IEnd, currentBorder); update = false; } } if (update) { - bEndIStartCorner.Update(eLogicalSideIEnd, currentBorder); + bEndIStartCorner.Update(LogicalSide::IEnd, currentBorder); } // Check that the spanned area is inside of the invalidation area if (info.GetCellEndRowIndex() < damageArea.EndRow() && @@ -5506,7 +5615,7 @@ void nsTableFrame::CalcBCBorders() { // Propagate this segment down the colspan for (int32_t c = colIdx + 1; c < colIdx + segLength; c++) { BCCornerInfo& corner = bEndCorners[c]; - corner.Set(eLogicalSideIEnd, currentBorder); + corner.Set(LogicalSide::IEnd, currentBorder); tableCellMap->SetBCBorderCorner( LogicalCorner::BEndIStart, *iter.mCellMap, iter.mRowGroupStart, info.GetCellEndRowIndex(), c, LogicalSide(corner.ownerSide), @@ -5533,15 +5642,21 @@ void nsTableFrame::CalcBCBorders() { if (info.GetCellEndRowIndex() < damageArea.EndRow() && colIdx >= damageArea.StartCol() && colIdx < damageArea.EndCol()) { tableCellMap->SetBCBorderEdge( - eLogicalSideBEnd, *iter.mCellMap, iter.mRowGroupStart, + LogicalSide::BEnd, *iter.mCellMap, iter.mRowGroupStart, info.GetCellEndRowIndex(), colIdx, segLength, currentBorder.owner, currentBorder.width, startSeg); + + if (!reset) { + info.ResetBEndBorderWidths(); + ajaInfo.ResetBStartBorderWidths(); + reset = true; + } info.SetBEndBorderWidths(currentBorder.width); ajaInfo.SetBStartBorderWidths(currentBorder.width); } // update bEnd-iEnd corner BCCornerInfo& bEndIEndCorner = bEndCorners[colIdx + segLength]; - bEndIEndCorner.Update(eLogicalSideIStart, currentBorder); + bEndIEndCorner.Update(LogicalSide::IStart, currentBorder); } } // o------o------o @@ -5570,7 +5685,7 @@ void nsTableFrame::CalcBCBorders() { // new segment if (iter.mCellMap) { tableCellMap->ResetBStartStart( - eLogicalSideBEnd, *iter.mCellMap, iter.mRowGroupStart, + LogicalSide::BEnd, *iter.mCellMap, iter.mRowGroupStart, info.GetCellEndRowIndex(), nextColIndex); } } @@ -6248,7 +6363,7 @@ static nscoord CalcVerCornerOffset(nsPresContext* aPresContext, offset = (aIsStartOfSeg) ? -largeHalf : smallHalf; } else { offset = - (eLogicalSideBStart == aCornerOwnerSide) ? smallHalf : -largeHalf; + (LogicalSide::BStart == aCornerOwnerSide) ? smallHalf : -largeHalf; } } else { DivideBCBorderSize(aHorWidth, smallHalf, largeHalf); @@ -6283,7 +6398,7 @@ static nscoord CalcHorCornerOffset(nsPresContext* aPresContext, offset = (aIsStartOfSeg) ? -largeHalf : smallHalf; } else { offset = - (eLogicalSideIStart == aCornerOwnerSide) ? smallHalf : -largeHalf; + (LogicalSide::IStart == aCornerOwnerSide) ? smallHalf : -largeHalf; } } else { DivideBCBorderSize(aVerWidth, smallHalf, largeHalf); @@ -6305,7 +6420,7 @@ BCBlockDirSeg::BCBlockDirSeg() mCol = nullptr; mFirstCell = mLastCell = mAjaCell = nullptr; mOffsetI = mOffsetB = mLength = mWidth = mBStartBevelOffset = 0; - mBStartBevelSide = eLogicalSideBStart; + mBStartBevelSide = LogicalSide::BStart; mOwner = eCellOwner; } @@ -6322,7 +6437,7 @@ void BCBlockDirSeg::Start(BCPaintBorderIterator& aIter, BCPixelSize aBlockSegISize, BCPixelSize aInlineSegBSize, Maybe<nscoord> aEmptyRowEndBSize) { - LogicalSide ownerSide = eLogicalSideBStart; + LogicalSide ownerSide = LogicalSide::BStart; bool bevel = false; nscoord cornerSubWidth = @@ -6339,7 +6454,7 @@ void BCBlockDirSeg::Start(BCPaintBorderIterator& aIter, bStartBevel ? presContext->DevPixelsToAppUnits(maxInlineSegBSize) : 0; // XXX this assumes that only corners where 2 segments join can be beveled mBStartBevelSide = - (aInlineSegBSize > 0) ? eLogicalSideIEnd : eLogicalSideIStart; + (aInlineSegBSize > 0) ? LogicalSide::IEnd : LogicalSide::IStart; if (aEmptyRowEndBSize && *aEmptyRowEndBSize < offset) { // This segment is starting from an empty row. This will require the the // starting segment to overlap with the previously drawn segment, unless the @@ -6390,7 +6505,7 @@ void BCBlockDirSeg::Initialize(BCPaintBorderIterator& aIter) { */ void BCBlockDirSeg::GetBEndCorner(BCPaintBorderIterator& aIter, BCPixelSize aInlineSegBSize) { - LogicalSide ownerSide = eLogicalSideBStart; + LogicalSide ownerSide = LogicalSide::BStart; nscoord cornerSubWidth = 0; bool bevel = false; if (aIter.mBCData) { @@ -6410,7 +6525,7 @@ Maybe<BCBorderParameters> BCBlockDirSeg::BuildBorderParameters( // get the border style, color and paint the segment LogicalSide side = - aIter.IsDamageAreaIEndMost() ? eLogicalSideIEnd : eLogicalSideIStart; + aIter.IsDamageAreaIEndMost() ? LogicalSide::IEnd : LogicalSide::IStart; int32_t relColIndex = aIter.GetRelativeColIndex(); nsTableColFrame* col = mCol; if (!col) ABORT1(Nothing()); @@ -6430,7 +6545,7 @@ Maybe<BCBorderParameters> BCBlockDirSeg::BuildBorderParameters( owner = aIter.mTable; break; case eAjaColGroupOwner: - side = eLogicalSideIEnd; + side = LogicalSide::IEnd; if (!aIter.IsTableIEndMost() && (relColIndex > 0)) { col = aIter.mBlockDirInfo[relColIndex - 1].mCol; } @@ -6441,7 +6556,7 @@ Maybe<BCBorderParameters> BCBlockDirSeg::BuildBorderParameters( } break; case eAjaColOwner: - side = eLogicalSideIEnd; + side = LogicalSide::IEnd; if (!aIter.IsTableIEndMost() && (relColIndex > 0)) { col = aIter.mBlockDirInfo[relColIndex - 1].mCol; } @@ -6466,7 +6581,7 @@ Maybe<BCBorderParameters> BCBlockDirSeg::BuildBorderParameters( owner = mFirstRow; break; case eAjaCellOwner: - side = eLogicalSideIEnd; + side = LogicalSide::IEnd; cell = mAjaCell; [[fallthrough]]; case eCellOwner: @@ -6487,7 +6602,7 @@ Maybe<BCBorderParameters> BCBlockDirSeg::BuildBorderParameters( (mIsBEndBevel) ? presContext->DevPixelsToAppUnits(mBEndInlineSegBSize) : 0; LogicalSide bEndBevelSide = - (aInlineSegBSize > 0) ? eLogicalSideIEnd : eLogicalSideIStart; + (aInlineSegBSize > 0) ? LogicalSide::IEnd : LogicalSide::IStart; // Convert logical to physical sides/coordinates for DrawTableBorderSegment. @@ -6733,11 +6848,11 @@ void BCBlockDirSeg::IncludeCurrentBorder(BCPaintBorderIterator& aIter) { BCInlineDirSeg::BCInlineDirSeg() : mIsIEndBevel(false), mIEndBevelOffset(0), - mIEndBevelSide(eLogicalSideBStart), + mIEndBevelSide(LogicalSide::BStart), mEndOffset(0), mOwner(eTableOwner) { mOffsetI = mOffsetB = mLength = mWidth = mIStartBevelOffset = 0; - mIStartBevelSide = eLogicalSideBStart; + mIStartBevelSide = LogicalSide::BStart; mFirstCell = mAjaCell = nullptr; } @@ -6751,7 +6866,7 @@ void BCInlineDirSeg::Start(BCPaintBorderIterator& aIter, BCBorderOwner aBorderOwner, BCPixelSize aBEndBlockSegISize, BCPixelSize aInlineSegBSize) { - LogicalSide cornerOwnerSide = eLogicalSideBStart; + LogicalSide cornerOwnerSide = LogicalSide::BStart; bool bevel = false; mOwner = aBorderOwner; @@ -6769,7 +6884,7 @@ void BCInlineDirSeg::Start(BCPaintBorderIterator& aIter, (iStartBevel && (aInlineSegBSize > 0)) ? maxBlockSegISize : 0; // XXX this assumes that only corners where 2 segments join can be beveled mIStartBevelSide = - (aBEndBlockSegISize > 0) ? eLogicalSideBEnd : eLogicalSideBStart; + (aBEndBlockSegISize > 0) ? LogicalSide::BEnd : LogicalSide::BStart; mOffsetI += offset; mLength = -offset; mWidth = aInlineSegBSize; @@ -6787,7 +6902,7 @@ void BCInlineDirSeg::Start(BCPaintBorderIterator& aIter, */ void BCInlineDirSeg::GetIEndCorner(BCPaintBorderIterator& aIter, BCPixelSize aIStartSegISize) { - LogicalSide ownerSide = eLogicalSideBStart; + LogicalSide ownerSide = LogicalSide::BStart; nscoord cornerSubWidth = 0; bool bevel = false; if (aIter.mBCData) { @@ -6805,7 +6920,7 @@ void BCInlineDirSeg::GetIEndCorner(BCPaintBorderIterator& aIter, mIEndBevelOffset = (mIsIEndBevel) ? presContext->DevPixelsToAppUnits(verWidth) : 0; mIEndBevelSide = - (aIStartSegISize > 0) ? eLogicalSideBEnd : eLogicalSideBStart; + (aIStartSegISize > 0) ? LogicalSide::BEnd : LogicalSide::BStart; } Maybe<BCBorderParameters> BCInlineDirSeg::BuildBorderParameters( @@ -6814,7 +6929,7 @@ Maybe<BCBorderParameters> BCInlineDirSeg::BuildBorderParameters( // get the border style, color and paint the segment LogicalSide side = - aIter.IsDamageAreaBEndMost() ? eLogicalSideBEnd : eLogicalSideBStart; + aIter.IsDamageAreaBEndMost() ? LogicalSide::BEnd : LogicalSide::BStart; nsIFrame* rg = aIter.mRg; if (!rg) ABORT1(Nothing()); nsIFrame* row = aIter.mRow; @@ -6855,21 +6970,21 @@ Maybe<BCBorderParameters> BCInlineDirSeg::BuildBorderParameters( owner = aIter.mTableFirstInFlow->GetColFrame(aIter.mColIndex - 1); break; case eAjaRowGroupOwner: - side = eLogicalSideBEnd; + side = LogicalSide::BEnd; rg = (aIter.IsTableBEndMost()) ? aIter.mRg : aIter.mPrevRg; [[fallthrough]]; case eRowGroupOwner: owner = rg; break; case eAjaRowOwner: - side = eLogicalSideBEnd; + side = LogicalSide::BEnd; row = (aIter.IsTableBEndMost()) ? aIter.mRow : aIter.mPrevRow; [[fallthrough]]; case eRowOwner: owner = row; break; case eAjaCellOwner: - side = eLogicalSideBEnd; + side = LogicalSide::BEnd; // if this is null due to the damage area origin-y > 0, then the border // won't show up anyway cell = mAjaCell; @@ -6974,14 +7089,14 @@ void BCPaintBorderIterator::StoreColumnWidth(int32_t aIndex) { * Determine if a block-dir segment owns the corner */ bool BCPaintBorderIterator::BlockDirSegmentOwnsCorner() { - LogicalSide cornerOwnerSide = eLogicalSideBStart; + LogicalSide cornerOwnerSide = LogicalSide::BStart; bool bevel = false; if (mBCData) { mBCData->GetCorner(cornerOwnerSide, bevel); } // unitialized ownerside, bevel - return (eLogicalSideBStart == cornerOwnerSide) || - (eLogicalSideBEnd == cornerOwnerSide); + return (LogicalSide::BStart == cornerOwnerSide) || + (LogicalSide::BEnd == cornerOwnerSide); } /** |