Bug 1088550 - Move nsRenderingContext's remaining GetWidth methods to nsLayoutUtils. r=mstange
authorJonathan Watt <jwatt@jwatt.org>
Fri, 24 Oct 2014 16:28:13 +0100
changeset 212252 cd13fcbf38538c9166849279fc4a7e83743e915f
parent 212251 e981fd5453dc71703d19408bbf78d1ad8685e6da
child 212253 e0a681c4c4fe334e024d1891c3a910ad7a571db1
push id27702
push userkwierso@gmail.com
push dateFri, 24 Oct 2014 22:05:50 +0000
treeherdermozilla-central@c70f62375f7d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1088550
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1088550 - Move nsRenderingContext's remaining GetWidth methods to nsLayoutUtils. r=mstange
gfx/src/nsRenderingContext.cpp
gfx/src/nsRenderingContext.h
layout/base/nsBidiPresUtils.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/xul/nsTextBoxFrame.cpp
layout/xul/tree/nsTreeBodyFrame.cpp
--- a/gfx/src/nsRenderingContext.cpp
+++ b/gfx/src/nsRenderingContext.cpp
@@ -82,42 +82,16 @@ nsRenderingContext::SetFont(nsFontMetric
 }
 
 int32_t
 nsRenderingContext::GetMaxChunkLength()
 {
     return std::min(mFontMetrics->GetMaxStringLength(), MAX_GFX_TEXT_BUF_SIZE);
 }
 
