Bug 1825384 - Use app units in border-collapsed table data, not dev pixels. r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D187140
This commit is contained in:
David Shin 2024-05-14 13:51:28 +00:00
parent d8f4e6b197
commit c2e27a0f1a
10 changed files with 289 additions and 254 deletions

View file

@ -146,26 +146,16 @@ enum BCBorderOwner {
eAjaCellOwner = 10 // cell to the top or to the left eAjaCellOwner = 10 // cell to the top or to the left
}; };
// BCPixelSize is in device pixels.
typedef uint16_t BCPixelSize;
// These are the max sizes that are stored. If they are exceeded, then the max // These are the max sizes that are stored. If they are exceeded, then the max
// is stored and the actual value is computed when needed. // is stored and the actual value is computed when needed.
#define MAX_BORDER_WIDTH nscoord((1u << (sizeof(BCPixelSize) * 8)) - 1) #define MAX_BORDER_WIDTH nscoord((1u << (sizeof(uint16_t) * 8)) - 1)
// The half of border on inline/block-axis start side // The half of border on inline/block-axis start side
static inline BCPixelSize BC_BORDER_START_HALF(BCPixelSize px) { static inline nscoord BC_BORDER_START_HALF(nscoord aCoord) {
return px - px / 2; return aCoord - aCoord / 2;
} }
// The half of border on inline/block-axis end side // The half of border on inline/block-axis end side
static inline BCPixelSize BC_BORDER_END_HALF(BCPixelSize px) { return px / 2; } static inline nscoord BC_BORDER_END_HALF(nscoord aCoord) { return aCoord / 2; }
static inline nscoord BC_BORDER_START_HALF_COORD(int32_t d2a, BCPixelSize px) {
return BC_BORDER_START_HALF(px) * d2a;
}
static inline nscoord BC_BORDER_END_HALF_COORD(int32_t d2a, BCPixelSize px) {
return BC_BORDER_END_HALF(px) * d2a;
}
// BCData stores the bstart and istart border info and the corner connecting the // BCData stores the bstart and istart border info and the corner connecting the
// two. // two.
@ -183,10 +173,9 @@ class BCData {
void SetBStartEdge(BCBorderOwner aOwner, nscoord aSize, bool aStart); void SetBStartEdge(BCBorderOwner aOwner, nscoord aSize, bool aStart);
BCPixelSize GetCorner(mozilla::LogicalSide& aCornerOwner, bool& aBevel) const; nscoord GetCorner(mozilla::LogicalSide& aOwnerSide, bool& aBevel) const;
void SetCorner(BCPixelSize aSubSize, mozilla::LogicalSide aOwner, void SetCorner(nscoord aSubSize, mozilla::LogicalSide aOwner, bool aBevel);
bool aBevel);
inline bool IsIStartStart() const { return (bool)mIStartStart; } inline bool IsIStartStart() const { return (bool)mIStartStart; }
@ -197,23 +186,23 @@ class BCData {
inline void SetBStartStart(bool aValue) { mBStartStart = aValue; } inline void SetBStartStart(bool aValue) { mBStartStart = aValue; }
protected: protected:
BCPixelSize mIStartSize; // size in pixels of iStart border nscoord mIStartSize; // size of iStart border
BCPixelSize mBStartSize; // size in pixels of bStart border nscoord mBStartSize; // size of bStart border
BCPixelSize mCornerSubSize; // size of the largest border not in the nscoord mCornerSubSize; // size of the largest border not in the
// dominant plane (for example, if corner is // dominant plane (for example, if corner is
// owned by the segment to its bStart or bEnd, // owned by the segment to its bStart or bEnd,
// then the size is the max of the border // then the size is the max of the border
// sizes of the segments to its iStart or iEnd. // sizes of the segments to its iStart or iEnd.
unsigned mIStartOwner : 4; // owner of iStart border unsigned mIStartOwner : 4; // owner of iStart border
unsigned mBStartOwner : 4; // owner of bStart border unsigned mBStartOwner : 4; // owner of bStart border
unsigned mIStartStart : 1; // set if this is the start of a block-dir border unsigned mIStartStart : 1; // set if this is the start of a block-dir border
// segment // segment
unsigned mBStartStart : 1; // set if this is the start of an inline-dir unsigned mBStartStart : 1; // set if this is the start of an inline-dir
// border segment // border segment
unsigned mCornerSide : 2; // LogicalSide of the owner of the bStart-iStart unsigned mCornerSide : 2; // LogicalSide of the owner of the bStart-iStart
// corner relative to the corner // corner relative to the corner
unsigned mCornerBevel : 1; // is the corner beveled (only two segments, unsigned mCornerBevel : 1; // is the corner beveled (only two segments,
// perpendicular, not dashed or dotted). // perpendicular, not dashed or dotted).
}; };
// BCCellData entries replace CellData entries in the cell map if the border // BCCellData entries replace CellData entries in the cell map if the border
@ -383,15 +372,15 @@ inline void BCData::SetBStartEdge(BCBorderOwner aOwner, nscoord aSize,
SetBStartStart(aStart); SetBStartStart(aStart);
} }
inline BCPixelSize BCData::GetCorner(mozilla::LogicalSide& aOwnerSide, inline nscoord BCData::GetCorner(mozilla::LogicalSide& aOwnerSide,
bool& aBevel) const { bool& aBevel) const {
aOwnerSide = mozilla::LogicalSide(mCornerSide); aOwnerSide = mozilla::LogicalSide(mCornerSide);
aBevel = (bool)mCornerBevel; aBevel = (bool)mCornerBevel;
return mCornerSubSize; return mCornerSubSize;
} }
inline void BCData::SetCorner(BCPixelSize aSubSize, inline void BCData::SetCorner(nscoord aSubSize, mozilla::LogicalSide aOwnerSide,
mozilla::LogicalSide aOwnerSide, bool aBevel) { bool aBevel) {
mCornerSubSize = aSubSize; mCornerSubSize = aSubSize;
mCornerSide = static_cast<uint8_t>(aOwnerSide); mCornerSide = static_cast<uint8_t>(aOwnerSide);
mCornerBevel = aBevel; mCornerBevel = aBevel;

View file

@ -5,6 +5,7 @@
#include "nsTableCellFrame.h" #include "nsTableCellFrame.h"
#include "celldata.h"
#include "gfxContext.h" #include "gfxContext.h"
#include "gfxUtils.h" #include "gfxUtils.h"
#include "mozilla/ComputedStyle.h" #include "mozilla/ComputedStyle.h"
@ -962,14 +963,12 @@ nsresult nsBCTableCellFrame::GetFrameName(nsAString& aResult) const {
#endif #endif
LogicalMargin nsBCTableCellFrame::GetBorderWidth(WritingMode aWM) const { LogicalMargin nsBCTableCellFrame::GetBorderWidth(WritingMode aWM) const {
int32_t d2a = PresContext()->AppUnitsPerDevPixel(); return LogicalMargin(
return LogicalMargin(aWM, BC_BORDER_END_HALF_COORD(d2a, mBStartBorder), aWM, BC_BORDER_END_HALF(mBStartBorder), BC_BORDER_START_HALF(mIEndBorder),
BC_BORDER_START_HALF_COORD(d2a, mIEndBorder), BC_BORDER_START_HALF(mBEndBorder), BC_BORDER_END_HALF(mIStartBorder));
BC_BORDER_START_HALF_COORD(d2a, mBEndBorder),
BC_BORDER_END_HALF_COORD(d2a, mIStartBorder));
} }
BCPixelSize nsBCTableCellFrame::GetBorderWidth(LogicalSide aSide) const { nscoord nsBCTableCellFrame::GetBorderWidth(LogicalSide aSide) const {
switch (aSide) { switch (aSide) {
case LogicalSide::BStart: case LogicalSide::BStart:
return BC_BORDER_END_HALF(mBStartBorder); return BC_BORDER_END_HALF(mBStartBorder);
@ -982,7 +981,7 @@ BCPixelSize nsBCTableCellFrame::GetBorderWidth(LogicalSide aSide) const {
} }
} }
void nsBCTableCellFrame::SetBorderWidth(LogicalSide aSide, BCPixelSize aValue) { void nsBCTableCellFrame::SetBorderWidth(LogicalSide aSide, nscoord aValue) {
switch (aSide) { switch (aSide) {
case LogicalSide::BStart: case LogicalSide::BStart:
mBStartBorder = aValue; mBStartBorder = aValue;
@ -1001,11 +1000,9 @@ void nsBCTableCellFrame::SetBorderWidth(LogicalSide aSide, BCPixelSize aValue) {
/* virtual */ /* virtual */
nsMargin nsBCTableCellFrame::GetBorderOverflow() { nsMargin nsBCTableCellFrame::GetBorderOverflow() {
WritingMode wm = GetWritingMode(); WritingMode wm = GetWritingMode();
int32_t d2a = PresContext()->AppUnitsPerDevPixel(); LogicalMargin halfBorder(
LogicalMargin halfBorder(wm, BC_BORDER_START_HALF_COORD(d2a, mBStartBorder), wm, BC_BORDER_START_HALF(mBStartBorder), BC_BORDER_END_HALF(mIEndBorder),
BC_BORDER_END_HALF_COORD(d2a, mIEndBorder), BC_BORDER_END_HALF(mBEndBorder), BC_BORDER_START_HALF(mIStartBorder));
BC_BORDER_END_HALF_COORD(d2a, mBEndBorder),
BC_BORDER_START_HALF_COORD(d2a, mIStartBorder));
return halfBorder.GetPhysicalMargin(wm); return halfBorder.GetPhysicalMargin(wm);
} }

View file

@ -273,11 +273,11 @@ class nsBCTableCellFrame final : public nsTableCellFrame {
mozilla::LogicalMargin GetBorderWidth( mozilla::LogicalMargin GetBorderWidth(
mozilla::WritingMode aWM) const override; mozilla::WritingMode aWM) const override;
// Get the *inner half of the border only*, in pixels. // Get the *inner half of the border only*
BCPixelSize GetBorderWidth(mozilla::LogicalSide aSide) const; nscoord GetBorderWidth(mozilla::LogicalSide aSide) const;
// Set the full (both halves) width of the border // Set the full (both halves) width of the border
void SetBorderWidth(mozilla::LogicalSide aSide, BCPixelSize aPixelValue); void SetBorderWidth(mozilla::LogicalSide aSide, nscoord aValue);
nsMargin GetBorderOverflow() override; nsMargin GetBorderOverflow() override;
@ -288,10 +288,10 @@ class nsBCTableCellFrame final : public nsTableCellFrame {
private: private:
// These are the entire width of the border (the cell edge contains only // These are the entire width of the border (the cell edge contains only
// the inner half). // the inner half).
BCPixelSize mBStartBorder; nscoord mBStartBorder;
BCPixelSize mIEndBorder; nscoord mIEndBorder;
BCPixelSize mBEndBorder; nscoord mBEndBorder;
BCPixelSize mIStartBorder; nscoord mIStartBorder;
}; };
// Implemented here because that's a sane-ish way to make the includes work out. // Implemented here because that's a sane-ish way to make the includes work out.

View file

@ -86,10 +86,10 @@ class nsTableColFrame final : public nsSplittableFrame {
/** convenience method, calls into cellmap */ /** convenience method, calls into cellmap */
int32_t Count() const; int32_t Count() const;
BCPixelSize GetIStartBorderWidth() const { return mIStartBorderWidth; } nscoord GetIStartBorderWidth() const { return mIStartBorderWidth; }
BCPixelSize GetIEndBorderWidth() const { return mIEndBorderWidth; } nscoord GetIEndBorderWidth() const { return mIEndBorderWidth; }
void SetIStartBorderWidth(BCPixelSize aWidth) { mIStartBorderWidth = aWidth; } void SetIStartBorderWidth(nscoord aWidth) { mIStartBorderWidth = aWidth; }
void SetIEndBorderWidth(BCPixelSize aWidth) { mIEndBorderWidth = aWidth; } void SetIEndBorderWidth(nscoord aWidth) { mIEndBorderWidth = aWidth; }
#ifdef DEBUG #ifdef DEBUG
void Dump(int32_t aIndent); void Dump(int32_t aIndent);
@ -272,9 +272,9 @@ class nsTableColFrame final : public nsSplittableFrame {
// colgroup // colgroup
uint32_t mColIndex; uint32_t mColIndex;
// border width in pixels of the inner half of the border only // border widths of the inner half of the border only
BCPixelSize mIStartBorderWidth; nscoord mIStartBorderWidth;
BCPixelSize mIEndBorderWidth; nscoord mIEndBorderWidth;
bool mHasSpecifiedCoord; bool mHasSpecifiedCoord;
}; };

View file

@ -133,12 +133,12 @@ struct TableReflowInput final {
struct TableBCData final { struct TableBCData final {
TableArea mDamageArea; TableArea mDamageArea;
BCPixelSize mBStartBorderWidth = 0; nscoord mBStartBorderWidth = 0;
BCPixelSize mIEndBorderWidth = 0; nscoord mIEndBorderWidth = 0;
BCPixelSize mBEndBorderWidth = 0; nscoord mBEndBorderWidth = 0;
BCPixelSize mIStartBorderWidth = 0; nscoord mIStartBorderWidth = 0;
BCPixelSize mIStartCellBorderWidth = 0; nscoord mIStartCellBorderWidth = 0;
BCPixelSize mIEndCellBorderWidth = 0; nscoord mIEndCellBorderWidth = 0;
}; };
} // namespace mozilla } // namespace mozilla
@ -2414,8 +2414,8 @@ TableBCData* nsTableFrame::GetOrCreateTableBCData() {
return value; return value;
} }
static void DivideBCBorderSize(BCPixelSize aPixelSize, BCPixelSize& aSmallHalf, static void DivideBCBorderSize(nscoord aPixelSize, nscoord& aSmallHalf,
BCPixelSize& aLargeHalf) { nscoord& aLargeHalf) {
aSmallHalf = aPixelSize / 2; aSmallHalf = aPixelSize / 2;
aLargeHalf = aPixelSize - aSmallHalf; aLargeHalf = aPixelSize - aSmallHalf;
} }
@ -2424,14 +2424,13 @@ LogicalMargin nsTableFrame::GetOuterBCBorder(const WritingMode aWM) const {
if (NeedToCalcBCBorders()) { if (NeedToCalcBCBorders()) {
const_cast<nsTableFrame*>(this)->CalcBCBorders(); const_cast<nsTableFrame*>(this)->CalcBCBorders();
} }
int32_t d2a = PresContext()->AppUnitsPerDevPixel();
TableBCData* propData = GetTableBCData(); TableBCData* propData = GetTableBCData();
if (propData) { if (propData) {
return LogicalMargin( return LogicalMargin(aWM,
aWM, BC_BORDER_START_HALF_COORD(d2a, propData->mBStartBorderWidth), BC_BORDER_START_HALF(propData->mBStartBorderWidth),
BC_BORDER_END_HALF_COORD(d2a, propData->mIEndBorderWidth), BC_BORDER_END_HALF(propData->mIEndBorderWidth),
BC_BORDER_END_HALF_COORD(d2a, propData->mBEndBorderWidth), BC_BORDER_END_HALF(propData->mBEndBorderWidth),
BC_BORDER_START_HALF_COORD(d2a, propData->mIStartBorderWidth)); BC_BORDER_START_HALF(propData->mIStartBorderWidth));
} }
return LogicalMargin(aWM); return LogicalMargin(aWM);
} }
@ -2442,14 +2441,13 @@ LogicalMargin nsTableFrame::GetIncludedOuterBCBorder(
const_cast<nsTableFrame*>(this)->CalcBCBorders(); const_cast<nsTableFrame*>(this)->CalcBCBorders();
} }
int32_t d2a = PresContext()->AppUnitsPerDevPixel();
TableBCData* propData = GetTableBCData(); TableBCData* propData = GetTableBCData();
if (propData) { if (propData) {
return LogicalMargin( return LogicalMargin(
aWM, BC_BORDER_START_HALF_COORD(d2a, propData->mBStartBorderWidth), aWM, BC_BORDER_START_HALF(propData->mBStartBorderWidth),
BC_BORDER_END_HALF_COORD(d2a, propData->mIEndCellBorderWidth), BC_BORDER_END_HALF(propData->mIEndCellBorderWidth),
BC_BORDER_END_HALF_COORD(d2a, propData->mBEndBorderWidth), BC_BORDER_END_HALF(propData->mBEndBorderWidth),
BC_BORDER_START_HALF_COORD(d2a, propData->mIStartCellBorderWidth)); BC_BORDER_START_HALF(propData->mIStartCellBorderWidth));
} }
return LogicalMargin(aWM); return LogicalMargin(aWM);
} }
@ -3775,7 +3773,7 @@ struct BCCellBorder {
BCCellBorder() { Reset(0, 1); } BCCellBorder() { Reset(0, 1); }
void Reset(uint32_t aRowIndex, uint32_t aRowSpan); void Reset(uint32_t aRowIndex, uint32_t aRowSpan);
nscolor color; // border segment color nscolor color; // border segment color
BCPixelSize width; // border segment width in pixel coordinates !! nscoord width; // border segment width
StyleBorderStyle style; // border segment style, possible values are defined StyleBorderStyle style; // border segment style, possible values are defined
// in nsStyleConsts.h as StyleBorderStyle::* // in nsStyleConsts.h as StyleBorderStyle::*
BCBorderOwner owner; // border segment owner, possible values are defined BCBorderOwner owner; // border segment owner, possible values are defined
@ -3825,10 +3823,10 @@ struct BCMapCellInfo final {
void ResetBStartBorderWidths(); void ResetBStartBorderWidths();
void ResetBEndBorderWidths(); void ResetBEndBorderWidths();
void SetIStartBorderWidths(BCPixelSize aWidth); void SetIStartBorderWidths(nscoord aWidth);
void SetIEndBorderWidths(BCPixelSize aWidth); void SetIEndBorderWidths(nscoord aWidth);
void SetBStartBorderWidths(BCPixelSize aWidth); void SetBStartBorderWidths(nscoord aWidth);
void SetBEndBorderWidths(BCPixelSize aWidth); void SetBEndBorderWidths(nscoord aWidth);
// functions to compute the borders; they depend on the // functions to compute the borders; they depend on the
// knowledge about the current position in the table. The edge functions // knowledge about the current position in the table. The edge functions
@ -3950,10 +3948,10 @@ struct BCMapTableInfo final {
void ResetTableBEndBorderWidth() { mTableBCData->mBEndBorderWidth = 0; } void ResetTableBEndBorderWidth() { mTableBCData->mBEndBorderWidth = 0; }
void SetTableIStartBorderWidth(int32_t aRowB, BCPixelSize aWidth); void SetTableIStartBorderWidth(int32_t aRowB, nscoord aWidth);
void SetTableIEndBorderWidth(int32_t aRowB, BCPixelSize aWidth); void SetTableIEndBorderWidth(int32_t aRowB, nscoord aWidth);
void SetTableBStartBorderWidth(BCPixelSize aWidth); void SetTableBStartBorderWidth(nscoord aWidth);
void SetTableBEndBorderWidth(BCPixelSize aWidth); void SetTableBEndBorderWidth(nscoord aWidth);
TableBCData* mTableBCData; TableBCData* mTableBCData;
}; };
@ -4337,18 +4335,18 @@ void BCMapCellIterator::PeekIAt(const BCMapCellInfo& aRefInfo,
#define CELL_CORNER true #define CELL_CORNER true
/** return the border style, border color and optionally the width in /** return the border style, border color and optionally the width for a given
* pixel for a given frame and side * frame and side
* @param aFrame - query the info for this frame * @param aFrame - query the info for this frame
* @param aTableWM - the writing-mode of the frame * @param aTableWM - the writing-mode of the frame
* @param aSide - the side of the frame * @param aSide - the side of the frame
* @param aStyle - the border style * @param aStyle - the border style
* @param aColor - the border color * @param aColor - the border color
* @param aWidth - the border width in px * @param aWidth - the border width
*/ */
static void GetColorAndStyle(const nsIFrame* aFrame, WritingMode aTableWM, static void GetColorAndStyle(const nsIFrame* aFrame, WritingMode aTableWM,
LogicalSide aSide, StyleBorderStyle* aStyle, LogicalSide aSide, StyleBorderStyle* aStyle,
nscolor* aColor, BCPixelSize* aWidth = nullptr) { nscolor* aColor, nscoord* aWidth = nullptr) {
MOZ_ASSERT(aFrame, "null frame"); MOZ_ASSERT(aFrame, "null frame");
MOZ_ASSERT(aStyle && aColor, "null argument"); MOZ_ASSERT(aStyle && aColor, "null argument");
@ -4370,8 +4368,7 @@ static void GetColorAndStyle(const nsIFrame* aFrame, WritingMode aTableWM,
nsStyleBorder::BorderColorFieldFor(physicalSide)); nsStyleBorder::BorderColorFieldFor(physicalSide));
if (aWidth) { if (aWidth) {
nscoord width = styleData->GetComputedBorderWidth(physicalSide); *aWidth = styleData->GetComputedBorderWidth(physicalSide);
*aWidth = aFrame->PresContext()->AppUnitsToDevPixels(width);
} }
} }
@ -4582,10 +4579,10 @@ struct BCCornerInfo {
void Update(mozilla::LogicalSide aSide, BCCellBorder border); void Update(mozilla::LogicalSide aSide, BCCellBorder border);
nscolor ownerColor; // color of borderOwner nscolor ownerColor; // color of borderOwner
uint16_t ownerWidth; // pixel width of borderOwner uint16_t ownerWidth; // width of borderOwner
uint16_t subWidth; // pixel width of the largest border intersecting the uint16_t subWidth; // width of the largest border intersecting the
// border perpendicular to ownerSide // border perpendicular to ownerSide
StyleBorderStyle subStyle; // border style of subElem StyleBorderStyle subStyle; // border style of subElem
StyleBorderStyle ownerStyle; // border style of ownerElem StyleBorderStyle ownerStyle; // border style of ownerElem
uint16_t ownerSide : 2; // LogicalSide (e.g LogicalSide::BStart, etc) of the uint16_t ownerSide : 2; // LogicalSide (e.g LogicalSide::BStart, etc) of the
@ -4895,8 +4892,7 @@ void nsTableFrame::ExpandBCDamageArea(TableArea& aArea) const {
#define ADJACENT true #define ADJACENT true
#define INLINE_DIR true #define INLINE_DIR true
void BCMapTableInfo::SetTableIStartBorderWidth(int32_t aRowB, void BCMapTableInfo::SetTableIStartBorderWidth(int32_t aRowB, nscoord aWidth) {
BCPixelSize aWidth) {
// update the iStart first cell border // update the iStart first cell border
if (aRowB == 0) { if (aRowB == 0) {
mTableBCData->mIStartCellBorderWidth = aWidth; mTableBCData->mIStartCellBorderWidth = aWidth;
@ -4905,8 +4901,7 @@ void BCMapTableInfo::SetTableIStartBorderWidth(int32_t aRowB,
std::max(mTableBCData->mIStartBorderWidth, aWidth); std::max(mTableBCData->mIStartBorderWidth, aWidth);
} }
void BCMapTableInfo::SetTableIEndBorderWidth(int32_t aRowB, void BCMapTableInfo::SetTableIEndBorderWidth(int32_t aRowB, nscoord aWidth) {
BCPixelSize aWidth) {
// update the iEnd first cell border // update the iEnd first cell border
if (aRowB == 0) { if (aRowB == 0) {
mTableBCData->mIEndCellBorderWidth = aWidth; mTableBCData->mIEndCellBorderWidth = aWidth;
@ -4915,12 +4910,12 @@ void BCMapTableInfo::SetTableIEndBorderWidth(int32_t aRowB,
std::max(mTableBCData->mIEndBorderWidth, aWidth); std::max(mTableBCData->mIEndBorderWidth, aWidth);
} }
void BCMapTableInfo::SetTableBStartBorderWidth(BCPixelSize aWidth) { void BCMapTableInfo::SetTableBStartBorderWidth(nscoord aWidth) {
mTableBCData->mBStartBorderWidth = mTableBCData->mBStartBorderWidth =
std::max(mTableBCData->mBStartBorderWidth, aWidth); std::max(mTableBCData->mBStartBorderWidth, aWidth);
} }
void BCMapTableInfo::SetTableBEndBorderWidth(BCPixelSize aWidth) { void BCMapTableInfo::SetTableBEndBorderWidth(nscoord aWidth) {
mTableBCData->mBEndBorderWidth = mTableBCData->mBEndBorderWidth =
std::max(mTableBCData->mBEndBorderWidth, aWidth); std::max(mTableBCData->mBEndBorderWidth, aWidth);
} }
@ -4961,20 +4956,20 @@ void BCMapCellInfo::ResetBEndBorderWidths() {
} }
} }
void BCMapCellInfo::SetIStartBorderWidths(BCPixelSize aWidth) { void BCMapCellInfo::SetIStartBorderWidths(nscoord aWidth) {
if (mCell) { if (mCell) {
mCell->SetBorderWidth( mCell->SetBorderWidth(
LogicalSide::IStart, LogicalSide::IStart,
std::max(aWidth, mCell->GetBorderWidth(LogicalSide::IStart))); std::max(aWidth, mCell->GetBorderWidth(LogicalSide::IStart)));
} }
if (mStartCol) { if (mStartCol) {
BCPixelSize half = BC_BORDER_END_HALF(aWidth); nscoord half = BC_BORDER_END_HALF(aWidth);
mStartCol->SetIStartBorderWidth( mStartCol->SetIStartBorderWidth(
std::max(half, mStartCol->GetIStartBorderWidth())); std::max(half, mStartCol->GetIStartBorderWidth()));
} }
} }
void BCMapCellInfo::SetIEndBorderWidths(BCPixelSize aWidth) { void BCMapCellInfo::SetIEndBorderWidths(nscoord aWidth) {
// update the borders of the cells and cols affected // update the borders of the cells and cols affected
if (mCell) { if (mCell) {
mCell->SetBorderWidth( mCell->SetBorderWidth(
@ -4982,25 +4977,25 @@ void BCMapCellInfo::SetIEndBorderWidths(BCPixelSize aWidth) {
std::max(aWidth, mCell->GetBorderWidth(LogicalSide::IEnd))); std::max(aWidth, mCell->GetBorderWidth(LogicalSide::IEnd)));
} }
if (mEndCol) { if (mEndCol) {
BCPixelSize half = BC_BORDER_START_HALF(aWidth); nscoord half = BC_BORDER_START_HALF(aWidth);
mEndCol->SetIEndBorderWidth(std::max(half, mEndCol->GetIEndBorderWidth())); mEndCol->SetIEndBorderWidth(std::max(half, mEndCol->GetIEndBorderWidth()));
} }
} }
void BCMapCellInfo::SetBStartBorderWidths(BCPixelSize aWidth) { void BCMapCellInfo::SetBStartBorderWidths(nscoord aWidth) {
if (mCell) { if (mCell) {
mCell->SetBorderWidth( mCell->SetBorderWidth(
LogicalSide::BStart, LogicalSide::BStart,
std::max(aWidth, mCell->GetBorderWidth(LogicalSide::BStart))); std::max(aWidth, mCell->GetBorderWidth(LogicalSide::BStart)));
} }
if (mStartRow) { if (mStartRow) {
BCPixelSize half = BC_BORDER_END_HALF(aWidth); nscoord half = BC_BORDER_END_HALF(aWidth);
mStartRow->SetBStartBCBorderWidth( mStartRow->SetBStartBCBorderWidth(
std::max(half, mStartRow->GetBStartBCBorderWidth())); std::max(half, mStartRow->GetBStartBCBorderWidth()));
} }
} }
void BCMapCellInfo::SetBEndBorderWidths(BCPixelSize aWidth) { void BCMapCellInfo::SetBEndBorderWidths(nscoord aWidth) {
// update the borders of the affected cells and rows // update the borders of the affected cells and rows
if (mCell) { if (mCell) {
mCell->SetBorderWidth( mCell->SetBorderWidth(
@ -5008,7 +5003,7 @@ void BCMapCellInfo::SetBEndBorderWidths(BCPixelSize aWidth) {
std::max(aWidth, mCell->GetBorderWidth(LogicalSide::BEnd))); std::max(aWidth, mCell->GetBorderWidth(LogicalSide::BEnd)));
} }
if (mEndRow) { if (mEndRow) {
BCPixelSize half = BC_BORDER_START_HALF(aWidth); nscoord half = BC_BORDER_START_HALF(aWidth);
mEndRow->SetBEndBCBorderWidth( mEndRow->SetBEndBCBorderWidth(
std::max(half, mEndRow->GetBEndBCBorderWidth())); std::max(half, mEndRow->GetBEndBCBorderWidth()));
} }
@ -5706,7 +5701,6 @@ struct BCBorderParameters {
StyleBorderStyle mBorderStyle; StyleBorderStyle mBorderStyle;
nscolor mBorderColor; nscolor mBorderColor;
nsRect mBorderRect; nsRect mBorderRect;
int32_t mAppUnitsPerDevPixel;
mozilla::Side mStartBevelSide; mozilla::Side mStartBevelSide;
nscoord mStartBevelOffset; nscoord mStartBevelOffset;
mozilla::Side mEndBevelSide; mozilla::Side mEndBevelSide;
@ -5731,18 +5725,18 @@ struct BCBlockDirSeg {
BCBlockDirSeg(); BCBlockDirSeg();
void Start(BCPaintBorderIterator& aIter, BCBorderOwner aBorderOwner, void Start(BCPaintBorderIterator& aIter, BCBorderOwner aBorderOwner,
BCPixelSize aBlockSegISize, BCPixelSize aInlineSegBSize, nscoord aBlockSegISize, nscoord aInlineSegBSize,
Maybe<nscoord> aEmptyRowEndSize); Maybe<nscoord> aEmptyRowEndSize);
void Initialize(BCPaintBorderIterator& aIter); void Initialize(BCPaintBorderIterator& aIter);
void GetBEndCorner(BCPaintBorderIterator& aIter, BCPixelSize aInlineSegBSize); void GetBEndCorner(BCPaintBorderIterator& aIter, nscoord aInlineSegBSize);
Maybe<BCBorderParameters> BuildBorderParameters(BCPaintBorderIterator& aIter, Maybe<BCBorderParameters> BuildBorderParameters(BCPaintBorderIterator& aIter,
BCPixelSize aInlineSegBSize); nscoord aInlineSegBSize);
void Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget, void Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget,
BCPixelSize aInlineSegBSize); nscoord aInlineSegBSize);
void CreateWebRenderCommands(BCPaintBorderIterator& aIter, void CreateWebRenderCommands(BCPaintBorderIterator& aIter,
BCPixelSize aInlineSegBSize, nscoord aInlineSegBSize,
wr::DisplayListBuilder& aBuilder, wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc, const layers::StackingContextHelper& aSc,
const nsPoint& aPt); const nsPoint& aPt);
@ -5753,10 +5747,10 @@ struct BCBlockDirSeg {
nsTableColFrame* mCol; nsTableColFrame* mCol;
int32_t mColWidth; int32_t mColWidth;
}; };
nscoord mOffsetI; // i-offset with respect to the table edge nscoord mOffsetI; // i-offset with respect to the table edge
nscoord mOffsetB; // b-offset with respect to the table edge nscoord mOffsetB; // b-offset with respect to the table edge
nscoord mLength; // block-dir length including corners nscoord mLength; // block-dir length including corners
BCPixelSize mWidth; // thickness in pixels nscoord mWidth; // thickness
nsTableCellFrame* mAjaCell; // previous sibling to the first cell nsTableCellFrame* mAjaCell; // previous sibling to the first cell
// where the segment starts, it can be // where the segment starts, it can be
@ -5768,25 +5762,25 @@ struct BCBlockDirSeg {
nsTableCellFrame* mLastCell; // cell at the current end of the nsTableCellFrame* mLastCell; // cell at the current end of the
// segment // segment
uint8_t mOwner; // owner of the border, defines the uint8_t mOwner; // owner of the border, defines the
// style // style
LogicalSide mBStartBevelSide; // direction to bevel at the bStart LogicalSide mBStartBevelSide; // direction to bevel at the bStart
nscoord mBStartBevelOffset; // how much to bevel at the bStart nscoord mBStartBevelOffset; // how much to bevel at the bStart
BCPixelSize mBEndInlineSegBSize; // bSize of the crossing nscoord mBEndInlineSegBSize; // bSize of the crossing
// inline-dir border // inline-dir border
nscoord mBEndOffset; // how much longer is the segment due nscoord mBEndOffset; // how much longer is the segment due
// to the inline-dir border, by this // to the inline-dir border, by this
// amount the next segment needs to be // amount the next segment needs to be
// shifted. // shifted.
bool mIsBEndBevel; // should we bevel at the bEnd bool mIsBEndBevel; // should we bevel at the bEnd
}; };
struct BCInlineDirSeg { struct BCInlineDirSeg {
BCInlineDirSeg(); BCInlineDirSeg();
void Start(BCPaintBorderIterator& aIter, BCBorderOwner aBorderOwner, void Start(BCPaintBorderIterator& aIter, BCBorderOwner aBorderOwner,
BCPixelSize aBEndBlockSegISize, BCPixelSize aInlineSegBSize); nscoord aBEndBlockSegISize, nscoord aInlineSegBSize);
void GetIEndCorner(BCPaintBorderIterator& aIter, BCPixelSize aIStartSegISize); void GetIEndCorner(BCPaintBorderIterator& aIter, nscoord aIStartSegISize);
void AdvanceOffsetI(); void AdvanceOffsetI();
void IncludeCurrentBorder(BCPaintBorderIterator& aIter); void IncludeCurrentBorder(BCPaintBorderIterator& aIter);
Maybe<BCBorderParameters> BuildBorderParameters(BCPaintBorderIterator& aIter); Maybe<BCBorderParameters> BuildBorderParameters(BCPaintBorderIterator& aIter);
@ -5799,7 +5793,7 @@ struct BCInlineDirSeg {
nscoord mOffsetI; // i-offset with respect to the table edge nscoord mOffsetI; // i-offset with respect to the table edge
nscoord mOffsetB; // b-offset with respect to the table edge nscoord mOffsetB; // b-offset with respect to the table edge
nscoord mLength; // inline-dir length including corners nscoord mLength; // inline-dir length including corners
BCPixelSize mWidth; // border thickness in pixels nscoord mWidth; // border thickness
nscoord mIStartBevelOffset; // how much to bevel at the iStart nscoord mIStartBevelOffset; // how much to bevel at the iStart
LogicalSide mIStartBevelSide; // direction to bevel at the iStart LogicalSide mIStartBevelSide; // direction to bevel at the iStart
bool mIsIEndBevel; // should we bevel at the iEnd end bool mIsIEndBevel; // should we bevel at the iEnd end
@ -5986,10 +5980,10 @@ class BCPaintBorderIterator {
// It has one more elements than columns are // It has one more elements than columns are
// in the table. // in the table.
UniquePtr<BCBlockDirSeg[]> mBlockDirInfo; UniquePtr<BCBlockDirSeg[]> mBlockDirInfo;
BCInlineDirSeg mInlineSeg; // the inline-dir segment while we BCInlineDirSeg mInlineSeg; // the inline-dir segment while we
// move over the colums // move over the colums
BCPixelSize mPrevInlineSegBSize; // the bSize of the previous nscoord mPrevInlineSegBSize; // the bSize of the previous
// inline-dir border // inline-dir border
private: private:
bool SetNewRow(nsTableRowFrame* aRow = nullptr); bool SetNewRow(nsTableRowFrame* aRow = nullptr);
@ -6050,19 +6044,18 @@ bool BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect) {
bool haveIntersect = false; bool haveIntersect = false;
// find startRowIndex, endRowIndex // find startRowIndex, endRowIndex
nscoord rowB = mInitialOffsetB; nscoord rowB = mInitialOffsetB;
nsPresContext* presContext = mTable->PresContext();
for (uint32_t rgIdx = 0; rgIdx < mRowGroups.Length() && !done; rgIdx++) { for (uint32_t rgIdx = 0; rgIdx < mRowGroups.Length() && !done; rgIdx++) {
nsTableRowGroupFrame* rgFrame = mRowGroups[rgIdx]; nsTableRowGroupFrame* rgFrame = mRowGroups[rgIdx];
for (nsTableRowFrame* rowFrame = rgFrame->GetFirstRow(); rowFrame; for (nsTableRowFrame* rowFrame = rgFrame->GetFirstRow(); rowFrame;
rowFrame = rowFrame->GetNextRow()) { rowFrame = rowFrame->GetNextRow()) {
// get the row rect relative to the table rather than the row group // get the row rect relative to the table rather than the row group
nscoord rowBSize = rowFrame->BSize(mTableWM); nscoord rowBSize = rowFrame->BSize(mTableWM);
const nscoord onePx = mTable->PresContext()->DevPixelsToAppUnits(1);
if (haveIntersect) { if (haveIntersect) {
// conservatively estimate the half border widths outside the row // conservatively estimate the half border widths outside the row
nscoord borderHalf = mTable->GetPrevInFlow() nscoord borderHalf = mTable->GetPrevInFlow()
? 0 ? 0
: presContext->DevPixelsToAppUnits( : rowFrame->GetBStartBCBorderWidth() + onePx;
rowFrame->GetBStartBCBorderWidth() + 1);
if (dirtyRect.BEnd(mTableWM) >= rowB - borderHalf) { if (dirtyRect.BEnd(mTableWM) >= rowB - borderHalf) {
nsTableRowFrame* fifRow = nsTableRowFrame* fifRow =
@ -6074,8 +6067,7 @@ bool BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect) {
// conservatively estimate the half border widths outside the row // conservatively estimate the half border widths outside the row
nscoord borderHalf = mTable->GetNextInFlow() nscoord borderHalf = mTable->GetNextInFlow()
? 0 ? 0
: presContext->DevPixelsToAppUnits( : rowFrame->GetBEndBCBorderWidth() + onePx;
rowFrame->GetBEndBCBorderWidth() + 1);
if (rowB + rowBSize + borderHalf >= dirtyRect.BStart(mTableWM)) { if (rowB + rowBSize + borderHalf >= dirtyRect.BStart(mTableWM)) {
mStartRg = rgFrame; mStartRg = rgFrame;
mStartRow = rowFrame; mStartRow = rowFrame;
@ -6112,20 +6104,19 @@ bool BCPaintBorderIterator::SetDamageArea(const nsRect& aDirtyRect) {
for (colIdx = 0; colIdx != mNumTableCols; colIdx++) { for (colIdx = 0; colIdx != mNumTableCols; colIdx++) {
nsTableColFrame* colFrame = mTableFirstInFlow->GetColFrame(colIdx); nsTableColFrame* colFrame = mTableFirstInFlow->GetColFrame(colIdx);
if (!colFrame) ABORT1(false); if (!colFrame) ABORT1(false);
const nscoord onePx = mTable->PresContext()->DevPixelsToAppUnits(1);
// get the col rect relative to the table rather than the col group // get the col rect relative to the table rather than the col group
nscoord colISize = colFrame->ISize(mTableWM); nscoord colISize = colFrame->ISize(mTableWM);
if (haveIntersect) { if (haveIntersect) {
// conservatively estimate the iStart half border width outside the col // conservatively estimate the iStart half border width outside the col
nscoord iStartBorderHalf = presContext->DevPixelsToAppUnits( nscoord iStartBorderHalf = colFrame->GetIStartBorderWidth() + onePx;
colFrame->GetIStartBorderWidth() + 1);
if (dirtyRect.IEnd(mTableWM) >= x - iStartBorderHalf) { if (dirtyRect.IEnd(mTableWM) >= x - iStartBorderHalf) {
endColIndex = colIdx; endColIndex = colIdx;
} else } else
break; break;
} else { } else {
// conservatively estimate the iEnd half border width outside the col // conservatively estimate the iEnd half border width outside the col
nscoord iEndBorderHalf = nscoord iEndBorderHalf = colFrame->GetIEndBorderWidth() + onePx;
presContext->DevPixelsToAppUnits(colFrame->GetIEndBorderWidth() + 1);
if (x + colISize + iEndBorderHalf >= dirtyRect.IStart(mTableWM)) { if (x + colISize + iEndBorderHalf >= dirtyRect.IStart(mTableWM)) {
startColIndex = endColIndex = colIdx; startColIndex = endColIndex = colIdx;
haveIntersect = true; haveIntersect = true;
@ -6349,14 +6340,12 @@ void BCPaintBorderIterator::Next() {
* @param aIsBevel - is this corner beveled * @param aIsBevel - is this corner beveled
* @return - offset in twips * @return - offset in twips
*/ */
static nscoord CalcVerCornerOffset(nsPresContext* aPresContext, static nscoord CalcVerCornerOffset(LogicalSide aCornerOwnerSide,
LogicalSide aCornerOwnerSide, nscoord aCornerSubWidth, nscoord aHorWidth,
BCPixelSize aCornerSubWidth, bool aIsStartOfSeg, bool aIsBevel) {
BCPixelSize aHorWidth, bool aIsStartOfSeg,
bool aIsBevel) {
nscoord offset = 0; nscoord offset = 0;
// XXX These should be replaced with appropriate side-specific macros (which?) // XXX These should be replaced with appropriate side-specific macros (which?)
BCPixelSize smallHalf, largeHalf; nscoord smallHalf, largeHalf;
if (IsBlock(aCornerOwnerSide)) { if (IsBlock(aCornerOwnerSide)) {
DivideBCBorderSize(aCornerSubWidth, smallHalf, largeHalf); DivideBCBorderSize(aCornerSubWidth, smallHalf, largeHalf);
if (aIsBevel) { if (aIsBevel) {
@ -6373,7 +6362,7 @@ static nscoord CalcVerCornerOffset(nsPresContext* aPresContext,
offset = (aIsStartOfSeg) ? smallHalf : -largeHalf; offset = (aIsStartOfSeg) ? smallHalf : -largeHalf;
} }
} }
return aPresContext->DevPixelsToAppUnits(offset); return offset;
} }
/** Compute the horizontal offset of a horizontal border segment /** Compute the horizontal offset of a horizontal border segment
@ -6384,14 +6373,12 @@ static nscoord CalcVerCornerOffset(nsPresContext* aPresContext,
* @param aIsBevel - is this corner beveled * @param aIsBevel - is this corner beveled
* @return - offset in twips * @return - offset in twips
*/ */
static nscoord CalcHorCornerOffset(nsPresContext* aPresContext, static nscoord CalcHorCornerOffset(LogicalSide aCornerOwnerSide,
LogicalSide aCornerOwnerSide, nscoord aCornerSubWidth, nscoord aVerWidth,
BCPixelSize aCornerSubWidth, bool aIsStartOfSeg, bool aIsBevel) {
BCPixelSize aVerWidth, bool aIsStartOfSeg,
bool aIsBevel) {
nscoord offset = 0; nscoord offset = 0;
// XXX These should be replaced with appropriate side-specific macros (which?) // XXX These should be replaced with appropriate side-specific macros (which?)
BCPixelSize smallHalf, largeHalf; nscoord smallHalf, largeHalf;
if (IsInline(aCornerOwnerSide)) { if (IsInline(aCornerOwnerSide)) {
DivideBCBorderSize(aCornerSubWidth, smallHalf, largeHalf); DivideBCBorderSize(aCornerSubWidth, smallHalf, largeHalf);
if (aIsBevel) { if (aIsBevel) {
@ -6408,7 +6395,7 @@ static nscoord CalcHorCornerOffset(nsPresContext* aPresContext,
offset = (aIsStartOfSeg) ? smallHalf : -largeHalf; offset = (aIsStartOfSeg) ? smallHalf : -largeHalf;
} }
} }
return aPresContext->DevPixelsToAppUnits(offset); return offset;
} }
BCBlockDirSeg::BCBlockDirSeg() BCBlockDirSeg::BCBlockDirSeg()
@ -6428,14 +6415,13 @@ BCBlockDirSeg::BCBlockDirSeg()
* Start a new block-direction segment * Start a new block-direction segment
* @param aIter - iterator containing the structural information * @param aIter - iterator containing the structural information
* @param aBorderOwner - determines the border style * @param aBorderOwner - determines the border style
* @param aBlockSegISize - the width of segment in pixel * @param aBlockSegISize - the width of segment
* @param aInlineSegBSize - the width of the inline-dir segment joining the * @param aInlineSegBSize - the width of the inline-dir segment joining the
* corner at the start * corner at the start
*/ */
void BCBlockDirSeg::Start(BCPaintBorderIterator& aIter, void BCBlockDirSeg::Start(BCPaintBorderIterator& aIter,
BCBorderOwner aBorderOwner, BCBorderOwner aBorderOwner, nscoord aBlockSegISize,
BCPixelSize aBlockSegISize, nscoord aInlineSegBSize,
BCPixelSize aInlineSegBSize,
Maybe<nscoord> aEmptyRowEndBSize) { Maybe<nscoord> aEmptyRowEndBSize) {
LogicalSide ownerSide = LogicalSide::BStart; LogicalSide ownerSide = LogicalSide::BStart;
bool bevel = false; bool bevel = false;
@ -6444,14 +6430,12 @@ void BCBlockDirSeg::Start(BCPaintBorderIterator& aIter,
(aIter.mBCData) ? aIter.mBCData->GetCorner(ownerSide, bevel) : 0; (aIter.mBCData) ? aIter.mBCData->GetCorner(ownerSide, bevel) : 0;
bool bStartBevel = (aBlockSegISize > 0) ? bevel : false; bool bStartBevel = (aBlockSegISize > 0) ? bevel : false;
BCPixelSize maxInlineSegBSize = nscoord maxInlineSegBSize =
std::max(aIter.mPrevInlineSegBSize, aInlineSegBSize); std::max(aIter.mPrevInlineSegBSize, aInlineSegBSize);
nsPresContext* presContext = aIter.mTable->PresContext(); nscoord offset = CalcVerCornerOffset(ownerSide, cornerSubWidth,
nscoord offset = CalcVerCornerOffset(presContext, ownerSide, cornerSubWidth,
maxInlineSegBSize, true, bStartBevel); maxInlineSegBSize, true, bStartBevel);
mBStartBevelOffset = mBStartBevelOffset = bStartBevel ? maxInlineSegBSize : 0;
bStartBevel ? presContext->DevPixelsToAppUnits(maxInlineSegBSize) : 0;
// XXX this assumes that only corners where 2 segments join can be beveled // XXX this assumes that only corners where 2 segments join can be beveled
mBStartBevelSide = mBStartBevelSide =
(aInlineSegBSize > 0) ? LogicalSide::IEnd : LogicalSide::IStart; (aInlineSegBSize > 0) ? LogicalSide::IEnd : LogicalSide::IStart;
@ -6504,7 +6488,7 @@ void BCBlockDirSeg::Initialize(BCPaintBorderIterator& aIter) {
* corner at the start * corner at the start
*/ */
void BCBlockDirSeg::GetBEndCorner(BCPaintBorderIterator& aIter, void BCBlockDirSeg::GetBEndCorner(BCPaintBorderIterator& aIter,
BCPixelSize aInlineSegBSize) { nscoord aInlineSegBSize) {
LogicalSide ownerSide = LogicalSide::BStart; LogicalSide ownerSide = LogicalSide::BStart;
nscoord cornerSubWidth = 0; nscoord cornerSubWidth = 0;
bool bevel = false; bool bevel = false;
@ -6513,14 +6497,13 @@ void BCBlockDirSeg::GetBEndCorner(BCPaintBorderIterator& aIter,
} }
mIsBEndBevel = (mWidth > 0) ? bevel : false; mIsBEndBevel = (mWidth > 0) ? bevel : false;
mBEndInlineSegBSize = std::max(aIter.mPrevInlineSegBSize, aInlineSegBSize); mBEndInlineSegBSize = std::max(aIter.mPrevInlineSegBSize, aInlineSegBSize);
mBEndOffset = CalcVerCornerOffset(aIter.mTable->PresContext(), ownerSide, mBEndOffset = CalcVerCornerOffset(ownerSide, cornerSubWidth,
cornerSubWidth, mBEndInlineSegBSize, false, mBEndInlineSegBSize, false, mIsBEndBevel);
mIsBEndBevel);
mLength += mBEndOffset; mLength += mBEndOffset;
} }
Maybe<BCBorderParameters> BCBlockDirSeg::BuildBorderParameters( Maybe<BCBorderParameters> BCBlockDirSeg::BuildBorderParameters(
BCPaintBorderIterator& aIter, BCPixelSize aInlineSegBSize) { BCPaintBorderIterator& aIter, nscoord aInlineSegBSize) {
BCBorderParameters result; BCBorderParameters result;
// get the border style, color and paint the segment // get the border style, color and paint the segment
@ -6535,11 +6518,6 @@ Maybe<BCBorderParameters> BCBlockDirSeg::BuildBorderParameters(
result.mBorderColor = 0xFFFFFFFF; result.mBorderColor = 0xFFFFFFFF;
result.mBackfaceIsVisible = true; result.mBackfaceIsVisible = true;
// All the tables frames have the same presContext, so we just use any one
// that exists here:
nsPresContext* presContext = aIter.mTable->PresContext();
result.mAppUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
switch (mOwner) { switch (mOwner) {
case eTableOwner: case eTableOwner:
owner = aIter.mTable; owner = aIter.mTable;
@ -6593,14 +6571,11 @@ Maybe<BCBorderParameters> BCBlockDirSeg::BuildBorderParameters(
&result.mBorderColor); &result.mBorderColor);
result.mBackfaceIsVisible = !owner->BackfaceIsHidden(); result.mBackfaceIsVisible = !owner->BackfaceIsHidden();
} }
BCPixelSize smallHalf, largeHalf; nscoord smallHalf, largeHalf;
DivideBCBorderSize(mWidth, smallHalf, largeHalf); DivideBCBorderSize(mWidth, smallHalf, largeHalf);
LogicalRect segRect( LogicalRect segRect(aIter.mTableWM, mOffsetI - largeHalf, mOffsetB, mWidth,
aIter.mTableWM, mOffsetI - presContext->DevPixelsToAppUnits(largeHalf), mLength);
mOffsetB, presContext->DevPixelsToAppUnits(mWidth), mLength); nscoord bEndBevelOffset = mIsBEndBevel ? mBEndInlineSegBSize : 0;
nscoord bEndBevelOffset =
(mIsBEndBevel) ? presContext->DevPixelsToAppUnits(mBEndInlineSegBSize)
: 0;
LogicalSide bEndBevelSide = LogicalSide bEndBevelSide =
(aInlineSegBSize > 0) ? LogicalSide::IEnd : LogicalSide::IStart; (aInlineSegBSize > 0) ? LogicalSide::IEnd : LogicalSide::IStart;
@ -6643,7 +6618,7 @@ Maybe<BCBorderParameters> BCBlockDirSeg::BuildBorderParameters(
* corner at the start * corner at the start
*/ */
void BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget, void BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget,
BCPixelSize aInlineSegBSize) { nscoord aInlineSegBSize) {
Maybe<BCBorderParameters> param = Maybe<BCBorderParameters> param =
BuildBorderParameters(aIter, aInlineSegBSize); BuildBorderParameters(aIter, aInlineSegBSize);
if (param.isNothing()) { if (param.isNothing()) {
@ -6652,8 +6627,9 @@ void BCBlockDirSeg::Paint(BCPaintBorderIterator& aIter, DrawTarget& aDrawTarget,
nsCSSRendering::DrawTableBorderSegment( nsCSSRendering::DrawTableBorderSegment(
aDrawTarget, param->mBorderStyle, param->mBorderColor, param->mBorderRect, aDrawTarget, param->mBorderStyle, param->mBorderColor, param->mBorderRect,
param->mAppUnitsPerDevPixel, param->mStartBevelSide, aIter.mTable->PresContext()->AppUnitsPerDevPixel(),
param->mStartBevelOffset, param->mEndBevelSide, param->mEndBevelOffset); param->mStartBevelSide, param->mStartBevelOffset, param->mEndBevelSide,
param->mEndBevelOffset);
} }
// Pushes a border bevel triangle and substracts the relevant rectangle from // Pushes a border bevel triangle and substracts the relevant rectangle from
@ -6750,30 +6726,31 @@ static void AdjustAndPushBevel(wr::DisplayListBuilder& aBuilder,
static void CreateWRCommandsForBeveledBorder( static void CreateWRCommandsForBeveledBorder(
const BCBorderParameters& aBorderParams, wr::DisplayListBuilder& aBuilder, const BCBorderParameters& aBorderParams, wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc, const nsPoint& aOffset) { const layers::StackingContextHelper& aSc, const nsPoint& aOffset,
nscoord aAppUnitsPerDevPixel) {
MOZ_ASSERT(aBorderParams.NeedToBevel()); MOZ_ASSERT(aBorderParams.NeedToBevel());
AutoTArray<nsCSSRendering::SolidBeveledBorderSegment, 3> segments; AutoTArray<nsCSSRendering::SolidBeveledBorderSegment, 3> segments;
nsCSSRendering::GetTableBorderSolidSegments( nsCSSRendering::GetTableBorderSolidSegments(
segments, aBorderParams.mBorderStyle, aBorderParams.mBorderColor, segments, aBorderParams.mBorderStyle, aBorderParams.mBorderColor,
aBorderParams.mBorderRect, aBorderParams.mAppUnitsPerDevPixel, aBorderParams.mBorderRect, aAppUnitsPerDevPixel,
aBorderParams.mStartBevelSide, aBorderParams.mStartBevelOffset, aBorderParams.mStartBevelSide, aBorderParams.mStartBevelOffset,
aBorderParams.mEndBevelSide, aBorderParams.mEndBevelOffset); aBorderParams.mEndBevelSide, aBorderParams.mEndBevelOffset);
for (const auto& segment : segments) { for (const auto& segment : segments) {
auto rect = LayoutDeviceRect::FromUnknownRect(NSRectToRect( auto rect = LayoutDeviceRect::FromUnknownRect(
segment.mRect + aOffset, aBorderParams.mAppUnitsPerDevPixel)); NSRectToRect(segment.mRect + aOffset, aAppUnitsPerDevPixel));
auto r = wr::ToLayoutRect(rect); auto r = wr::ToLayoutRect(rect);
auto color = wr::ToColorF(ToDeviceColor(segment.mColor)); auto color = wr::ToColorF(ToDeviceColor(segment.mColor));
// Adjust for the start bevel if needed. // Adjust for the start bevel if needed.
AdjustAndPushBevel(aBuilder, r, segment.mColor, segment.mStartBevel, AdjustAndPushBevel(aBuilder, r, segment.mColor, segment.mStartBevel,
aBorderParams.mAppUnitsPerDevPixel, aAppUnitsPerDevPixel, aBorderParams.mBackfaceIsVisible,
aBorderParams.mBackfaceIsVisible, true); true);
AdjustAndPushBevel(aBuilder, r, segment.mColor, segment.mEndBevel, AdjustAndPushBevel(aBuilder, r, segment.mColor, segment.mEndBevel,
aBorderParams.mAppUnitsPerDevPixel, aAppUnitsPerDevPixel, aBorderParams.mBackfaceIsVisible,
aBorderParams.mBackfaceIsVisible, false); false);
aBuilder.PushRect(r, r, aBorderParams.mBackfaceIsVisible, false, false, aBuilder.PushRect(r, r, aBorderParams.mBackfaceIsVisible, false, false,
color); color);
@ -6782,14 +6759,16 @@ static void CreateWRCommandsForBeveledBorder(
static void CreateWRCommandsForBorderSegment( static void CreateWRCommandsForBorderSegment(
const BCBorderParameters& aBorderParams, wr::DisplayListBuilder& aBuilder, const BCBorderParameters& aBorderParams, wr::DisplayListBuilder& aBuilder,
const layers::StackingContextHelper& aSc, const nsPoint& aOffset) { const layers::StackingContextHelper& aSc, const nsPoint& aOffset,
nscoord aAppUnitsPerDevPixel) {
if (aBorderParams.NeedToBevel()) { if (aBorderParams.NeedToBevel()) {
CreateWRCommandsForBeveledBorder(aBorderParams, aBuilder, aSc, aOffset); CreateWRCommandsForBeveledBorder(aBorderParams, aBuilder, aSc, aOffset,
aAppUnitsPerDevPixel);
return; return;
} }
auto borderRect = LayoutDeviceRect::FromUnknownRect(NSRectToRect( auto borderRect = LayoutDeviceRect::FromUnknownRect(
aBorderParams.mBorderRect + aOffset, aBorderParams.mAppUnitsPerDevPixel)); NSRectToRect(aBorderParams.mBorderRect + aOffset, aAppUnitsPerDevPixel));
wr::LayoutRect r = wr::ToLayoutRect(borderRect); wr::LayoutRect r = wr::ToLayoutRect(borderRect);
wr::BorderSide wrSide[4]; wr::BorderSide wrSide[4];
@ -6820,7 +6799,7 @@ static void CreateWRCommandsForBorderSegment(
} }
void BCBlockDirSeg::CreateWebRenderCommands( void BCBlockDirSeg::CreateWebRenderCommands(
BCPaintBorderIterator& aIter, BCPixelSize aInlineSegBSize, BCPaintBorderIterator& aIter, nscoord aInlineSegBSize,
wr::DisplayListBuilder& aBuilder, const layers::StackingContextHelper& aSc, wr::DisplayListBuilder& aBuilder, const layers::StackingContextHelper& aSc,
const nsPoint& aOffset) { const nsPoint& aOffset) {
Maybe<BCBorderParameters> param = Maybe<BCBorderParameters> param =
@ -6829,7 +6808,9 @@ void BCBlockDirSeg::CreateWebRenderCommands(
return; return;
} }
CreateWRCommandsForBorderSegment(*param, aBuilder, aSc, aOffset); CreateWRCommandsForBorderSegment(
*param, aBuilder, aSc, aOffset,
aIter.mTable->PresContext()->AppUnitsPerDevPixel());
} }
/** /**
@ -6864,8 +6845,8 @@ BCInlineDirSeg::BCInlineDirSeg()
+ */ + */
void BCInlineDirSeg::Start(BCPaintBorderIterator& aIter, void BCInlineDirSeg::Start(BCPaintBorderIterator& aIter,
BCBorderOwner aBorderOwner, BCBorderOwner aBorderOwner,
BCPixelSize aBEndBlockSegISize, nscoord aBEndBlockSegISize,
BCPixelSize aInlineSegBSize) { nscoord aInlineSegBSize) {
LogicalSide cornerOwnerSide = LogicalSide::BStart; LogicalSide cornerOwnerSide = LogicalSide::BStart;
bool bevel = false; bool bevel = false;
@ -6877,9 +6858,8 @@ void BCInlineDirSeg::Start(BCPaintBorderIterator& aIter,
int32_t relColIndex = aIter.GetRelativeColIndex(); int32_t relColIndex = aIter.GetRelativeColIndex();
nscoord maxBlockSegISize = nscoord maxBlockSegISize =
std::max(aIter.mBlockDirInfo[relColIndex].mWidth, aBEndBlockSegISize); std::max(aIter.mBlockDirInfo[relColIndex].mWidth, aBEndBlockSegISize);
nscoord offset = nscoord offset = CalcHorCornerOffset(cornerOwnerSide, cornerSubWidth,
CalcHorCornerOffset(aIter.mTable->PresContext(), cornerOwnerSide, maxBlockSegISize, true, iStartBevel);
cornerSubWidth, maxBlockSegISize, true, iStartBevel);
mIStartBevelOffset = mIStartBevelOffset =
(iStartBevel && (aInlineSegBSize > 0)) ? maxBlockSegISize : 0; (iStartBevel && (aInlineSegBSize > 0)) ? maxBlockSegISize : 0;
// XXX this assumes that only corners where 2 segments join can be beveled // XXX this assumes that only corners where 2 segments join can be beveled
@ -6901,7 +6881,7 @@ void BCInlineDirSeg::Start(BCPaintBorderIterator& aIter,
* corner at the start * corner at the start
*/ */
void BCInlineDirSeg::GetIEndCorner(BCPaintBorderIterator& aIter, void BCInlineDirSeg::GetIEndCorner(BCPaintBorderIterator& aIter,
BCPixelSize aIStartSegISize) { nscoord aIStartSegISize) {
LogicalSide ownerSide = LogicalSide::BStart; LogicalSide ownerSide = LogicalSide::BStart;
nscoord cornerSubWidth = 0; nscoord cornerSubWidth = 0;
bool bevel = false; bool bevel = false;
@ -6913,12 +6893,10 @@ void BCInlineDirSeg::GetIEndCorner(BCPaintBorderIterator& aIter,
int32_t relColIndex = aIter.GetRelativeColIndex(); int32_t relColIndex = aIter.GetRelativeColIndex();
nscoord verWidth = nscoord verWidth =
std::max(aIter.mBlockDirInfo[relColIndex].mWidth, aIStartSegISize); std::max(aIter.mBlockDirInfo[relColIndex].mWidth, aIStartSegISize);
nsPresContext* presContext = aIter.mTable->PresContext(); mEndOffset = CalcHorCornerOffset(ownerSide, cornerSubWidth, verWidth, false,
mEndOffset = CalcHorCornerOffset(presContext, ownerSide, cornerSubWidth, mIsIEndBevel);
verWidth, false, mIsIEndBevel);
mLength += mEndOffset; mLength += mEndOffset;
mIEndBevelOffset = mIEndBevelOffset = mIsIEndBevel ? verWidth : 0;
(mIsIEndBevel) ? presContext->DevPixelsToAppUnits(verWidth) : 0;
mIEndBevelSide = mIEndBevelSide =
(aIStartSegISize > 0) ? LogicalSide::BEnd : LogicalSide::BStart; (aIStartSegISize > 0) ? LogicalSide::BEnd : LogicalSide::BStart;
} }
@ -6938,12 +6916,6 @@ Maybe<BCBorderParameters> BCInlineDirSeg::BuildBorderParameters(
nsIFrame* col; nsIFrame* col;
nsIFrame* owner = nullptr; nsIFrame* owner = nullptr;
result.mBackfaceIsVisible = true; result.mBackfaceIsVisible = true;
// All the tables frames have the same presContext, so we just use any one
// that exists here:
nsPresContext* presContext = aIter.mTable->PresContext();
result.mAppUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
result.mBorderStyle = StyleBorderStyle::Solid; result.mBorderStyle = StyleBorderStyle::Solid;
result.mBorderColor = 0xFFFFFFFF; result.mBorderColor = 0xFFFFFFFF;
@ -6998,19 +6970,17 @@ Maybe<BCBorderParameters> BCInlineDirSeg::BuildBorderParameters(
&result.mBorderColor); &result.mBorderColor);
result.mBackfaceIsVisible = !owner->BackfaceIsHidden(); result.mBackfaceIsVisible = !owner->BackfaceIsHidden();
} }
BCPixelSize smallHalf, largeHalf; nscoord smallHalf, largeHalf;
DivideBCBorderSize(mWidth, smallHalf, largeHalf); DivideBCBorderSize(mWidth, smallHalf, largeHalf);
LogicalRect segRect(aIter.mTableWM, mOffsetI, LogicalRect segRect(aIter.mTableWM, mOffsetI, mOffsetB - largeHalf, mLength,
mOffsetB - presContext->DevPixelsToAppUnits(largeHalf), mWidth);
mLength, presContext->DevPixelsToAppUnits(mWidth));
// Convert logical to physical sides/coordinates for DrawTableBorderSegment. // Convert logical to physical sides/coordinates for DrawTableBorderSegment.
result.mBorderRect = result.mBorderRect =
segRect.GetPhysicalRect(aIter.mTableWM, aIter.mTable->GetSize()); segRect.GetPhysicalRect(aIter.mTableWM, aIter.mTable->GetSize());
result.mStartBevelSide = aIter.mTableWM.PhysicalSide(mIStartBevelSide); result.mStartBevelSide = aIter.mTableWM.PhysicalSide(mIStartBevelSide);
result.mEndBevelSide = aIter.mTableWM.PhysicalSide(mIEndBevelSide); result.mEndBevelSide = aIter.mTableWM.PhysicalSide(mIEndBevelSide);
result.mStartBevelOffset = result.mStartBevelOffset = mIStartBevelOffset;
presContext->DevPixelsToAppUnits(mIStartBevelOffset);
result.mEndBevelOffset = mIEndBevelOffset; result.mEndBevelOffset = mIEndBevelOffset;
// With inline-RTL directionality, the 'start' and 'end' of the inline-dir // With inline-RTL directionality, the 'start' and 'end' of the inline-dir
// border segment need to be swapped because DrawTableBorderSegment will // border segment need to be swapped because DrawTableBorderSegment will
@ -7046,8 +7016,9 @@ void BCInlineDirSeg::Paint(BCPaintBorderIterator& aIter,
nsCSSRendering::DrawTableBorderSegment( nsCSSRendering::DrawTableBorderSegment(
aDrawTarget, param->mBorderStyle, param->mBorderColor, param->mBorderRect, aDrawTarget, param->mBorderStyle, param->mBorderColor, param->mBorderRect,
param->mAppUnitsPerDevPixel, param->mStartBevelSide, aIter.mTable->PresContext()->AppUnitsPerDevPixel(),
param->mStartBevelOffset, param->mEndBevelSide, param->mEndBevelOffset); param->mStartBevelSide, param->mStartBevelOffset, param->mEndBevelSide,
param->mEndBevelOffset);
} }
void BCInlineDirSeg::CreateWebRenderCommands( void BCInlineDirSeg::CreateWebRenderCommands(
@ -7058,7 +7029,9 @@ void BCInlineDirSeg::CreateWebRenderCommands(
return; return;
} }
CreateWRCommandsForBorderSegment(*param, aBuilder, aSc, aPt); CreateWRCommandsForBorderSegment(
*param, aBuilder, aSc, aPt,
aIter.mTable->PresContext()->AppUnitsPerDevPixel());
} }
/** /**

View file

@ -225,12 +225,10 @@ class nsTableRowFrame : public nsContainerFrame {
nscoord GetUnpaginatedBSize() const; nscoord GetUnpaginatedBSize() const;
void SetUnpaginatedBSize(nscoord aValue); void SetUnpaginatedBSize(nscoord aValue);
BCPixelSize GetBStartBCBorderWidth() const { return mBStartBorderWidth; } nscoord GetBStartBCBorderWidth() const { return mBStartBorderWidth; }
BCPixelSize GetBEndBCBorderWidth() const { return mBEndBorderWidth; } nscoord GetBEndBCBorderWidth() const { return mBEndBorderWidth; }
void SetBStartBCBorderWidth(BCPixelSize aWidth) { void SetBStartBCBorderWidth(nscoord aWidth) { mBStartBorderWidth = aWidth; }
mBStartBorderWidth = aWidth; void SetBEndBCBorderWidth(nscoord aWidth) { mBEndBorderWidth = aWidth; }
}
void SetBEndBCBorderWidth(BCPixelSize aWidth) { mBEndBorderWidth = aWidth; }
mozilla::LogicalMargin GetBCBorderWidth(mozilla::WritingMode aWM); mozilla::LogicalMargin GetBCBorderWidth(mozilla::WritingMode aWM);
void InvalidateFrame(uint32_t aDisplayItemKey = 0, void InvalidateFrame(uint32_t aDisplayItemKey = 0,
@ -295,10 +293,13 @@ class nsTableRowFrame : public nsContainerFrame {
nscoord mMaxCellAscent = 0; // does include cells with rowspan > 1 nscoord mMaxCellAscent = 0; // does include cells with rowspan > 1
nscoord mMaxCellDescent = 0; // does *not* include cells with rowspan > 1 nscoord mMaxCellDescent = 0; // does *not* include cells with rowspan > 1
// border widths in pixels in the collapsing border model of the *inner* // border widths in the collapsing border model of the *inner*
// half of the border only // half of the border only
BCPixelSize mBStartBorderWidth = 0; nscoord mBStartBorderWidth = 0;
BCPixelSize mBEndBorderWidth = 0; nscoord mBEndBorderWidth = 0;
nscoord mIEndContBorderWidth = 0;
nscoord mBStartContBorderWidth = 0;
nscoord mIStartContBorderWidth = 0;
/** /**
* Sets the NS_ROW_HAS_CELL_WITH_STYLE_BSIZE bit to indicate whether * Sets the NS_ROW_HAS_CELL_WITH_STYLE_BSIZE bit to indicate whether
@ -387,10 +388,8 @@ inline float nsTableRowFrame::GetPctBSize() const {
inline mozilla::LogicalMargin nsTableRowFrame::GetBCBorderWidth( inline mozilla::LogicalMargin nsTableRowFrame::GetBCBorderWidth(
mozilla::WritingMode aWM) { mozilla::WritingMode aWM) {
nsPresContext* presContext = PresContext(); return mozilla::LogicalMargin(aWM, mBStartBorderWidth, 0, mBEndBorderWidth,
return mozilla::LogicalMargin( 0);
aWM, presContext->DevPixelsToAppUnits(mBStartBorderWidth), 0,
presContext->DevPixelsToAppUnits(mBEndBorderWidth), 0);
} }
#endif #endif

View file

@ -1626,10 +1626,8 @@ LogicalMargin nsTableRowGroupFrame::GetBCBorderWidth(WritingMode aWM) {
rowFrame = rowFrame->GetNextRow()) { rowFrame = rowFrame->GetNextRow()) {
lastRowFrame = rowFrame; lastRowFrame = rowFrame;
} }
border.BStart(aWM) = PresContext()->DevPixelsToAppUnits( border.BStart(aWM) = firstRowFrame->GetBStartBCBorderWidth();
firstRowFrame->GetBStartBCBorderWidth()); border.BEnd(aWM) = lastRowFrame->GetBEndBCBorderWidth();
border.BEnd(aWM) =
PresContext()->DevPixelsToAppUnits(lastRowFrame->GetBEndBCBorderWidth());
return border; return border;
} }

View file

@ -5,3 +5,5 @@
["test_bug541668_table_event_delivery.html"] ["test_bug541668_table_event_delivery.html"]
["test_bug1832110.html"] ["test_bug1832110.html"]
["test_bug1825384.html"]

View file

@ -0,0 +1,77 @@
<!DOCTYPE HTML>
<title>Test for Bug 1825384</title>
<style>
div {
display: inline-block;
}
table {
border-collapse: collapse;
}
td {
border: 10px solid black;
line-height: 0;
padding: 0;
}
span {
display: inline-block;
width: 10px;
height: 10px;
background: grey;
}
</style>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/WindowSnapshot.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script class="testbody" type="text/javascript">
function raf() {
return new Promise(resolve => {
requestAnimationFrame(resolve);
});
}
const zoomsToTest = [
110,
120,
130,
140,
150,
160,
170,
180,
190,
200,
];
const originalZoom = SpecialPowers.getFullZoom(window);
SimpleTest.waitForExplicitFinish();
add_task(async () => {
const s1 = await snapshotRect(window, emptyrows.getBoundingClientRect());
for (let i = 0; i < zoomsToTest.length; ++i) {
let relativeZoom = originalZoom * zoomsToTest[i] / 100;
SpecialPowers.setFullZoom(window, relativeZoom);
await raf();
}
SpecialPowers.setFullZoom(window, originalZoom);
await raf();
const s2 = await snapshotRect(window, emptyrows.getBoundingClientRect());
assertSnapshots(s1, s2, true, null, "before", "after");
});
add_task(async () => { SpecialPowers.setFullZoom(window, originalZoom); });
</script>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1825384">Mozilla Bug 1825384</a><br>
<div id="emptyrows">
<table>
<tr><td><span></span></td><td><span></span></td><td><span></span></td></tr>
<tr></tr>
<tr><td><span></span></td><td><span></span></td><td><span></span></td></tr>
<tr></tr>
<tr><td><span></span></td><td><span></span></td><td><span></span></td></tr>
<tr></tr>
<tr><td><span></span></td><td><span></span></td><td><span></span></td></tr>
</table>
</div>

View file

@ -45,7 +45,7 @@ function raf() {
} }
async function show_table(table, other) { async function show_table(table, other) {
// TODO(dshin): Once bug 1825384 resolves, this should not be needed. // Don't tempt subpixel snapping - try to position each table exactly the same.
table.classList.remove("hide"); table.classList.remove("hide");
other.classList.add("hide"); other.classList.add("hide");
getComputedStyle(table).getPropertyValue("display"); getComputedStyle(table).getPropertyValue("display");