Bug 1079151 - patch 1 - Update constraint calculations in nsHTMLReflowState to work with logical coordinates. r=smontagu

This commit is contained in:
Jonathan Kew 2015-06-05 08:47:09 +01:00
Родитель 2e16faf502
Коммит e4a31ad160
2 изменённых файлов: 295 добавлений и 289 удалений

Просмотреть файл

@ -1002,7 +1002,7 @@ nsHTMLReflowState::GetHypotheticalBoxContainer(nsIFrame* aFrame,
state = nullptr; state = nullptr;
} }
WritingMode wm = GetWritingMode(); WritingMode wm = aFrame->GetWritingMode();
if (state) { if (state) {
WritingMode stateWM = state->GetWritingMode(); WritingMode stateWM = state->GetWritingMode();
aCBIStartEdge = aCBIStartEdge =
@ -1016,31 +1016,31 @@ nsHTMLReflowState::GetHypotheticalBoxContainer(nsIFrame* aFrame,
"aFrame shouldn't be in reflow; we'll lie if it is"); "aFrame shouldn't be in reflow; we'll lie if it is");
LogicalMargin borderPadding = aFrame->GetLogicalUsedBorderAndPadding(wm); LogicalMargin borderPadding = aFrame->GetLogicalUsedBorderAndPadding(wm);
aCBIStartEdge = borderPadding.IStart(wm); aCBIStartEdge = borderPadding.IStart(wm);
aCBISize = aFrame->GetLogicalSize(wm).ISize(wm) - aCBISize = aFrame->ISize(wm) - borderPadding.IStartEnd(wm);
borderPadding.IStartEnd(wm);
} }
return aFrame; return aFrame;
} }
// When determining the hypothetical box that would have been if the element // When determining the hypothetical box that would have been if the element
// had been in the flow we may not be able to exactly determine both the left // had been in the flow we may not be able to exactly determine both the IStart
// and right edges. For example, if the element is a non-replaced inline-level // and IEnd edges. For example, if the element is a non-replaced inline-level
// element we would have to reflow it in order to determine it desired width. // element we would have to reflow it in order to determine its desired ISize.
// In that case depending on the progression direction either the left or // In that case depending on the progression direction either the IStart or
// right edge would be marked as not being exact // IEnd edge would be marked as not being exact.
struct nsHypotheticalBox { struct nsHypotheticalBox {
// offsets from left edge of containing block (which is a padding edge) // offsets from inline-start edge of containing block (which is a padding edge)
nscoord mLeft, mRight; nscoord mIStart, mIEnd;
// offset from top edge of containing block (which is a padding edge) // offset from block-start edge of containing block (which is a padding edge)
nscoord mTop; nscoord mBStart;
WritingMode mWritingMode;
#ifdef DEBUG #ifdef DEBUG
bool mLeftIsExact, mRightIsExact; bool mIStartIsExact, mIEndIsExact;
#endif #endif
nsHypotheticalBox() { nsHypotheticalBox() {
#ifdef DEBUG #ifdef DEBUG
mLeftIsExact = mRightIsExact = false; mIStartIsExact = mIEndIsExact = false;
#endif #endif
} }
}; };
@ -1164,15 +1164,11 @@ static bool AreAllEarlierInFlowFramesEmpty(nsIFrame* aFrame,
// Calculate the hypothetical box that the element would have if it were in // Calculate the hypothetical box that the element would have if it were in
// the flow. The values returned are relative to the padding edge of the // the flow. The values returned are relative to the padding edge of the
// absolute containing block // absolute containing block, in the actual containing block's writing mode.
// aContainingBlock is the placeholder's containing block (XXX rename it?)
// cbrs->frame is the actual containing block // cbrs->frame is the actual containing block
void void
nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext, nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext,
nsIFrame* aPlaceholderFrame, nsIFrame* aPlaceholderFrame,
nsIFrame* aContainingBlock,
nscoord aBlockIStartContentEdge,
nscoord aBlockContentISize,
const nsHTMLReflowState* cbrs, const nsHTMLReflowState* cbrs,
nsHypotheticalBox& aHypotheticalBox, nsHypotheticalBox& aHypotheticalBox,
nsIAtom* aFrameType) nsIAtom* aFrameType)
@ -1180,11 +1176,20 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext,
NS_ASSERTION(mStyleDisplay->mOriginalDisplay != NS_STYLE_DISPLAY_NONE, NS_ASSERTION(mStyleDisplay->mOriginalDisplay != NS_STYLE_DISPLAY_NONE,
"mOriginalDisplay has not been properly initialized"); "mOriginalDisplay has not been properly initialized");
// Find the nearest containing block frame to the placeholder frame,
// and its inline-start edge and width.
nscoord blockIStartContentEdge, blockContentISize;
nsIFrame* containingBlock =
GetHypotheticalBoxContainer(aPlaceholderFrame, blockIStartContentEdge,
blockContentISize);
// If it's a replaced element and it has a 'auto' value for // If it's a replaced element and it has a 'auto' value for
//'inline size', see if we can get the intrinsic size. This will allow //'inline size', see if we can get the intrinsic size. This will allow
// us to exactly determine both the inline edges // us to exactly determine both the inline edges
WritingMode cbWM = cbrs->GetWritingMode(); WritingMode wm = containingBlock->GetWritingMode();
nsStyleCoord styleISize = mStylePosition->ISize(cbWM); aHypotheticalBox.mWritingMode = wm;
nsStyleCoord styleISize = mStylePosition->ISize(wm);
bool isAutoISize = styleISize.GetUnit() == eStyleUnit_Auto; bool isAutoISize = styleISize.GetUnit() == eStyleUnit_Auto;
nsSize intrinsicSize; nsSize intrinsicSize;
bool knowIntrinsicSize = false; bool knowIntrinsicSize = false;
@ -1211,28 +1216,28 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext,
// been in the flow. Note that we ignore any 'auto' and 'inherit' // been in the flow. Note that we ignore any 'auto' and 'inherit'
// values // values
nscoord insideBoxSizing, outsideBoxSizing; nscoord insideBoxSizing, outsideBoxSizing;
CalculateInlineBorderPaddingMargin(aBlockContentISize, CalculateInlineBorderPaddingMargin(blockContentISize,
&insideBoxSizing, &outsideBoxSizing); &insideBoxSizing, &outsideBoxSizing);
if (NS_FRAME_IS_REPLACED(mFrameType) && isAutoISize) { if (NS_FRAME_IS_REPLACED(mFrameType) && isAutoISize) {
// It's a replaced element with an 'auto' inline size so the box // It's a replaced element with an 'auto' inline size so the box
// inline size is its intrinsic size plus any border/padding/margin // inline size is its intrinsic size plus any border/padding/margin
if (knowIntrinsicSize) { if (knowIntrinsicSize) {
boxISize = LogicalSize(cbWM, intrinsicSize).ISize(cbWM) + boxISize = LogicalSize(wm, intrinsicSize).ISize(wm) +
outsideBoxSizing + insideBoxSizing; outsideBoxSizing + insideBoxSizing;
knowBoxISize = true; knowBoxISize = true;
} }
} else if (isAutoISize) { } else if (isAutoISize) {
// The box inline size is the containing block inline size // The box inline size is the containing block inline size
boxISize = aBlockContentISize; boxISize = blockContentISize;
knowBoxISize = true; knowBoxISize = true;
} else { } else {
// We need to compute it. It's important we do this, because if it's // We need to compute it. It's important we do this, because if it's
// percentage based this computed value may be different from the computed // percentage based this computed value may be different from the computed
// value calculated using the absolute containing block width // value calculated using the absolute containing block width
boxISize = ComputeISizeValue(aBlockContentISize, boxISize = ComputeISizeValue(blockContentISize,
insideBoxSizing, outsideBoxSizing, insideBoxSizing, outsideBoxSizing,
styleISize) + styleISize) +
insideBoxSizing + outsideBoxSizing; insideBoxSizing + outsideBoxSizing;
@ -1240,29 +1245,39 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext,
} }
} }
// Get the 'direction' of the block
const nsStyleVisibility* blockVis = aContainingBlock->StyleVisibility();
// Get the placeholder x-offset and y-offset in the coordinate // Get the placeholder x-offset and y-offset in the coordinate
// space of its containing block // space of its containing block
// XXXbz the placeholder is not fully reflowed yet if our containing block is // XXXbz the placeholder is not fully reflowed yet if our containing block is
// relatively positioned... // relatively positioned...
nsPoint placeholderOffset = aPlaceholderFrame->GetOffsetTo(aContainingBlock); WritingMode cbwm = cbrs->GetWritingMode();
nscoord containerWidth = containingBlock->GetStateBits() & NS_FRAME_IN_REFLOW
? cbrs->ComputedWidth() +
cbrs->ComputedLogicalBorderPadding().LeftRight(cbwm)
: containingBlock->GetSize().width;
LogicalPoint placeholderOffset(wm, aPlaceholderFrame->GetOffsetTo(containingBlock),
containerWidth);
// First, determine the hypothetical box's mTop. We want to check the // XXX hack to correct for lack of LogicalPoint bidi support in vertical mode
// content insertion frame of aContainingBlock for block-ness, but make if (wm.IsVertical() && !wm.IsBidiLTR()) {
placeholderOffset.I(wm) = cbrs->ComputedHeight() +
cbrs->ComputedLogicalBorderPadding().TopBottom(cbwm) -
placeholderOffset.I(wm);
}
// First, determine the hypothetical box's mBStart. We want to check the
// content insertion frame of containingBlock for block-ness, but make
// sure to compute all coordinates in the coordinate system of // sure to compute all coordinates in the coordinate system of
// aContainingBlock. // containingBlock.
nsBlockFrame* blockFrame = nsBlockFrame* blockFrame =
nsLayoutUtils::GetAsBlock(aContainingBlock->GetContentInsertionFrame()); nsLayoutUtils::GetAsBlock(containingBlock->GetContentInsertionFrame());
if (blockFrame) { if (blockFrame) {
nscoord blockYOffset = blockFrame->GetOffsetTo(aContainingBlock).y; LogicalPoint blockOffset(wm, blockFrame->GetOffsetTo(containingBlock), 0);
bool isValid; bool isValid;
nsBlockInFlowLineIterator iter(blockFrame, aPlaceholderFrame, &isValid); nsBlockInFlowLineIterator iter(blockFrame, aPlaceholderFrame, &isValid);
if (!isValid) { if (!isValid) {
// Give up. We're probably dealing with somebody using // Give up. We're probably dealing with somebody using
// position:absolute inside native-anonymous content anyway. // position:absolute inside native-anonymous content anyway.
aHypotheticalBox.mTop = placeholderOffset.y; aHypotheticalBox.mBStart = placeholderOffset.B(wm);
} else { } else {
NS_ASSERTION(iter.GetContainer() == blockFrame, NS_ASSERTION(iter.GetContainer() == blockFrame,
"Found placeholder in wrong block!"); "Found placeholder in wrong block!");
@ -1270,10 +1285,13 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext,
// How we determine the hypothetical box depends on whether the element // How we determine the hypothetical box depends on whether the element
// would have been inline-level or block-level // would have been inline-level or block-level
LogicalRect lineBounds =
lineBox->GetBounds().ConvertTo(wm, lineBox->mWritingMode,
lineBox->mContainerWidth);
if (mStyleDisplay->IsOriginalDisplayInlineOutsideStyle()) { if (mStyleDisplay->IsOriginalDisplayInlineOutsideStyle()) {
// Use the top of the inline box which the placeholder lives in // Use the block-start of the inline box which the placeholder lives in
// as the hypothetical box's top. // as the hypothetical box's block-start.
aHypotheticalBox.mTop = lineBox->GetPhysicalBounds().y + blockYOffset; aHypotheticalBox.mBStart = lineBounds.BStart(wm) + blockOffset.B(wm);
} else { } else {
// The element would have been block-level which means it would // The element would have been block-level which means it would
// be below the line containing the placeholder frame, unless // be below the line containing the placeholder frame, unless
@ -1298,81 +1316,51 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext,
// The top of the hypothetical box is the top of the line // The top of the hypothetical box is the top of the line
// containing the placeholder, since there is nothing in the // containing the placeholder, since there is nothing in the
// line before our placeholder except empty frames. // line before our placeholder except empty frames.
aHypotheticalBox.mTop = lineBox->GetPhysicalBounds().y + blockYOffset; aHypotheticalBox.mBStart = lineBounds.BStart(wm) + blockOffset.B(wm);
} else { } else {
// The top of the hypothetical box is just below the line // The top of the hypothetical box is just below the line
// containing the placeholder. // containing the placeholder.
aHypotheticalBox.mTop = lineBox->GetPhysicalBounds().YMost() + blockYOffset; aHypotheticalBox.mBStart = lineBounds.BEnd(wm) + blockOffset.B(wm);
} }
} else { } else {
// Just use the placeholder's y-offset wrt the containing block // Just use the placeholder's block-offset wrt the containing block
aHypotheticalBox.mTop = placeholderOffset.y; aHypotheticalBox.mBStart = placeholderOffset.B(wm);
} }
} }
} }
} else { } else {
// The containing block is not a block, so it's probably something // The containing block is not a block, so it's probably something
// like a XUL box, etc. // like a XUL box, etc.
// Just use the placeholder's y-offset // Just use the placeholder's block-offset
aHypotheticalBox.mTop = placeholderOffset.y; aHypotheticalBox.mBStart = placeholderOffset.B(wm);
} }
// Second, determine the hypothetical box's mLeft & mRight // Second, determine the hypothetical box's mIStart & mIEnd.
// To determine the left and right offsets we need to look at the block's 'direction' // How we determine the hypothetical box depends on whether the element
if (NS_STYLE_DIRECTION_LTR == blockVis->mDirection) { // would have been inline-level or block-level
// How we determine the hypothetical box depends on whether the element if (mStyleDisplay->IsOriginalDisplayInlineOutsideStyle()) {
// would have been inline-level or block-level // The placeholder represents the left edge of the hypothetical box
if (mStyleDisplay->IsOriginalDisplayInlineOutsideStyle()) { aHypotheticalBox.mIStart = placeholderOffset.I(wm);
// The placeholder represents the left edge of the hypothetical box
aHypotheticalBox.mLeft = placeholderOffset.x;
} else {
aHypotheticalBox.mLeft = aBlockIStartContentEdge;
}
#ifdef DEBUG
aHypotheticalBox.mLeftIsExact = true;
#endif
if (knowBoxISize) {
aHypotheticalBox.mRight = aHypotheticalBox.mLeft + boxISize;
#ifdef DEBUG
aHypotheticalBox.mRightIsExact = true;
#endif
} else {
// We can't compute the right edge because we don't know the desired
// width. So instead use the right content edge of the block parent,
// but remember it's not exact
aHypotheticalBox.mRight = aBlockIStartContentEdge + aBlockContentISize;
#ifdef DEBUG
aHypotheticalBox.mRightIsExact = false;
#endif
}
} else { } else {
// The placeholder represents the right edge of the hypothetical box aHypotheticalBox.mIStart = blockIStartContentEdge;
if (mStyleDisplay->IsOriginalDisplayInlineOutsideStyle()) { }
aHypotheticalBox.mRight = placeholderOffset.x;
} else {
aHypotheticalBox.mRight = aBlockIStartContentEdge + aBlockContentISize;
}
#ifdef DEBUG #ifdef DEBUG
aHypotheticalBox.mRightIsExact = true; aHypotheticalBox.mIStartIsExact = true;
#endif #endif
if (knowBoxISize) { if (knowBoxISize) {
aHypotheticalBox.mLeft = aHypotheticalBox.mRight - boxISize; aHypotheticalBox.mIEnd = aHypotheticalBox.mIStart + boxISize;
#ifdef DEBUG #ifdef DEBUG
aHypotheticalBox.mLeftIsExact = true; aHypotheticalBox.mIEndIsExact = true;
#endif #endif
} else { } else {
// We can't compute the left edge because we don't know the desired // We can't compute the inline-end edge because we don't know the desired
// width. So instead use the left content edge of the block parent, // inline-size. So instead use the end content edge of the block parent,
// but remember it's not exact // but remember it's not exact
aHypotheticalBox.mLeft = aBlockIStartContentEdge; aHypotheticalBox.mIEnd = blockIStartContentEdge + blockContentISize;
#ifdef DEBUG #ifdef DEBUG
aHypotheticalBox.mLeftIsExact = false; aHypotheticalBox.mIEndIsExact = false;
#endif #endif
}
} }
// The current coordinate space is that of the nearest block to the placeholder. // The current coordinate space is that of the nearest block to the placeholder.
@ -1385,44 +1373,49 @@ nsHTMLReflowState::CalculateHypotheticalBox(nsPresContext* aPresContext,
// Exclude cases inside -moz-transform where fixed is like absolute. // Exclude cases inside -moz-transform where fixed is like absolute.
nsLayoutUtils::IsReallyFixedPos(frame)) { nsLayoutUtils::IsReallyFixedPos(frame)) {
// In this case, cbrs->frame will likely be an ancestor of // In this case, cbrs->frame will likely be an ancestor of
// aContainingBlock, so can just walk our way up the frame tree. // containingBlock, so can just walk our way up the frame tree.
// Make sure to not add positions of frames whose parent is a // Make sure to not add positions of frames whose parent is a
// scrollFrame, since we're doing fixed positioning, which assumes // scrollFrame, since we're doing fixed positioning, which assumes
// everything is scrolled to (0,0). // everything is scrolled to (0,0).
cbOffset.MoveTo(0, 0); cbOffset.MoveTo(0, 0);
do { do {
cbOffset += aContainingBlock->GetPositionIgnoringScrolling(); cbOffset += containingBlock->GetPositionIgnoringScrolling();
nsContainerFrame* parent = aContainingBlock->GetParent(); nsContainerFrame* parent = containingBlock->GetParent();
if (!parent) { if (!parent) {
// Oops, our absolute containing block isn't an ancestor of the // Oops, our absolute containing block isn't an ancestor of the
// placeholder's containing block. This can happen if the placeholder // placeholder's containing block. This can happen if the placeholder
// is pushed to a different page in a printing context. 'cbOffset' is // is pushed to a different page in a printing context. 'cbOffset' is
// currently relative to the root frame (aContainingBlock) - so just // currently relative to the root frame (containingBlock) - so just
// subtract the offset to the absolute containing block to make it // subtract the offset to the absolute containing block to make it
// relative to that. // relative to that.
cbOffset -= aContainingBlock->GetOffsetTo(cbrs->frame); cbOffset -= containingBlock->GetOffsetTo(cbrs->frame);
break; break;
} }
aContainingBlock = parent; containingBlock = parent;
} while (aContainingBlock != cbrs->frame); } while (containingBlock != cbrs->frame);
} else { } else {
// XXXldb We need to either ignore scrolling for the absolute // XXXldb We need to either ignore scrolling for the absolute
// positioning case too (and take the incompatibility) or figure out // positioning case too (and take the incompatibility) or figure out
// how to make these positioned elements actually *move* when we // how to make these positioned elements actually *move* when we
// scroll, and thus avoid the resulting incremental reflow bugs. // scroll, and thus avoid the resulting incremental reflow bugs.
cbOffset = aContainingBlock->GetOffsetTo(cbrs->frame); cbOffset = containingBlock->GetOffsetTo(cbrs->frame);
} }
aHypotheticalBox.mLeft += cbOffset.x; nscoord cbrsWidth = cbrs->ComputedWidth() +
aHypotheticalBox.mTop += cbOffset.y; cbrs->ComputedLogicalBorderPadding().LeftRight(cbwm);
aHypotheticalBox.mRight += cbOffset.x; LogicalPoint logCBOffs(wm, cbOffset, cbrsWidth - containerWidth);
aHypotheticalBox.mIStart += logCBOffs.I(wm);
aHypotheticalBox.mIEnd += logCBOffs.I(wm);
aHypotheticalBox.mBStart += logCBOffs.B(wm);
// The specified offsets are relative to the absolute containing block's // The specified offsets are relative to the absolute containing block's
// padding edge and our current values are relative to the border edge, so // padding edge and our current values are relative to the border edge, so
// translate. // translate.
nsMargin border = cbrs->ComputedPhysicalBorderPadding() - cbrs->ComputedPhysicalPadding(); LogicalMargin border =
aHypotheticalBox.mLeft -= border.left; cbrs->ComputedLogicalBorderPadding() - cbrs->ComputedLogicalPadding();
aHypotheticalBox.mRight -= border.left; border = border.ConvertTo(wm, cbrs->GetWritingMode());
aHypotheticalBox.mTop -= border.top; aHypotheticalBox.mIStart -= border.IStart(wm);
aHypotheticalBox.mIEnd -= border.IStart(wm);
aHypotheticalBox.mBStart -= border.BStart(wm);
} }
void void
@ -1432,8 +1425,9 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext,
nsIAtom* aFrameType) nsIAtom* aFrameType)
{ {
WritingMode wm = GetWritingMode(); WritingMode wm = GetWritingMode();
NS_PRECONDITION(aCBSize.BSize(wm) != NS_AUTOHEIGHT, WritingMode cbwm = cbrs->GetWritingMode();
"containing block height must be constrained"); NS_PRECONDITION(aCBSize.BSize(cbwm) != NS_AUTOHEIGHT,
"containing block bsize must be constrained");
NS_ASSERTION(aFrameType != nsGkAtoms::tableFrame, NS_ASSERTION(aFrameType != nsGkAtoms::tableFrame,
"InitAbsoluteConstraints should not be called on table frames"); "InitAbsoluteConstraints should not be called on table frames");
@ -1454,143 +1448,151 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext,
(eStyleUnit_Auto == mStylePosition->mOffset.GetRightUnit())) || (eStyleUnit_Auto == mStylePosition->mOffset.GetRightUnit())) ||
((eStyleUnit_Auto == mStylePosition->mOffset.GetTopUnit()) && ((eStyleUnit_Auto == mStylePosition->mOffset.GetTopUnit()) &&
(eStyleUnit_Auto == mStylePosition->mOffset.GetBottomUnit()))) { (eStyleUnit_Auto == mStylePosition->mOffset.GetBottomUnit()))) {
// Find the nearest containing block frame to the placeholder frame, CalculateHypotheticalBox(aPresContext, placeholderFrame, cbrs,
// and return its left edge and width. hypotheticalBox, aFrameType);
nscoord cbIStartEdge, cbISize;
nsIFrame* cbFrame = GetHypotheticalBoxContainer(placeholderFrame,
cbIStartEdge,
cbISize);
CalculateHypotheticalBox(aPresContext, placeholderFrame, cbFrame,
cbIStartEdge, cbISize, cbrs, hypotheticalBox,
aFrameType);
} }
// Initialize the 'left' and 'right' computed offsets // Initialize the 'left' and 'right' computed offsets
// XXX Handle new 'static-position' value... // XXX Handle new 'static-position' value...
bool leftIsAuto = false, rightIsAuto = false;
if (eStyleUnit_Auto == mStylePosition->mOffset.GetLeftUnit()) { bool iStartIsAuto = false, iEndIsAuto = false;
ComputedPhysicalOffsets().left = 0; bool bStartIsAuto = false, bEndIsAuto = false;
leftIsAuto = true;
// Size of the containing block in its writing mode
LogicalSize cbSize = aCBSize;
LogicalMargin offsets = ComputedLogicalOffsets().ConvertTo(cbwm, wm);
if (eStyleUnit_Auto == mStylePosition->mOffset.GetIStartUnit(cbwm)) {
offsets.IStart(cbwm) = 0;
iStartIsAuto = true;
} else { } else {
ComputedPhysicalOffsets().left = nsLayoutUtils:: offsets.IStart(cbwm) = nsLayoutUtils::
ComputeCBDependentValue(aCBSize.ISize(wm), ComputeCBDependentValue(cbSize.ISize(cbwm),
mStylePosition->mOffset.GetLeft()); mStylePosition->mOffset.GetIStart(cbwm));
} }
if (eStyleUnit_Auto == mStylePosition->mOffset.GetRightUnit()) { if (eStyleUnit_Auto == mStylePosition->mOffset.GetIEndUnit(cbwm)) {
ComputedPhysicalOffsets().right = 0; offsets.IEnd(cbwm) = 0;
rightIsAuto = true; iEndIsAuto = true;
} else { } else {
ComputedPhysicalOffsets().right = nsLayoutUtils:: offsets.IEnd(cbwm) = nsLayoutUtils::
ComputeCBDependentValue(aCBSize.ISize(wm), ComputeCBDependentValue(cbSize.ISize(cbwm),
mStylePosition->mOffset.GetRight()); mStylePosition->mOffset.GetIEnd(cbwm));
} }
// Use the horizontal component of the hypothetical box in the cases if (iStartIsAuto && iEndIsAuto) {
// where it's needed. NS_ASSERTION(hypotheticalBox.mIStartIsExact, "should always have "
if (leftIsAuto && rightIsAuto) { "exact value on containing block's start side");
// Use the direction of the original ("static-position") containing block if (cbwm.IsBidiLTR() != hypotheticalBox.mWritingMode.IsBidiLTR()) {
// to dictate whether 'left' or 'right' is treated like 'static-position'. offsets.IEnd(cbwm) = hypotheticalBox.mIStart;
if (NS_STYLE_DIRECTION_LTR == placeholderFrame->GetContainingBlock() iEndIsAuto = false;
->StyleVisibility()->mDirection) {
NS_ASSERTION(hypotheticalBox.mLeftIsExact, "should always have "
"exact value on containing block's start side");
ComputedPhysicalOffsets().left = hypotheticalBox.mLeft;
leftIsAuto = false;
} else { } else {
NS_ASSERTION(hypotheticalBox.mRightIsExact, "should always have " offsets.IStart(cbwm) = hypotheticalBox.mIStart;
"exact value on containing block's start side"); iStartIsAuto = false;
ComputedPhysicalOffsets().right = aCBSize.ISize(wm) -
hypotheticalBox.mRight;
rightIsAuto = false;
} }
} }
// Initialize the 'top' and 'bottom' computed offsets if (eStyleUnit_Auto == mStylePosition->mOffset.GetBStartUnit(cbwm)) {
bool topIsAuto = false, bottomIsAuto = false; offsets.BStart(cbwm) = 0;
if (eStyleUnit_Auto == mStylePosition->mOffset.GetTopUnit()) { bStartIsAuto = true;
ComputedPhysicalOffsets().top = 0;
topIsAuto = true;
} else { } else {
ComputedPhysicalOffsets().top = nsLayoutUtils:: offsets.BStart(cbwm) = nsLayoutUtils::
ComputeBSizeDependentValue(aCBSize.BSize(wm), ComputeBSizeDependentValue(cbSize.BSize(cbwm),
mStylePosition->mOffset.GetTop()); mStylePosition->mOffset.GetBStart(cbwm));
} }
if (eStyleUnit_Auto == mStylePosition->mOffset.GetBottomUnit()) { if (eStyleUnit_Auto == mStylePosition->mOffset.GetBEndUnit(cbwm)) {
ComputedPhysicalOffsets().bottom = 0; offsets.BEnd(cbwm) = 0;
bottomIsAuto = true; bEndIsAuto = true;
} else { } else {
ComputedPhysicalOffsets().bottom = nsLayoutUtils:: offsets.BEnd(cbwm) = nsLayoutUtils::
ComputeBSizeDependentValue(aCBSize.BSize(wm), ComputeBSizeDependentValue(cbSize.BSize(cbwm),
mStylePosition->mOffset.GetBottom()); mStylePosition->mOffset.GetBEnd(cbwm));
} }
if (topIsAuto && bottomIsAuto) { if (bStartIsAuto && bEndIsAuto) {
// Treat 'top' like 'static-position' // Treat 'top' like 'static-position'
ComputedPhysicalOffsets().top = hypotheticalBox.mTop; NS_ASSERTION(hypotheticalBox.mWritingMode.GetBlockDir() == cbwm.GetBlockDir(),
topIsAuto = false; "block direction mismatch");
offsets.BStart(cbwm) = hypotheticalBox.mBStart;
bStartIsAuto = false;
} }
bool widthIsAuto = eStyleUnit_Auto == mStylePosition->mWidth.GetUnit(); SetComputedLogicalOffsets(offsets.ConvertTo(wm, cbwm));
bool heightIsAuto = eStyleUnit_Auto == mStylePosition->mHeight.GetUnit();
bool iSizeIsAuto = eStyleUnit_Auto == mStylePosition->ISize(cbwm).GetUnit();
bool bSizeIsAuto = eStyleUnit_Auto == mStylePosition->BSize(cbwm).GetUnit();
typedef nsIFrame::ComputeSizeFlags ComputeSizeFlags; typedef nsIFrame::ComputeSizeFlags ComputeSizeFlags;
ComputeSizeFlags computeSizeFlags = ComputeSizeFlags::eDefault; ComputeSizeFlags computeSizeFlags = ComputeSizeFlags::eDefault;
if (leftIsAuto || rightIsAuto) { if (wm.IsOrthogonalTo(cbwm)) {
computeSizeFlags = if (bStartIsAuto || bEndIsAuto) {
ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap); computeSizeFlags =
ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap);
}
} else {
if (iStartIsAuto || iEndIsAuto) {
computeSizeFlags =
ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap);
}
} }
LogicalSize computedSize(wm);
{ {
AutoMaybeDisableFontInflation an(frame); AutoMaybeDisableFontInflation an(frame);
LogicalSize size = computedSize =
frame->ComputeSize(rendContext, wm, aCBSize, frame->ComputeSize(rendContext, wm, cbSize.ConvertTo(wm, cbwm),
aCBSize.ISize(wm), // XXX or AvailableISize()? cbSize.ConvertTo(wm, cbwm).ISize(wm), // XXX or AvailableISize()?
ComputedLogicalMargin().Size(wm) + ComputedLogicalMargin().Size(wm) +
ComputedLogicalOffsets().Size(wm), ComputedLogicalOffsets().Size(wm),
ComputedLogicalBorderPadding().Size(wm) - ComputedLogicalBorderPadding().Size(wm) -
ComputedLogicalPadding().Size(wm), ComputedLogicalPadding().Size(wm),
ComputedLogicalPadding().Size(wm), ComputedLogicalPadding().Size(wm),
computeSizeFlags); computeSizeFlags);
ComputedISize() = size.ISize(wm); ComputedISize() = computedSize.ISize(wm);
ComputedBSize() = size.BSize(wm); ComputedBSize() = computedSize.BSize(wm);
NS_ASSERTION(ComputedISize() >= 0, "Bogus inline-size");
NS_ASSERTION(ComputedBSize() == NS_UNCONSTRAINEDSIZE ||
ComputedBSize() >= 0, "Bogus block-size");
} }
NS_ASSERTION(ComputedISize() >= 0, "Bogus inline-size"); computedSize = computedSize.ConvertTo(cbwm, wm);
NS_ASSERTION(ComputedBSize() == NS_UNCONSTRAINEDSIZE ||
ComputedBSize() >= 0, "Bogus block-size");
// XXX Now that we have ComputeSize, can we condense many of the // XXX Now that we have ComputeSize, can we condense many of the
// branches off of widthIsAuto? // branches off of widthIsAuto?
if (leftIsAuto) { LogicalMargin margin = ComputedLogicalMargin().ConvertTo(cbwm, wm);
const LogicalMargin borderPadding =
ComputedLogicalBorderPadding().ConvertTo(cbwm, wm);
if (iStartIsAuto) {
// We know 'right' is not 'auto' anymore thanks to the hypothetical // We know 'right' is not 'auto' anymore thanks to the hypothetical
// box code above. // box code above.
// Solve for 'left'. // Solve for 'left'.
if (widthIsAuto) { if (iSizeIsAuto) {
// XXXldb This, and the corresponding code in // XXXldb This, and the corresponding code in
// nsAbsoluteContainingBlock.cpp, could probably go away now that // nsAbsoluteContainingBlock.cpp, could probably go away now that
// we always compute widths. // we always compute widths.
ComputedPhysicalOffsets().left = NS_AUTOOFFSET; offsets.IStart(cbwm) = NS_AUTOOFFSET;
} else { } else {
ComputedPhysicalOffsets().left = aCBSize.Width(wm) - ComputedPhysicalMargin().left - offsets.IStart(cbwm) =
ComputedPhysicalBorderPadding().left - ComputedWidth() - ComputedPhysicalBorderPadding().right - cbSize.ISize(cbwm) - offsets.IEnd(cbwm) -
ComputedPhysicalMargin().right - ComputedPhysicalOffsets().right; computedSize.ISize(cbwm) - margin.IStartEnd(cbwm) -
borderPadding.IStartEnd(cbwm);
} }
} else if (rightIsAuto) { } else if (iEndIsAuto) {
// We know 'left' is not 'auto' anymore thanks to the hypothetical // We know 'left' is not 'auto' anymore thanks to the hypothetical
// box code above. // box code above.
// Solve for 'right'. // Solve for 'right'.
if (widthIsAuto) { if (iSizeIsAuto) {
// XXXldb This, and the corresponding code in // XXXldb This, and the corresponding code in
// nsAbsoluteContainingBlock.cpp, could probably go away now that // nsAbsoluteContainingBlock.cpp, could probably go away now that
// we always compute widths. // we always compute widths.
ComputedPhysicalOffsets().right = NS_AUTOOFFSET; offsets.IEnd(cbwm) = NS_AUTOOFFSET;
} else { } else {
ComputedPhysicalOffsets().right = aCBSize.Width(wm) - ComputedPhysicalOffsets().left - offsets.IEnd(cbwm) =
ComputedPhysicalMargin().left - ComputedPhysicalBorderPadding().left - ComputedWidth() - cbSize.ISize(cbwm) - offsets.IStart(cbwm) -
ComputedPhysicalBorderPadding().right - ComputedPhysicalMargin().right; computedSize.ISize(cbwm) - margin.IStartEnd(cbwm) -
borderPadding.IStartEnd(cbwm);
} }
} else { } else {
// Neither 'left' nor 'right' is 'auto'. However, the width might // Neither 'left' nor 'right' is 'auto'. However, the width might
@ -1600,43 +1602,35 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext,
// * we're dealing with a replaced element // * we're dealing with a replaced element
// * width was constrained by min-width or max-width. // * width was constrained by min-width or max-width.
nscoord availMarginSpace = aCBSize.Width(wm) - nscoord availMarginSpace =
ComputedPhysicalOffsets().LeftRight() - aCBSize.ISize(cbwm) - offsets.IStartEnd(cbwm) - margin.IStartEnd(cbwm) -
ComputedPhysicalMargin().LeftRight() - borderPadding.IStartEnd(cbwm) - computedSize.ISize(cbwm);
ComputedPhysicalBorderPadding().LeftRight() - bool marginIStartIsAuto =
ComputedWidth(); eStyleUnit_Auto == mStyleMargin->mMargin.GetIStartUnit(cbwm);
bool marginLeftIsAuto = bool marginIEndIsAuto =
eStyleUnit_Auto == mStyleMargin->mMargin.GetLeftUnit(); eStyleUnit_Auto == mStyleMargin->mMargin.GetIEndUnit(cbwm);
bool marginRightIsAuto =
eStyleUnit_Auto == mStyleMargin->mMargin.GetRightUnit();
if (marginLeftIsAuto) { if (marginIStartIsAuto) {
if (marginRightIsAuto) { if (marginIEndIsAuto) {
if (availMarginSpace < 0) { if (availMarginSpace < 0) {
// Note that this case is different from the neither-'auto' // Note that this case is different from the neither-'auto'
// case below, where the spec says to ignore 'left'/'right'. // case below, where the spec says to ignore 'left'/'right'.
if (cbrs && // Ignore the specified value for 'margin-right'.
NS_STYLE_DIRECTION_RTL == cbrs->mStyleVisibility->mDirection) { margin.IEnd(cbwm) = availMarginSpace;
// Ignore the specified value for 'margin-left'.
ComputedPhysicalMargin().left = availMarginSpace;
} else {
// Ignore the specified value for 'margin-right'.
ComputedPhysicalMargin().right = availMarginSpace;
}
} else { } else {
// Both 'margin-left' and 'margin-right' are 'auto', so they get // Both 'margin-left' and 'margin-right' are 'auto', so they get
// equal values // equal values
ComputedPhysicalMargin().left = availMarginSpace / 2; margin.IStart(cbwm) = availMarginSpace / 2;
ComputedPhysicalMargin().right = availMarginSpace - ComputedPhysicalMargin().left; margin.IEnd(cbwm) = availMarginSpace - margin.IStart(cbwm);
} }
} else { } else {
// Just 'margin-left' is 'auto' // Just 'margin-left' is 'auto'
ComputedPhysicalMargin().left = availMarginSpace; margin.IStart(cbwm) = availMarginSpace;
} }
} else { } else {
if (marginRightIsAuto) { if (marginIEndIsAuto) {
// Just 'margin-right' is 'auto' // Just 'margin-right' is 'auto'
ComputedPhysicalMargin().right = availMarginSpace; margin.IEnd(cbwm) = availMarginSpace;
} else { } else {
// We're over-constrained so use the direction of the containing // We're over-constrained so use the direction of the containing
// block to dictate which value to ignore. (And note that the // block to dictate which value to ignore. (And note that the
@ -1645,95 +1639,100 @@ nsHTMLReflowState::InitAbsoluteConstraints(nsPresContext* aPresContext,
// Note that this case is different from the both-'auto' case // Note that this case is different from the both-'auto' case
// above, where the spec says to ignore // above, where the spec says to ignore
// 'margin-left'/'margin-right'. // 'margin-left'/'margin-right'.
if (cbrs && // Ignore the specified value for 'right'.
NS_STYLE_DIRECTION_RTL == cbrs->mStyleVisibility->mDirection) { offsets.IEnd(cbwm) += availMarginSpace;
// Ignore the specified value for 'left'.
ComputedPhysicalOffsets().left += availMarginSpace;
} else {
// Ignore the specified value for 'right'.
ComputedPhysicalOffsets().right += availMarginSpace;
}
} }
} }
} }
if (topIsAuto) { if (bStartIsAuto) {
// solve for 'top' // solve for block-start
if (heightIsAuto) { if (bSizeIsAuto) {
ComputedPhysicalOffsets().top = NS_AUTOOFFSET; offsets.BStart(cbwm) = NS_AUTOOFFSET;
} else { } else {
ComputedPhysicalOffsets().top = aCBSize.Height(wm) - ComputedPhysicalMargin().top - offsets.BStart(cbwm) = cbSize.BSize(cbwm) - margin.BStartEnd(cbwm) -
ComputedPhysicalBorderPadding().top - ComputedHeight() - ComputedPhysicalBorderPadding().bottom - borderPadding.BStartEnd(cbwm) - computedSize.BSize(cbwm) -
ComputedPhysicalMargin().bottom - ComputedPhysicalOffsets().bottom; offsets.BEnd(cbwm);
} }
} else if (bottomIsAuto) { } else if (bEndIsAuto) {
// solve for 'bottom' // solve for block-end
if (heightIsAuto) { if (bSizeIsAuto) {
ComputedPhysicalOffsets().bottom = NS_AUTOOFFSET; offsets.BEnd(cbwm) = NS_AUTOOFFSET;
} else { } else {
ComputedPhysicalOffsets().bottom = aCBSize.Height(wm) - ComputedPhysicalOffsets().top - offsets.BEnd(cbwm) = cbSize.BSize(cbwm) - margin.BStartEnd(cbwm) -
ComputedPhysicalMargin().top - ComputedPhysicalBorderPadding().top - ComputedHeight() - borderPadding.BStartEnd(cbwm) - computedSize.BSize(cbwm) -
ComputedPhysicalBorderPadding().bottom - ComputedPhysicalMargin().bottom; offsets.BStart(cbwm);
} }
} else { } else {
// Neither 'top' nor 'bottom' is 'auto'. // Neither block-start nor -end is 'auto'.
nscoord autoHeight = aCBSize.Height(wm) - nscoord autoBSize = cbSize.BSize(cbwm) - margin.BStartEnd(cbwm) -
ComputedPhysicalOffsets().TopBottom() - borderPadding.BStartEnd(cbwm) - offsets.BStartEnd(cbwm);
ComputedPhysicalMargin().TopBottom() - if (autoBSize < 0) {
ComputedPhysicalBorderPadding().TopBottom(); autoBSize = 0;
if (autoHeight < 0) {
autoHeight = 0;
} }
if (ComputedHeight() == NS_UNCONSTRAINEDSIZE) { if (computedSize.BSize(cbwm) == NS_UNCONSTRAINEDSIZE) {
// For non-replaced elements with 'height' auto, the 'height' // For non-replaced elements with block-size auto, the block-size
// fills the remaining space. // fills the remaining space.
ComputedHeight() = autoHeight; computedSize.BSize(cbwm) = autoBSize;
// XXX Do these need box-sizing adjustments? // XXX Do these need box-sizing adjustments?
if (ComputedHeight() > ComputedMaxHeight()) LogicalSize maxSize =
ComputedHeight() = ComputedMaxHeight(); LogicalSize(wm, ComputedMaxISize(),
if (ComputedHeight() < ComputedMinHeight()) ComputedMaxBSize()).ConvertTo(cbwm, wm);
ComputedHeight() = ComputedMinHeight(); LogicalSize minSize =
LogicalSize(wm, ComputedMinISize(),
ComputedMinBSize()).ConvertTo(cbwm, wm);
if (computedSize.BSize(cbwm) > maxSize.BSize(cbwm)) {
computedSize.BSize(cbwm) = maxSize.BSize(cbwm);
}
if (computedSize.BSize(cbwm) < minSize.BSize(cbwm)) {
computedSize.BSize(cbwm) = minSize.BSize(cbwm);
}
} }
// The height might still not fill all the available space in case: // The block-size might still not fill all the available space in case:
// * height was specified // * bsize was specified
// * we're dealing with a replaced element // * we're dealing with a replaced element
// * height was constrained by min-height or max-height. // * bsize was constrained by min- or max-bsize.
nscoord availMarginSpace = autoHeight - ComputedHeight(); nscoord availMarginSpace = autoBSize - computedSize.BSize(cbwm);
bool marginTopIsAuto = bool marginBStartIsAuto =
eStyleUnit_Auto == mStyleMargin->mMargin.GetTopUnit(); eStyleUnit_Auto == mStyleMargin->mMargin.GetBStartUnit(cbwm);
bool marginBottomIsAuto = bool marginBEndIsAuto =
eStyleUnit_Auto == mStyleMargin->mMargin.GetBottomUnit(); eStyleUnit_Auto == mStyleMargin->mMargin.GetBEndUnit(cbwm);
if (marginTopIsAuto) { if (marginBStartIsAuto) {
if (marginBottomIsAuto) { if (marginBEndIsAuto) {
if (availMarginSpace < 0) { if (availMarginSpace < 0) {
// FIXME: Note that the spec doesn't actually say we should do this! // FIXME: Note that the spec doesn't actually say we should do this!
ComputedPhysicalMargin().bottom = availMarginSpace; margin.BEnd(cbwm) = availMarginSpace;
} else { } else {
// Both 'margin-top' and 'margin-bottom' are 'auto', so they get // Both margin-block-start and -end are 'auto', so they get
// equal values // equal values
ComputedPhysicalMargin().top = availMarginSpace / 2; margin.BStart(cbwm) = availMarginSpace / 2;
ComputedPhysicalMargin().bottom = availMarginSpace - ComputedPhysicalMargin().top; margin.BEnd(cbwm) = availMarginSpace - margin.BStart(cbwm);
} }
} else { } else {
// Just 'margin-top' is 'auto' // Just margin-block-start is 'auto'
ComputedPhysicalMargin().top = availMarginSpace; margin.BStart(cbwm) = availMarginSpace;
} }
} else { } else {
if (marginBottomIsAuto) { if (marginBEndIsAuto) {
// Just 'margin-bottom' is 'auto' // Just margin-block-end is 'auto'
ComputedPhysicalMargin().bottom = availMarginSpace; margin.BEnd(cbwm) = availMarginSpace;
} else { } else {
// We're over-constrained so ignore the specified value for // We're over-constrained so ignore the specified value for
// 'bottom'. (And note that the spec says to ignore 'bottom' // block-end. (And note that the spec says to ignore 'bottom'
// rather than 'margin-bottom'.) // rather than 'margin-bottom'.)
ComputedPhysicalOffsets().bottom += availMarginSpace; offsets.BEnd(cbwm) += availMarginSpace;
} }
} }
} }
ComputedBSize() = computedSize.ConvertTo(wm, cbwm).BSize(wm);
ComputedISize() = computedSize.ConvertTo(wm, cbwm).ISize(wm);
SetComputedLogicalOffsets(offsets.ConvertTo(wm, cbwm));
SetComputedLogicalMargin(margin.ConvertTo(wm, cbwm));
} }
// This will not be converted to abstract coordinates because it's only // This will not be converted to abstract coordinates because it's only
@ -1764,7 +1763,8 @@ GetBlockMarginBorderPadding(const nsHTMLReflowState* aReflowState)
* until it finds the canvas frame, or it encounters a frame that is not a block, * until it finds the canvas frame, or it encounters a frame that is not a block,
* area, or scroll frame. This handles compatibility with IE (see bug 85016 and bug 219693) * area, or scroll frame. This handles compatibility with IE (see bug 85016 and bug 219693)
* *
* When we encounter scrolledContent block frames, we skip over them, since they are guaranteed to not be useful for computing the containing block. * When we encounter scrolledContent block frames, we skip over them,
* since they are guaranteed to not be useful for computing the containing block.
* *
* See also IsQuirkContainingBlockHeight. * See also IsQuirkContainingBlockHeight.
*/ */
@ -1838,13 +1838,15 @@ CalcQuirkContainingBlockHeight(const nsHTMLReflowState* aCBReflowState)
if (firstAncestorRS) { if (firstAncestorRS) {
nsIContent* frameContent = firstAncestorRS->frame->GetContent(); nsIContent* frameContent = firstAncestorRS->frame->GetContent();
if (frameContent) { if (frameContent) {
NS_ASSERTION(frameContent->IsHTMLElement(nsGkAtoms::html), "First ancestor is not HTML"); NS_ASSERTION(frameContent->IsHTMLElement(nsGkAtoms::html),
"First ancestor is not HTML");
} }
} }
if (secondAncestorRS) { if (secondAncestorRS) {
nsIContent* frameContent = secondAncestorRS->frame->GetContent(); nsIContent* frameContent = secondAncestorRS->frame->GetContent();
if (frameContent) { if (frameContent) {
NS_ASSERTION(frameContent->IsHTMLElement(nsGkAtoms::body), "Second ancestor is not BODY"); NS_ASSERTION(frameContent->IsHTMLElement(nsGkAtoms::body),
"Second ancestor is not BODY");
} }
} }
#endif #endif
@ -2011,15 +2013,19 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
ComputedPhysicalMargin().SizeTo(0, 0, 0, 0); ComputedPhysicalMargin().SizeTo(0, 0, 0, 0);
ComputedPhysicalOffsets().SizeTo(0, 0, 0, 0); ComputedPhysicalOffsets().SizeTo(0, 0, 0, 0);
ComputedWidth() = AvailableWidth() - ComputedPhysicalBorderPadding().LeftRight(); ComputedISize() =
if (ComputedWidth() < 0) AvailableISize() - ComputedLogicalBorderPadding().IStartEnd(wm);
ComputedWidth() = 0; if (ComputedISize() < 0) {
if (AvailableHeight() != NS_UNCONSTRAINEDSIZE) { ComputedISize() = 0;
ComputedHeight() = AvailableHeight() - ComputedPhysicalBorderPadding().TopBottom(); }
if (ComputedHeight() < 0) if (AvailableBSize() != NS_UNCONSTRAINEDSIZE) {
ComputedHeight() = 0; ComputedBSize() =
AvailableBSize() - ComputedLogicalBorderPadding().BStartEnd(wm);
if (ComputedBSize() < 0) {
ComputedBSize() = 0;
}
} else { } else {
ComputedHeight() = NS_UNCONSTRAINEDSIZE; ComputedBSize() = NS_UNCONSTRAINEDSIZE;
} }
ComputedMinWidth() = ComputedMinHeight() = 0; ComputedMinWidth() = ComputedMinHeight() = 0;
@ -2185,7 +2191,7 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
} else if (NS_FRAME_GET_TYPE(mFrameType) == NS_CSS_FRAME_TYPE_ABSOLUTE) { } else if (NS_FRAME_GET_TYPE(mFrameType) == NS_CSS_FRAME_TYPE_ABSOLUTE) {
// XXX not sure if this belongs here or somewhere else - cwk // XXX not sure if this belongs here or somewhere else - cwk
InitAbsoluteConstraints(aPresContext, cbrs, cbSize, aFrameType); InitAbsoluteConstraints(aPresContext, cbrs, cbSize.ConvertTo(cbrs->GetWritingMode(), wm), aFrameType);
} else { } else {
AutoMaybeDisableFontInflation an(frame); AutoMaybeDisableFontInflation an(frame);

Просмотреть файл

@ -422,9 +422,12 @@ struct nsHTMLReflowState : public nsCSSOffsetState {
const nsMargin& ComputedPhysicalOffsets() const { return mComputedOffsets; } const nsMargin& ComputedPhysicalOffsets() const { return mComputedOffsets; }
nsMargin& ComputedPhysicalOffsets() { return mComputedOffsets; } nsMargin& ComputedPhysicalOffsets() { return mComputedOffsets; }
LogicalMargin ComputedLogicalOffsets() const const LogicalMargin ComputedLogicalOffsets() const
{ return LogicalMargin(mWritingMode, mComputedOffsets); } { return LogicalMargin(mWritingMode, mComputedOffsets); }
void SetComputedLogicalOffsets(const LogicalMargin& aOffsets)
{ mComputedOffsets = aOffsets.GetPhysicalMargin(mWritingMode); }
private: private:
// the available width in which to reflow the frame. The space // the available width in which to reflow the frame. The space
// represents the amount of room for the frame's margin, border, // represents the amount of room for the frame's margin, border,
@ -881,9 +884,6 @@ protected:
void CalculateHypotheticalBox(nsPresContext* aPresContext, void CalculateHypotheticalBox(nsPresContext* aPresContext,
nsIFrame* aPlaceholderFrame, nsIFrame* aPlaceholderFrame,
nsIFrame* aContainingBlock,
nscoord aBlockIStartContentEdge,
nscoord aBlockContentISize,
const nsHTMLReflowState* cbrs, const nsHTMLReflowState* cbrs,
nsHypotheticalBox& aHypotheticalBox, nsHypotheticalBox& aHypotheticalBox,
nsIAtom* aFrameType); nsIAtom* aFrameType);