mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 10:00:54 +00:00
Bug 1105268 - part 1 - Fix the logical/physical confusion with min- and max- dimensions in nsFrame::ComputeSize(). r=smontagu
This commit is contained in:
parent
c5ea153ed0
commit
f8c40475ef
@ -4354,27 +4354,27 @@ nsLayoutUtils::ComputeCBDependentValue(nscoord aPercentBasis,
|
||||
}
|
||||
|
||||
/* static */ nscoord
|
||||
nsLayoutUtils::ComputeWidthValue(
|
||||
nsLayoutUtils::ComputeISizeValue(
|
||||
nsRenderingContext* aRenderingContext,
|
||||
nsIFrame* aFrame,
|
||||
nscoord aContainingBlockWidth,
|
||||
nscoord aContainingBlockISize,
|
||||
nscoord aContentEdgeToBoxSizing,
|
||||
nscoord aBoxSizingToMarginEdge,
|
||||
const nsStyleCoord& aCoord)
|
||||
{
|
||||
NS_PRECONDITION(aFrame, "non-null frame expected");
|
||||
NS_PRECONDITION(aRenderingContext, "non-null rendering context expected");
|
||||
NS_WARN_IF_FALSE(aContainingBlockWidth != NS_UNCONSTRAINEDSIZE,
|
||||
"have unconstrained width; this should only result from "
|
||||
"very large sizes, not attempts at intrinsic width "
|
||||
NS_WARN_IF_FALSE(aContainingBlockISize != NS_UNCONSTRAINEDSIZE,
|
||||
"have unconstrained inline-size; this should only result from "
|
||||
"very large sizes, not attempts at intrinsic inline-size "
|
||||
"calculation");
|
||||
NS_PRECONDITION(aContainingBlockWidth >= 0,
|
||||
"width less than zero");
|
||||
NS_PRECONDITION(aContainingBlockISize >= 0,
|
||||
"inline-size less than zero");
|
||||
|
||||
nscoord result;
|
||||
if (aCoord.IsCoordPercentCalcUnit()) {
|
||||
result = nsRuleNode::ComputeCoordPercentCalc(aCoord,
|
||||
aContainingBlockWidth);
|
||||
aContainingBlockISize);
|
||||
// The result of a calc() expression might be less than 0; we
|
||||
// should clamp at runtime (below). (Percentages and coords that
|
||||
// are less than 0 have already been dropped by the parser.)
|
||||
@ -4389,24 +4389,24 @@ nsLayoutUtils::ComputeWidthValue(
|
||||
switch (val) {
|
||||
case NS_STYLE_WIDTH_MAX_CONTENT:
|
||||
result = aFrame->GetPrefISize(aRenderingContext);
|
||||
NS_ASSERTION(result >= 0, "width less than zero");
|
||||
NS_ASSERTION(result >= 0, "inline-size less than zero");
|
||||
break;
|
||||
case NS_STYLE_WIDTH_MIN_CONTENT:
|
||||
result = aFrame->GetMinISize(aRenderingContext);
|
||||
NS_ASSERTION(result >= 0, "width less than zero");
|
||||
NS_ASSERTION(result >= 0, "inline-size less than zero");
|
||||
break;
|
||||
case NS_STYLE_WIDTH_FIT_CONTENT:
|
||||
{
|
||||
nscoord pref = aFrame->GetPrefISize(aRenderingContext),
|
||||
min = aFrame->GetMinISize(aRenderingContext),
|
||||
fill = aContainingBlockWidth -
|
||||
fill = aContainingBlockISize -
|
||||
(aBoxSizingToMarginEdge + aContentEdgeToBoxSizing);
|
||||
result = std::max(min, std::min(pref, fill));
|
||||
NS_ASSERTION(result >= 0, "width less than zero");
|
||||
NS_ASSERTION(result >= 0, "inline-size less than zero");
|
||||
}
|
||||
break;
|
||||
case NS_STYLE_WIDTH_AVAILABLE:
|
||||
result = aContainingBlockWidth -
|
||||
result = aContainingBlockISize -
|
||||
(aBoxSizingToMarginEdge + aContentEdgeToBoxSizing);
|
||||
}
|
||||
}
|
||||
@ -4415,28 +4415,28 @@ nsLayoutUtils::ComputeWidthValue(
|
||||
}
|
||||
|
||||
/* static */ nscoord
|
||||
nsLayoutUtils::ComputeHeightDependentValue(
|
||||
nscoord aContainingBlockHeight,
|
||||
nsLayoutUtils::ComputeBSizeDependentValue(
|
||||
nscoord aContainingBlockBSize,
|
||||
const nsStyleCoord& aCoord)
|
||||
{
|
||||
// XXXldb Some callers explicitly check aContainingBlockHeight
|
||||
// XXXldb Some callers explicitly check aContainingBlockBSize
|
||||
// against NS_AUTOHEIGHT *and* unit against eStyleUnit_Percent or
|
||||
// calc()s containing percents before calling this function.
|
||||
// However, it would be much more likely to catch problems without
|
||||
// the unit conditions.
|
||||
// XXXldb Many callers pass a non-'auto' containing block height when
|
||||
// according to CSS2.1 they should be passing 'auto'.
|
||||
NS_PRECONDITION(NS_AUTOHEIGHT != aContainingBlockHeight ||
|
||||
NS_PRECONDITION(NS_AUTOHEIGHT != aContainingBlockBSize ||
|
||||
!aCoord.HasPercent(),
|
||||
"unexpected containing block height");
|
||||
"unexpected containing block block-size");
|
||||
|
||||
if (aCoord.IsCoordPercentCalcUnit()) {
|
||||
return nsRuleNode::ComputeCoordPercentCalc(aCoord, aContainingBlockHeight);
|
||||
return nsRuleNode::ComputeCoordPercentCalc(aCoord, aContainingBlockBSize);
|
||||
}
|
||||
|
||||
NS_ASSERTION(aCoord.GetUnit() == eStyleUnit_None ||
|
||||
aCoord.GetUnit() == eStyleUnit_Auto,
|
||||
"unexpected height value");
|
||||
"unexpected block-size value");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1295,45 +1295,86 @@ public:
|
||||
* and margin that goes outside the rect chosen by box-sizing.
|
||||
* @param aCoord The width value to compute.
|
||||
*/
|
||||
// XXX to be removed
|
||||
static nscoord ComputeWidthValue(
|
||||
nsRenderingContext* aRenderingContext,
|
||||
nsIFrame* aFrame,
|
||||
nscoord aContainingBlockWidth,
|
||||
nscoord aContentEdgeToBoxSizing,
|
||||
nscoord aBoxSizingToMarginEdge,
|
||||
const nsStyleCoord& aCoord);
|
||||
const nsStyleCoord& aCoord)
|
||||
{
|
||||
return ComputeISizeValue(aRenderingContext,
|
||||
aFrame,
|
||||
aContainingBlockWidth,
|
||||
aContentEdgeToBoxSizing,
|
||||
aBoxSizingToMarginEdge,
|
||||
aCoord);
|
||||
}
|
||||
|
||||
static nscoord ComputeISizeValue(
|
||||
nsRenderingContext* aRenderingContext,
|
||||
nsIFrame* aFrame,
|
||||
nscoord aContainingBlockISize,
|
||||
nscoord aContentEdgeToBoxSizing,
|
||||
nscoord aBoxSizingToMarginEdge,
|
||||
const nsStyleCoord& aCoord);
|
||||
|
||||
/*
|
||||
* Convert nsStyleCoord to nscoord when percentages depend on the
|
||||
* containing block height.
|
||||
*/
|
||||
// XXX to be removed
|
||||
static nscoord ComputeHeightDependentValue(
|
||||
nscoord aContainingBlockHeight,
|
||||
const nsStyleCoord& aCoord)
|
||||
{
|
||||
return ComputeBSizeDependentValue(aContainingBlockHeight, aCoord);
|
||||
}
|
||||
|
||||
static nscoord ComputeBSizeDependentValue(
|
||||
nscoord aContainingBlockBSize,
|
||||
const nsStyleCoord& aCoord);
|
||||
|
||||
/*
|
||||
* Likewise, but for 'height', 'min-height', or 'max-height'.
|
||||
*/
|
||||
// XXX to be removed
|
||||
static nscoord ComputeHeightValue(nscoord aContainingBlockHeight,
|
||||
nscoord aContentEdgeToBoxSizingBoxEdge,
|
||||
const nsStyleCoord& aCoord)
|
||||
{
|
||||
MOZ_ASSERT(aContainingBlockHeight != nscoord_MAX || !aCoord.HasPercent(),
|
||||
"caller must deal with %% of unconstrained height");
|
||||
return ComputeBSizeValue(aContainingBlockHeight,
|
||||
aContentEdgeToBoxSizingBoxEdge,
|
||||
aCoord);
|
||||
}
|
||||
|
||||
static nscoord ComputeBSizeValue(nscoord aContainingBlockBSize,
|
||||
nscoord aContentEdgeToBoxSizingBoxEdge,
|
||||
const nsStyleCoord& aCoord)
|
||||
{
|
||||
MOZ_ASSERT(aContainingBlockBSize != nscoord_MAX || !aCoord.HasPercent(),
|
||||
"caller must deal with %% of unconstrained block-size");
|
||||
MOZ_ASSERT(aCoord.IsCoordPercentCalcUnit());
|
||||
|
||||
nscoord result =
|
||||
nsRuleNode::ComputeCoordPercentCalc(aCoord, aContainingBlockHeight);
|
||||
nsRuleNode::ComputeCoordPercentCalc(aCoord, aContainingBlockBSize);
|
||||
// Clamp calc(), and the subtraction for box-sizing.
|
||||
return std::max(0, result - aContentEdgeToBoxSizingBoxEdge);
|
||||
}
|
||||
|
||||
// XXX to be removed
|
||||
static bool IsAutoHeight(const nsStyleCoord &aCoord, nscoord aCBHeight)
|
||||
{
|
||||
return IsAutoBSize(aCoord, aCBHeight);
|
||||
}
|
||||
|
||||
static bool IsAutoBSize(const nsStyleCoord &aCoord, nscoord aCBBSize)
|
||||
{
|
||||
nsStyleUnit unit = aCoord.GetUnit();
|
||||
return unit == eStyleUnit_Auto || // only for 'height'
|
||||
unit == eStyleUnit_None || // only for 'max-height'
|
||||
(aCBHeight == nscoord_MAX && aCoord.HasPercent());
|
||||
(aCBBSize == nscoord_MAX && aCoord.HasPercent());
|
||||
}
|
||||
|
||||
static bool IsPaddingZero(const nsStyleCoord &aCoord)
|
||||
|
@ -4139,15 +4139,12 @@ nsFrame::ComputeSize(nsRenderingContext *aRenderingContext,
|
||||
aMargin.ISize(aWM) + aBorder.ISize(aWM) + aPadding.ISize(aWM) -
|
||||
boxSizingAdjust.ISize(aWM);
|
||||
|
||||
const nsStyleCoord* inlineStyleCoord;
|
||||
const nsStyleCoord* blockStyleCoord;
|
||||
if (aWM.IsVertical()) {
|
||||
inlineStyleCoord = &(stylePos->mHeight);
|
||||
blockStyleCoord = &(stylePos->mWidth);
|
||||
} else {
|
||||
inlineStyleCoord = &(stylePos->mWidth);
|
||||
blockStyleCoord = &(stylePos->mHeight);
|
||||
}
|
||||
bool isVertical = aWM.IsVertical();
|
||||
|
||||
const nsStyleCoord* inlineStyleCoord =
|
||||
isVertical ? &(stylePos->mHeight) : &(stylePos->mWidth);
|
||||
const nsStyleCoord* blockStyleCoord =
|
||||
isVertical ? &(stylePos->mWidth) : &(stylePos->mHeight);
|
||||
|
||||
bool isFlexItem = IsFlexItem();
|
||||
bool isInlineFlexItem = false;
|
||||
@ -4188,30 +4185,36 @@ nsFrame::ComputeSize(nsRenderingContext *aRenderingContext,
|
||||
|
||||
if (inlineStyleCoord->GetUnit() != eStyleUnit_Auto) {
|
||||
result.ISize(aWM) =
|
||||
nsLayoutUtils::ComputeWidthValue(aRenderingContext, this,
|
||||
nsLayoutUtils::ComputeISizeValue(aRenderingContext, this,
|
||||
aCBSize.ISize(aWM), boxSizingAdjust.ISize(aWM), boxSizingToMarginEdgeISize,
|
||||
*inlineStyleCoord);
|
||||
}
|
||||
|
||||
const nsStyleCoord& maxISizeCoord =
|
||||
isVertical ? stylePos->mMaxHeight : stylePos->mMaxWidth;
|
||||
|
||||
// Flex items ignore their min & max sizing properties in their
|
||||
// flex container's main-axis. (Those properties get applied later in
|
||||
// the flexbox algorithm.)
|
||||
if (stylePos->mMaxWidth.GetUnit() != eStyleUnit_None &&
|
||||
if (maxISizeCoord.GetUnit() != eStyleUnit_None &&
|
||||
!(isFlexItem && isInlineFlexItem)) {
|
||||
nscoord maxISize =
|
||||
nsLayoutUtils::ComputeWidthValue(aRenderingContext, this,
|
||||
nsLayoutUtils::ComputeISizeValue(aRenderingContext, this,
|
||||
aCBSize.ISize(aWM), boxSizingAdjust.ISize(aWM), boxSizingToMarginEdgeISize,
|
||||
stylePos->mMaxWidth);
|
||||
maxISizeCoord);
|
||||
result.ISize(aWM) = std::min(maxISize, result.ISize(aWM));
|
||||
}
|
||||
|
||||
const nsStyleCoord& minISizeCoord =
|
||||
isVertical ? stylePos->mMinHeight : stylePos->mMinWidth;
|
||||
|
||||
nscoord minISize;
|
||||
if (stylePos->mMinWidth.GetUnit() != eStyleUnit_Auto &&
|
||||
if (minISizeCoord.GetUnit() != eStyleUnit_Auto &&
|
||||
!(isFlexItem && isInlineFlexItem)) {
|
||||
minISize =
|
||||
nsLayoutUtils::ComputeWidthValue(aRenderingContext, this,
|
||||
nsLayoutUtils::ComputeISizeValue(aRenderingContext, this,
|
||||
aCBSize.ISize(aWM), boxSizingAdjust.ISize(aWM), boxSizingToMarginEdgeISize,
|
||||
stylePos->mMinWidth);
|
||||
minISizeCoord);
|
||||
} else {
|
||||
// Treat "min-width: auto" as 0.
|
||||
// NOTE: Technically, "auto" is supposed to behave like "min-content" on
|
||||
@ -4226,30 +4229,36 @@ nsFrame::ComputeSize(nsRenderingContext *aRenderingContext,
|
||||
// (but not if we're auto-height or if we recieved the "eUseAutoHeight"
|
||||
// flag -- then, we'll just stick with the height that we already calculated
|
||||
// in the initial ComputeAutoSize() call.)
|
||||
if (!nsLayoutUtils::IsAutoHeight(*blockStyleCoord, aCBSize.BSize(aWM)) &&
|
||||
if (!nsLayoutUtils::IsAutoBSize(*blockStyleCoord, aCBSize.BSize(aWM)) &&
|
||||
!(aFlags & nsIFrame::eUseAutoHeight)) {
|
||||
result.BSize(aWM) =
|
||||
nsLayoutUtils::ComputeHeightValue(aCBSize.BSize(aWM),
|
||||
boxSizingAdjust.BSize(aWM),
|
||||
*blockStyleCoord);
|
||||
nsLayoutUtils::ComputeBSizeValue(aCBSize.BSize(aWM),
|
||||
boxSizingAdjust.BSize(aWM),
|
||||
*blockStyleCoord);
|
||||
}
|
||||
|
||||
const nsStyleCoord& maxBSizeCoord =
|
||||
isVertical ? stylePos->mMaxWidth : stylePos->mMaxHeight;
|
||||
|
||||
if (result.BSize(aWM) != NS_UNCONSTRAINEDSIZE) {
|
||||
if (!nsLayoutUtils::IsAutoHeight(stylePos->mMaxHeight, aCBSize.BSize(aWM)) &&
|
||||
if (!nsLayoutUtils::IsAutoBSize(maxBSizeCoord, aCBSize.BSize(aWM)) &&
|
||||
!(isFlexItem && !isInlineFlexItem)) {
|
||||
nscoord maxBSize =
|
||||
nsLayoutUtils::ComputeHeightValue(aCBSize.BSize(aWM),
|
||||
boxSizingAdjust.BSize(aWM),
|
||||
stylePos->mMaxHeight);
|
||||
nsLayoutUtils::ComputeBSizeValue(aCBSize.BSize(aWM),
|
||||
boxSizingAdjust.BSize(aWM),
|
||||
maxBSizeCoord);
|
||||
result.BSize(aWM) = std::min(maxBSize, result.BSize(aWM));
|
||||
}
|
||||
|
||||
if (!nsLayoutUtils::IsAutoHeight(stylePos->mMinHeight, aCBSize.BSize(aWM)) &&
|
||||
const nsStyleCoord& minBSizeCoord =
|
||||
isVertical ? stylePos->mMinWidth : stylePos->mMinHeight;
|
||||
|
||||
if (!nsLayoutUtils::IsAutoBSize(minBSizeCoord, aCBSize.BSize(aWM)) &&
|
||||
!(isFlexItem && !isInlineFlexItem)) {
|
||||
nscoord minBSize =
|
||||
nsLayoutUtils::ComputeHeightValue(aCBSize.BSize(aWM),
|
||||
boxSizingAdjust.BSize(aWM),
|
||||
stylePos->mMinHeight);
|
||||
nsLayoutUtils::ComputeBSizeValue(aCBSize.BSize(aWM),
|
||||
boxSizingAdjust.BSize(aWM),
|
||||
minBSizeCoord);
|
||||
result.BSize(aWM) = std::max(minBSize, result.BSize(aWM));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user