Bug 1117227 part 5 - Render ellipsis in correct orientation. r=jfkthame
authorXidorn Quan <quanxunzhen@gmail.com>
Fri, 24 Apr 2015 10:15:32 +1200
changeset 240826 18d118c05f8a38e15f3b7757a63e6ef501b738ad
parent 240825 d33657df2b288d5612bf61587bc04654d77ac916
child 240827 58f1b4f600d4a8754dd6c3cb11f7cc172f1ba5ff
push id58940
push userxquan@mozilla.com
push dateThu, 23 Apr 2015 22:19:58 +0000
treeherdermozilla-inbound@58f1b4f600d4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame
bugs1117227
milestone40.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 1117227 part 5 - Render ellipsis in correct orientation. r=jfkthame
gfx/thebes/gfxTextRun.cpp
gfx/thebes/gfxTextRun.h
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/generic/TextOverflow.cpp
--- a/gfx/thebes/gfxTextRun.cpp
+++ b/gfx/thebes/gfxTextRun.cpp
@@ -2568,20 +2568,23 @@ gfxFontGroup::InitScriptRun(gfxContext *
     }
 
     if (aMFR && missingChars) {
         aMFR->RecordScript(aRunScript);
     }
 }
 
 gfxTextRun *
-gfxFontGroup::GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel,
+gfxFontGroup::GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel, uint32_t aFlags,
                                  LazyReferenceContextGetter& aRefContextGetter)
 {
+    MOZ_ASSERT(!(aFlags & ~TEXT_ORIENT_MASK),
+               "flags here should only be used to specify orientation");
     if (mCachedEllipsisTextRun &&
+        (mCachedEllipsisTextRun->GetFlags() & TEXT_ORIENT_MASK) == aFlags &&
         mCachedEllipsisTextRun->GetAppUnitsPerDevUnit() == aAppUnitsPerDevPixel) {
         return mCachedEllipsisTextRun;
     }
 
     // Use a Unicode ellipsis if the font supports it,
     // otherwise use three ASCII periods as fallback.
     gfxFont* firstFont = GetFirstValidFont(uint32_t(kEllipsisChar[0]));
     nsString ellipsis = firstFont->HasCharacter(kEllipsisChar[0])
@@ -2591,17 +2594,17 @@ gfxFontGroup::GetEllipsisTextRun(int32_t
                             ArrayLength(kASCIIPeriodsChar) - 1);
 
     nsRefPtr<gfxContext> refCtx = aRefContextGetter.GetRefContext();
     Parameters params = {
         refCtx, nullptr, nullptr, nullptr, 0, aAppUnitsPerDevPixel
     };
     gfxTextRun* textRun =
         MakeTextRun(ellipsis.get(), ellipsis.Length(), &params,
-                    TEXT_IS_PERSISTENT, nullptr);
+                    aFlags | TEXT_IS_PERSISTENT, nullptr);
     if (!textRun) {
         return nullptr;
     }
     mCachedEllipsisTextRun = textRun;
     textRun->ReleaseFontGroup(); // don't let the presence of a cached ellipsis
                                  // textrun prolong the fontgroup's life
     return textRun;
 }
--- a/gfx/thebes/gfxTextRun.h
+++ b/gfx/thebes/gfxTextRun.h
@@ -873,20 +873,20 @@ public:
     }
 
     class LazyReferenceContextGetter {
     public:
       virtual already_AddRefed<gfxContext> GetRefContext() = 0;
     };
     // The gfxFontGroup keeps ownership of this textrun.
     // It is only guaranteed to exist until the next call to GetEllipsisTextRun
-    // (which might use a different appUnitsPerDev value) for the font group,
-    // or until UpdateUserFonts is called, or the fontgroup is destroyed.
+    // (which might use a different appUnitsPerDev value or flags) for the font
+    // group, or until UpdateUserFonts is called, or the fontgroup is destroyed.
     // Get it/use it/forget it :) - don't keep a reference that might go stale.
-    gfxTextRun* GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel,
+    gfxTextRun* GetEllipsisTextRun(int32_t aAppUnitsPerDevPixel, uint32_t aFlags,
                                    LazyReferenceContextGetter& aRefContextGetter);
 
     // helper method for resolving generic font families
     static void
     ResolveGenericFontNames(mozilla::FontFamilyType aGenericType,
                             nsIAtom *aLanguage,
                             nsTArray<nsString>& aGenericFamilies);
 
@@ -1037,17 +1037,17 @@ protected:
     gfxFloat mHyphenWidth;
 
     nsRefPtr<gfxUserFontSet> mUserFontSet;
     uint64_t mCurrGeneration;  // track the current user font set generation, rebuild font list if needed
 
     gfxTextPerfMetrics *mTextPerf;
 
     // Cache a textrun representing an ellipsis (useful for CSS text-overflow)
