diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 1eeb495d9e9..c334406aab5 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -1243,11 +1243,8 @@ static PRBool GetAbsoluteCoord(const nsStyleCoord& aStyle, return PR_TRUE; } if (eStyleUnit_Chars == unit) { - SetFontFromStyle(aRenderingContext, aFrame->GetStyleContext()); - nscoord fontWidth; - aRenderingContext->SetTextRunRTL(PR_FALSE); - aRenderingContext->GetWidth('M', fontWidth); - aResult = aStyle.GetIntValue() * fontWidth; + aResult = nsLayoutUtils::CharsToCoord(aStyle, aRenderingContext, + aFrame->GetStyleContext()); return PR_TRUE; } return PR_FALSE; @@ -2154,3 +2151,27 @@ nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext, */ #endif } + +void +nsLayoutUtils::SetFontFromStyle(nsIRenderingContext* aRC, nsStyleContext* aSC) +{ + const nsStyleFont* font = aSC->GetStyleFont(); + const nsStyleVisibility* visibility = aSC->GetStyleVisibility(); + + aRC->SetFont(font->mFont, visibility->mLangGroup); +} + +nscoord +nsLayoutUtils::CharsToCoord(const nsStyleCoord& aStyle, + nsIRenderingContext* aRenderingContext, + nsStyleContext* aStyleContext) +{ + NS_ASSERTION(aStyle.GetUnit() == eStyleUnit_Chars, + "Shouldn't have called this"); + + SetFontFromStyle(aRenderingContext, aStyleContext); + nscoord fontWidth; + aRenderingContext->SetTextRunRTL(PR_FALSE); + aRenderingContext->GetWidth('M', fontWidth); + return aStyle.GetIntValue() * fontWidth; +} diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index ac8d24e228e..18e6fd415d0 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -647,6 +647,22 @@ public: const nsRect& aDestRect, const nsRect& aDirtyRect, const nsRect* aSourceRect = nsnull); + + /** + * Set the font on aRC based on the style in aSC + */ + static void SetFontFromStyle(nsIRenderingContext* aRC, nsStyleContext* aSC); + + /** + * Convert an eStyleUnit_Chars nsStyleCoord to an nscoord. + * + * @param aStyle the style coord + * @param aRenderingContext the rendering context to use for font measurement + * @param aStyleContext the style context to use for font infomation + */ + static nscoord CharsToCoord(const nsStyleCoord& aStyle, + nsIRenderingContext* aRenderingContext, + nsStyleContext* aStyleContext); }; #endif // nsLayoutUtils_h__ diff --git a/layout/generic/nsBRFrame.cpp b/layout/generic/nsBRFrame.cpp index d551df7aef8..13d501553d1 100644 --- a/layout/generic/nsBRFrame.cpp +++ b/layout/generic/nsBRFrame.cpp @@ -46,7 +46,7 @@ #include "nsGkAtoms.h" #include "nsIFontMetrics.h" #include "nsIRenderingContext.h" -#include "nsTextTransformer.h" +#include "nsLayoutUtils.h" #ifdef ACCESSIBILITY #include "nsIServiceManager.h" @@ -144,7 +144,7 @@ BRFrame::Reflow(nsPresContext* aPresContext, // We also do this in strict mode because BR should act like a // normal inline frame. That line-height is used is important // here for cases where the line-height is less that 1. - SetFontFromStyle(aReflowState.rendContext, mStyleContext); + nsLayoutUtils::SetFontFromStyle(aReflowState.rendContext, mStyleContext); nsCOMPtr fm; aReflowState.rendContext->GetFontMetrics(*getter_AddRefs(fm)); if (fm) { diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 49c87326c00..a940a1e50a7 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -437,15 +437,6 @@ nsresult NS_NewSelectionImageService(nsISelectionImageService** aResult) //end selection service -// a handy utility to set font -void SetFontFromStyle(nsIRenderingContext* aRC, nsStyleContext* aSC) -{ - const nsStyleFont* font = aSC->GetStyleFont(); - const nsStyleVisibility* visibility = aSC->GetStyleVisibility(); - - aRC->SetFont(font->mFont, visibility->mLangGroup); -} - void nsWeakFrame::Init(nsIFrame* aFrame) { @@ -3059,11 +3050,8 @@ AddCoord(const nsStyleCoord& aStyle, *aPercent += aStyle.GetPercentValue(); break; case eStyleUnit_Chars: { - SetFontFromStyle(aRenderingContext, aFrame->GetStyleContext()); - nscoord fontWidth; - aRenderingContext->SetTextRunRTL(PR_FALSE); - aRenderingContext->GetWidth('M', fontWidth); - *aCoord += aStyle.GetIntValue() * fontWidth; + *aCoord += nsLayoutUtils::CharsToCoord(aStyle, aRenderingContext, + aFrame->GetStyleContext()); break; } default: diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h index 4024b24b24f..28b7a8bd69b 100644 --- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -113,10 +113,6 @@ #define NS_FRAME_TRACE_REFLOW_OUT(_method, _status) #endif -// handy utilities -// XXXldb Move to nsLayoutUtils! -void SetFontFromStyle(nsIRenderingContext* aRC, nsStyleContext* aSC); - //---------------------------------------------------------------------- struct nsBoxLayoutMetrics; diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index 38c6d66c38e..4476d8db940 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -941,7 +941,7 @@ nsImageFrame::DisplayAltText(nsPresContext* aPresContext, { // Set font and color aRenderingContext.SetColor(GetStyleColor()->mColor); - SetFontFromStyle(&aRenderingContext, mStyleContext); + nsLayoutUtils::SetFontFromStyle(&aRenderingContext, mStyleContext); // Format the text to display within the formatting rect nsIFontMetrics* fm; diff --git a/layout/generic/nsInlineFrame.cpp b/layout/generic/nsInlineFrame.cpp index ef6b943b4dc..023ab76fa68 100644 --- a/layout/generic/nsInlineFrame.cpp +++ b/layout/generic/nsInlineFrame.cpp @@ -568,7 +568,7 @@ nsInlineFrame::ReflowFrames(nsPresContext* aPresContext, : aReflowState.mComputedBorderPadding.left; } - SetFontFromStyle(aReflowState.rendContext, mStyleContext); + nsLayoutUtils::SetFontFromStyle(aReflowState.rendContext, mStyleContext); nsCOMPtr fm; aReflowState.rendContext->GetFontMetrics(*getter_AddRefs(fm)); diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index 84fec164bc9..bda7fd5248a 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -1615,7 +1615,7 @@ nsLineLayout::VerticalAlignFrames(PerSpanData* psd) // Get the parent frame's font for all of the frames in this span nsStyleContext* styleContext = spanFrame->GetStyleContext(); nsIRenderingContext* rc = mBlockReflowState->rendContext; - SetFontFromStyle(mBlockReflowState->rendContext, styleContext); + nsLayoutUtils::SetFontFromStyle(mBlockReflowState->rendContext, styleContext); nsCOMPtr fm; rc->GetFontMetrics(*getter_AddRefs(fm)); diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index b6fae47ef99..1921bda3d79 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -893,7 +893,8 @@ nsTextStyle::nsTextStyle(nsPresContext* aPresContext, PRUint8 originalDecorations = plainFont->decorations; plainFont->decorations = NS_FONT_DECORATION_NONE; mAveCharWidth = 0; - SetFontFromStyle(&aRenderingContext, sc); // some users of the struct expect this state + // Set the font: some users of the struct expect this state + nsLayoutUtils::SetFontFromStyle(&aRenderingContext, sc); aRenderingContext.GetFontMetrics(mNormalFont); mNormalFont->GetSpaceWidth(mSpaceWidth); mNormalFont->GetAveCharWidth(mAveCharWidth); @@ -2140,7 +2141,7 @@ nsTextFrame::FillClusterBuffer(nsPresContext *aPresContext, const PRUnichar *aTe NS_ENSURE_SUCCESS(rv, rv); // Find the font metrics for this text - SetFontFromStyle(acx, mStyleContext); + nsLayoutUtils::SetFontFromStyle(acx, mStyleContext); acx->GetHints(clusterHint); clusterHint &= NS_RENDERING_HINT_TEXT_CLUSTERS; @@ -4131,7 +4132,7 @@ nsTextFrame::GetPositionHelper(const nsPoint& aPoint, } // Find the font metrics for this text - SetFontFromStyle(rendContext, mStyleContext); + nsLayoutUtils::SetFontFromStyle(rendContext, mStyleContext); // Get the renderable form of the text nsTextTransformer tx(PresContext()); @@ -6173,7 +6174,7 @@ nsTextFrame::Reflow(nsPresContext* aPresContext, #ifdef MOZ_MATHML if (calcMathMLMetrics) { - SetFontFromStyle(aReflowState.rendContext, mStyleContext); + nsLayoutUtils::SetFontFromStyle(aReflowState.rendContext, mStyleContext); nsBoundingMetrics bm; rv = aReflowState.rendContext->GetBoundingMetrics(textBuffer.mBuffer, textLength, bm); if (NS_SUCCEEDED(rv)) @@ -6277,7 +6278,7 @@ nsTextFrame::TrimTrailingWhiteSpace(nsPresContext* aPresContext, if (XP_IS_SPACE(ch)) { // Get font metrics for a space so we can adjust the width by the // right amount. - SetFontFromStyle(&aRC, mStyleContext); + nsLayoutUtils::SetFontFromStyle(&aRC, mStyleContext); aRC.GetWidth(' ', dw); // NOTE: Trailing whitespace includes word and letter spacing! diff --git a/layout/reftests/bugs/371043-1-ref.html b/layout/reftests/bugs/371043-1-ref.html new file mode 100644 index 00000000000..022d34aa183 --- /dev/null +++ b/layout/reftests/bugs/371043-1-ref.html @@ -0,0 +1,9 @@ + + +
+ MM + +
+ diff --git a/layout/reftests/bugs/371043-1.html b/layout/reftests/bugs/371043-1.html new file mode 100644 index 00000000000..735e7d52746 --- /dev/null +++ b/layout/reftests/bugs/371043-1.html @@ -0,0 +1,14 @@ + + +
+ + + +
+ diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index dd5b50bb5a3..bdb4b02590c 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -210,6 +210,7 @@ fails == 368504-1.html 368504-1-ref.html # bug 368504 == 370629-2.html 370629-2-ref.html == 370692-1.xhtml 370692-1-ref.xhtml == 371041-1.html 371041-1-ref.html +== 371043-1.html 371043-1-ref.html == 371925-1a.html 371925-1-ref.html == 371925-1b.html 371925-1-ref.html == 372553-1.html 372553-1-ref.html diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index a5a61e323e6..eea9be6e874 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -68,6 +68,8 @@ #include "nsStyleSet.h" #include "imgIRequest.h" #include "nsInspectorCSSUtils.h" +#include "nsLayoutUtils.h" +#include "nsFrameManager.h" #if defined(DEBUG_bzbarsky) || defined(DEBUG_caillon) #define DEBUG_ComputedDOMStyle @@ -2747,11 +2749,24 @@ nsComputedDOMStyle::SetValueToCoord(nsROCSSPrimitiveValue* aValue, aTable)); break; - case eStyleUnit_Chars: - // XXX we need a frame and a rendering context to calculate this, bug 281972, bug 282126. - aValue->SetAppUnits(0); + case eStyleUnit_Chars: { + // Get a rendering context + nsCOMPtr cx; + nsIFrame* frame = mPresShell->FrameManager()->GetRootFrame(); + if (frame) { + mPresShell->CreateRenderingContext(frame, getter_AddRefs(cx)); + } + if (cx) { + nscoord val = + nsLayoutUtils::CharsToCoord(aCoord, cx, mStyleContextHolder); + aValue->SetAppUnits(PR_MAX(aMinAppUnits, val)); + } else { + // Oh, well. Give up. + aValue->SetAppUnits(0); + } break; - + } + case eStyleUnit_Null: aValue->SetIdent(nsGkAtoms::none); break;