зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1174450 part 1 - Split IntrinsicForContainer in two parts; move the latter part to a new function, AddIntrinsicSizeOffset, which applies the padding/border/margin from the given IntrinsicISizeOffsetData. r=jfkthame
This commit is contained in:
Родитель
674cd507a1
Коммит
3323248afe
|
@ -4319,6 +4319,148 @@ GetIntrinsicCoord(const nsStyleCoord& aStyle,
|
|||
static int32_t gNoiseIndent = 0;
|
||||
#endif
|
||||
|
||||
static nscoord
|
||||
AddIntrinsicSizeOffset(nsRenderingContext* aRenderingContext,
|
||||
nsIFrame* aFrame,
|
||||
const nsIFrame::IntrinsicISizeOffsetData& offsets,
|
||||
nsLayoutUtils::IntrinsicISizeType aType,
|
||||
uint8_t boxSizing,
|
||||
nscoord result,
|
||||
nscoord min,
|
||||
const nsStyleCoord& styleISize,
|
||||
const nsStyleCoord& styleMinISize,
|
||||
const nsStyleCoord& styleMaxISize,
|
||||
uint32_t aFlags,
|
||||
WritingMode aContainerWM)
|
||||
{
|
||||
// We also need to track what has been added on outside of the box
|
||||
// (controlled by 'box-sizing') where 'width', 'min-width' and
|
||||
// 'max-width' are applied. We have to account for these properties
|
||||
// after getting all the offsets (margin, border, padding) because
|
||||
// percentages do not operate linearly.
|
||||
// Doing this is ok because although percentages aren't handled
|
||||
// linearly, they are handled monotonically.
|
||||
nscoord coordOutsideISize = 0;
|
||||
float pctOutsideISize = 0;
|
||||
float pctTotal = 0.0f;
|
||||
|
||||
if (!(aFlags & nsLayoutUtils::IGNORE_PADDING)) {
|
||||
coordOutsideISize += offsets.hPadding;
|
||||
pctOutsideISize += offsets.hPctPadding;
|
||||
|
||||
if (boxSizing == NS_STYLE_BOX_SIZING_PADDING) {
|
||||
min += coordOutsideISize;
|
||||
result = NSCoordSaturatingAdd(result, coordOutsideISize);
|
||||
pctTotal += pctOutsideISize;
|
||||
|
||||
coordOutsideISize = 0;
|
||||
pctOutsideISize = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
coordOutsideISize += offsets.hBorder;
|
||||
|
||||
if (boxSizing == NS_STYLE_BOX_SIZING_BORDER) {
|
||||
min += coordOutsideISize;
|
||||
result = NSCoordSaturatingAdd(result, coordOutsideISize);
|
||||
pctTotal += pctOutsideISize;
|
||||
|
||||
coordOutsideISize = 0;
|
||||
pctOutsideISize = 0.0f;
|
||||
}
|
||||
|
||||
coordOutsideISize += offsets.hMargin;
|
||||
pctOutsideISize += offsets.hPctMargin;
|
||||
|
||||
min += coordOutsideISize;
|
||||
result = NSCoordSaturatingAdd(result, coordOutsideISize);
|
||||
pctTotal += pctOutsideISize;
|
||||
|
||||
nscoord w;
|
||||
if (GetAbsoluteCoord(styleISize, w) ||
|
||||
GetIntrinsicCoord(styleISize, aRenderingContext, aFrame,
|
||||
PROP_WIDTH, w)) {
|
||||
result = AddPercents(aType, w + coordOutsideISize, pctOutsideISize);
|
||||
}
|
||||
else if (aType == nsLayoutUtils::MIN_ISIZE &&
|
||||
// The only cases of coord-percent-calc() units that
|
||||
// GetAbsoluteCoord didn't handle are percent and calc()s
|
||||
// containing percent.
|
||||
styleISize.IsCoordPercentCalcUnit() &&
|
||||
aFrame->IsFrameOfType(nsIFrame::eReplaced)) {
|
||||
// A percentage width on replaced elements means they can shrink to 0.
|
||||
result = 0; // let |min| handle padding/border/margin
|
||||
}
|
||||
else {
|
||||
// NOTE: We could really do a lot better for percents and for some
|
||||
// cases of calc() containing percent (certainly including any where
|
||||
// the coefficient on the percent is positive and there are no max()
|
||||
// expressions). However, doing better for percents wouldn't be
|
||||
// backwards compatible.
|
||||
result = AddPercents(aType, result, pctTotal);
|
||||
}
|
||||
|
||||
nscoord maxISize;
|
||||
bool haveFixedMaxISize = GetAbsoluteCoord(styleMaxISize, maxISize);
|
||||
nscoord minISize;
|
||||
|
||||
// Treat "min-width: auto" as 0.
|
||||
bool haveFixedMinISize;
|
||||
if (eStyleUnit_Auto == styleMinISize.GetUnit()) {
|
||||
// NOTE: Technically, "auto" is supposed to behave like "min-content" on
|
||||
// flex items. However, we don't need to worry about that here, because
|
||||
// flex items' min-sizes are intentionally ignored until the flex
|
||||
// container explicitly considers them during space distribution.
|
||||
minISize = 0;
|
||||
haveFixedMinISize = true;
|
||||
} else {
|
||||
haveFixedMinISize = GetAbsoluteCoord(styleMinISize, minISize);
|
||||
}
|
||||
|
||||
if (haveFixedMaxISize ||
|
||||
GetIntrinsicCoord(styleMaxISize, aRenderingContext, aFrame,
|
||||
PROP_MAX_WIDTH, maxISize)) {
|
||||
maxISize = AddPercents(aType, maxISize + coordOutsideISize, pctOutsideISize);
|
||||
if (result > maxISize)
|
||||
result = maxISize;
|
||||
}
|
||||
|
||||
if (haveFixedMinISize ||
|
||||
GetIntrinsicCoord(styleMinISize, aRenderingContext, aFrame,
|
||||
PROP_MIN_WIDTH, minISize)) {
|
||||
minISize = AddPercents(aType, minISize + coordOutsideISize, pctOutsideISize);
|
||||
if (result < minISize)
|
||||
result = minISize;
|
||||
}
|
||||
|
||||
min = AddPercents(aType, min, pctTotal);
|
||||
if (result < min)
|
||||
result = min;
|
||||
|
||||
const nsStyleDisplay *disp = aFrame->StyleDisplay();
|
||||
if (aFrame->IsThemed(disp)) {
|
||||
LayoutDeviceIntSize size;
|
||||
bool canOverride = true;
|
||||
nsPresContext *presContext = aFrame->PresContext();
|
||||
presContext->GetTheme()->
|
||||
GetMinimumWidgetSize(presContext, aFrame, disp->mAppearance,
|
||||
&size, &canOverride);
|
||||
|
||||
nscoord themeISize =
|
||||
presContext->DevPixelsToAppUnits(aContainerWM.IsVertical() ? size.height
|
||||
: size.width);
|
||||
|
||||
// GMWS() returns a border-box width
|
||||
themeISize += offsets.hMargin;
|
||||
themeISize = AddPercents(aType, themeISize, offsets.hPctMargin);
|
||||
|
||||
if (themeISize > result || !canOverride) {
|
||||
result = themeISize;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* static */ nscoord
|
||||
nsLayoutUtils::IntrinsicForContainer(nsRenderingContext *aRenderingContext,
|
||||
nsIFrame *aFrame,
|
||||
|
@ -4341,18 +4483,11 @@ nsLayoutUtils::IntrinsicForContainer(nsRenderingContext *aRenderingContext,
|
|||
// wrapping inside of it should not apply font size inflation.
|
||||
AutoMaybeDisableFontInflation an(aFrame);
|
||||
|
||||
nsIFrame::IntrinsicISizeOffsetData offsets =
|
||||
aFrame->IntrinsicISizeOffsets(aRenderingContext);
|
||||
|
||||
// We want the size this frame will contribute to the parent's inline-size,
|
||||
// so we work in the parent's writing mode; but if aFrame is orthogonal to
|
||||
// its parent, we'll need to look at its BSize instead of min/pref-ISize.
|
||||
WritingMode wm = aFrame->GetParent()->GetWritingMode();
|
||||
WritingMode ourWM = aFrame->GetWritingMode();
|
||||
bool isOrthogonal = ourWM.IsOrthogonalTo(wm);
|
||||
bool isVertical = wm.IsVertical();
|
||||
|
||||
const nsStylePosition *stylePos = aFrame->StylePosition();
|
||||
const nsStylePosition* stylePos = aFrame->StylePosition();
|
||||
uint8_t boxSizing = stylePos->mBoxSizing;
|
||||
|
||||
const nsStyleCoord& styleISize = stylePos->ISize(wm);
|
||||
|
@ -4406,7 +4541,8 @@ nsLayoutUtils::IntrinsicForContainer(nsRenderingContext *aRenderingContext,
|
|||
#ifdef DEBUG_INTRINSIC_WIDTH
|
||||
++gNoiseIndent;
|
||||
#endif
|
||||
if (isOrthogonal) {
|
||||
WritingMode ourWM = aFrame->GetWritingMode();
|
||||
if (ourWM.IsOrthogonalTo(wm)) {
|
||||
// We need aFrame's block-dir size, which will become its inline-size
|
||||
// contribution in the container.
|
||||
// XXX Unfortunately, we probably don't know this yet, so this is wrong...
|
||||
|
@ -4513,113 +4649,12 @@ nsLayoutUtils::IntrinsicForContainer(nsRenderingContext *aRenderingContext,
|
|||
min = aFrame->GetMinISize(aRenderingContext);
|
||||
}
|
||||
|
||||
// We also need to track what has been added on outside of the box
|
||||
// (controlled by 'box-sizing') where 'width', 'min-width' and
|
||||
// 'max-width' are applied. We have to account for these properties
|
||||
// after getting all the offsets (margin, border, padding) because
|
||||
// percentages do not operate linearly.
|
||||
// Doing this is ok because although percentages aren't handled
|
||||
// linearly, they are handled monotonically.
|
||||
nscoord coordOutsideISize = 0;
|
||||
float pctOutsideISize = 0;
|
||||
float pctTotal = 0.0f;
|
||||
|
||||
if (!(aFlags & IGNORE_PADDING)) {
|
||||
coordOutsideISize += offsets.hPadding;
|
||||
pctOutsideISize += offsets.hPctPadding;
|
||||
|
||||
if (boxSizing == NS_STYLE_BOX_SIZING_PADDING) {
|
||||
min += coordOutsideISize;
|
||||
result = NSCoordSaturatingAdd(result, coordOutsideISize);
|
||||
pctTotal += pctOutsideISize;
|
||||
|
||||
coordOutsideISize = 0;
|
||||
pctOutsideISize = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
coordOutsideISize += offsets.hBorder;
|
||||
|
||||
if (boxSizing == NS_STYLE_BOX_SIZING_BORDER) {
|
||||
min += coordOutsideISize;
|
||||
result = NSCoordSaturatingAdd(result, coordOutsideISize);
|
||||
pctTotal += pctOutsideISize;
|
||||
|
||||
coordOutsideISize = 0;
|
||||
pctOutsideISize = 0.0f;
|
||||
}
|
||||
|
||||
coordOutsideISize += offsets.hMargin;
|
||||
pctOutsideISize += offsets.hPctMargin;
|
||||
|
||||
min += coordOutsideISize;
|
||||
result = NSCoordSaturatingAdd(result, coordOutsideISize);
|
||||
pctTotal += pctOutsideISize;
|
||||
|
||||
nscoord w;
|
||||
if (GetAbsoluteCoord(styleISize, w) ||
|
||||
GetIntrinsicCoord(styleISize, aRenderingContext, aFrame,
|
||||
PROP_WIDTH, w)) {
|
||||
result = AddPercents(aType, w + coordOutsideISize, pctOutsideISize);
|
||||
}
|
||||
else if (aType == MIN_ISIZE &&
|
||||
// The only cases of coord-percent-calc() units that
|
||||
// GetAbsoluteCoord didn't handle are percent and calc()s
|
||||
// containing percent.
|
||||
styleISize.IsCoordPercentCalcUnit() &&
|
||||
aFrame->IsFrameOfType(nsIFrame::eReplaced)) {
|
||||
// A percentage width on replaced elements means they can shrink to 0.
|
||||
result = 0; // let |min| handle padding/border/margin
|
||||
}
|
||||
else {
|
||||
// NOTE: We could really do a lot better for percents and for some
|
||||
// cases of calc() containing percent (certainly including any where
|
||||
// the coefficient on the percent is positive and there are no max()
|
||||
// expressions). However, doing better for percents wouldn't be
|
||||
// backwards compatible.
|
||||
result = AddPercents(aType, result, pctTotal);
|
||||
}
|
||||
|
||||
if (haveFixedMaxISize ||
|
||||
GetIntrinsicCoord(styleMaxISize, aRenderingContext, aFrame,
|
||||
PROP_MAX_WIDTH, maxISize)) {
|
||||
maxISize = AddPercents(aType, maxISize + coordOutsideISize, pctOutsideISize);
|
||||
if (result > maxISize)
|
||||
result = maxISize;
|
||||
}
|
||||
|
||||
if (haveFixedMinISize ||
|
||||
GetIntrinsicCoord(styleMinISize, aRenderingContext, aFrame,
|
||||
PROP_MIN_WIDTH, minISize)) {
|
||||
minISize = AddPercents(aType, minISize + coordOutsideISize, pctOutsideISize);
|
||||
if (result < minISize)
|
||||
result = minISize;
|
||||
}
|
||||
|
||||
min = AddPercents(aType, min, pctTotal);
|
||||
if (result < min)
|
||||
result = min;
|
||||
|
||||
const nsStyleDisplay *disp = aFrame->StyleDisplay();
|
||||
if (aFrame->IsThemed(disp)) {
|
||||
LayoutDeviceIntSize size;
|
||||
bool canOverride = true;
|
||||
nsPresContext *presContext = aFrame->PresContext();
|
||||
presContext->GetTheme()->
|
||||
GetMinimumWidgetSize(presContext, aFrame, disp->mAppearance,
|
||||
&size, &canOverride);
|
||||
|
||||
nscoord themeISize =
|
||||
presContext->DevPixelsToAppUnits(isVertical ? size.height : size.width);
|
||||
|
||||
// GMWS() returns a border-box width
|
||||
themeISize += offsets.hMargin;
|
||||
themeISize = AddPercents(aType, themeISize, offsets.hPctMargin);
|
||||
|
||||
if (themeISize > result || !canOverride) {
|
||||
result = themeISize;
|
||||
}
|
||||
}
|
||||
nsIFrame::IntrinsicISizeOffsetData offsets =
|
||||
aFrame->IntrinsicISizeOffsets(aRenderingContext);
|
||||
result = AddIntrinsicSizeOffset(aRenderingContext, aFrame, offsets, aType,
|
||||
boxSizing, result, min, styleISize,
|
||||
styleMinISize, styleMaxISize, aFlags,
|
||||
wm);
|
||||
|
||||
#ifdef DEBUG_INTRINSIC_WIDTH
|
||||
nsFrame::IndentBy(stderr, gNoiseIndent);
|
||||
|
|
Загрузка…
Ссылка в новой задаче