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:
mats.palmgren%bredband.net
2006-12-17 14:06:42 +00:00
parent ae532eaa4c
commit 34a45a87f6
10 changed files with 84 additions and 58 deletions

View File

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

View File

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

View File

@@ -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,

View File

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

View File

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

View File

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

View File

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

View File

@@ -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,

View File

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

View File

@@ -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,