-nscoord
-nsRenderingContext::GetWidth(char16_t aC)
-{
-    return GetWidth(&aC, 1);
-}
-
-nscoord
-nsRenderingContext::GetWidth(const nsString& aString)
-{
-    return GetWidth(aString.get(), aString.Length());
-}
-
-nscoord
-nsRenderingContext::GetWidth(const char16_t *aString, uint32_t aLength)
-{
-    uint32_t maxChunkLength = GetMaxChunkLength();
-    nscoord width = 0;
-    while (aLength > 0) {
-        int32_t len = FindSafeLength(aString, aLength, maxChunkLength);
-        width += mFontMetrics->GetWidth(aString, len, this);
-        aLength -= len;
-        aString += len;
-    }
-    return width;
-}
-
 nsBoundingMetrics
 nsRenderingContext::GetBoundingMetrics(const char16_t* aString,
                                        uint32_t aLength)
 {
     uint32_t maxChunkLength = GetMaxChunkLength();
     int32_t len = FindSafeLength(aString, aLength, maxChunkLength);
     // Assign directly in the first iteration. This ensures that
     // negative ascent/descent can be returned and the left bearing
--- a/gfx/src/nsRenderingContext.h
+++ b/gfx/src/nsRenderingContext.h
@@ -42,20 +42,16 @@ public:
 
     // Text
 
     void SetFont(nsFontMetrics *aFontMetrics);
     nsFontMetrics *FontMetrics() { return mFontMetrics; } // may be null
 
     void SetTextRunRTL(bool aIsRTL);
 
-    nscoord GetWidth(char16_t aC);
-    nscoord GetWidth(const nsString& aString);
-    nscoord GetWidth(const char16_t *aString, uint32_t aLength);
-
     nsBoundingMetrics GetBoundingMetrics(const char16_t *aString,
                                          uint32_t aLength);
 
     int32_t GetMaxChunkLength();
     static int32_t FindSafeLength(const char16_t *aString, uint32_t aLength,
                                   uint32_t aMaxChunkLength);
 private:
     // Private destructor, to discourage deletion outside of Release():
--- a/layout/base/nsBidiPresUtils.cpp
+++ b/layout/base/nsBidiPresUtils.cpp
@@ -2072,17 +2072,18 @@ public:
   {
     mTextRunConstructionContext->SetTextRunRTL(aDirection==NSBIDI_RTL);
     mText = aText;
     mLength = aLength;
   }
 
   virtual nscoord GetWidth() MOZ_OVERRIDE
   {
-    return mTextRunConstructionContext->GetWidth(mText, mLength);
+    return nsLayoutUtils::AppUnitWidthOfString(mText, mLength,
+                                               *mTextRunConstructionContext);
   }
 
   virtual void DrawText(nscoord aXOffset,
                         nscoord) MOZ_OVERRIDE
   {
     mCtx->FontMetrics()->DrawString(mText, mLength, mPt.x + aXOffset, mPt.y,
                                     mCtx, mTextRunConstructionContext);
   }
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -3192,27 +3192,29 @@ nsLayoutUtils::BinarySearchForPosition(n
                         int32_t    aEndInx,
                         int32_t    aCursorPos,
                         int32_t&   aIndex,
                         int32_t&   aTextWidth)
 {
   int32_t range = aEndInx - aStartInx;
   if ((range == 1) || (range == 2 && NS_IS_HIGH_SURROGATE(aText[aStartInx]))) {
     aIndex   = aStartInx + aBaseInx;
-    aTextWidth = aRendContext->GetWidth(aText, aIndex);
+    aTextWidth = nsLayoutUtils::AppUnitWidthOfString(aText, aIndex,
+                                                     *aRendContext);
     return true;
   }
 
   int32_t inx = aStartInx + (range / 2);
 
   // Make sure we don't leave a dangling low surrogate
   if (NS_IS_HIGH_SURROGATE(aText[inx-1]))
     inx++;
 
-  int32_t textWidth = aRendContext->GetWidth(aText, inx);
+  int32_t textWidth = nsLayoutUtils::AppUnitWidthOfString(aText, inx,
+                                                          *aRendContext);
 
   int32_t fullWidth = aBaseWidth + textWidth;
   if (fullWidth == aCursorPos) {
     aTextWidth = textWidth;
     aIndex = inx;
     return true;
   } else if (aCursorPos < fullWidth) {
     aTextWidth = aBaseWidth;
@@ -4623,16 +4625,39 @@ nsLayoutUtils::GetSnappedBaselineY(nsIFr
   gfxFloat appUnitsPerDevUnit = aFrame->PresContext()->AppUnitsPerDevPixel();
   gfxFloat baseline = gfxFloat(aY) + aAscent;
   gfxRect putativeRect(0, baseline/appUnitsPerDevUnit, 1, 1);
   if (!aContext->UserToDevicePixelSnapped(putativeRect, true))
     return baseline;
   return aContext->DeviceToUser(putativeRect.TopLeft()).y * appUnitsPerDevUnit;
 }
 
+nscoord
+nsLayoutUtils::AppUnitWidthOfString(const nsString& aString,
+                                    nsRenderingContext& aContext)
+{
+  return AppUnitWidthOfString(aString.get(), aString.Length(), aContext);
+}
+
+nscoord
+nsLayoutUtils::AppUnitWidthOfString(const char16_t *aString,
+                                    uint32_t aLength,
+                                    nsRenderingContext& aContext)
+{
+  uint32_t maxChunkLength = aContext.GetMaxChunkLength();
+  nscoord width = 0;
+  while (aLength > 0) {
+    int32_t len = aContext.FindSafeLength(aString, aLength, maxChunkLength);
+    width += aContext.FontMetrics()->GetWidth(aString, len, &aContext);
+    aLength -= len;
+    aString += len;
+  }
+  return width;
+}
+
 void
 nsLayoutUtils::DrawString(const nsIFrame*       aFrame,
                           nsRenderingContext*   aContext,
                           const char16_t*      aString,
                           int32_t               aLength,
                           nsPoint               aPoint,
                           nsStyleContext*       aStyleContext)
 {
@@ -4669,17 +4694,17 @@ nsLayoutUtils::DrawUniDirString(const ch
     fm->DrawString(aString, aLength, x, y, &aContext, &aContext);
     return;
   }
 
   bool isRTL = fm->GetTextRunRTL();
 
   // If we're drawing right to left, we must start at the end.
   if (isRTL) {
-    x += aContext.GetWidth(aString, aLength);
+    x += nsLayoutUtils::AppUnitWidthOfString(aString, aLength, aContext);
   }
 
   while (aLength > 0) {
     int32_t len = nsRenderingContext::FindSafeLength(aString, aLength, maxChunkLength);
     nscoord width = fm->GetWidth(aString, len, &aContext);
     if (isRTL) {
       x -= width;
     }
@@ -4701,17 +4726,17 @@ nsLayoutUtils::GetStringWidth(const nsIF
   nsPresContext* presContext = aFrame->PresContext();
   if (presContext->BidiEnabled()) {
     nsBidiLevel level =
       nsBidiPresUtils::BidiLevelFromStyle(aFrame->StyleContext());
     return nsBidiPresUtils::MeasureTextWidth(aString, aLength,
                                              level, presContext, *aContext);
   }
   aContext->SetTextRunRTL(false);
-  return aContext->GetWidth(aString, aLength);
+  return nsLayoutUtils::AppUnitWidthOfString(aString, aLength, *aContext);
 }
 
 /* static */ void
 nsLayoutUtils::PaintTextShadow(const nsIFrame* aFrame,
                                nsRenderingContext* aContext,
                                const nsRect& aTextRect,
                                const nsRect& aDirtyRect,
                                const nscolor& aForegroundColor,
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -1312,16 +1312,26 @@ public:
 
   // Get a suitable foreground color for painting aProperty for aFrame.
   static nscolor GetColor(nsIFrame* aFrame, nsCSSProperty aProperty);
 
   // Get a baseline y position in app units that is snapped to device pixels.
   static gfxFloat GetSnappedBaselineY(nsIFrame* aFrame, gfxContext* aContext,
                                       nscoord aY, nscoord aAscent);
 
+  static nscoord AppUnitWidthOfString(char16_t aC,
+                                      nsRenderingContext& aContext) {
+    return AppUnitWidthOfString(&aC, 1, aContext);
+  }
+  static nscoord AppUnitWidthOfString(const nsString& aString,
+                                      nsRenderingContext& aContext);
+  static nscoord AppUnitWidthOfString(const char16_t *aString,
+                                      uint32_t aLength,
+                                      nsRenderingContext& aContext);
+
   static void DrawString(const nsIFrame*       aFrame,
                          nsRenderingContext*   aContext,
                          const char16_t*      aString,
                          int32_t               aLength,
                          nsPoint               aPoint,
                          nsStyleContext*       aStyleContext = nullptr);
 
   /**
--- a/layout/xul/nsTextBoxFrame.cpp
+++ b/layout/xul/nsTextBoxFrame.cpp
@@ -539,19 +539,20 @@ nsTextBoxFrame::DrawText(nsRenderingCont
     if (NS_FAILED(rv)) {
        aRenderingContext.SetTextRunRTL(false);
 
        if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) {
            // In the simple (non-BiDi) case, we calculate the mnemonic's
            // underline position by getting the text metric.
            // XXX are attribute values always two byte?
            if (mAccessKeyInfo->mAccesskeyIndex > 0)
-               mAccessKeyInfo->mBeforeWidth =
-                   refContext->GetWidth(mCroppedTitle.get(),
-                                        mAccessKeyInfo->mAccesskeyIndex);
+               mAccessKeyInfo->mBeforeWidth = nsLayoutUtils::
+                   AppUnitWidthOfString(mCroppedTitle.get(),
+                                        mAccessKeyInfo->mAccesskeyIndex,
+                                        *refContext);
            else
                mAccessKeyInfo->mBeforeWidth = 0;
        }
 
        fontMet->DrawString(mCroppedTitle.get(), mCroppedTitle.Length(),
                            aTextRect.x, baseline, &aRenderingContext,
                            refContext.get());
     }
@@ -583,19 +584,19 @@ nsTextBoxFrame::DrawText(nsRenderingCont
 void
 nsTextBoxFrame::CalculateUnderline(nsRenderingContext& aRenderingContext)
 {
     if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) {
          // Calculate all fields of mAccessKeyInfo which
          // are the same for both BiDi and non-BiDi frames.
          const char16_t *titleString = mCroppedTitle.get();
          aRenderingContext.SetTextRunRTL(false);
-         mAccessKeyInfo->mAccessWidth =
-             aRenderingContext.GetWidth(titleString[mAccessKeyInfo->
-                                                    mAccesskeyIndex]);
+         mAccessKeyInfo->mAccessWidth = nsLayoutUtils::
+             AppUnitWidthOfString(titleString[mAccessKeyInfo->mAccesskeyIndex],
+                                  aRenderingContext);
 
          nscoord offset, baseline;
          nsFontMetrics* metrics = aRenderingContext.FontMetrics();
          metrics->GetUnderline(offset, mAccessKeyInfo->mAccessUnderlineSize);
          baseline = metrics->MaxAscent();
          mAccessKeyInfo->mAccessOffset = baseline - offset;
     }
 }
@@ -628,17 +629,18 @@ nsTextBoxFrame::CalculateTitleForWidth(n
 
     const nsDependentString& kEllipsis = nsContentUtils::GetLocalizedEllipsis();
     // start with an ellipsis
     mCroppedTitle.Assign(kEllipsis);
 
     // see if the width is even smaller than the ellipsis
     // if so, clear the text (XXX set as many '.' as we can?).
     aRenderingContext.SetTextRunRTL(false);
-    titleWidth = aRenderingContext.GetWidth(kEllipsis);
+    titleWidth = nsLayoutUtils::AppUnitWidthOfString(kEllipsis,
+                                                     aRenderingContext);
 
     if (titleWidth > aWidth) {
         mCroppedTitle.SetLength(0);
         return 0;
     }
 
     // if the ellipsis fits perfectly, no use in trying to insert
     if (titleWidth == aWidth)
@@ -656,17 +658,18 @@ nsTextBoxFrame::CalculateTitleForWidth(n
         {
             nscoord cwidth;
             nscoord twidth = 0;
             int length = mTitle.Length();
             int i;
             for (i = 0; i < length; ++i) {
                 char16_t ch = mTitle.CharAt(i);
                 // still in LTR mode
-                cwidth = aRenderingContext.GetWidth(ch);
+                cwidth =
+                    nsLayoutUtils::AppUnitWidthOfString(ch, aRenderingContext);
                 if (twidth + cwidth > aWidth)
                     break;
 
                 twidth += cwidth;
                 if (UCS2_CHAR_IS_BIDI(ch) ) {
                   mState |= NS_FRAME_IS_BIDI;
                 }
             }
@@ -684,17 +687,18 @@ nsTextBoxFrame::CalculateTitleForWidth(n
         case CropLeft:
         {
             nscoord cwidth;
             nscoord twidth = 0;
             int length = mTitle.Length();
             int i;
             for (i=length-1; i >= 0; --i) {
                 char16_t ch = mTitle.CharAt(i);
-                cwidth = aRenderingContext.GetWidth(ch);
+                cwidth =
+                    nsLayoutUtils::AppUnitWidthOfString(ch, aRenderingContext);
                 if (twidth + cwidth > aWidth)
                     break;
 
                 twidth += cwidth;
                 if (UCS2_CHAR_IS_BIDI(ch) ) {
                   mState |= NS_FRAME_IS_BIDI;
                 }
             }
@@ -726,31 +730,34 @@ nsTextBoxFrame::CalculateTitleForWidth(n
             int leftPos, rightPos;
             nsAutoString leftString, rightString;
 
             rightPos = mTitle.Length() - 1;
             aRenderingContext.SetTextRunRTL(false);
             for (leftPos = 0; leftPos <= rightPos;) {
                 // look at the next character on the left end
                 ch = mTitle.CharAt(leftPos);
-                charWidth = aRenderingContext.GetWidth(ch);
+                charWidth =
+                    nsLayoutUtils::AppUnitWidthOfString(ch, aRenderingContext);
                 totalWidth += charWidth;
                 if (totalWidth > aWidth)
                     // greater than the allowable width
                     break;
                 leftString.Insert(ch, leftString.Length());
 
                 if (UCS2_CHAR_IS_BIDI(ch))
                     mState |= NS_FRAME_IS_BIDI;
 
                 // look at the next character on the right end
                 if (rightPos > leftPos) {
                     // haven't looked at this character yet
                     ch = mTitle.CharAt(rightPos);
-                    charWidth = aRenderingContext.GetWidth(ch);
+                    charWidth =
+                        nsLayoutUtils::AppUnitWidthOfString(ch,
+                                                            aRenderingContext);
                     totalWidth += charWidth;
                     if (totalWidth > aWidth)
                         // greater than the allowable width
                         break;
                     rightString.Insert(ch, 0);
 
                     if (UCS2_CHAR_IS_BIDI(ch))
                         mState |= NS_FRAME_IS_BIDI;
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
@@ -1359,17 +1359,18 @@ nsTreeBodyFrame::AdjustForCellText(nsAut
     }
   }
 
   if (width > maxWidth) {
     // See if the width is even smaller than the ellipsis
     // If so, clear the text completely.
     const nsDependentString& kEllipsis = nsContentUtils::GetLocalizedEllipsis();
     aRenderingContext.SetTextRunRTL(false);
-    nscoord ellipsisWidth = aRenderingContext.GetWidth(kEllipsis);
+    nscoord ellipsisWidth =
+      nsLayoutUtils::AppUnitWidthOfString(kEllipsis, aRenderingContext);
 
     width = maxWidth;
     if (ellipsisWidth > width)
       aText.SetLength(0);
     else if (ellipsisWidth == width)
       aText.Assign(kEllipsis);
     else {
       // We will be drawing an ellipsis, thank you very much.
@@ -1384,17 +1385,18 @@ nsTreeBodyFrame::AdjustForCellText(nsAut
           // Crop right.
           nscoord cwidth;
           nscoord twidth = 0;
           uint32_t length = aText.Length();
           uint32_t i;
           for (i = 0; i < length; ++i) {
             char16_t ch = aText[i];
             // XXX this is horrible and doesn't handle clusters
-            cwidth = aRenderingContext.GetWidth(ch);
+            cwidth =
+              nsLayoutUtils::AppUnitWidthOfString(ch, aRenderingContext);
             if (twidth + cwidth > width)
               break;
             twidth += cwidth;
           }
           aText.Truncate(i);
           aText.Append(kEllipsis);
         }
         break;
@@ -1402,17 +1404,17 @@ nsTreeBodyFrame::AdjustForCellText(nsAut
         case 2: {
           // Crop left.
           nscoord cwidth;
           nscoord twidth = 0;
           int32_t length = aText.Length();
           int32_t i;
           for (i=length-1; i >= 0; --i) {
             char16_t ch = aText[i];
-            cwidth = aRenderingContext.GetWidth(ch);
+            cwidth = nsLayoutUtils::AppUnitWidthOfString(ch, aRenderingContext);
             if (twidth + cwidth > width)
               break;
             twidth += cwidth;
           }
 
           nsAutoString copy;
           aText.Right(copy, length-1-i);
           aText.Assign(kEllipsis);
@@ -1424,24 +1426,24 @@ nsTreeBodyFrame::AdjustForCellText(nsAut
         {
           // Crop center.
           nsAutoString leftStr, rightStr;
           nscoord cwidth, twidth = 0;
           int32_t length = aText.Length();
           int32_t rightPos = length - 1;
           for (int32_t leftPos = 0; leftPos < rightPos; ++leftPos) {
             char16_t ch = aText[leftPos];
-            cwidth = aRenderingContext.GetWidth(ch);
+            cwidth = nsLayoutUtils::AppUnitWidthOfString(ch, aRenderingContext);
             twidth += cwidth;
             if (twidth > width)
               break;
             leftStr.Append(ch);
 
             ch = aText[rightPos];
-            cwidth = aRenderingContext.GetWidth(ch);
+            cwidth = nsLayoutUtils::AppUnitWidthOfString(ch, aRenderingContext);
             twidth += cwidth;
             if (twidth > width)
               break;
             rightStr.Insert(ch, 0);
             --rightPos;
           }
           aText = leftStr;
           aText.Append(kEllipsis);