Make the CSS 'ch' length unit work in most cases. b=363573 r+sr=dbaron
git-svn-id: svn://10.0.0.236/trunk@217089 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -1101,7 +1101,27 @@ static nscoord AddPercents(nsLayoutUtils::IntrinsicWidthType aType,
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static PRBool GetAbsoluteCoord(const nsStyleCoord& aStyle,
|
||||
nsIRenderingContext* aRenderingContext,
|
||||
nsIFrame* aFrame,
|
||||
nscoord& aResult)
|
||||
{
|
||||
nsStyleUnit unit = aStyle.GetUnit();
|
||||
if (eStyleUnit_Coord == unit) {
|
||||
aResult = aStyle.GetCoordValue();
|
||||
return PR_TRUE;
|
||||
}
|
||||
if (eStyleUnit_Chars == unit) {
|
||||
SetFontFromStyle(aRenderingContext, aFrame->GetStyleContext());
|
||||
nscoord fontWidth;
|
||||
aRenderingContext->GetWidth('M', fontWidth);
|
||||
aResult = aStyle.GetIntValue() * fontWidth;
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
#undef DEBUG_INTRINSIC_WIDTH
|
||||
|
||||
#ifdef DEBUG_INTRINSIC_WIDTH
|
||||
@@ -1123,7 +1143,8 @@ nsLayoutUtils::IntrinsicForContainer(nsIRenderingContext *aRenderingContext,
|
||||
aType == MIN_WIDTH ? "min" : "pref");
|
||||
#endif
|
||||
|
||||
nsIFrame::IntrinsicWidthOffsetData offsets = aFrame->IntrinsicWidthOffsets();
|
||||
nsIFrame::IntrinsicWidthOffsetData offsets =
|
||||
aFrame->IntrinsicWidthOffsets(aRenderingContext);
|
||||
|
||||
const nsStylePosition *stylePos = aFrame->GetStylePosition();
|
||||
const PRUint8 boxSizing = stylePos->mBoxSizing;
|
||||
@@ -1211,32 +1232,29 @@ nsLayoutUtils::IntrinsicForContainer(nsIRenderingContext *aRenderingContext,
|
||||
result += coordOutsideWidth;
|
||||
pctTotal += pctOutsideWidth;
|
||||
|
||||
result = AddPercents(aType, result, pctTotal);
|
||||
|
||||
switch (styleWidth.GetUnit()) {
|
||||
case eStyleUnit_Coord:
|
||||
result = AddPercents(aType,
|
||||
styleWidth.GetCoordValue() + coordOutsideWidth,
|
||||
pctOutsideWidth);
|
||||
break;
|
||||
case eStyleUnit_Percent:
|
||||
if (aType == MIN_WIDTH && aFrame->IsFrameOfType(nsIFrame::eReplaced)) {
|
||||
// A percentage width on replaced elements means they can shrink to 0.
|
||||
result = 0; // let |min| handle padding/border/margin
|
||||
}
|
||||
break;
|
||||
nscoord w;
|
||||
if (GetAbsoluteCoord(styleWidth, aRenderingContext, aFrame, w)) {
|
||||
result = AddPercents(aType, w + coordOutsideWidth, pctOutsideWidth);
|
||||
}
|
||||
else if (aType == MIN_WIDTH && eStyleUnit_Percent == styleWidth.GetUnit() &&
|
||||
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 {
|
||||
result = AddPercents(aType, result, pctTotal);
|
||||
}
|
||||
|
||||
if (styleMaxWidth.GetUnit() == eStyleUnit_Coord) {
|
||||
nscoord maxw = AddPercents(aType,
|
||||
styleMaxWidth.GetCoordValue() + coordOutsideWidth, pctOutsideWidth);
|
||||
nscoord maxw;
|
||||
if (GetAbsoluteCoord(styleMaxWidth, aRenderingContext, aFrame, maxw)) {
|
||||
maxw = AddPercents(aType, maxw + coordOutsideWidth, pctOutsideWidth);
|
||||
if (result > maxw)
|
||||
result = maxw;
|
||||
}
|
||||
|
||||
if (styleMinWidth.GetUnit() == eStyleUnit_Coord) {
|
||||
nscoord minw = AddPercents(aType,
|
||||
styleMinWidth.GetCoordValue() + coordOutsideWidth, pctOutsideWidth);
|
||||
nscoord minw;
|
||||
if (GetAbsoluteCoord(styleMinWidth, aRenderingContext, aFrame, minw)) {
|
||||
minw = AddPercents(aType, minw + coordOutsideWidth, pctOutsideWidth);
|
||||
if (result < minw)
|
||||
result = minw;
|
||||
}
|
||||
@@ -1266,20 +1284,14 @@ nsLayoutUtils::ComputeHorizontalValue(nsIRenderingContext* aRenderingContext,
|
||||
NS_PRECONDITION(aContainingBlockWidth != NS_UNCONSTRAINEDSIZE,
|
||||
"unconstrained widths no longer supported");
|
||||
|
||||
nscoord result = 0;
|
||||
nsStyleUnit unit = aCoord.GetUnit();
|
||||
if (eStyleUnit_Percent == unit) {
|
||||
result = NSToCoordFloor(aContainingBlockWidth * aCoord.GetPercentValue());
|
||||
} else if (eStyleUnit_Coord == unit) {
|
||||
result = aCoord.GetCoordValue();
|
||||
nscoord result;
|
||||
if (GetAbsoluteCoord(aCoord, aRenderingContext, aFrame, result)) {
|
||||
return result;
|
||||
}
|
||||
else if (eStyleUnit_Chars == unit) {
|
||||
SetFontFromStyle(aRenderingContext, aFrame->GetStyleContext());
|
||||
nscoord fontWidth;
|
||||
aRenderingContext->GetWidth('M', fontWidth);
|
||||
result = aCoord.GetIntValue() * fontWidth;
|
||||
if (eStyleUnit_Percent == aCoord.GetUnit()) {
|
||||
return NSToCoordFloor(aContainingBlockWidth * aCoord.GetPercentValue());
|
||||
}
|
||||
return result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* static */ nscoord
|
||||
@@ -1290,9 +1302,12 @@ nsLayoutUtils::ComputeVerticalValue(nsIRenderingContext* aRenderingContext,
|
||||
{
|
||||
NS_PRECONDITION(aFrame, "non-null frame expected");
|
||||
NS_PRECONDITION(aRenderingContext, "non-null rendering context expected");
|
||||
nscoord result = 0;
|
||||
nsStyleUnit unit = aCoord.GetUnit();
|
||||
if (eStyleUnit_Percent == unit) {
|
||||
|
||||
nscoord result;
|
||||
if (GetAbsoluteCoord(aCoord, aRenderingContext, aFrame, result)) {
|
||||
return result;
|
||||
}
|
||||
if (eStyleUnit_Percent == aCoord.GetUnit()) {
|
||||
// XXXldb Some callers explicitly check aContainingBlockHeight
|
||||
// against NS_AUTOHEIGHT *and* unit against eStyleUnit_Percent
|
||||
// before calling this function, so this assertion probably needs to
|
||||
@@ -1304,13 +1319,10 @@ nsLayoutUtils::ComputeVerticalValue(nsIRenderingContext* aRenderingContext,
|
||||
"unexpected 'containing block height'");
|
||||
|
||||
if (NS_AUTOHEIGHT != aContainingBlockHeight) {
|
||||
result =
|
||||
NSToCoordFloor(aContainingBlockHeight * aCoord.GetPercentValue());
|
||||
return NSToCoordFloor(aContainingBlockHeight * aCoord.GetPercentValue());
|
||||
}
|
||||
} else if (eStyleUnit_Coord == unit) {
|
||||
result = aCoord.GetCoordValue();
|
||||
}
|
||||
return result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline PRBool
|
||||
|
||||
@@ -2916,7 +2916,10 @@ nsIFrame::InlinePrefWidthData::Break(nsIRenderingContext *aRenderingContext)
|
||||
}
|
||||
|
||||
static void
|
||||
AddCoord(const nsStyleCoord& aStyle, nscoord* aCoord, float* aPercent)
|
||||
AddCoord(const nsStyleCoord& aStyle,
|
||||
nsIRenderingContext* aRenderingContext,
|
||||
nsIFrame* aFrame,
|
||||
nscoord* aCoord, float* aPercent)
|
||||
{
|
||||
switch (aStyle.GetUnit()) {
|
||||
case eStyleUnit_Coord:
|
||||
@@ -2925,27 +2928,34 @@ AddCoord(const nsStyleCoord& aStyle, nscoord* aCoord, float* aPercent)
|
||||
case eStyleUnit_Percent:
|
||||
*aPercent += aStyle.GetPercentValue();
|
||||
break;
|
||||
case eStyleUnit_Chars: {
|
||||
SetFontFromStyle(aRenderingContext, aFrame->GetStyleContext());
|
||||
nscoord fontWidth;
|
||||
aRenderingContext->GetWidth('M', fontWidth);
|
||||
*aCoord += aStyle.GetIntValue() * fontWidth;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */ nsIFrame::IntrinsicWidthOffsetData
|
||||
nsFrame::IntrinsicWidthOffsets()
|
||||
nsFrame::IntrinsicWidthOffsets(nsIRenderingContext* aRenderingContext)
|
||||
{
|
||||
IntrinsicWidthOffsetData result;
|
||||
nsStyleCoord tmp;
|
||||
|
||||
const nsStyleMargin *styleMargin = GetStyleMargin();
|
||||
AddCoord(styleMargin->mMargin.GetLeft(tmp),
|
||||
AddCoord(styleMargin->mMargin.GetLeft(tmp), aRenderingContext, this,
|
||||
&result.hMargin, &result.hPctMargin);
|
||||
AddCoord(styleMargin->mMargin.GetRight(tmp),
|
||||
AddCoord(styleMargin->mMargin.GetRight(tmp), aRenderingContext, this,
|
||||
&result.hMargin, &result.hPctMargin);
|
||||
|
||||
const nsStylePadding *stylePadding = GetStylePadding();
|
||||
AddCoord(stylePadding->mPadding.GetLeft(tmp),
|
||||
AddCoord(stylePadding->mPadding.GetLeft(tmp), aRenderingContext, this,
|
||||
&result.hPadding, &result.hPctPadding);
|
||||
AddCoord(stylePadding->mPadding.GetRight(tmp),
|
||||
AddCoord(stylePadding->mPadding.GetRight(tmp), aRenderingContext, this,
|
||||
&result.hPadding, &result.hPctPadding);
|
||||
|
||||
const nsStyleBorder *styleBorder = GetStyleBorder();
|
||||
|
||||
@@ -278,7 +278,8 @@ public:
|
||||
InlineMinWidthData *aData);
|
||||
virtual void AddInlinePrefWidth(nsIRenderingContext *aRenderingContext,
|
||||
InlinePrefWidthData *aData);
|
||||
virtual IntrinsicWidthOffsetData IntrinsicWidthOffsets();
|
||||
virtual IntrinsicWidthOffsetData
|
||||
IntrinsicWidthOffsets(nsIRenderingContext* aRenderingContext);
|
||||
|
||||
virtual nsSize ComputeSize(nsIRenderingContext *aRenderingContext,
|
||||
nsSize aCBSize, nscoord aAvailableWidth,
|
||||
|
||||
@@ -1157,7 +1157,8 @@ public:
|
||||
, hPctPadding(0.0f), hPctMargin(0.0f)
|
||||
{}
|
||||
};
|
||||
virtual IntrinsicWidthOffsetData IntrinsicWidthOffsets() = 0;
|
||||
virtual IntrinsicWidthOffsetData
|
||||
IntrinsicWidthOffsets(nsIRenderingContext* aRenderingContext) = 0;
|
||||
|
||||
/**
|
||||
* Compute the size that a frame will occupy. Called while
|
||||
|
||||
@@ -183,7 +183,7 @@ GetWidthInfo(nsIRenderingContext *aRenderingContext,
|
||||
// XXX Should col frame have border/padding considered?
|
||||
if (aCellFrame) {
|
||||
nsIFrame::IntrinsicWidthOffsetData offsets =
|
||||
aCellFrame->IntrinsicWidthOffsets();
|
||||
aCellFrame->IntrinsicWidthOffsets(aRenderingContext);
|
||||
// XXX Should we ignore percentage padding?
|
||||
nscoord add = offsets.hPadding + offsets.hBorder;
|
||||
minCoord += add;
|
||||
|
||||
@@ -239,7 +239,7 @@ FixedTableLayoutStrategy::ComputeColumnWidths(const nsHTMLReflowState& aReflowSt
|
||||
// Add in cell's padding and border.
|
||||
// XXX This should use real percentage padding
|
||||
nsIFrame::IntrinsicWidthOffsetData offsets =
|
||||
cellFrame->IntrinsicWidthOffsets();
|
||||
cellFrame->IntrinsicWidthOffsets(aReflowState.rendContext);
|
||||
colWidth += offsets.hPadding + offsets.hBorder;
|
||||
|
||||
if (colSpan > 1) {
|
||||
|
||||
@@ -671,10 +671,10 @@ nsTableCellFrame::GetPrefWidth(nsIRenderingContext *aRenderingContext)
|
||||
}
|
||||
|
||||
/* virtual */ nsIFrame::IntrinsicWidthOffsetData
|
||||
nsTableCellFrame::IntrinsicWidthOffsets()
|
||||
nsTableCellFrame::IntrinsicWidthOffsets(nsIRenderingContext* aRenderingContext)
|
||||
{
|
||||
IntrinsicWidthOffsetData result =
|
||||
nsHTMLContainerFrame::IntrinsicWidthOffsets();
|
||||
nsHTMLContainerFrame::IntrinsicWidthOffsets(aRenderingContext);
|
||||
|
||||
result.hMargin = 0;
|
||||
result.hPctMargin = 0;
|
||||
|
||||
@@ -133,7 +133,8 @@ public:
|
||||
|
||||
virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext);
|
||||
virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext);
|
||||
virtual IntrinsicWidthOffsetData IntrinsicWidthOffsets();
|
||||
virtual IntrinsicWidthOffsetData
|
||||
IntrinsicWidthOffsets(nsIRenderingContext* aRenderingContext);
|
||||
|
||||
NS_IMETHOD Reflow(nsPresContext* aPresContext,
|
||||
nsHTMLReflowMetrics& aDesiredSize,
|
||||
|
||||
@@ -1659,10 +1659,10 @@ nsTableFrame::GetPrefWidth(nsIRenderingContext *aRenderingContext)
|
||||
}
|
||||
|
||||
/* virtual */ nsIFrame::IntrinsicWidthOffsetData
|
||||
nsTableFrame::IntrinsicWidthOffsets()
|
||||
nsTableFrame::IntrinsicWidthOffsets(nsIRenderingContext* aRenderingContext)
|
||||
{
|
||||
IntrinsicWidthOffsetData result =
|
||||
nsHTMLContainerFrame::IntrinsicWidthOffsets();
|
||||
nsHTMLContainerFrame::IntrinsicWidthOffsets(aRenderingContext);
|
||||
|
||||
if (IsBorderCollapse()) {
|
||||
result.hPadding = 0;
|
||||
|
||||
@@ -266,7 +266,8 @@ public:
|
||||
// border to the results of these functions.
|
||||
virtual nscoord GetMinWidth(nsIRenderingContext *aRenderingContext);
|
||||
virtual nscoord GetPrefWidth(nsIRenderingContext *aRenderingContext);
|
||||
virtual IntrinsicWidthOffsetData IntrinsicWidthOffsets();
|
||||
virtual IntrinsicWidthOffsetData
|
||||
IntrinsicWidthOffsets(nsIRenderingContext* aRenderingContext);
|
||||
|
||||
virtual nsSize ComputeSize(nsIRenderingContext *aRenderingContext,
|
||||
nsSize aCBSize, nscoord aAvailableWidth,
|
||||
|
||||
Reference in New Issue
Block a user