Bug 1173307 - Convert nsTableCellFrame to work with logical coordinates. r=dholbert

This commit is contained in:
Jonathan Kew
2015-06-18 10:11:40 +01:00
parent 59af48a75e
commit 4b4c742821
3 changed files with 143 additions and 130 deletions

View File

@@ -48,10 +48,10 @@ nsTableCellFrame::nsTableCellFrame(nsStyleContext* aContext,
, mDesiredSize(aTableFrame->GetWritingMode()) , mDesiredSize(aTableFrame->GetWritingMode())
{ {
mColIndex = 0; mColIndex = 0;
mPriorAvailWidth = 0; mPriorAvailISize = 0;
SetContentEmpty(false); SetContentEmpty(false);
SetHasPctOverHeight(false); SetHasPctOverBSize(false);
} }
nsTableCellFrame::~nsTableCellFrame() nsTableCellFrame::~nsTableCellFrame()
@@ -581,66 +581,68 @@ nsTableCellFrame::GetBorderOverflow()
// Align the cell's child frame within the cell // Align the cell's child frame within the cell
void nsTableCellFrame::VerticallyAlignChild(nscoord aMaxAscent) void nsTableCellFrame::BlockDirAlignChild(WritingMode aWM, nscoord aMaxAscent)
{ {
/* It's the 'border-collapse' on the table that matters */ /* It's the 'border-collapse' on the table that matters */
nsMargin borderPadding = GetUsedBorderAndPadding(); LogicalMargin borderPadding = GetLogicalUsedBorderAndPadding(aWM);
nscoord topInset = borderPadding.top; nscoord bStartInset = borderPadding.BStart(aWM);
nscoord bottomInset = borderPadding.bottom; nscoord bEndInset = borderPadding.BEnd(aWM);
uint8_t verticalAlignFlags = GetVerticalAlign(); uint8_t verticalAlignFlags = GetVerticalAlign();
nscoord height = mRect.height; nscoord bSize = BSize(aWM);
nsIFrame* firstKid = mFrames.FirstChild(); nsIFrame* firstKid = mFrames.FirstChild();
NS_ASSERTION(firstKid, "Frame construction error, a table cell always has an inner cell frame"); nscoord containerWidth = mRect.width;
nsRect kidRect = firstKid->GetRect(); NS_ASSERTION(firstKid, "Frame construction error, a table cell always has "
nscoord childHeight = kidRect.height; "an inner cell frame");
LogicalRect kidRect = firstKid->GetLogicalRect(aWM, containerWidth);
nscoord childBSize = kidRect.BSize(aWM);
// Vertically align the child // Vertically align the child
nscoord kidYTop = 0; nscoord kidBStart = 0;
switch (verticalAlignFlags) switch (verticalAlignFlags)
{ {
case NS_STYLE_VERTICAL_ALIGN_BASELINE: case NS_STYLE_VERTICAL_ALIGN_BASELINE:
// Align the baselines of the child frame with the baselines of // Align the baselines of the child frame with the baselines of
// other children in the same row which have 'vertical-align: baseline' // other children in the same row which have 'vertical-align: baseline'
kidYTop = topInset + aMaxAscent - GetCellBaseline(); kidBStart = bStartInset + aMaxAscent - GetCellBaseline();
break; break;
case NS_STYLE_VERTICAL_ALIGN_TOP: case NS_STYLE_VERTICAL_ALIGN_TOP:
// Align the top of the child frame with the top of the content area, // Align the top of the child frame with the top of the content area,
kidYTop = topInset; kidBStart = bStartInset;
break; break;
case NS_STYLE_VERTICAL_ALIGN_BOTTOM: case NS_STYLE_VERTICAL_ALIGN_BOTTOM:
// Align the bottom of the child frame with the bottom of the content area, // Align the bottom of the child frame with the bottom of the content area,
kidYTop = height - childHeight - bottomInset; kidBStart = bSize - childBSize - bEndInset;
break; break;
default: default:
case NS_STYLE_VERTICAL_ALIGN_MIDDLE: case NS_STYLE_VERTICAL_ALIGN_MIDDLE:
// Align the middle of the child frame with the middle of the content area, // Align the middle of the child frame with the middle of the content area,
kidYTop = (height - childHeight - bottomInset + topInset) / 2; kidBStart = (bSize - childBSize - bEndInset + bStartInset) / 2;
} }
// if the content is larger than the cell height align from top // if the content is larger than the cell bsize, align from bstart
kidYTop = std::max(0, kidYTop); kidBStart = std::max(0, kidBStart);
if (kidYTop != kidRect.y) { if (kidBStart != kidRect.BStart(aWM)) {
// Invalidate at the old position first // Invalidate at the old position first
firstKid->InvalidateFrameSubtree(); firstKid->InvalidateFrameSubtree();
} }
firstKid->SetPosition(nsPoint(kidRect.x, kidYTop)); firstKid->SetPosition(aWM, LogicalPoint(aWM, kidRect.IStart(aWM),
WritingMode wm = GetWritingMode(); kidBStart), containerWidth);
nsHTMLReflowMetrics desiredSize(wm); nsHTMLReflowMetrics desiredSize(aWM);
desiredSize.SetSize(wm, GetLogicalSize(wm)); desiredSize.SetSize(aWM, GetLogicalSize(aWM));
nsRect overflow(nsPoint(0,0), GetSize()); nsRect overflow(nsPoint(0,0), GetSize());
overflow.Inflate(GetBorderOverflow()); overflow.Inflate(GetBorderOverflow());
desiredSize.mOverflowAreas.SetAllTo(overflow); desiredSize.mOverflowAreas.SetAllTo(overflow);
ConsiderChildOverflow(desiredSize.mOverflowAreas, firstKid); ConsiderChildOverflow(desiredSize.mOverflowAreas, firstKid);
FinishAndStoreOverflow(&desiredSize); FinishAndStoreOverflow(&desiredSize);
if (kidYTop != kidRect.y) { if (kidBStart != kidRect.BStart(aWM)) {
// Make sure any child views are correctly positioned. We know the inner table // Make sure any child views are correctly positioned. We know the inner table
// cell won't have a view // cell won't have a view
nsContainerFrame::PositionChildViews(firstKid); nsContainerFrame::PositionChildViews(firstKid);
@@ -805,8 +807,7 @@ nsTableCellFrame::IntrinsicISizeOffsets()
#define PROBABLY_TOO_LARGE 1000000 #define PROBABLY_TOO_LARGE 1000000
static static
void DebugCheckChildSize(nsIFrame* aChild, void DebugCheckChildSize(nsIFrame* aChild,
nsHTMLReflowMetrics& aMet, nsHTMLReflowMetrics& aMet)
nsSize& aAvailSize)
{ {
WritingMode wm = aMet.GetWritingMode(); WritingMode wm = aMet.GetWritingMode();
if ((aMet.ISize(wm) < 0) || (aMet.ISize(wm) > PROBABLY_TOO_LARGE)) { if ((aMet.ISize(wm) < 0) || (aMet.ISize(wm) > PROBABLY_TOO_LARGE)) {
@@ -816,14 +817,14 @@ void DebugCheckChildSize(nsIFrame* aChild,
} }
#endif #endif
// the computed height for the cell, which descendants use for percent height calculations // the computed bsize for the cell, which descendants use for percent bsize calculations
// it is the height (minus border, padding) of the cell's first in flow during its final // it is the bsize (minus border, padding) of the cell's first in flow during its final
// reflow without an unconstrained height. // reflow without an unconstrained bsize.
static nscoord static nscoord
CalcUnpaginagedHeight(nsPresContext* aPresContext, CalcUnpaginatedBSize(nsPresContext* aPresContext,
nsTableCellFrame& aCellFrame, nsTableCellFrame& aCellFrame,
nsTableFrame& aTableFrame, nsTableFrame& aTableFrame,
nscoord aVerticalBorderPadding) nscoord aBlockDirBorderPadding)
{ {
const nsTableCellFrame* firstCellInFlow = const nsTableCellFrame* firstCellInFlow =
static_cast<nsTableCellFrame*>(aCellFrame.FirstInFlow()); static_cast<nsTableCellFrame*>(aCellFrame.FirstInFlow());
@@ -838,19 +839,19 @@ CalcUnpaginagedHeight(nsPresContext* aPresContext,
firstCellInFlow->GetRowIndex(rowIndex); firstCellInFlow->GetRowIndex(rowIndex);
int32_t rowSpan = aTableFrame.GetEffectiveRowSpan(*firstCellInFlow); int32_t rowSpan = aTableFrame.GetEffectiveRowSpan(*firstCellInFlow);
nscoord computedHeight = firstTableInFlow->GetRowSpacing(rowIndex, nscoord computedBSize = firstTableInFlow->GetRowSpacing(rowIndex,
rowIndex + rowSpan - 1); rowIndex + rowSpan - 1);
computedHeight -= aVerticalBorderPadding; computedBSize -= aBlockDirBorderPadding;
int32_t rowX; int32_t rowX;
for (row = firstRGInFlow->GetFirstRow(), rowX = 0; row; row = row->GetNextRow(), rowX++) { for (row = firstRGInFlow->GetFirstRow(), rowX = 0; row; row = row->GetNextRow(), rowX++) {
if (rowX > rowIndex + rowSpan - 1) { if (rowX > rowIndex + rowSpan - 1) {
break; break;
} }
else if (rowX >= rowIndex) { else if (rowX >= rowIndex) {
computedHeight += row->GetUnpaginatedHeight(aPresContext); computedBSize += row->GetUnpaginatedHeight(aPresContext);
} }
} }
return computedHeight; return computedBSize;
} }
void void
@@ -871,55 +872,54 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext,
nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState); nsTableFrame::CheckRequestSpecialHeightReflow(aReflowState);
aStatus = NS_FRAME_COMPLETE; aStatus = NS_FRAME_COMPLETE;
nsSize availSize(aReflowState.AvailableWidth(), aReflowState.AvailableHeight());
WritingMode wm = aReflowState.GetWritingMode(); WritingMode wm = aReflowState.GetWritingMode();
LogicalSize availSize(wm, aReflowState.AvailableISize(),
aReflowState.AvailableBSize());
LogicalMargin borderPadding = aReflowState.ComputedLogicalPadding(); LogicalMargin borderPadding = aReflowState.ComputedLogicalPadding();
LogicalMargin border = GetBorderWidth(wm); LogicalMargin border = GetBorderWidth(wm);
borderPadding += border; borderPadding += border;
nscoord topInset = borderPadding.Top(wm);
nscoord rightInset = borderPadding.Right(wm);
nscoord bottomInset = borderPadding.Bottom(wm);
nscoord leftInset = borderPadding.Left(wm);
// reduce available space by insets, if we're in a constrained situation // reduce available space by insets, if we're in a constrained situation
availSize.width -= leftInset + rightInset; availSize.ISize(wm) -= borderPadding.IStartEnd(wm);
if (NS_UNCONSTRAINEDSIZE != availSize.height) if (NS_UNCONSTRAINEDSIZE != availSize.BSize(wm)) {
availSize.height -= topInset + bottomInset; availSize.BSize(wm) -= borderPadding.BStartEnd(wm);
}
// Try to reflow the child into the available space. It might not // Try to reflow the child into the available space. It might not
// fit or might need continuing. // fit or might need continuing.
if (availSize.height < 0) if (availSize.BSize(wm) < 0) {
availSize.height = 1; availSize.BSize(wm) = 1;
}
nsHTMLReflowMetrics kidSize(wm, aDesiredSize.mFlags); nsHTMLReflowMetrics kidSize(wm, aDesiredSize.mFlags);
kidSize.ClearSize(); kidSize.ClearSize();
SetPriorAvailWidth(aReflowState.AvailableWidth()); SetPriorAvailISize(aReflowState.AvailableISize());
nsIFrame* firstKid = mFrames.FirstChild(); nsIFrame* firstKid = mFrames.FirstChild();
NS_ASSERTION(firstKid, "Frame construction error, a table cell always has an inner cell frame"); NS_ASSERTION(firstKid, "Frame construction error, a table cell always has an inner cell frame");
nsTableFrame* tableFrame = GetTableFrame(); nsTableFrame* tableFrame = GetTableFrame();
if (aReflowState.mFlags.mSpecialHeightReflow) { if (aReflowState.mFlags.mSpecialHeightReflow) {
const_cast<nsHTMLReflowState&>(aReflowState).SetComputedHeight(mRect.height - topInset - bottomInset); const_cast<nsHTMLReflowState&>(aReflowState).
SetComputedBSize(BSize(wm) - borderPadding.BStartEnd(wm));
DISPLAY_REFLOW_CHANGE(); DISPLAY_REFLOW_CHANGE();
} }
else if (aPresContext->IsPaginated()) { else if (aPresContext->IsPaginated()) {
nscoord computedUnpaginatedHeight = nscoord computedUnpaginatedBSize =
CalcUnpaginagedHeight(aPresContext, (nsTableCellFrame&)*this, CalcUnpaginatedBSize(aPresContext, (nsTableCellFrame&)*this,
*tableFrame, topInset + bottomInset); *tableFrame, borderPadding.BStartEnd(wm));
if (computedUnpaginatedHeight > 0) { if (computedUnpaginatedBSize > 0) {
const_cast<nsHTMLReflowState&>(aReflowState).SetComputedHeight(computedUnpaginatedHeight); const_cast<nsHTMLReflowState&>(aReflowState).SetComputedBSize(computedUnpaginatedBSize);
DISPLAY_REFLOW_CHANGE(); DISPLAY_REFLOW_CHANGE();
} }
} }
else { else {
SetHasPctOverHeight(false); SetHasPctOverBSize(false);
} }
WritingMode kidWM = firstKid->GetWritingMode();
nsHTMLReflowState kidReflowState(aPresContext, aReflowState, firstKid, nsHTMLReflowState kidReflowState(aPresContext, aReflowState, firstKid,
LogicalSize(firstKid->GetWritingMode(), availSize.ConvertTo(kidWM, wm));
availSize));
// Don't be a percent height observer if we're in the middle of // Don't be a percent height observer if we're in the middle of
// special-height reflow, in case we get an accidental NotifyPercentHeight() // special-height reflow, in case we get an accidental NotifyPercentHeight()
@@ -935,19 +935,28 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext,
if (aReflowState.mFlags.mSpecialHeightReflow || if (aReflowState.mFlags.mSpecialHeightReflow ||
(FirstInFlow()->GetStateBits() & NS_TABLE_CELL_HAD_SPECIAL_REFLOW)) { (FirstInFlow()->GetStateBits() & NS_TABLE_CELL_HAD_SPECIAL_REFLOW)) {
// We need to force the kid to have mVResize set if we've had a // We need to force the kid to have mBResize set if we've had a
// special reflow in the past, since the non-special reflow needs to // special reflow in the past, since the non-special reflow needs to
// resize back to what it was without the special height reflow. // resize back to what it was without the special height reflow.
kidReflowState.SetVResize(true); kidReflowState.SetBResize(true);
} }
nsPoint kidOrigin(leftInset, topInset); nscoord containerWidth;
if (aReflowState.ComputedWidth() == NS_UNCONSTRAINEDSIZE) {
containerWidth = 0; // avoid passing unconstrained container width to
// ReflowChild; but position will not be valid
} else {
containerWidth = aReflowState.ComputedWidth() +
aReflowState.ComputedPhysicalBorderPadding().LeftRight();
}
LogicalPoint kidOrigin(wm, borderPadding.IStart(wm),
borderPadding.BStart(wm));
nsRect origRect = firstKid->GetRect(); nsRect origRect = firstKid->GetRect();
nsRect origVisualOverflow = firstKid->GetVisualOverflowRect(); nsRect origVisualOverflow = firstKid->GetVisualOverflowRect();
bool firstReflow = (firstKid->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0; bool firstReflow = (firstKid->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
ReflowChild(firstKid, aPresContext, kidSize, kidReflowState, ReflowChild(firstKid, aPresContext, kidSize, kidReflowState,
kidOrigin.x, kidOrigin.y, 0, aStatus); wm, kidOrigin, containerWidth, 0, aStatus);
if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aStatus)) { if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aStatus)) {
// Don't pass OVERFLOW_INCOMPLETE through tables until they can actually handle it // Don't pass OVERFLOW_INCOMPLETE through tables until they can actually handle it
//XXX should paginate overflow as overflow, but not in this patch (bug 379349) //XXX should paginate overflow as overflow, but not in this patch (bug 379349)
@@ -961,7 +970,7 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext,
} }
#ifdef DEBUG #ifdef DEBUG
DebugCheckChildSize(firstKid, kidSize, availSize); DebugCheckChildSize(firstKid, kidSize);
#endif #endif
// 0 dimensioned cells need to be treated specially in Standard/NavQuirks mode // 0 dimensioned cells need to be treated specially in Standard/NavQuirks mode
@@ -977,42 +986,41 @@ nsTableCellFrame::Reflow(nsPresContext* aPresContext,
// Place the child // Place the child
FinishReflowChild(firstKid, aPresContext, kidSize, &kidReflowState, FinishReflowChild(firstKid, aPresContext, kidSize, &kidReflowState,
kidOrigin.x, kidOrigin.y, 0); wm, kidOrigin, containerWidth, 0);
nsTableFrame::InvalidateTableFrame(firstKid, origRect, origVisualOverflow, nsTableFrame::InvalidateTableFrame(firstKid, origRect, origVisualOverflow,
firstReflow); firstReflow);
// first, compute the height which can be set w/o being restricted by aMaxSize.height // first, compute the bsize which can be set w/o being restricted by
// available bsize
LogicalSize cellSize(wm); LogicalSize cellSize(wm);
LogicalMargin logicalInsets(wm, nsMargin(topInset, rightInset,
bottomInset, leftInset));
cellSize.BSize(wm) = kidSize.BSize(wm); cellSize.BSize(wm) = kidSize.BSize(wm);
if (NS_UNCONSTRAINEDSIZE != cellSize.BSize(wm)) { if (NS_UNCONSTRAINEDSIZE != cellSize.BSize(wm)) {
cellSize.BSize(wm) += logicalInsets.BStartEnd(wm); cellSize.BSize(wm) += borderPadding.BStartEnd(wm);
} }
// next determine the cell's width // next determine the cell's isize
cellSize.ISize(wm) = kidSize.ISize(wm); // at this point, we've factored in the cell's style attributes cellSize.ISize(wm) = kidSize.ISize(wm); // at this point, we've factored in the cell's style attributes
// factor in border and padding // factor in border and padding
if (NS_UNCONSTRAINEDSIZE != cellSize.ISize(wm)) { if (NS_UNCONSTRAINEDSIZE != cellSize.ISize(wm)) {
cellSize.ISize(wm) += logicalInsets.IStartEnd(wm); cellSize.ISize(wm) += borderPadding.IStartEnd(wm);
} }
// set the cell's desired size and max element size // set the cell's desired size and max element size
aDesiredSize.SetSize(wm, cellSize); aDesiredSize.SetSize(wm, cellSize);
// the overflow area will be computed when the child will be vertically aligned // the overflow area will be computed when BlockDirAlignChild() gets called
if (aReflowState.mFlags.mSpecialHeightReflow) { if (aReflowState.mFlags.mSpecialHeightReflow) {
if (aDesiredSize.Height() > mRect.height) { if (aDesiredSize.BSize(wm) > BSize(wm)) {
// set a bit indicating that the pct height contents exceeded // set a bit indicating that the pct bsize contents exceeded
// the height that they could honor in the pass 2 reflow // the height that they could honor in the pass 2 reflow
SetHasPctOverHeight(true); SetHasPctOverBSize(true);
} }
if (NS_UNCONSTRAINEDSIZE == aReflowState.AvailableHeight()) { if (NS_UNCONSTRAINEDSIZE == aReflowState.AvailableBSize()) {
aDesiredSize.Height() = mRect.height; aDesiredSize.BSize(wm) = BSize(wm);
} }
} }

View File

@@ -143,7 +143,7 @@ public:
virtual mozilla::WritingMode GetWritingMode() const override virtual mozilla::WritingMode GetWritingMode() const override
{ return GetTableFrame()->GetWritingMode(); } { return GetTableFrame()->GetWritingMode(); }
void VerticallyAlignChild(nscoord aMaxAscent); void BlockDirAlignChild(mozilla::WritingMode aWM, nscoord aMaxAscent);
/* /*
* Get the value of vertical-align adjusted for CSS 2's rules for a * Get the value of vertical-align adjusted for CSS 2's rules for a
@@ -156,12 +156,12 @@ public:
return GetVerticalAlign() == NS_STYLE_VERTICAL_ALIGN_BASELINE; return GetVerticalAlign() == NS_STYLE_VERTICAL_ALIGN_BASELINE;
} }
bool CellHasVisibleContent(nscoord height, bool CellHasVisibleContent(nscoord aBSize,
nsTableFrame* tableFrame, nsTableFrame* tableFrame,
nsIFrame* kidFrame); nsIFrame* kidFrame);
/** /**
* Get the first-line baseline of the cell relative to its top border * Get the first-line baseline of the cell relative to its block-start border
* edge, as if the cell were vertically aligned to the top of the row. * edge, as if the cell were vertically aligned to the top of the row.
*/ */
nscoord GetCellBaseline() const; nscoord GetCellBaseline() const;
@@ -200,11 +200,11 @@ public:
virtual nsresult GetColIndex(int32_t &aColIndex) const override; virtual nsresult GetColIndex(int32_t &aColIndex) const override;
void SetColIndex(int32_t aColIndex); void SetColIndex(int32_t aColIndex);
/** return the available width given to this frame during its last reflow */ /** return the available isize given to this frame during its last reflow */
inline nscoord GetPriorAvailWidth(); inline nscoord GetPriorAvailISize();
/** set the available width given to this frame during its last reflow */ /** set the available isize given to this frame during its last reflow */
inline void SetPriorAvailWidth(nscoord aPriorAvailWidth); inline void SetPriorAvailISize(nscoord aPriorAvailISize);
/** return the desired size returned by this frame during its last reflow */ /** return the desired size returned by this frame during its last reflow */
inline mozilla::LogicalSize GetDesiredSize(); inline mozilla::LogicalSize GetDesiredSize();
@@ -215,8 +215,8 @@ public:
bool GetContentEmpty(); bool GetContentEmpty();
void SetContentEmpty(bool aContentEmpty); void SetContentEmpty(bool aContentEmpty);
bool HasPctOverHeight(); bool HasPctOverBSize();
void SetHasPctOverHeight(bool aValue); void SetHasPctOverBSize(bool aValue);
nsTableCellFrame* GetNextCell() const; nsTableCellFrame* GetNextCell() const;
@@ -242,7 +242,8 @@ public:
virtual void InvalidateFrameForRemoval() override { InvalidateFrameSubtree(); } virtual void InvalidateFrameForRemoval() override { InvalidateFrameSubtree(); }
protected: protected:
virtual LogicalSides GetLogicalSkipSides(const nsHTMLReflowState* aReflowState= nullptr) const override; virtual LogicalSides
GetLogicalSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const override;
/** /**
* GetBorderOverflow says how far the cell's own borders extend * GetBorderOverflow says how far the cell's own borders extend
@@ -257,15 +258,15 @@ protected:
uint32_t mColIndex; // the starting column for this cell uint32_t mColIndex; // the starting column for this cell
nscoord mPriorAvailWidth; // the avail width during the last reflow nscoord mPriorAvailISize; // the avail isize during the last reflow
mozilla::LogicalSize mDesiredSize; // the last desired inline and block size mozilla::LogicalSize mDesiredSize; // the last desired inline and block size
}; };
inline nscoord nsTableCellFrame::GetPriorAvailWidth() inline nscoord nsTableCellFrame::GetPriorAvailISize()
{ return mPriorAvailWidth;} { return mPriorAvailISize; }
inline void nsTableCellFrame::SetPriorAvailWidth(nscoord aPriorAvailWidth) inline void nsTableCellFrame::SetPriorAvailISize(nscoord aPriorAvailISize)
{ mPriorAvailWidth = aPriorAvailWidth;} { mPriorAvailISize = aPriorAvailISize; }
inline mozilla::LogicalSize nsTableCellFrame::GetDesiredSize() inline mozilla::LogicalSize nsTableCellFrame::GetDesiredSize()
{ return mDesiredSize; } { return mDesiredSize; }
@@ -291,13 +292,13 @@ inline void nsTableCellFrame::SetContentEmpty(bool aContentEmpty)
} }
} }
inline bool nsTableCellFrame::HasPctOverHeight() inline bool nsTableCellFrame::HasPctOverBSize()
{ {
return (mState & NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT) == return (mState & NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT) ==
NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT; NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT;
} }
inline void nsTableCellFrame::SetHasPctOverHeight(bool aValue) inline void nsTableCellFrame::SetHasPctOverBSize(bool aValue)
{ {
if (aValue) { if (aValue) {
mState |= NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT; mState |= NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT;

View File

@@ -343,9 +343,9 @@ nsTableRowFrame::DidResize()
false); false);
} }
// realign cell content based on the new height. We might be able to // realign cell content based on the new bsize. We might be able to
// skip this if the height didn't change... maybe. Hard to tell. // skip this if the bsize didn't change... maybe. Hard to tell.
cellFrame->VerticallyAlignChild(mMaxCellAscent); cellFrame->BlockDirAlignChild(wm, mMaxCellAscent);
// Always store the overflow, even if the height didn't change, since // Always store the overflow, even if the height didn't change, since
// we'll lose part of our overflow area otherwise. // we'll lose part of our overflow area otherwise.
@@ -668,26 +668,26 @@ nsTableRowFrame::CalculateCellActualHeight(nsTableCellFrame* aCellFrame,
return NS_OK; return NS_OK;
} }
// Calculates the available width for the table cell based on the known // Calculates the available isize for the table cell based on the known
// column widths taking into account column spans and column spacing // column isizes taking into account column spans and column spacing
static nscoord static nscoord
CalcAvailWidth(nsTableFrame& aTableFrame, CalcAvailISize(nsTableFrame& aTableFrame,
nsTableCellFrame& aCellFrame) nsTableCellFrame& aCellFrame)
{ {
nscoord cellAvailWidth = 0; nscoord cellAvailISize = 0;
int32_t colIndex; int32_t colIndex;
aCellFrame.GetColIndex(colIndex); aCellFrame.GetColIndex(colIndex);
int32_t colspan = aTableFrame.GetEffectiveColSpan(aCellFrame); int32_t colspan = aTableFrame.GetEffectiveColSpan(aCellFrame);
NS_ASSERTION(colspan > 0, "effective colspan should be positive"); NS_ASSERTION(colspan > 0, "effective colspan should be positive");
for (int32_t spanX = 0; spanX < colspan; spanX++) { for (int32_t spanX = 0; spanX < colspan; spanX++) {
cellAvailWidth += aTableFrame.GetColumnISize(colIndex + spanX); cellAvailISize += aTableFrame.GetColumnISize(colIndex + spanX);
if (spanX > 0 && if (spanX > 0 &&
aTableFrame.ColumnHasCellSpacingBefore(colIndex + spanX)) { aTableFrame.ColumnHasCellSpacingBefore(colIndex + spanX)) {
cellAvailWidth += aTableFrame.GetColSpacing(colIndex + spanX - 1); cellAvailISize += aTableFrame.GetColSpacing(colIndex + spanX - 1);
} }
} }
return cellAvailWidth; return cellAvailISize;
} }
nscoord nscoord
@@ -859,41 +859,42 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext,
(kidFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0; (kidFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW) != 0;
if (doReflowChild) { if (doReflowChild) {
// Calculate the available width for the table cell using the known column widths // Calculate the available isize for the table cell using the known
nscoord availCellWidth = // column isizes
CalcAvailWidth(aTableFrame, *cellFrame); nscoord availCellISize =
CalcAvailISize(aTableFrame, *cellFrame);
Maybe<nsTableCellReflowState> kidReflowState; Maybe<nsTableCellReflowState> kidReflowState;
nsHTMLReflowMetrics desiredSize(aReflowState); nsHTMLReflowMetrics desiredSize(aReflowState);
// If the avail width is not the same as last time we reflowed the cell or // If the avail isize is not the same as last time we reflowed the cell or
// the cell wants to be bigger than what was available last time or // the cell wants to be bigger than what was available last time or
// it is a style change reflow or we are printing, then we must reflow the // it is a style change reflow or we are printing, then we must reflow the
// cell. Otherwise we can skip the reflow. // cell. Otherwise we can skip the reflow.
// XXXldb Why is this condition distinct from doReflowChild above? // XXXldb Why is this condition distinct from doReflowChild above?
WritingMode rowWM = aReflowState.GetWritingMode(); WritingMode wm = aReflowState.GetWritingMode();
WritingMode cellWM = cellFrame->GetWritingMode(); NS_ASSERTION(cellFrame->GetWritingMode() == wm,
"expected consistent writing-mode within table");
LogicalSize cellDesiredSize = cellFrame->GetDesiredSize(); LogicalSize cellDesiredSize = cellFrame->GetDesiredSize();
if ((availCellWidth != cellFrame->GetPriorAvailWidth()) || if ((availCellISize != cellFrame->GetPriorAvailISize()) ||
(cellDesiredSize.ISize(cellWM) > cellFrame->GetPriorAvailWidth()) || (cellDesiredSize.ISize(wm) > cellFrame->GetPriorAvailISize()) ||
(GetStateBits() & NS_FRAME_IS_DIRTY) || (GetStateBits() & NS_FRAME_IS_DIRTY) ||
isPaginated || isPaginated ||
NS_SUBTREE_DIRTY(cellFrame) || NS_SUBTREE_DIRTY(cellFrame) ||
// See if it needs a special reflow, or if it had one that we need to undo. // See if it needs a special reflow, or if it had one that we need to undo.
(cellFrame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_BSIZE) || (cellFrame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_BSIZE) ||
HasPctHeight()) { HasPctHeight()) {
// Reflow the cell to fit the available width, height // Reflow the cell to fit the available isize, bsize
// XXX The old IR_ChildIsDirty code used availCellWidth here. // XXX The old IR_ChildIsDirty code used availCellISize here.
nsSize kidAvailSize(availCellWidth, aReflowState.AvailableHeight()); LogicalSize kidAvailSize(wm, availCellISize, aReflowState.AvailableBSize());
// Reflow the child // Reflow the child
kidReflowState.emplace(aPresContext, aReflowState, kidFrame, kidReflowState.emplace(aPresContext, aReflowState, kidFrame,
LogicalSize(kidFrame->GetWritingMode(), kidAvailSize,
kidAvailSize),
// Cast needed for gcc 4.4. // Cast needed for gcc 4.4.
uint32_t(nsHTMLReflowState::CALLER_WILL_INIT)); uint32_t(nsHTMLReflowState::CALLER_WILL_INIT));
InitChildReflowState(*aPresContext, kidAvailSize, borderCollapse, InitChildReflowState(*aPresContext, kidAvailSize.GetPhysicalSize(wm),
*kidReflowState); borderCollapse, *kidReflowState);
nsReflowStatus status; nsReflowStatus status;
ReflowChild(kidFrame, aPresContext, desiredSize, *kidReflowState, ReflowChild(kidFrame, aPresContext, desiredSize, *kidReflowState,
@@ -910,7 +911,7 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext,
kidFrame->InvalidateFrameSubtree(); kidFrame->InvalidateFrameSubtree();
} }
desiredSize.SetSize(cellWM, cellDesiredSize); desiredSize.SetSize(wm, cellDesiredSize);
desiredSize.mOverflowAreas = cellFrame->GetOverflowAreas(); desiredSize.mOverflowAreas = cellFrame->GetOverflowAreas();
// if we are in a floated table, our position is not yet established, so we cannot reposition our views // if we are in a floated table, our position is not yet established, so we cannot reposition our views
@@ -932,12 +933,12 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext,
// height may have changed, adjust descent to absorb any excess difference // height may have changed, adjust descent to absorb any excess difference
nscoord ascent; nscoord ascent;
if (!kidFrame->GetFirstPrincipalChild()->GetFirstPrincipalChild()) { if (!kidFrame->GetFirstPrincipalChild()->GetFirstPrincipalChild()) {
ascent = desiredSize.BSize(rowWM); ascent = desiredSize.BSize(wm);
} else { } else {
ascent = ((nsTableCellFrame *)kidFrame)->GetCellBaseline(); ascent = ((nsTableCellFrame *)kidFrame)->GetCellBaseline();
} }
nscoord descent = desiredSize.BSize(rowWM) - ascent; nscoord descent = desiredSize.BSize(wm) - ascent;
UpdateHeight(desiredSize.BSize(rowWM), ascent, descent, &aTableFrame, cellFrame); UpdateHeight(desiredSize.BSize(wm), ascent, descent, &aTableFrame, cellFrame);
} }
else { else {
cellMaxHeight = std::max(cellMaxHeight, desiredSize.Height()); cellMaxHeight = std::max(cellMaxHeight, desiredSize.Height());
@@ -948,7 +949,7 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext,
} }
// Place the child // Place the child
desiredSize.ISize(rowWM) = availCellWidth; desiredSize.ISize(wm) = availCellISize;
if (kidReflowState) { if (kidReflowState) {
// We reflowed. Apply relative positioning in the normal way. // We reflowed. Apply relative positioning in the normal way.
@@ -1093,16 +1094,19 @@ nsTableRowFrame::ReflowCellFrame(nsPresContext* aPresContext,
nscoord aAvailableHeight, nscoord aAvailableHeight,
nsReflowStatus& aStatus) nsReflowStatus& aStatus)
{ {
WritingMode wm = aReflowState.GetWritingMode();
// Reflow the cell frame with the specified height. Use the existing width // Reflow the cell frame with the specified height. Use the existing width
nsRect cellRect = aCellFrame->GetRect(); nsRect cellRect = aCellFrame->GetRect();
nsRect cellVisualOverflow = aCellFrame->GetVisualOverflowRect(); nsRect cellVisualOverflow = aCellFrame->GetVisualOverflowRect();
nsSize availSize(cellRect.width, aAvailableHeight); nsSize availSize(cellRect.width, aAvailableHeight);
bool borderCollapse = GetTableFrame()->IsBorderCollapse(); bool borderCollapse = GetTableFrame()->IsBorderCollapse();
NS_ASSERTION(aCellFrame->GetWritingMode() == wm,
"expected consistent writing-mode within table");
nsTableCellReflowState nsTableCellReflowState
cellReflowState(aPresContext, aReflowState, aCellFrame, cellReflowState(aPresContext, aReflowState, aCellFrame,
LogicalSize(aCellFrame->GetWritingMode(), LogicalSize(wm, availSize),
availSize),
nsHTMLReflowState::CALLER_WILL_INIT); nsHTMLReflowState::CALLER_WILL_INIT);
InitChildReflowState(*aPresContext, availSize, borderCollapse, cellReflowState); InitChildReflowState(*aPresContext, availSize, borderCollapse, cellReflowState);
cellReflowState.mFlags.mIsTopOfPage = aIsTopOfPage; cellReflowState.mFlags.mIsTopOfPage = aIsTopOfPage;
@@ -1117,11 +1121,11 @@ nsTableRowFrame::ReflowCellFrame(nsPresContext* aPresContext,
} }
aCellFrame->SetSize(nsSize(cellRect.width, desiredSize.Height())); aCellFrame->SetSize(nsSize(cellRect.width, desiredSize.Height()));
// Note: VerticallyAlignChild can affect the overflow rect. // Note: BlockDirAlignChild can affect the overflow rect.
// XXX What happens if this cell has 'vertical-align: baseline' ? // XXX What happens if this cell has 'vertical-align: baseline' ?
// XXX Why is it assumed that the cell's ascent hasn't changed ? // XXX Why is it assumed that the cell's ascent hasn't changed ?
if (fullyComplete) { if (fullyComplete) {
aCellFrame->VerticallyAlignChild(mMaxCellAscent); aCellFrame->BlockDirAlignChild(wm, mMaxCellAscent);
} }
nsTableFrame::InvalidateTableFrame(aCellFrame, cellRect, nsTableFrame::InvalidateTableFrame(aCellFrame, cellRect,