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:
Mats Palmgren 2015-06-16 11:21:03 +00:00
Родитель 674cd507a1
Коммит 3323248afe
1 изменённых файлов: 151 добавлений и 116 удалений

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

@ -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);