diff --git a/mozilla/layout/base/nsLayoutUtils.cpp b/mozilla/layout/base/nsLayoutUtils.cpp index e7cf5476488..f1323abca47 100644 --- a/mozilla/layout/base/nsLayoutUtils.cpp +++ b/mozilla/layout/base/nsLayoutUtils.cpp @@ -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 diff --git a/mozilla/layout/generic/nsFrame.cpp b/mozilla/layout/generic/nsFrame.cpp index e8395562ecf..a10b76d92b4 100644 --- a/mozilla/layout/generic/nsFrame.cpp +++ b/mozilla/layout/generic/nsFrame.cpp @@ -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(); diff --git a/mozilla/layout/generic/nsFrame.h b/mozilla/layout/generic/nsFrame.h index 9ccc5c39fd0..6c996ffc468 100644 --- a/mozilla/layout/generic/nsFrame.h +++ b/mozilla/layout/generic/nsFrame.h @@ -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, diff --git a/mozilla/layout/generic/nsIFrame.h b/mozilla/layout/generic/nsIFrame.h index 4d133bac85f..805bb99a9f3 100644 --- a/mozilla/layout/generic/nsIFrame.h +++ b/mozilla/layout/generic/nsIFrame.h @@ -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 diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp index 16e876a5bfd..e9583889d52 100644 --- a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp +++ b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp @@ -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; diff --git a/mozilla/layout/tables/FixedTableLayoutStrategy.cpp b/mozilla/layout/tables/FixedTableLayoutStrategy.cpp index 14f9b1ed19a..1faa9a3a244 100644 --- a/mozilla/layout/tables/FixedTableLayoutStrategy.cpp +++ b/mozilla/layout/tables/FixedTableLayoutStrategy.cpp @@ -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) { diff --git a/mozilla/layout/tables/nsTableCellFrame.cpp b/mozilla/layout/tables/nsTableCellFrame.cpp index f33c417f05b..48aa3f69acd 100644 --- a/mozilla/layout/tables/nsTableCellFrame.cpp +++ b/mozilla/layout/tables/nsTableCellFrame.cpp @@ -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; diff --git a/mozilla/layout/tables/nsTableCellFrame.h b/mozilla/layout/tables/nsTableCellFrame.h index f2bbe8e2899..082660edb48 100644 --- a/mozilla/layout/tables/nsTableCellFrame.h +++ b/mozilla/layout/tables/nsTableCellFrame.h @@ -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, diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp index 3d63ab52113..a7290e55a7b 100644 --- a/mozilla/layout/tables/nsTableFrame.cpp +++ b/mozilla/layout/tables/nsTableFrame.cpp @@ -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; diff --git a/mozilla/layout/tables/nsTableFrame.h b/mozilla/layout/tables/nsTableFrame.h index 1e13c3ca4ed..60f2490eacc 100644 --- a/mozilla/layout/tables/nsTableFrame.h +++ b/mozilla/layout/tables/nsTableFrame.h @@ -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,