Bug 1358634 - Handle fallback to default variable font in case of nonexistant generic ; r=heycam
authorManish Goregaokar <manishearth@gmail.com>
Fri, 21 Apr 2017 16:10:50 -0700
changeset 356847 de6c23251b7585559dda4c12eca980bb58be3e15
parent 356846 bb299d98bdc428ffe9ae3aef5ace8cb03e27052b
child 356848 62b03dd84117bf8795643dfe96aa0a50119e6c2c
push id31775
push userihsiao@mozilla.com
push dateMon, 08 May 2017 03:10:38 +0000
treeherdermozilla-central@22aaf8bad4df [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1358634
milestone55.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 1358634 - Handle fallback to default variable font in case of nonexistant generic ; r=heycam MozReview-Commit-ID: GHUfkmJNgqG
layout/style/ServoBindings.cpp
layout/style/ServoBindings.h
layout/style/nsRuleNode.cpp
layout/style/nsRuleNode.h
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -1788,16 +1788,27 @@ Gecko_nsStyleFont_SetLang(nsStyleFont* a
 
 void
 Gecko_nsStyleFont_CopyLangFrom(nsStyleFont* aFont, const nsStyleFont* aSource)
 {
   aFont->mLanguage = aSource->mLanguage;
 }
 
 void
+Gecko_nsStyleFont_FixupNoneGeneric(nsStyleFont* aFont,
+                                   RawGeckoPresContextBorrowed aPresContext)
+{
+  const nsFont* defaultVariableFont =
+    aPresContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID,
+                                 aFont->mLanguage);
+  nsRuleNode::FixupNoneGeneric(&aFont->mFont, aPresContext,
+                               aFont->mGenericID, defaultVariableFont);
+}
+
+void
 FontSizePrefs::CopyFrom(const LangGroupFontPrefs& prefs)
 {
   mDefaultVariableSize = prefs.mDefaultVariableFont.size;
   mDefaultFixedSize = prefs.mDefaultFixedFont.size;
   mDefaultSerifSize = prefs.mDefaultSerifFont.size;
   mDefaultSansSerifSize = prefs.mDefaultSansSerifFont.size;
   mDefaultMonospaceSize = prefs.mDefaultMonospaceFont.size;
   mDefaultCursiveSize = prefs.mDefaultCursiveFont.size;
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -429,16 +429,18 @@ void Gecko_CSSValue_SetArray(nsCSSValueB
 void Gecko_CSSValue_SetURL(nsCSSValueBorrowedMut css_value, ServoBundledURI uri);
 void Gecko_CSSValue_SetInt(nsCSSValueBorrowedMut css_value, int32_t integer, nsCSSUnit unit);
 void Gecko_CSSValue_Drop(nsCSSValueBorrowedMut css_value);
 NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsCSSValueSharedList, CSSValueSharedList);
 bool Gecko_PropertyId_IsPrefEnabled(nsCSSPropertyID id);
 
 void Gecko_nsStyleFont_SetLang(nsStyleFont* font, nsIAtom* atom);
 void Gecko_nsStyleFont_CopyLangFrom(nsStyleFont* aFont, const nsStyleFont* aSource);
+void Gecko_nsStyleFont_FixupNoneGeneric(nsStyleFont* font,
+                                        RawGeckoPresContextBorrowed pres_context);
 FontSizePrefs Gecko_GetBaseSize(nsIAtom* lang);
 
 struct GeckoFontMetrics
 {
   nscoord mChSize;
   nscoord mXSize;
 };
 
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -405,16 +405,48 @@ nsRuleNode::GetMetricsFor(nsPresContext*
     if (wm.IsVertical() && !wm.IsSideways()) {
       isVertical = true;
     }
   }
   return nsRuleNode::GetMetricsFor(aPresContext, isVertical, aStyleFont,
                                    aFontSize, aUseUserFontSet);
 }
 
+/* static */
+void
+nsRuleNode::FixupNoneGeneric(nsFont* aFont,
+                             const nsPresContext* aPresContext,
+                             uint8_t aGenericFontID,
+                             const nsFont* aDefaultVariableFont)
+{
+  bool useDocumentFonts =
+    aPresContext->GetCachedBoolPref(kPresContext_UseDocumentFonts);
+  if (aGenericFontID == kGenericFont_NONE ||
+      (!useDocumentFonts && (aGenericFontID == kGenericFont_cursive ||
+                             aGenericFontID == kGenericFont_fantasy))) {
+    FontFamilyType defaultGeneric =
+      aDefaultVariableFont->fontlist.FirstGeneric();
+    MOZ_ASSERT(aDefaultVariableFont->fontlist.Length() == 1 &&
+               (defaultGeneric == eFamily_serif ||
+                defaultGeneric == eFamily_sans_serif));
+    if (defaultGeneric != eFamily_none) {
+      if (useDocumentFonts) {
+        aFont->fontlist.SetDefaultFontType(defaultGeneric);
+      } else {
+        // Either prioritize the first generic in the list,
+        // or (if there isn't one) prepend the default variable font.
+        if (!aFont->fontlist.PrioritizeFirstGeneric()) {
+          aFont->fontlist.PrependGeneric(defaultGeneric);
+        }
+      }
+    }
+  } else {
+    aFont->fontlist.SetDefaultFontType(eFamily_none);
+  }
+}
 
 static nsSize CalcViewportUnitsScale(nsPresContext* aPresContext)
 {
   // The caller is making use of viewport units, so notify the pres context
   // that it will need to rebuild the rule tree if the size of the viewport
   // changes.
   aPresContext->SetUsesViewportUnits(true);
 
@@ -3551,40 +3583,19 @@ nsRuleNode::SetFont(nsPresContext* aPres
 
   // font-family: font family list, enum, inherit
   const nsCSSValue* familyValue = aRuleData->ValueForFontFamily();
   NS_ASSERTION(eCSSUnit_Enumerated != familyValue->GetUnit(),
                "system fonts should not be in mFamily anymore");
   if (eCSSUnit_FontFamilyList == familyValue->GetUnit()) {
     // set the correct font if we are using DocumentFonts OR we are overriding for XUL
     // MJA: bug 31816
-    bool useDocumentFonts =
-      aPresContext->GetCachedBoolPref(kPresContext_UseDocumentFonts);
-    if (aGenericFontID == kGenericFont_NONE ||
-        (!useDocumentFonts && (aGenericFontID == kGenericFont_cursive ||
-                               aGenericFontID == kGenericFont_fantasy))) {
-      FontFamilyType defaultGeneric =
-        defaultVariableFont->fontlist.FirstGeneric();
-      MOZ_ASSERT(defaultVariableFont->fontlist.Length() == 1 &&
-                 (defaultGeneric == eFamily_serif ||
-                  defaultGeneric == eFamily_sans_serif));
-      if (defaultGeneric != eFamily_none) {
-        if (useDocumentFonts) {
-          aFont->mFont.fontlist.SetDefaultFontType(defaultGeneric);
-        } else {
-          // Either prioritize the first generic in the list,
-          // or (if there isn't one) prepend the default variable font.
-          if (!aFont->mFont.fontlist.PrioritizeFirstGeneric()) {
-            aFont->mFont.fontlist.PrependGeneric(defaultGeneric);
-          }
-        }
-      }
-    } else {
-      aFont->mFont.fontlist.SetDefaultFontType(eFamily_none);
-    }
+    nsRuleNode::FixupNoneGeneric(&aFont->mFont, aPresContext,
+                                 aGenericFontID, defaultVariableFont);
+
     aFont->mFont.systemFont = false;
     // Technically this is redundant with the code below, but it's good
     // to have since we'll still want it once we get rid of
     // SetGenericFont (bug 380915).
     aFont->mGenericID = aGenericFontID;
   }
   else if (eCSSUnit_System_Font == familyValue->GetUnit()) {
     aFont->mFont.fontlist = systemFont.fontlist;
--- a/layout/style/nsRuleNode.h
+++ b/layout/style/nsRuleNode.h
@@ -806,16 +806,25 @@ public:
                                                        bool aUseUserFontSet);
 
   static already_AddRefed<nsFontMetrics> GetMetricsFor(nsPresContext* aPresContext,
                                                        nsStyleContext* aStyleContext,
                                                        const nsStyleFont* aStyleFont,
                                                        nscoord aFontSize,
                                                        bool aUseUserFontSet);
 
+  /**
+   * Appropriately add the correct font if we are using DocumentFonts or
+   * overriding for XUL
+   */
+  static void FixupNoneGeneric(nsFont* aFont,
+                               const nsPresContext* aPresContext,
+                               uint8_t aGenericFontID,
+                               const nsFont* aDefaultVariableFont);
+
   // Transition never returns null; on out of memory it'll just return |this|.
   nsRuleNode* Transition(nsIStyleRule* aRule, mozilla::SheetType aLevel,
                          bool aIsImportantRule);
   nsRuleNode* GetParent() const { return mParent; }
   bool IsRoot() const { return mParent == nullptr; }
 
   // Return the root of the rule tree that this rule node is in.
   nsRuleNode* RuleTree();