-    // at a specific appUnitsPerDevPixel size
+    // at a specific appUnitsPerDevPixel size and orientation
     nsAutoPtr<gfxTextRun>   mCachedEllipsisTextRun;
 
     // cache the most recent pref font to avoid general pref font lookup
     nsRefPtr<gfxFontFamily> mLastPrefFamily;
     nsRefPtr<gfxFont>       mLastPrefFont;
     eFontPrefLang           mLastPrefLang;       // lang group for last pref font
     eFontPrefLang           mPageLang;
     bool                    mLastPrefFirstFont;  // is this the first font in the list of pref fonts for this lang group?
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -6467,52 +6467,52 @@ nsLayoutUtils::GetTextRunFlagsForStyle(n
     if (aStyleFont->mFont.size <
         aStyleContext->PresContext()->GetAutoQualityMinFontSize()) {
       result |= gfxTextRunFactory::TEXT_OPTIMIZE_SPEED;
     }
     break;
   default:
     break;
   }
+  return result | GetTextRunOrientFlagsForStyle(aStyleContext);
+}
+
+/* static */ uint32_t
+nsLayoutUtils::GetTextRunOrientFlagsForStyle(nsStyleContext* aStyleContext)
+{
   WritingMode wm(aStyleContext);
   if (wm.IsVertical()) {
     switch (aStyleContext->StyleVisibility()->mTextOrientation) {
     case NS_STYLE_TEXT_ORIENTATION_MIXED:
-      result |= gfxTextRunFactory::TEXT_ORIENT_VERTICAL_MIXED;
-      break;
+      return gfxTextRunFactory::TEXT_ORIENT_VERTICAL_MIXED;
     case NS_STYLE_TEXT_ORIENTATION_UPRIGHT:
-      result |= gfxTextRunFactory::TEXT_ORIENT_VERTICAL_UPRIGHT;
-      break;
+      return gfxTextRunFactory::TEXT_ORIENT_VERTICAL_UPRIGHT;
     case NS_STYLE_TEXT_ORIENTATION_SIDEWAYS:
       // This should depend on writing mode vertical-lr vs vertical-rl,
       // but until we support SIDEWAYS_LEFT, we'll treat this the same
       // as SIDEWAYS_RIGHT and simply fall through.
       /*
       if (wm.IsVerticalLR()) {
-        result |= gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_LEFT;
+        return gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_LEFT;
       } else {
-        result |= gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_RIGHT;
+        return gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_RIGHT;
       }
-      break;
       */
     case NS_STYLE_TEXT_ORIENTATION_SIDEWAYS_RIGHT:
-      result |= gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_RIGHT;
-      break;
+      return gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_RIGHT;
     case NS_STYLE_TEXT_ORIENTATION_SIDEWAYS_LEFT:
       // Not yet supported, so fall through to the default (error) case.
       /*
-      result |= gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_LEFT;
-      break;
+      return gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_LEFT;
       */
     default:
       NS_NOTREACHED("unknown text-orientation");
-      break;
-    }
-  }
-  return result;
+    }
+  }
+  return 0;
 }
 
 /* static */ void
 nsLayoutUtils::GetRectDifferenceStrips(const nsRect& aR1, const nsRect& aR2,
                                        nsRect* aHStrip, nsRect* aVStrip) {
   NS_ASSERTION(aR1.TopLeft() == aR2.TopLeft(),
                "expected rects at the same position");
   nsRect unionRect(aR1.x, aR1.y, std::max(aR1.width, aR2.width),
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -1919,16 +1919,21 @@ public:
    * and prefs indicate we should be optimizing for speed over quality
    */
   static uint32_t GetTextRunFlagsForStyle(nsStyleContext* aStyleContext,
                                           const nsStyleFont* aStyleFont,
                                           const nsStyleText* aStyleText,
                                           nscoord aLetterSpacing);
 
   /**
+   * Get orientation flags for textrun construction.
+   */
+  static uint32_t GetTextRunOrientFlagsForStyle(nsStyleContext* aStyleContext);
+
+  /**
    * Takes two rectangles whose origins must be the same, and computes
    * the difference between their union and their intersection as two
    * rectangles. (This difference is a superset of the difference
    * between the two rectangles.)
    */
   static void GetRectDifferenceStrips(const nsRect& aR1, const nsRect& aR2,
                                       nsRect* aHStrip, nsRect* aVStrip);
 
--- a/layout/generic/TextOverflow.cpp
+++ b/layout/generic/TextOverflow.cpp
@@ -44,17 +44,19 @@ private:
 static gfxTextRun*
 GetEllipsisTextRun(nsIFrame* aFrame)
 {
   nsRefPtr<nsFontMetrics> fm;
   nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm),
     nsLayoutUtils::FontSizeInflationFor(aFrame));
   LazyReferenceRenderingContextGetterFromFrame lazyRefContextGetter(aFrame);
   return fm->GetThebesFontGroup()->GetEllipsisTextRun(
-      aFrame->PresContext()->AppUnitsPerDevPixel(), lazyRefContextGetter);
+    aFrame->PresContext()->AppUnitsPerDevPixel(),
+    nsLayoutUtils::GetTextRunOrientFlagsForStyle(aFrame->StyleContext()),
+    lazyRefContextGetter);
 }
 
 static nsIFrame*
 GetSelfOrNearestBlock(nsIFrame* aFrame)
 {
   return nsLayoutUtils::GetAsBlock(aFrame) ? aFrame :
          nsLayoutUtils::FindNearestBlockAncestor(aFrame);
 }