зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1108923 - Use the correct containing box dimension as the percent basis for margin/padding in vertical writing modes. r=smontagu
This commit is contained in:
Родитель
fc140a436a
Коммит
f067b8adaf
|
@ -1041,6 +1041,36 @@ public:
|
|||
mMargin.SizeTo(aBStart, aIEnd, aBEnd, aIStart);
|
||||
}
|
||||
|
||||
nscoord& Top(WritingMode aWritingMode)
|
||||
{
|
||||
CHECK_WRITING_MODE(aWritingMode);
|
||||
return aWritingMode.IsVertical() ?
|
||||
(aWritingMode.IsBidiLTR() ? IStart() : IEnd()) : BStart();
|
||||
}
|
||||
|
||||
nscoord& Bottom(WritingMode aWritingMode)
|
||||
{
|
||||
CHECK_WRITING_MODE(aWritingMode);
|
||||
return aWritingMode.IsVertical() ?
|
||||
(aWritingMode.IsBidiLTR() ? IEnd() : IStart()) : BEnd();
|
||||
}
|
||||
|
||||
nscoord& Left(WritingMode aWritingMode)
|
||||
{
|
||||
CHECK_WRITING_MODE(aWritingMode);
|
||||
return aWritingMode.IsVertical() ?
|
||||
(aWritingMode.IsVerticalLR() ? BStart() : BEnd()) :
|
||||
(aWritingMode.IsBidiLTR() ? IStart() : IEnd());
|
||||
}
|
||||
|
||||
nscoord& Right(WritingMode aWritingMode)
|
||||
{
|
||||
CHECK_WRITING_MODE(aWritingMode);
|
||||
return aWritingMode.IsVertical() ?
|
||||
(aWritingMode.IsVerticalLR() ? BEnd() : BStart()) :
|
||||
(aWritingMode.IsBidiLTR() ? IEnd() : IStart());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an nsMargin containing our physical coordinates
|
||||
*/
|
||||
|
|
|
@ -1907,19 +1907,19 @@ GetFlexContainer(nsIFrame* aFrame)
|
|||
// percentage values are calculated with respect to the *width* of the
|
||||
// containing block, even for margin & padding in the vertical axis.
|
||||
static nscoord
|
||||
VerticalOffsetPercentBasis(const nsIFrame* aFrame,
|
||||
nscoord aContainingBlockWidth,
|
||||
nscoord aContainingBlockHeight)
|
||||
BlockDirOffsetPercentBasis(const nsIFrame* aFrame,
|
||||
nscoord aContainingBlockISize,
|
||||
nscoord aContainingBlockBSize)
|
||||
{
|
||||
if (!aFrame->IsFlexOrGridItem()) {
|
||||
return aContainingBlockWidth;
|
||||
return aContainingBlockISize;
|
||||
}
|
||||
|
||||
if (aContainingBlockHeight == NS_AUTOHEIGHT) {
|
||||
if (aContainingBlockBSize == NS_AUTOHEIGHT) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return aContainingBlockHeight;
|
||||
return aContainingBlockBSize;
|
||||
}
|
||||
|
||||
// XXX refactor this code to have methods for each set of properties
|
||||
|
@ -1937,13 +1937,17 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
|
|||
aContainingBlockWidth, aContainingBlockHeight,
|
||||
aBorder, aPadding);
|
||||
|
||||
WritingMode wm = GetWritingMode();
|
||||
|
||||
// If this is a reflow root, then set the computed width and
|
||||
// height equal to the available space
|
||||
if (nullptr == parentReflowState || mFlags.mDummyParentReflowState) {
|
||||
// XXXldb This doesn't mean what it used to!
|
||||
InitOffsets(aContainingBlockWidth,
|
||||
VerticalOffsetPercentBasis(frame, aContainingBlockWidth,
|
||||
aContainingBlockHeight),
|
||||
LogicalSize cbSize(wm, nsSize(aContainingBlockWidth,
|
||||
aContainingBlockHeight));
|
||||
InitOffsets(cbSize.ISize(wm),
|
||||
BlockDirOffsetPercentBasis(frame, cbSize.ISize(wm),
|
||||
cbSize.BSize(wm)),
|
||||
aFrameType, aBorder, aPadding);
|
||||
// Override mComputedMargin since reflow roots start from the
|
||||
// frame's boundary, which is inside the margin.
|
||||
|
@ -1993,9 +1997,12 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
|
|||
|
||||
// XXX Might need to also pass the CB height (not width) for page boxes,
|
||||
// too, if we implement them.
|
||||
InitOffsets(aContainingBlockWidth,
|
||||
VerticalOffsetPercentBasis(frame, aContainingBlockWidth,
|
||||
aContainingBlockHeight),
|
||||
WritingMode cbwm = mCBReflowState->GetWritingMode();
|
||||
LogicalSize cbSize(cbwm, nsSize(aContainingBlockWidth,
|
||||
aContainingBlockHeight));
|
||||
InitOffsets(cbSize.ISize(cbwm),
|
||||
BlockDirOffsetPercentBasis(frame, cbSize.ISize(cbwm),
|
||||
cbSize.BSize(cbwm)),
|
||||
aFrameType, aBorder, aPadding);
|
||||
|
||||
const nsStyleCoord &height = mStylePosition->mHeight;
|
||||
|
@ -2166,8 +2173,6 @@ nsHTMLReflowState::InitConstraints(nsPresContext* aPresContext,
|
|||
"'mIsFlexContainerMeasuringHeight' shouldn't be set");
|
||||
}
|
||||
|
||||
WritingMode wm = GetWritingMode();
|
||||
|
||||
LogicalSize cbSize(wm, nsSize(aContainingBlockWidth,
|
||||
aContainingBlockHeight));
|
||||
if (cbSize.ISize(wm) == NS_UNCONSTRAINEDSIZE) {
|
||||
|
@ -2221,15 +2226,15 @@ UpdateProp(FrameProperties& aProps,
|
|||
}
|
||||
|
||||
void
|
||||
nsCSSOffsetState::InitOffsets(nscoord aHorizontalPercentBasis,
|
||||
nscoord aVerticalPercentBasis,
|
||||
nsCSSOffsetState::InitOffsets(nscoord aInlineDirPercentBasis,
|
||||
nscoord aBlockDirPercentBasis,
|
||||
nsIAtom* aFrameType,
|
||||
const nsMargin *aBorder,
|
||||
const nsMargin *aPadding)
|
||||
{
|
||||
DISPLAY_INIT_OFFSETS(frame, this,
|
||||
aHorizontalPercentBasis,
|
||||
aVerticalPercentBasis,
|
||||
aInlineDirPercentBasis,
|
||||
aBlockDirPercentBasis,
|
||||
aBorder, aPadding);
|
||||
|
||||
// Since we are in reflow, we don't need to store these properties anymore
|
||||
|
@ -2242,8 +2247,8 @@ nsCSSOffsetState::InitOffsets(nscoord aHorizontalPercentBasis,
|
|||
// become the default computed values, and may be adjusted below
|
||||
// XXX fix to provide 0,0 for the top&bottom margins for
|
||||
// inline-non-replaced elements
|
||||
bool needMarginProp = ComputeMargin(aHorizontalPercentBasis,
|
||||
aVerticalPercentBasis);
|
||||
bool needMarginProp = ComputeMargin(aInlineDirPercentBasis,
|
||||
aBlockDirPercentBasis);
|
||||
// XXX We need to include 'auto' horizontal margins in this too!
|
||||
// ... but if we did that, we'd need to fix nsFrame::GetUsedMargin
|
||||
// to use it even when the margins are all zero (since sometimes
|
||||
|
@ -2276,8 +2281,8 @@ nsCSSOffsetState::InitOffsets(nscoord aHorizontalPercentBasis,
|
|||
(frame->GetStateBits() & NS_FRAME_REFLOW_ROOT);
|
||||
}
|
||||
else {
|
||||
needPaddingProp = ComputePadding(aHorizontalPercentBasis,
|
||||
aVerticalPercentBasis, aFrameType);
|
||||
needPaddingProp = ComputePadding(aInlineDirPercentBasis,
|
||||
aBlockDirPercentBasis, aFrameType);
|
||||
}
|
||||
|
||||
if (isThemed) {
|
||||
|
@ -2586,8 +2591,8 @@ nsHTMLReflowState::CalcLineHeight(nsIContent* aContent,
|
|||
}
|
||||
|
||||
bool
|
||||
nsCSSOffsetState::ComputeMargin(nscoord aHorizontalPercentBasis,
|
||||
nscoord aVerticalPercentBasis)
|
||||
nsCSSOffsetState::ComputeMargin(nscoord aInlineDirPercentBasis,
|
||||
nscoord aBlockDirPercentBasis)
|
||||
{
|
||||
// SVG text frames have no margin.
|
||||
if (frame->IsSVGText()) {
|
||||
|
@ -2599,38 +2604,44 @@ nsCSSOffsetState::ComputeMargin(nscoord aHorizontalPercentBasis,
|
|||
bool isCBDependent = !styleMargin->GetMargin(ComputedPhysicalMargin());
|
||||
if (isCBDependent) {
|
||||
// We have to compute the value
|
||||
ComputedPhysicalMargin().left = nsLayoutUtils::
|
||||
ComputeCBDependentValue(aHorizontalPercentBasis,
|
||||
LogicalMargin m(mWritingMode);
|
||||
nscoord horizontalPercentBasis =
|
||||
mWritingMode.IsVertical() ? aBlockDirPercentBasis
|
||||
: aInlineDirPercentBasis;
|
||||
m.Left(mWritingMode) = nsLayoutUtils::
|
||||
ComputeCBDependentValue(horizontalPercentBasis,
|
||||
styleMargin->mMargin.GetLeft());
|
||||
ComputedPhysicalMargin().right = nsLayoutUtils::
|
||||
ComputeCBDependentValue(aHorizontalPercentBasis,
|
||||
m.Right(mWritingMode) = nsLayoutUtils::
|
||||
ComputeCBDependentValue(horizontalPercentBasis,
|
||||
styleMargin->mMargin.GetRight());
|
||||
|
||||
ComputedPhysicalMargin().top = nsLayoutUtils::
|
||||
ComputeCBDependentValue(aVerticalPercentBasis,
|
||||
nscoord verticalPercentBasis =
|
||||
mWritingMode.IsVertical() ? aInlineDirPercentBasis
|
||||
: aBlockDirPercentBasis;
|
||||
m.Top(mWritingMode) = nsLayoutUtils::
|
||||
ComputeCBDependentValue(verticalPercentBasis,
|
||||
styleMargin->mMargin.GetTop());
|
||||
ComputedPhysicalMargin().bottom = nsLayoutUtils::
|
||||
ComputeCBDependentValue(aVerticalPercentBasis,
|
||||
m.Bottom(mWritingMode) = nsLayoutUtils::
|
||||
ComputeCBDependentValue(verticalPercentBasis,
|
||||
styleMargin->mMargin.GetBottom());
|
||||
|
||||
SetComputedLogicalMargin(m);
|
||||
}
|
||||
|
||||
nscoord marginAdjustment = FontSizeInflationListMarginAdjustment(frame);
|
||||
|
||||
if (marginAdjustment > 0) {
|
||||
const nsStyleVisibility* visibility = frame->StyleVisibility();
|
||||
if (visibility->mDirection == NS_STYLE_DIRECTION_RTL) {
|
||||
ComputedPhysicalMargin().right = ComputedPhysicalMargin().right + marginAdjustment;
|
||||
} else {
|
||||
ComputedPhysicalMargin().left = ComputedPhysicalMargin().left + marginAdjustment;
|
||||
}
|
||||
LogicalMargin m = ComputedLogicalMargin();
|
||||
m.IStart(mWritingMode) += marginAdjustment;
|
||||
SetComputedLogicalMargin(m);
|
||||
}
|
||||
|
||||
return isCBDependent;
|
||||
}
|
||||
|
||||
bool
|
||||
nsCSSOffsetState::ComputePadding(nscoord aHorizontalPercentBasis,
|
||||
nscoord aVerticalPercentBasis,
|
||||
nsCSSOffsetState::ComputePadding(nscoord aInlineDirPercentBasis,
|
||||
nscoord aBlockDirPercentBasis,
|
||||
nsIAtom* aFrameType)
|
||||
{
|
||||
// If style can provide us the padding directly, then use it.
|
||||
|
@ -2647,19 +2658,28 @@ nsCSSOffsetState::ComputePadding(nscoord aHorizontalPercentBasis,
|
|||
else if (isCBDependent) {
|
||||
// We have to compute the value
|
||||
// clamp negative calc() results to 0
|
||||
ComputedPhysicalPadding().left = std::max(0, nsLayoutUtils::
|
||||
ComputeCBDependentValue(aHorizontalPercentBasis,
|
||||
LogicalMargin p(mWritingMode);
|
||||
nscoord horizontalPercentBasis =
|
||||
mWritingMode.IsVertical() ? aBlockDirPercentBasis
|
||||
: aInlineDirPercentBasis;
|
||||
p.Left(mWritingMode) = std::max(0, nsLayoutUtils::
|
||||
ComputeCBDependentValue(horizontalPercentBasis,
|
||||
stylePadding->mPadding.GetLeft()));
|
||||
ComputedPhysicalPadding().right = std::max(0, nsLayoutUtils::
|
||||
ComputeCBDependentValue(aHorizontalPercentBasis,
|
||||
p.Right(mWritingMode) = std::max(0, nsLayoutUtils::
|
||||
ComputeCBDependentValue(horizontalPercentBasis,
|
||||
stylePadding->mPadding.GetRight()));
|
||||
|
||||
ComputedPhysicalPadding().top = std::max(0, nsLayoutUtils::
|
||||
ComputeCBDependentValue(aVerticalPercentBasis,
|
||||
nscoord verticalPercentBasis =
|
||||
mWritingMode.IsVertical() ? aInlineDirPercentBasis
|
||||
: aBlockDirPercentBasis;
|
||||
p.Top(mWritingMode) = std::max(0, nsLayoutUtils::
|
||||
ComputeCBDependentValue(verticalPercentBasis,
|
||||
stylePadding->mPadding.GetTop()));
|
||||
ComputedPhysicalPadding().bottom = std::max(0, nsLayoutUtils::
|
||||
ComputeCBDependentValue(aVerticalPercentBasis,
|
||||
p.Bottom(mWritingMode) = std::max(0, nsLayoutUtils::
|
||||
ComputeCBDependentValue(verticalPercentBasis,
|
||||
stylePadding->mPadding.GetBottom()));
|
||||
|
||||
SetComputedLogicalPadding(p);
|
||||
}
|
||||
return isCBDependent;
|
||||
}
|
||||
|
|
|
@ -166,8 +166,8 @@ public:
|
|||
// to the display-reflow infrastructure.
|
||||
static void* DisplayInitOffsetsEnter(nsIFrame* aFrame,
|
||||
nsCSSOffsetState* aState,
|
||||
nscoord aHorizontalPercentBasis,
|
||||
nscoord aVerticalPercentBasis,
|
||||
nscoord aInlineDirPercentBasis,
|
||||
nscoord aBlockDirPercentBasis,
|
||||
const nsMargin* aBorder,
|
||||
const nsMargin* aPadding);
|
||||
static void DisplayInitOffsetsExit(nsIFrame* aFrame,
|
||||
|
@ -189,8 +189,8 @@ private:
|
|||
* be the containing block *height*, e.g. in CSS3 Flexbox and Grid.
|
||||
* @return true if the margin is dependent on the containing block size.
|
||||
*/
|
||||
bool ComputeMargin(nscoord aHorizontalPercentBasis,
|
||||
nscoord aVerticalPercentBasis);
|
||||
bool ComputeMargin(nscoord aInlineDirPercentBasis,
|
||||
nscoord aBlockDirPercentBasis);
|
||||
|
||||
/**
|
||||
* Computes padding values from the specified padding style information, and
|
||||
|
@ -205,13 +205,13 @@ private:
|
|||
* be the containing block *height* in e.g. CSS3 Flexbox and Grid.
|
||||
* @return true if the padding is dependent on the containing block size.
|
||||
*/
|
||||
bool ComputePadding(nscoord aHorizontalPercentBasis,
|
||||
nscoord aVerticalPercentBasis, nsIAtom* aFrameType);
|
||||
bool ComputePadding(nscoord aInlineDirPercentBasis,
|
||||
nscoord aBlockDirPercentBasis, nsIAtom* aFrameType);
|
||||
|
||||
protected:
|
||||
|
||||
void InitOffsets(nscoord aHorizontalPercentBasis,
|
||||
nscoord aVerticalPercentBasis,
|
||||
void InitOffsets(nscoord aInlineDirPercentBasis,
|
||||
nscoord aBlockDirPercentBasis,
|
||||
nsIAtom* aFrameType,
|
||||
const nsMargin *aBorder = nullptr,
|
||||
const nsMargin *aPadding = nullptr);
|
||||
|
|
Загрузка…
Ссылка в новой задаче