Bug 390740: Pass lang-group into GetMetricsFor more consistently (general patch). r+sr=roc, a=dbaron
authorsharparrow1@yahoo.com
Tue, 07 Aug 2007 12:07:43 -0700
changeset 4353 3c5c847d85dd9adcd5c6af3d47d0c5bcfaa82a62
parent 4352 f8608384ae8a21b288fd4d84e9b833097632a952
child 4354 9fccb89289d6e397436594b716edba79f2195480
push id1
push userbsmedberg@mozilla.com
push dateThu, 20 Mar 2008 16:49:24 +0000
treeherdermozilla-central@61007906a1f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron
bugs390740
milestone1.9a8pre
Bug 390740: Pass lang-group into GetMetricsFor more consistently (general patch). r+sr=roc, a=dbaron
layout/base/nsCaret.cpp
layout/base/nsLayoutUtils.h
layout/generic/nsBulletFrame.cpp
layout/generic/nsHTMLContainerFrame.cpp
layout/generic/nsHTMLReflowState.cpp
layout/generic/nsTextFrameThebes.cpp
layout/xul/base/src/nsListBoxBodyFrame.cpp
layout/xul/base/src/nsTextBoxFrame.cpp
layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
--- a/layout/base/nsCaret.cpp
+++ b/layout/base/nsCaret.cpp
@@ -993,33 +993,19 @@ nsresult nsCaret::UpdateCaretRects(nsIFr
 
   nsPresContext *presContext = presShell->GetPresContext();
 
   // if we got a zero-height frame, it's probably a BR frame at the end of a non-empty line
   // (see BRFrame::Reflow). In that case, figure out a height. We have to do this
   // after we've got an RC.
   if (frameRect.height == 0)
   {
-    nsIWidget *widget = aFrame->GetWindow();
-    if (!widget)
-      return NS_ERROR_FAILURE;
+    nsCOMPtr<nsIFontMetrics> fm;
+    nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm));
 
