Bug 1173307 - Convert nsTableCellFrame to work with logical coordinates. r=dholbert
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user