-    nsCOMPtr<nsIRenderingContext> rendContext;
-    nsresult rv = presContext->DeviceContext()->
-      CreateRenderingContext(widget, *getter_AddRefs(rendContext));
-    NS_ENSURE_SUCCESS(rv, rv);
-    if (!rendContext)
-      return NS_ERROR_UNEXPECTED;
-
-    const nsStyleFont* fontStyle = aFrame->GetStyleFont();
-    const nsStyleVisibility* vis = aFrame->GetStyleVisibility();
-    rendContext->SetFont(fontStyle->mFont, vis->mLangGroup);
-
-    nsCOMPtr<nsIFontMetrics> fm;
-    rendContext->GetFontMetrics(*getter_AddRefs(fm));
     if (fm)
     {
       nscoord ascent, descent;
       fm->GetMaxAscent(ascent);
       fm->GetMaxDescent(descent);
       frameRect.height = ascent + descent;
       frameRect.y -= ascent; // BR frames sit on the baseline of the text, so we need to subtract
       // the ascent to account for the frame height.
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -474,16 +474,25 @@ public:
    * @param aFrame the frame
    * @param aFontMetrics the font metrics result
    * @return success or failure code
    */
   static nsresult GetFontMetricsForFrame(nsIFrame* aFrame,
                                          nsIFontMetrics** aFontMetrics);
 
   /**
+   * Get the font metrics corresponding to the given style data.
+   * @param aStyleContext the style data
+   * @param aFontMetrics the font metrics result
+   * @return success or failure code
+   */
+  static nsresult GetFontMetricsForStyleContext(nsStyleContext* aStyleContext,
+                                                nsIFontMetrics** aFontMetrics);
+
+  /**
    * Find the immediate child of aParent whose frame subtree contains
    * aDescendantFrame. Returns null if aDescendantFrame is not a descendant
    * of aParent.
    */
   static nsIFrame* FindChildContainingDescendant(nsIFrame* aParent, nsIFrame* aDescendantFrame);
   
   /**
    * Find the nearest ancestor that's a block
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -231,17 +231,16 @@ nsBulletFrame::PaintBullet(nsIRenderingC
                     mRect.height - (mPadding.top + mPadding.bottom));
         nsLayoutUtils::DrawImage(&aRenderingContext, imageCon,
                                  dest + aPt, aDirtyRect);
         return;
       }
     }
   }
 
-  const nsStyleFont* myFont = GetStyleFont();
   const nsStyleColor* myColor = GetStyleColor();
 
   nsCOMPtr<nsIFontMetrics> fm;
   aRenderingContext.SetColor(myColor->mColor);
 
 #ifdef IBMBIDI
   nsCharType charType = eCharType_LeftToRight;
   PRUint8 level = 0;
@@ -356,17 +355,17 @@ nsBulletFrame::PaintBullet(nsIRenderingC
   case NS_STYLE_LIST_STYLE_MOZ_KHMER:
   case NS_STYLE_LIST_STYLE_MOZ_HANGUL:
   case NS_STYLE_LIST_STYLE_MOZ_HANGUL_CONSONANT:
   case NS_STYLE_LIST_STYLE_MOZ_ETHIOPIC_HALEHAME:
   case NS_STYLE_LIST_STYLE_MOZ_ETHIOPIC_NUMERIC:
   case NS_STYLE_LIST_STYLE_MOZ_ETHIOPIC_HALEHAME_AM:
   case NS_STYLE_LIST_STYLE_MOZ_ETHIOPIC_HALEHAME_TI_ER:
   case NS_STYLE_LIST_STYLE_MOZ_ETHIOPIC_HALEHAME_TI_ET:
-    fm = PresContext()->GetMetricsFor(myFont->mFont);
+    nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm));
 #ifdef IBMBIDI
     // If we can't render our numeral using the chars in the numbering
     // system, we'll be using "decimal"...
     PRBool usedChars =
 #endif // IBMBIDI
     GetListItemText(*myList, text);
 #ifdef IBMBIDI
     if (!usedChars)
@@ -378,17 +377,17 @@ nsBulletFrame::PaintBullet(nsIRenderingC
     aRenderingContext.SetTextRunRTL(PR_FALSE);
     aRenderingContext.DrawString(text, mPadding.left + aPt.x,
                                  mPadding.top + aPt.y + ascent);
     break;
   }
 #ifdef IBMBIDI
   if (charType != eCharType_LeftToRight) {
     nsPresContext* presContext = PresContext();
-    fm = presContext->GetMetricsFor(myFont->mFont);
+    nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm));
     aRenderingContext.SetFont(fm);
     nscoord ascent;
     fm->GetMaxAscent(ascent);
 
     nsBidiPresUtils* bidiUtils = presContext->GetBidiUtils();
     if (bidiUtils) {
       const PRUnichar* buffer = text.get();
       PRInt32 textLength = text.Length();
@@ -1455,18 +1454,18 @@ nsBulletFrame::GetDesiredSize(nsPresCont
   // If we're getting our desired size and don't have an image, reset
   // mIntrinsicSize to (0,0).  Otherwise, if we used to have an image, it
   // changed, and the new one is coming in, but we're reflowing before it's
   // fully there, we'll end up with mIntrinsicSize not matching our size, but
   // won't trigger a reflow in OnStartContainer (because mIntrinsicSize will
   // match the image size).
   mIntrinsicSize.SizeTo(0, 0);
 
-  const nsStyleFont* myFont = GetStyleFont();
-  nsCOMPtr<nsIFontMetrics> fm = aCX->GetMetricsFor(myFont->mFont);
+  nsCOMPtr<nsIFontMetrics> fm;
+  nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm));
   nscoord bulletSize;
 
   nsAutoString text;
   switch (myList->mListStyleType) {
     case NS_STYLE_LIST_STYLE_NONE:
       aMetrics.width = 0;
       aMetrics.ascent = aMetrics.height = 0;
       break;
--- a/layout/generic/nsHTMLContainerFrame.cpp
+++ b/layout/generic/nsHTMLContainerFrame.cpp
@@ -89,31 +89,22 @@ public:
 private:
   nsLineBox*            mLine;
   nscolor               mColor;
   PRUint8               mDecoration;
 };
 
 void
 nsDisplayTextDecoration::Paint(nsDisplayListBuilder* aBuilder,
-    nsIRenderingContext* aCtx, const nsRect& aDirtyRect) {
-  // REVIEW: From nsHTMLContainerFrame::PaintTextDecorationsAndChildren
-  const nsStyleFont* font = mFrame->GetStyleFont();
-  NS_ASSERTION(font->mFont.decorations == NS_FONT_DECORATION_NONE,
-               "fonts on style structs shouldn't have decorations");
+                               nsIRenderingContext* aCtx,
+                               const nsRect& aDirtyRect)
+{
+  nsCOMPtr<nsIFontMetrics> fm;
+  nsLayoutUtils::GetFontMetricsForFrame(mFrame, getter_AddRefs(fm));
 
-  // XXX This is relatively slow and shouldn't need to be used here.
-  nsCOMPtr<nsIDeviceContext> deviceContext;
-  aCtx->GetDeviceContext(*getter_AddRefs(deviceContext));
-  nsCOMPtr<nsIFontMetrics> normalFont;
-  const nsStyleVisibility* visibility = mFrame->GetStyleVisibility();
-  nsCOMPtr<nsIFontMetrics> fm;
-  deviceContext->GetMetricsFor(font->mFont, visibility->mLangGroup,
-      *getter_AddRefs(fm));
-      
   nsPoint pt = aBuilder->ToReferenceFrame(mFrame);
 
   // REVIEW: From nsHTMLContainerFrame::PaintTextDecorations
   nscoord ascent, offset, size;
   nsHTMLContainerFrame* f = static_cast<nsHTMLContainerFrame*>(mFrame);
   fm->GetMaxAscent(ascent);
   if (mDecoration != NS_STYLE_TEXT_DECORATION_LINE_THROUGH) {
     fm->GetUnderline(offset, size);
--- a/layout/generic/nsHTMLReflowState.cpp
+++ b/layout/generic/nsHTMLReflowState.cpp
@@ -2057,24 +2057,19 @@ ComputeLineHeight(nsIRenderingContext* a
   } else if (unit == eStyleUnit_Factor) {
     // For factor units the computed value of the line-height property 
     // is found by multiplying the factor by the font's computed size
     // (adjusted for min-size prefs and text zoom).
     float factor = lhCoord.GetFactorValue();
     lineHeight = NSToCoordRound(factor * font->mFont.size);
   } else {
     NS_ASSERTION(eStyleUnit_Normal == unit, "bad unit");
-    nsCOMPtr<nsIDeviceContext> deviceContext = aDeviceContext;
-    if (NS_UNLIKELY(!deviceContext)) {
-      aRenderingContext->GetDeviceContext(*getter_AddRefs(deviceContext));
-    }
-    const nsStyleVisibility* vis = aStyleContext->GetStyleVisibility();
     nsCOMPtr<nsIFontMetrics> fm;
-    deviceContext->GetMetricsFor(font->mFont, vis->mLangGroup,
-                                 *getter_AddRefs(fm));
+    nsLayoutUtils::GetFontMetricsForStyleContext(aStyleContext,
+                                                 getter_AddRefs(fm));
     lineHeight = GetNormalLineHeight(fm);
   }
   return lineHeight;
 }
 
 nscoord
 nsHTMLReflowState::CalcLineHeight(nsIRenderingContext* aRenderingContext,
                                   nsIFrame* aFrame)
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -1438,22 +1438,19 @@ GetSpacingFlags(const nsStyleCoord& aSty
     return gfxTextRunFactory::TEXT_ENABLE_SPACING;
   return gfxTextRunFactory::TEXT_ENABLE_SPACING |
          gfxTextRunFactory::TEXT_ENABLE_NEGATIVE_SPACING;
 }
 
 static gfxFontGroup*
 GetFontGroupForFrame(nsIFrame* aFrame)
 {
-  nsIDeviceContext* devContext = aFrame->PresContext()->DeviceContext();
-  const nsStyleFont* fontStyle = aFrame->GetStyleFont();
-  const nsStyleVisibility* visibilityStyle = aFrame->GetStyleVisibility();
   nsCOMPtr<nsIFontMetrics> metrics;
-  devContext->GetMetricsFor(fontStyle->mFont, visibilityStyle->mLangGroup,
-                            *getter_AddRefs(metrics));
+  nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(metrics));
+
   if (!metrics)
     return nsnull;
 
   nsIFontMetrics* metricsRaw = metrics;
   nsIThebesFontMetrics* fm = static_cast<nsIThebesFontMetrics*>(metricsRaw);
   return fm->GetThebesFontGroup();
 }
 
--- a/layout/xul/base/src/nsListBoxBodyFrame.cpp
+++ b/layout/xul/base/src/nsListBoxBodyFrame.cpp
@@ -245,19 +245,17 @@ nsListBoxBodyFrame::Init(nsIContent*    
     nsIBox* verticalScrollbar = scrollFrame->GetScrollbarBox(PR_TRUE);
     if (verticalScrollbar) {
       nsIScrollbarFrame* scrollbarFrame = nsnull;
       CallQueryInterface(verticalScrollbar, &scrollbarFrame);
       scrollbarFrame->SetScrollbarMediatorContent(GetContent());
     }
   }
   nsCOMPtr<nsIFontMetrics> fm;
-  PresContext()->DeviceContext()->GetMetricsFor(
-    GetStyleContext()->GetStyleFont()->mFont, *getter_AddRefs(fm)
-    );
+  nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm));
   fm->GetHeight(mRowHeight);
 
   return rv;
 }
 
 void
 nsListBoxBodyFrame::Destroy()
 {
@@ -779,21 +777,18 @@ nsListBoxBodyFrame::ComputeIntrinsicWidt
           nsAutoString value;
           PRUint32 textCount = child->GetChildCount();
           for (PRUint32 j = 0; j < textCount; ++j) {
             nsIContent* text = child->GetChildAt(j);
             if (text && text->IsNodeOfType(nsINode::eTEXT)) {
               text->AppendTextTo(value);
             }
           }
-          nsCOMPtr<nsIFontMetrics> fm;
-          presContext->DeviceContext()->
-            GetMetricsFor(styleContext->GetStyleFont()->mFont,
-                          *getter_AddRefs(fm));
-          rendContext->SetFont(fm);
+
+          nsLayoutUtils::SetFontFromStyle(rendContext, styleContext);
 
           nscoord textWidth =
             nsLayoutUtils::GetStringWidth(this, rendContext, value.get(), value.Length());
           textWidth += width;
 
           if (textWidth > largestWidth) 
             largestWidth = textWidth;
         }
--- a/layout/xul/base/src/nsTextBoxFrame.cpp
+++ b/layout/xul/base/src/nsTextBoxFrame.cpp
@@ -388,24 +388,22 @@ nsTextBoxFrame::PaintTitle(nsIRenderingC
       if (0 != decorMask) {
         context = context->GetParent();
         if (context) {
           hasDecorations = context->HasTextDecorations();
         }
       }
     } while (context && hasDecorations && (0 != decorMask));
 
-    const nsStyleFont* fontStyle = GetStyleFont();
-    
+    nsCOMPtr<nsIFontMetrics> fontMet;
+    nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet));
+
     nscoord offset;
     nscoord size;
     nscoord baseline;
-    nsCOMPtr<nsIFontMetrics> fontMet;
-    presContext->DeviceContext()->GetMetricsFor(fontStyle->mFont,
-                                                *getter_AddRefs(fontMet));
     fontMet->GetMaxAscent(baseline);
     PRBool isRTL = vis->mDirection == NS_STYLE_DIRECTION_RTL;
 
     nsRefPtr<gfxContext> ctx = (gfxContext*)
       aRenderingContext.GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT);
     gfxFloat a2p = 1.0 / presContext->AppUnitsPerDevPixel();
     gfxPoint pt(textRect.x * a2p, textRect.y * a2p);
     gfxFloat width = textRect.width * a2p;
@@ -440,18 +438,18 @@ nsTextBoxFrame::PaintTitle(nsIRenderingC
       nsCSSRendering::PaintDecorationLine(ctx, underColor,
                                           pt, gfxSize(width, sizePixel),
                                           baselinePixel, offsetPixel,
                                           sizePixel,
                                           NS_STYLE_TEXT_DECORATION_LINE_THROUGH,
                                           NS_STYLE_BORDER_STYLE_SOLID,
                                           isRTL);
     }
- 
-    aRenderingContext.SetFont(fontStyle->mFont, nsnull);
+
+    aRenderingContext.SetFont(fontMet);
 
     CalculateUnderline(aRenderingContext);
 
     aRenderingContext.SetColor(GetStyleColor()->mColor);
 
 #ifdef IBMBIDI
     nsresult rv = NS_ERROR_FAILURE;
 
@@ -552,20 +550,17 @@ nsTextBoxFrame::CalculateUnderline(nsIRe
 void
 nsTextBoxFrame::CalculateTitleForWidth(nsPresContext*      aPresContext,
                                        nsIRenderingContext& aRenderingContext,
                                        nscoord              aWidth)
 {
     if (mTitle.IsEmpty())
         return;
 
-    nsCOMPtr<nsIFontMetrics> fontMet;
-    aPresContext->DeviceContext()->GetMetricsFor(GetStyleFont()->mFont,
-                                                 *getter_AddRefs(fontMet));
-    aRenderingContext.SetFont(fontMet);
+    nsLayoutUtils::SetFontFromStyle(&aRenderingContext, GetStyleContext());
 
     // see if the text will completely fit in the width given
     mTitleWidth = nsLayoutUtils::GetStringWidth(this, &aRenderingContext,
                                                 mTitle.get(), mTitle.Length());
 
     if (mTitleWidth <= aWidth) {
         mCroppedTitle = mTitle;
 #ifdef IBMBIDI
@@ -858,18 +853,17 @@ nsTextBoxFrame::MarkIntrinsicWidthsDirty
     nsTextBoxFrameSuper::MarkIntrinsicWidthsDirty();
 }
 
 void
 nsTextBoxFrame::GetTextSize(nsPresContext* aPresContext, nsIRenderingContext& aRenderingContext,
                                 const nsString& aString, nsSize& aSize, nscoord& aAscent)
 {
     nsCOMPtr<nsIFontMetrics> fontMet;
-    aPresContext->DeviceContext()->GetMetricsFor(GetStyleFont()->mFont,
-                                                 *getter_AddRefs(fontMet));
+    nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fontMet));
     fontMet->GetHeight(aSize.height);
     aRenderingContext.SetFont(fontMet);
     aSize.width =
       nsLayoutUtils::GetStringWidth(this, &aRenderingContext, aString.get(), aString.Length());
     fontMet->GetMaxAscent(aAscent);
 }
 
 void
--- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
+++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
@@ -1201,18 +1201,18 @@ nsTreeBodyFrame::GetCoordsForCellItem(PR
 
     // Measure the width of the text. If the width of the text is greater than 
     // the remaining width available, then we just assume that the text has 
     // been cropped and use the remaining rect as the text Rect. Otherwise,
     // we add in borders and padding to the text dimension and give that back. 
     nsStyleContext* textContext = GetPseudoStyleContext(nsCSSAnonBoxes::moztreecelltext);
 
     nsCOMPtr<nsIFontMetrics> fm;
-    presContext->DeviceContext()->
-      GetMetricsFor(textContext->GetStyleFont()->mFont, *getter_AddRefs(fm));
+    nsLayoutUtils::GetFontMetricsForStyleContext(textContext,
+                                                 getter_AddRefs(fm));
     nscoord height;
     fm->GetHeight(height);
 
     nsMargin textMargin;
     textContext->GetStyleMargin()->GetMargin(textMargin);
     textRect.Deflate(textMargin);
 
     // Center the text. XXX Obey vertical-align style prop?
@@ -1570,17 +1570,17 @@ nsTreeBodyFrame::GetItemWithinCellAt(nsc
   textContext->GetStyleMargin()->GetMargin(textMargin);
   textRect.Deflate(textMargin);
 
   AdjustForBorderPadding(textContext, textRect);
 
   nsCOMPtr<nsIRenderingContext> renderingContext;
   PresContext()->PresShell()->CreateRenderingContext(this, getter_AddRefs(renderingContext));
 
-  renderingContext->SetFont(textContext->GetStyleFont()->mFont, nsnull);
+  nsLayoutUtils::SetFontFromStyle(renderingContext, textContext);
 
   AdjustForCellText(cellText, aRowIndex, aColumn, *renderingContext, textRect);
 
   if (aX >= textRect.x && aX < textRect.x + textRect.width)
     return nsCSSAnonBoxes::moztreecelltext;
   else
     return nsCSSAnonBoxes::moztreecell;
 }
@@ -1701,19 +1701,18 @@ nsTreeBodyFrame::GetCellWidth(PRInt32 aR
   // We're going to measure this text so we need to ensure bidi is enabled if
   // necessary
   CheckTextForBidi(cellText);
 
   nsStyleContext* textContext = GetPseudoStyleContext(nsCSSAnonBoxes::moztreecelltext);
 
   // Get the borders and padding for the text.
   GetBorderPadding(textContext, bp);
-  
-  // Get the font style for the text and pass it to the rendering context.
-  aRenderingContext->SetFont(textContext->GetStyleFont()->mFont, nsnull);
+
+  nsLayoutUtils::SetFontFromStyle(aRenderingContext, textContext);
 
   // Get the width of the text itself
   nscoord width =
     nsLayoutUtils::GetStringWidth(this, aRenderingContext, cellText.get(), cellText.Length());
   nscoord totalTextWidth = width + bp.left + bp.right;
   aDesiredSize += totalTextWidth;
   return NS_OK;
 }
@@ -3407,18 +3406,18 @@ nsTreeBodyFrame::PaintText(PRInt32      
 
   // Adjust the rect for its border and padding.
   nsMargin bp(0,0,0,0);
   GetBorderPadding(textContext, bp);
   textRect.Deflate(bp);
 
   // Compute our text size.
   nsCOMPtr<nsIFontMetrics> fontMet;
-  aPresContext->DeviceContext()->
-    GetMetricsFor(textContext->GetStyleFont()->mFont, *getter_AddRefs(fontMet));
+  nsLayoutUtils::GetFontMetricsForStyleContext(textContext,
+                                               getter_AddRefs(fontMet));
 
   nscoord height, baseline;
   fontMet->GetHeight(height);
   fontMet->GetMaxAscent(baseline);
 
   // Center the text. XXX Obey vertical-align style prop?
   if (height < textRect.height) {
     textRect.y += (textRect.height - height)/2;