Bug 1353596 part 3 - Make LookAndFeel::GetFont return an nsFont. r?jfkthame draft
authorXidorn Quan <me@upsuper.org>
Thu, 06 Apr 2017 16:17:02 +1000
changeset 558252 eb9c495ae99bf8c5760c811d92e54bb1c4d64124
parent 558251 5ec28dee1411d617399e0c50c17bc24a981f10a3
child 623176 f3a093cf268844337e08cd185370d88b6f14fa1d
push id52850
push userxquan@mozilla.com
push dateFri, 07 Apr 2017 11:54:10 +0000
reviewersjfkthame
bugs1353596
milestone55.0a1
Bug 1353596 part 3 - Make LookAndFeel::GetFont return an nsFont. r?jfkthame MozReview-Commit-ID: J0NT2PDlp7b
gfx/thebes/gfxMacPlatformFontList.h
gfx/thebes/gfxMacPlatformFontList.mm
gfx/thebes/gfxPlatformMac.cpp
gfx/thebes/gfxPlatformMac.h
layout/style/nsRuleNode.cpp
widget/LookAndFeel.h
widget/android/nsLookAndFeel.cpp
widget/android/nsLookAndFeel.h
widget/cocoa/nsLookAndFeel.h
widget/cocoa/nsLookAndFeel.mm
widget/gonk/nsLookAndFeel.cpp
widget/gonk/nsLookAndFeel.h
widget/gtk/nsLookAndFeel.cpp
widget/gtk/nsLookAndFeel.h
widget/nsXPLookAndFeel.cpp
widget/nsXPLookAndFeel.h
widget/uikit/nsLookAndFeel.h
widget/uikit/nsLookAndFeel.mm
widget/windows/nsLookAndFeel.cpp
widget/windows/nsLookAndFeel.h
--- a/gfx/thebes/gfxMacPlatformFontList.h
+++ b/gfx/thebes/gfxMacPlatformFontList.h
@@ -103,19 +103,17 @@ public:
     bool FindAndAddFamilies(const nsAString& aFamily,
                             nsTArray<gfxFontFamily*>* aOutput,
                             gfxFontStyle* aStyle = nullptr,
                             gfxFloat aDevToCssSize = 1.0) override;
 
     // lookup the system font for a particular system font type and set
     // the name and style characteristics
     void LookupSystemFont(mozilla::LookAndFeel::FontID aSystemFontID,
-                          nsAString& aSystemFontName,
-                          gfxFontStyle &aFontStyle,
-                          float aDevPixPerCSSPixel);
+                          nsFont& aFont);
 
     // Values for the entryType field in FontFamilyListEntry records passed
     // from chrome to content process.
     enum FontFamilyEntryType {
         kStandardFontFamily = 0, // a standard installed font family
         kHiddenSystemFontFamily = 1, // hidden system family, not exposed to UI
         kTextSizeSystemFontFamily = 2, // name of 'system' font at text sizes
         kDisplaySizeSystemFontFamily = 3 // 'system' font at display sizes
--- a/gfx/thebes/gfxMacPlatformFontList.mm
+++ b/gfx/thebes/gfxMacPlatformFontList.mm
@@ -55,16 +55,17 @@
 
 #include "nsDirectoryServiceUtils.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsISimpleEnumerator.h"
 #include "nsCharTraits.h"
 #include "nsCocoaFeatures.h"
 #include "nsCocoaUtils.h"
+#include "nsPresContext.h"
 #include "gfxFontConstants.h"
 
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/SizePrintfMacros.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/Telemetry.h"
@@ -1236,109 +1237,107 @@ gfxMacPlatformFontList::MakePlatformFont
     NS_WARNING("downloaded font not loaded properly");
 #endif
 
     return nullptr;
 }
 
 // Webkit code uses a system font meta name, so mimic that here
 // WebCore/platform/graphics/mac/FontCacheMac.mm
-static const char kSystemFont_system[] = "-apple-system";
+static const char16_t kSystemFont_system[] = u"-apple-system";
 
 bool
 gfxMacPlatformFontList::FindAndAddFamilies(const nsAString& aFamily,
                                            nsTArray<gfxFontFamily*>* aOutput,
                                            gfxFontStyle* aStyle,
                                            gfxFloat aDevToCssSize)
 {
     // search for special system font name, -apple-system
-    if (aFamily.EqualsLiteral(kSystemFont_system)) {
+    if (aFamily.Equals(kSystemFont_system)) {
         if (mUseSizeSensitiveSystemFont &&
             aStyle && (aStyle->size * aDevToCssSize) >= kTextDisplayCrossover) {
             aOutput->AppendElement(FindSystemFontFamily(mSystemDisplayFontFamilyName));
             return true;
         }
         aOutput->AppendElement(FindSystemFontFamily(mSystemTextFontFamilyName));
         return true;
     }
 
     return gfxPlatformFontList::FindAndAddFamilies(aFamily, aOutput, aStyle,
                                                    aDevToCssSize);
 }
 
 void
 gfxMacPlatformFontList::LookupSystemFont(LookAndFeel::FontID aSystemFontID,
-                                         nsAString& aSystemFontName,
-                                         gfxFontStyle &aFontStyle,
-                                         float aDevPixPerCSSPixel)
+                                         nsFont& aFont)
 {
     // code moved here from widget/cocoa/nsLookAndFeel.mm
     NSFont *font = nullptr;
-    char* systemFontName = nullptr;
+    const char16_t* systemFontName = nullptr;
     switch (aSystemFontID) {
         case LookAndFeel::eFont_MessageBox:
         case LookAndFeel::eFont_StatusBar:
         case LookAndFeel::eFont_List:
         case LookAndFeel::eFont_Field:
         case LookAndFeel::eFont_Button:
         case LookAndFeel::eFont_Widget:
             font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
-            systemFontName = (char*) kSystemFont_system;
+            systemFontName = kSystemFont_system;
             break;
 
         case LookAndFeel::eFont_SmallCaption:
             font = [NSFont boldSystemFontOfSize:[NSFont smallSystemFontSize]];
-            systemFontName = (char*) kSystemFont_system;
+            systemFontName = kSystemFont_system;
             break;
 
         case LookAndFeel::eFont_Icon: // used in urlbar; tried labelFont, but too small
         case LookAndFeel::eFont_Workspace:
         case LookAndFeel::eFont_Desktop:
         case LookAndFeel::eFont_Info:
             font = [NSFont controlContentFontOfSize:0.0];
-            systemFontName = (char*) kSystemFont_system;
+            systemFontName = kSystemFont_system;
             break;
 
         case LookAndFeel::eFont_PullDownMenu:
             font = [NSFont menuBarFontOfSize:0.0];
-            systemFontName = (char*) kSystemFont_system;
+            systemFontName = kSystemFont_system;
             break;
 
         case LookAndFeel::eFont_Tooltips:
             font = [NSFont toolTipsFontOfSize:0.0];
-            systemFontName = (char*) kSystemFont_system;
+            systemFontName = kSystemFont_system;
             break;
 
         case LookAndFeel::eFont_Caption:
         case LookAndFeel::eFont_Menu:
         case LookAndFeel::eFont_Dialog:
         default:
             font = [NSFont systemFontOfSize:0.0];
-            systemFontName = (char*) kSystemFont_system;
+            systemFontName = kSystemFont_system;
             break;
     }
     NS_ASSERTION(font, "system font not set");
     NS_ASSERTION(systemFontName, "system font name not set");
 
     if (systemFontName) {
-        aSystemFontName.AssignASCII(systemFontName);
+        aFont.fontlist = FontFamilyList(nsDependentString(systemFontName),
+                                        eUnquotedName);
     }
 
     NSFontSymbolicTraits traits = [[font fontDescriptor] symbolicTraits];
-    aFontStyle.style =
+    aFont.style =
         (traits & NSFontItalicTrait) ?  NS_FONT_STYLE_ITALIC : NS_FONT_STYLE_NORMAL;
-    aFontStyle.weight =
+    aFont.weight =
         (traits & NSFontBoldTrait) ? NS_FONT_WEIGHT_BOLD : NS_FONT_WEIGHT_NORMAL;
-    aFontStyle.stretch =
+    aFont.stretch =
         (traits & NSFontExpandedTrait) ?
             NS_FONT_STRETCH_EXPANDED : (traits & NSFontCondensedTrait) ?
                 NS_FONT_STRETCH_CONDENSED : NS_FONT_STRETCH_NORMAL;
-    // convert size from css pixels to device pixels
-    aFontStyle.size = [font pointSize] * aDevPixPerCSSPixel;
-    aFontStyle.systemFont = true;
+    aFont.size = nsPresContext::CSSPixelsToAppUnits([font pointSize]);
+    aFont.systemFont = true;
 }
 
 // used to load system-wide font info on off-main thread
 class MacFontInfo : public FontInfoData {
 public:
     MacFontInfo(bool aLoadOtherNames,
                 bool aLoadFaceNames,
                 bool aLoadCmaps) :
--- a/gfx/thebes/gfxPlatformMac.cpp
+++ b/gfx/thebes/gfxPlatformMac.cpp
@@ -340,23 +340,20 @@ gfxPlatformMac::GetCommonFallbackFonts(u
     }
 
     // Arial Unicode MS has lots of glyphs for obscure, use it as a last resort
     aFontList.AppendElement(kFontArialUnicodeMS);
 }
 
 /*static*/ void
 gfxPlatformMac::LookupSystemFont(mozilla::LookAndFeel::FontID aSystemFontID,
-                                 nsAString& aSystemFontName,
-                                 gfxFontStyle& aFontStyle,
-                                 float aDevPixPerCSSPixel)
+                                 nsFont& aFont)
 {
     gfxMacPlatformFontList* pfl = gfxMacPlatformFontList::PlatformFontList();
-    return pfl->LookupSystemFont(aSystemFontID, aSystemFontName, aFontStyle,
-                                 aDevPixPerCSSPixel);
+    return pfl->LookupSystemFont(aSystemFontID, aFont);
 }
 
 uint32_t
 gfxPlatformMac::ReadAntiAliasingThreshold()
 {
     uint32_t threshold = 0;  // default == no threshold
 
     // first read prefs flag to determine whether to use the setting or not
--- a/gfx/thebes/gfxPlatformMac.h
+++ b/gfx/thebes/gfxPlatformMac.h
@@ -50,20 +50,17 @@ public:
 
     virtual void GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
                                         Script aRunScript,
                                         nsTArray<const char*>& aFontList) override;
 
     // lookup the system font for a particular system font type and set
     // the name and style characteristics
     static void
-    LookupSystemFont(mozilla::LookAndFeel::FontID aSystemFontID,
-                     nsAString& aSystemFontName,
-                     gfxFontStyle &aFontStyle,
-                     float aDevPixPerCSSPixel);
+    LookupSystemFont(mozilla::LookAndFeel::FontID aSystemFontID, nsFont& aFont);
 
     virtual bool CanRenderContentToDataSurface() const override {
       return true;
     }
 
     virtual bool SupportsApzWheelInput() const override {
       return true;
     }
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -3595,41 +3595,28 @@ nsRuleNode::SetFont(nsPresContext* aPres
     NS_STYLE_FONT_DIALOG         == LookAndFeel::eFont_Dialog &&
     NS_STYLE_FONT_BUTTON         == LookAndFeel::eFont_Button &&
     NS_STYLE_FONT_PULL_DOWN_MENU == LookAndFeel::eFont_PullDownMenu &&
     NS_STYLE_FONT_LIST           == LookAndFeel::eFont_List &&
     NS_STYLE_FONT_FIELD          == LookAndFeel::eFont_Field,
     "LookAndFeel.h system-font constants out of sync with nsStyleConsts.h");
 
   // Fall back to defaultVariableFont.
-  nsFont systemFont = *defaultVariableFont;
+  bool systemFontSet = false;
+  nsFont systemFont;
   const nsCSSValue* systemFontValue = aRuleData->ValueForSystemFont();
   if (eCSSUnit_Enumerated == systemFontValue->GetUnit()) {
-    gfxFontStyle fontStyle;
     LookAndFeel::FontID fontID =
       (LookAndFeel::FontID)systemFontValue->GetIntValue();
-    float devPerCSS =
-      (float)nsPresContext::AppUnitsPerCSSPixel() /
-      aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom();
-    nsAutoString systemFontName;
-    if (LookAndFeel::GetFont(fontID, systemFontName, fontStyle, devPerCSS)) {
-      systemFontName.Trim("\"'");
-      systemFont.fontlist = FontFamilyList(systemFontName, eUnquotedName);
-      systemFont.fontlist.SetDefaultFontType(eFamily_none);
-      systemFont.style = fontStyle.style;
-      systemFont.systemFont = fontStyle.systemFont;
-      systemFont.weight = fontStyle.weight;
-      systemFont.stretch = fontStyle.stretch;
-      systemFont.size =
-        NSFloatPixelsToAppUnits(fontStyle.size,
-                                aPresContext->DeviceContext()->
-                                  AppUnitsPerDevPixelAtUnitFullZoom());
-      //systemFont.langGroup = fontStyle.langGroup;
-      systemFont.sizeAdjust = fontStyle.sizeAdjust;
-    }
+    if (LookAndFeel::GetFont(fontID, systemFont)) {
+      systemFontSet = true;
+    }
+  }
+  if (!systemFontSet) {
+    systemFont = *defaultVariableFont;
   }
 
   // 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
--- a/widget/LookAndFeel.h
+++ b/widget/LookAndFeel.h
@@ -9,17 +9,17 @@
 #ifndef MOZILLA_INTERNAL_API
 #error "This header is only usable from within libxul (MOZILLA_INTERNAL_API)."
 #endif
 
 #include "nsDebug.h"
 #include "nsColor.h"
 #include "nsTArray.h"
 
-struct gfxFontStyle;
+struct nsFont;
 
 struct LookAndFeelInt
 {
   int32_t id;
   int32_t value;
 };
 
 namespace mozilla {
@@ -554,22 +554,19 @@ public:
   }
 
   /**
    * Retrieve the name and style of a system-theme font.  Returns true
    * if the system theme specifies this font, false if a default should
    * be used.  In the latter case neither aName nor aStyle is modified.
    *
    * @param aID    Which system-theme font is wanted.
-   * @param aName  The name of the font to use.
-   * @param aStyle Styling to apply to the font.
-   * @param aDevPixPerCSSPixel  Ratio of device pixels to CSS pixels
+   * @param aFont  The output font data.
    */
-  static bool GetFont(FontID aID, nsString& aName, gfxFontStyle& aStyle,
-                      float aDevPixPerCSSPixel);
+  static bool GetFont(FontID aID, nsFont& aFont);
 
   /**
    * GetPasswordCharacter() returns a unicode character which should be used
    * for a masked character in password editor.  E.g., '*'.
    */
   static char16_t GetPasswordCharacter();
 
   /**
--- a/widget/android/nsLookAndFeel.cpp
+++ b/widget/android/nsLookAndFeel.cpp
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/ContentChild.h"
 #include "nsStyleConsts.h"
 #include "nsXULAppAPI.h"
 #include "nsLookAndFeel.h"
+#include "nsPresContext.h"
 #include "gfxFont.h"
 #include "gfxFontConstants.h"
 #include "mozilla/gfx/2D.h"
 
 using namespace mozilla;
 using mozilla::dom::ContentChild;
 
 bool nsLookAndFeel::mInitializedSystemColors = false;
@@ -451,26 +452,25 @@ nsLookAndFeel::GetFloatImpl(FloatID aID,
             rv = NS_ERROR_FAILURE;
             break;
     }
     return rv;
 }
 
 /*virtual*/
 bool
-nsLookAndFeel::GetFontImpl(FontID aID, nsString& aFontName,
-                           gfxFontStyle& aFontStyle,
-                           float aDevPixPerCSSPixel)
+nsLookAndFeel::GetFontImpl(FontID aID, nsFont& aFont)
 {
-    aFontName.AssignLiteral("\"Droid Sans\"");
-    aFontStyle.style = NS_FONT_STYLE_NORMAL;
-    aFontStyle.weight = NS_FONT_WEIGHT_NORMAL;
-    aFontStyle.stretch = NS_FONT_STRETCH_NORMAL;
-    aFontStyle.size = 9.0 * 96.0f / 72.0f * aDevPixPerCSSPixel;
-    aFontStyle.systemFont = true;
+    aFont.fontlist = FontFamilyList(NS_LITERAL_STRING("Droid Sans"),
+                                    eUnquotedName);
+    aFont.style = NS_FONT_STYLE_NORMAL;
+    aFont.weight = NS_FONT_WEIGHT_NORMAL;
+    aFont.stretch = NS_FONT_STRETCH_NORMAL;
+    aFont.size = nsPresContext::CSSPixelsToAppUnits(9.0f * 96.0f / 72.0f);
+    aFont.systemFont = true;
     return true;
 }
 
 /*virtual*/
 bool
 nsLookAndFeel::GetEchoPasswordImpl()
 {
     if (!mInitializedShowPassword) {
--- a/widget/android/nsLookAndFeel.h
+++ b/widget/android/nsLookAndFeel.h
@@ -12,18 +12,17 @@ class nsLookAndFeel: public nsXPLookAndF
 {
 public:
     nsLookAndFeel();
     virtual ~nsLookAndFeel();
 
     virtual nsresult NativeGetColor(ColorID aID, nscolor &aResult);
     virtual nsresult GetIntImpl(IntID aID, int32_t &aResult);
     virtual nsresult GetFloatImpl(FloatID aID, float &aResult);
-    virtual bool GetFontImpl(FontID aID, nsString& aName, gfxFontStyle& aStyle,
-                             float aDevPixPerCSSPixel);
+    virtual bool GetFontImpl(FontID aID, nsFont& aFont);
     virtual bool GetEchoPasswordImpl();
     virtual uint32_t GetPasswordMaskDelayImpl();
     virtual char16_t GetPasswordCharacterImpl();
 
 protected:
     static bool mInitializedSystemColors;
     static mozilla::AndroidSystemColors mSystemColors;
     static bool mInitializedShowPassword;
--- a/widget/cocoa/nsLookAndFeel.h
+++ b/widget/cocoa/nsLookAndFeel.h
@@ -10,19 +10,17 @@
 class nsLookAndFeel: public nsXPLookAndFeel {
 public:
   nsLookAndFeel();
   virtual ~nsLookAndFeel();
 
   virtual nsresult NativeGetColor(ColorID aID, nscolor &aResult);
   virtual nsresult GetIntImpl(IntID aID, int32_t &aResult);
   virtual nsresult GetFloatImpl(FloatID aID, float &aResult);
-  virtual bool GetFontImpl(FontID aID, nsString& aFontName,
-                           gfxFontStyle& aFontStyle,
-                           float aDevPixPerCSSPixel);
+  virtual bool GetFontImpl(FontID aID, nsFont& aFont);
   virtual char16_t GetPasswordCharacterImpl()
   {
     // unicode value for the bullet character, used for password textfields.
     return 0x2022;
   }
 
   static bool UseOverlayScrollbars();
 
--- a/widget/cocoa/nsLookAndFeel.mm
+++ b/widget/cocoa/nsLookAndFeel.mm
@@ -5,16 +5,17 @@
 
 #include "nsLookAndFeel.h"
 #include "nsCocoaFeatures.h"
 #include "nsIServiceManager.h"
 #include "nsNativeThemeColors.h"
 #include "nsStyleConsts.h"
 #include "nsCocoaFeatures.h"
 #include "nsIContent.h"
+#include "nsPresContext.h"
 #include "gfxFont.h"
 #include "gfxFontConstants.h"
 #include "gfxPlatformMac.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/widget/WidgetMessageUtils.h"
 
 #import <Cocoa/Cocoa.h>
 
@@ -506,37 +507,33 @@ bool nsLookAndFeel::SystemWantsOverlaySc
 }
 
 bool nsLookAndFeel::AllowOverlayScrollbarsOverlap()
 {
   return (UseOverlayScrollbars());
 }
 
 bool
-nsLookAndFeel::GetFontImpl(FontID aID, nsString &aFontName,
-                           gfxFontStyle &aFontStyle,
-                           float aDevPixPerCSSPixel)
+nsLookAndFeel::GetFontImpl(FontID aID, nsFont& aFont)
 {
     NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
 
     // hack for now
     if (aID == eFont_Window || aID == eFont_Document) {
-        aFontStyle.style      = NS_FONT_STYLE_NORMAL;
-        aFontStyle.weight     = NS_FONT_WEIGHT_NORMAL;
-        aFontStyle.stretch    = NS_FONT_STRETCH_NORMAL;
-        aFontStyle.size       = 14 * aDevPixPerCSSPixel;
-        aFontStyle.systemFont = true;
-
-        aFontName.AssignLiteral("sans-serif");
+        aFont.fontlist = FontFamilyList(NS_LITERAL_STRING("sans-serif"),
+                                        eUnquotedName);
+        aFont.style      = NS_FONT_STYLE_NORMAL;
+        aFont.weight     = NS_FONT_WEIGHT_NORMAL;
+        aFont.stretch    = NS_FONT_STRETCH_NORMAL;
+        aFont.size       = nsPresContext::CSSPixelsToAppUnits(14.0f);
+        aFont.systemFont = true;
         return true;
     }
 
-    gfxPlatformMac::LookupSystemFont(aID, aFontName, aFontStyle,
-                                     aDevPixPerCSSPixel);
-
+    gfxPlatformMac::LookupSystemFont(aID, aFont);
     return true;
 
     NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(false);
 }
 
 nsTArray<LookAndFeelInt>
 nsLookAndFeel::GetIntCacheImpl()
 {
--- a/widget/gonk/nsLookAndFeel.cpp
+++ b/widget/gonk/nsLookAndFeel.cpp
@@ -11,16 +11,17 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 #include "nsLookAndFeel.h"
 #include "nsStyleConsts.h"
+#include "nsPresContext.h"
 #include "gfxFont.h"
 #include "gfxFontConstants.h"
 #include "mozilla/gfx/2D.h"
 #include "cutils/properties.h"
 
 static const char16_t UNICODE_BULLET = 0x2022;
 
 nsLookAndFeel::nsLookAndFeel()
@@ -425,26 +426,25 @@ nsLookAndFeel::GetFloatImpl(FloatID aID,
         aResult = -1.0;
         res = NS_ERROR_FAILURE;
     }
   return res;
 }
 
 /*virtual*/
 bool
-nsLookAndFeel::GetFontImpl(FontID aID, nsString& aFontName,
-                           gfxFontStyle& aFontStyle,
-                           float aDevPixPerCSSPixel)
+nsLookAndFeel::GetFontImpl(FontID aID, nsFont& aFont)
 {
-    aFontName.AssignLiteral("\"Fira Sans\"");
-    aFontStyle.style = NS_FONT_STYLE_NORMAL;
-    aFontStyle.weight = NS_FONT_WEIGHT_NORMAL;
-    aFontStyle.stretch = NS_FONT_STRETCH_NORMAL;
-    aFontStyle.size = 9.0 * 96.0f / 72.0f;
-    aFontStyle.systemFont = true;
+    aFont.fontlist = FontFamilyList(NS_LITERAL_STRING("Fira Sans"),
+                                    eUnquotedName);
+    aFont.style = NS_FONT_STYLE_NORMAL;
+    aFont.weight = NS_FONT_WEIGHT_NORMAL;
+    aFont.stretch = NS_FONT_STRETCH_NORMAL;
+    aFont.size = nsPresContext::CSSPixelsToAppUnits(9.0f * 96.0f / 72.0f);
+    aFont.systemFont = true;
     return true;
 }
 
 /*virtual*/
 bool
 nsLookAndFeel::GetEchoPasswordImpl() {
     return true;
 }
--- a/widget/gonk/nsLookAndFeel.h
+++ b/widget/gonk/nsLookAndFeel.h
@@ -20,18 +20,17 @@
 #include "nsXPLookAndFeel.h"
 
 class nsLookAndFeel : public nsXPLookAndFeel
 {
 public:
     nsLookAndFeel();
     virtual ~nsLookAndFeel();
 
-    virtual bool GetFontImpl(FontID aID, nsString& aName, gfxFontStyle& aStyle,
-                             float aDevPixPerCSSPixel);
+    virtual bool GetFontImpl(FontID aID, nsFont& aFont);
     virtual nsresult GetIntImpl(IntID aID, int32_t &aResult);
     virtual nsresult GetFloatImpl(FloatID aID, float &aResult);
     virtual bool GetEchoPasswordImpl();
     virtual uint32_t GetPasswordMaskDelayImpl();
     virtual char16_t GetPasswordCharacterImpl();
 
 protected:
     virtual nsresult NativeGetColor(ColorID aID, nscolor &aColor);
--- a/widget/gtk/nsLookAndFeel.cpp
+++ b/widget/gtk/nsLookAndFeel.cpp
@@ -19,16 +19,17 @@
 #include <fontconfig/fontconfig.h>
 #include "gfxPlatformGtk.h"
 #include "ScreenHelperGTK.h"
 
 #include "gtkdrawing.h"
 #include "nsStyleConsts.h"
 #include "gfxFontConstants.h"
 #include "WidgetUtils.h"
+#include "nsPresContext.h"
 
 #include <dlfcn.h>
 
 #include "mozilla/gfx/2D.h"
 
 #if MOZ_WIDGET_GTK != 2
 #include <cairo-gobject.h>
 #include "WidgetStyleCache.h"
@@ -890,178 +891,167 @@ nsLookAndFeel::GetFloatImpl(FloatID aID,
     default:
         aResult = -1.0;
         res = NS_ERROR_FAILURE;
     }
     return res;
 }
 
 static void
-GetSystemFontInfo(GtkWidget *aWidget,
-                  nsString *aFontName,
-                  gfxFontStyle *aFontStyle)
+GetSystemFontInfo(GtkWidget *aWidget, nsFont* aFont)
 {
     GtkSettings *settings = gtk_widget_get_settings(aWidget);
 
-    aFontStyle->style       = NS_FONT_STYLE_NORMAL;
+    aFont->style = NS_FONT_STYLE_NORMAL;
 
     gchar *fontname;
     g_object_get(settings, "gtk-font-name", &fontname, nullptr);
 
     PangoFontDescription *desc;
     desc = pango_font_description_from_string(fontname);
 
-    aFontStyle->systemFont = true;
+    aFont->systemFont = true;
 
     g_free(fontname);
 
-    NS_NAMED_LITERAL_STRING(quote, "\"");
     NS_ConvertUTF8toUTF16 family(pango_font_description_get_family(desc));
-    *aFontName = quote + family + quote;
+    aFont->fontlist = FontFamilyList(family, eUnquotedName);
 
-    aFontStyle->weight = pango_font_description_get_weight(desc);
+    aFont->weight = pango_font_description_get_weight(desc);
 
     // FIXME: Set aFontStyle->stretch correctly!
-    aFontStyle->stretch = NS_FONT_STRETCH_NORMAL;
+    aFont->stretch = NS_FONT_STRETCH_NORMAL;
 
     float size = float(pango_font_description_get_size(desc)) / PANGO_SCALE;
 
     // |size| is now either pixels or pango-points (not Mozilla-points!)
 
     if (!pango_font_description_get_size_is_absolute(desc)) {
         // |size| is in pango-points, so convert to pixels.
         size *= float(gfxPlatformGtk::GetDPI()) / POINTS_PER_INCH_FLOAT;
     }
 
     // Scale fonts to unzoomed CSS pixel
-    aFontStyle->size = size * ScreenHelperGTK::GetGTKMonitorScaleFactor()
-                            / ScreenHelperGTK::GetDefaultCssScale();
+    size = size * ScreenHelperGTK::GetGTKMonitorScaleFactor()
+                / ScreenHelperGTK::GetDefaultCssScale();
+
+    // Save app units to the font struct
+    aFont->size = nsPresContext::CSSPixelsToAppUnits(size);
 
     pango_font_description_free(desc);
 }
 
 static void
-GetSystemFontInfo(LookAndFeel::FontID aID,
-                  nsString *aFontName,
-                  gfxFontStyle *aFontStyle)
+GetSystemFontInfo(LookAndFeel::FontID aID, nsFont* aFont)
 {
     if (aID == LookAndFeel::eFont_Widget) {
         GtkWidget *label = gtk_label_new("M");
         GtkWidget *parent = gtk_fixed_new();
         GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP);
 
         gtk_container_add(GTK_CONTAINER(parent), label);
         gtk_container_add(GTK_CONTAINER(window), parent);
 
         gtk_widget_ensure_style(label);
-        GetSystemFontInfo(label, aFontName, aFontStyle);
+        GetSystemFontInfo(label, aFont);
         gtk_widget_destroy(window);  // no unref, windows are different
 
     } else if (aID == LookAndFeel::eFont_Button) {
         GtkWidget *label = gtk_label_new("M");
         GtkWidget *parent = gtk_fixed_new();
         GtkWidget *button = gtk_button_new();
         GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP);
 
         gtk_container_add(GTK_CONTAINER(button), label);
         gtk_container_add(GTK_CONTAINER(parent), button);
         gtk_container_add(GTK_CONTAINER(window), parent);
 
         gtk_widget_ensure_style(label);
-        GetSystemFontInfo(label, aFontName, aFontStyle);
+        GetSystemFontInfo(label, aFont);
         gtk_widget_destroy(window);  // no unref, windows are different
 
     } else if (aID == LookAndFeel::eFont_Field) {
         GtkWidget *entry = gtk_entry_new();
         GtkWidget *parent = gtk_fixed_new();
         GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP);
 
         gtk_container_add(GTK_CONTAINER(parent), entry);
         gtk_container_add(GTK_CONTAINER(window), parent);
 
         gtk_widget_ensure_style(entry);
-        GetSystemFontInfo(entry, aFontName, aFontStyle);
+        GetSystemFontInfo(entry, aFont);
         gtk_widget_destroy(window);  // no unref, windows are different
 
     } else {
         MOZ_ASSERT(aID == LookAndFeel::eFont_Menu, "unexpected font ID");
         GtkWidget *accel_label = gtk_accel_label_new("M");
         GtkWidget *menuitem = gtk_menu_item_new();
         GtkWidget *menu = gtk_menu_new();
         g_object_ref_sink(menu);
 
         gtk_container_add(GTK_CONTAINER(menuitem), accel_label);
         gtk_menu_shell_append((GtkMenuShell *)GTK_MENU(menu), menuitem);
 
         gtk_widget_ensure_style(accel_label);
-        GetSystemFontInfo(accel_label, aFontName, aFontStyle);
+        GetSystemFontInfo(accel_label, aFont);
         g_object_unref(menu);
     }
 }
 
 bool
-nsLookAndFeel::GetFontImpl(FontID aID, nsString& aFontName,
-                           gfxFontStyle& aFontStyle,
-                           float aDevPixPerCSSPixel)
+nsLookAndFeel::GetFontImpl(FontID aID, nsFont& aFont)
 {
-  nsString *cachedFontName = nullptr;
-  gfxFontStyle *cachedFontStyle = nullptr;
+  nsFont* cachedFont = nullptr;
   bool *isCached = nullptr;
 
   switch (aID) {
     case eFont_Menu:         // css2
     case eFont_PullDownMenu: // css3
-      cachedFontName = &mMenuFontName;
-      cachedFontStyle = &mMenuFontStyle;
+      cachedFont = &mMenuFont;
       isCached = &mMenuFontCached;
       aID = eFont_Menu;
       break;
 
     case eFont_Field:        // css3
     case eFont_List:         // css3
-      cachedFontName = &mFieldFontName;
-      cachedFontStyle = &mFieldFontStyle;
+      cachedFont = &mFieldFont;
       isCached = &mFieldFontCached;
       aID = eFont_Field;
       break;
 
     case eFont_Button:       // css3
-      cachedFontName = &mButtonFontName;
-      cachedFontStyle = &mButtonFontStyle;
+      cachedFont = &mButtonFont;
       isCached = &mButtonFontCached;
       break;
 
     case eFont_Caption:      // css2
     case eFont_Icon:         // css2
     case eFont_MessageBox:   // css2
     case eFont_SmallCaption: // css2
     case eFont_StatusBar:    // css2
     case eFont_Window:       // css3
     case eFont_Document:     // css3
     case eFont_Workspace:    // css3
     case eFont_Desktop:      // css3
     case eFont_Info:         // css3
     case eFont_Dialog:       // css3
     case eFont_Tooltips:     // moz
     case eFont_Widget:       // moz
-      cachedFontName = &mDefaultFontName;
-      cachedFontStyle = &mDefaultFontStyle;
+      cachedFont = &mDefaultFont;
       isCached = &mDefaultFontCached;
       aID = eFont_Widget;
       break;
   }
 
   if (!*isCached) {
-    GetSystemFontInfo(aID, cachedFontName, cachedFontStyle);
+    GetSystemFontInfo(aID, cachedFont);
     *isCached = true;
   }
 
-  aFontName = *cachedFontName;
-  aFontStyle = *cachedFontStyle;
-  aFontStyle.size *= aDevPixPerCSSPixel;
+  aFont = *cachedFont;
   return true;
 }
 
 void
 nsLookAndFeel::EnsureInit()
 {
     GdkColor colorValue;
     GdkColor *colorValuePtr;
--- a/widget/gtk/nsLookAndFeel.h
+++ b/widget/gtk/nsLookAndFeel.h
@@ -5,54 +5,48 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __nsLookAndFeel
 #define __nsLookAndFeel
 
 #include "nsXPLookAndFeel.h"
 #include "nsCOMPtr.h"
-#include "gfxFont.h"
+#include "nsFont.h"
 
 struct _GtkStyle;
 
 class nsLookAndFeel: public nsXPLookAndFeel {
 public:
     nsLookAndFeel();
     virtual ~nsLookAndFeel();
 
     virtual nsresult NativeGetColor(ColorID aID, nscolor &aResult);
     virtual nsresult GetIntImpl(IntID aID, int32_t &aResult);
     virtual nsresult GetFloatImpl(FloatID aID, float &aResult);
-    virtual bool GetFontImpl(FontID aID, nsString& aFontName,
-                             gfxFontStyle& aFontStyle,
-                             float aDevPixPerCSSPixel);
+    virtual bool GetFontImpl(FontID aID, nsFont& aFont);
 
     virtual void RefreshImpl();
     virtual char16_t GetPasswordCharacterImpl();
     virtual bool GetEchoPasswordImpl();
 
 protected:
 #if (MOZ_WIDGET_GTK == 2)
     struct _GtkStyle *mStyle;
 #endif
 
     // Cached fonts
     bool mDefaultFontCached;
     bool mButtonFontCached;
     bool mFieldFontCached;
     bool mMenuFontCached;
-    nsString mDefaultFontName;
-    nsString mButtonFontName;
-    nsString mFieldFontName;
-    nsString mMenuFontName;
-    gfxFontStyle mDefaultFontStyle;
-    gfxFontStyle mButtonFontStyle;
-    gfxFontStyle mFieldFontStyle;
-    gfxFontStyle mMenuFontStyle;
+    nsFont mDefaultFont;
+    nsFont mButtonFont;
+    nsFont mFieldFont;
+    nsFont mMenuFont;
 
     // Cached colors
     nscolor sInfoBackground;
     nscolor sInfoText;
     nscolor sMenuBackground;
     nscolor sMenuBarText;
     nscolor sMenuBarHoverText;
     nscolor sMenuText;
--- a/widget/nsXPLookAndFeel.cpp
+++ b/widget/nsXPLookAndFeel.cpp
@@ -935,21 +935,19 @@ LookAndFeel::GetInt(IntID aID, int32_t* 
 nsresult
 LookAndFeel::GetFloat(FloatID aID, float* aResult)
 {
   return nsLookAndFeel::GetInstance()->GetFloatImpl(aID, *aResult);
 }
 
 // static
 bool
-LookAndFeel::GetFont(FontID aID, nsString& aName, gfxFontStyle& aStyle,
-                     float aDevPixPerCSSPixel)
+LookAndFeel::GetFont(FontID aID, nsFont& aFont)
 {
-  return nsLookAndFeel::GetInstance()->GetFontImpl(aID, aName, aStyle,
-                                                   aDevPixPerCSSPixel);
+  return nsLookAndFeel::GetInstance()->GetFontImpl(aID, aFont);
 }
 
 // static
 char16_t
 LookAndFeel::GetPasswordCharacter()
 {
   return nsLookAndFeel::GetInstance()->GetPasswordCharacterImpl();
 }
--- a/widget/nsXPLookAndFeel.h
+++ b/widget/nsXPLookAndFeel.h
@@ -55,19 +55,17 @@ public:
   //
   nsresult GetColorImpl(ColorID aID, bool aUseStandinsForNativeColors,
                         nscolor &aResult);
   virtual nsresult GetIntImpl(IntID aID, int32_t &aResult);
   virtual nsresult GetFloatImpl(FloatID aID, float &aResult);
 
   // This one is different: there are no override prefs (fixme?), so
   // there is no XP implementation, only per-system impls.
-  virtual bool GetFontImpl(FontID aID, nsString& aName,
-                           gfxFontStyle& aStyle,
-                           float aDevPixPerCSSPixel) = 0;
+  virtual bool GetFontImpl(FontID aID, nsFont& aFont) = 0;
 
   virtual void RefreshImpl();
 
   virtual char16_t GetPasswordCharacterImpl()
   {
     return char16_t('*');
   }
 
--- a/widget/uikit/nsLookAndFeel.h
+++ b/widget/uikit/nsLookAndFeel.h
@@ -12,19 +12,17 @@ class nsLookAndFeel: public nsXPLookAndF
 {
 public:
     nsLookAndFeel();
     virtual ~nsLookAndFeel();
 
     virtual nsresult NativeGetColor(const ColorID aID, nscolor &aResult);
     virtual nsresult GetIntImpl(IntID aID, int32_t &aResult);
     virtual nsresult GetFloatImpl(FloatID aID, float &aResult);
-    virtual bool GetFontImpl(FontID aID, nsString& aFontName,
-                             gfxFontStyle& aFontStyle,
-                             float aDevPixPerCSSPixel);
+    virtual bool GetFontImpl(FontID aID, nsFont& aFont);
     virtual char16_t GetPasswordCharacterImpl()
     {
         // unicode value for the bullet character, used for password textfields.
         return 0x2022;
     }
 
     static bool UseOverlayScrollbars()
     {
--- a/widget/uikit/nsLookAndFeel.mm
+++ b/widget/uikit/nsLookAndFeel.mm
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #import <UIKit/UIColor.h>
 #import <UIKit/UIInterface.h>
 
 #include "nsLookAndFeel.h"
+#include "nsPresContext.h"
 #include "nsStyleConsts.h"
 #include "gfxFont.h"
 #include "gfxFontConstants.h"
 
 nsLookAndFeel::nsLookAndFeel()
     : nsXPLookAndFeel()
 {
 }
@@ -375,27 +376,24 @@ nsLookAndFeel::GetFloatImpl(FloatID aID,
       aResult = -1.0;
       res = NS_ERROR_FAILURE;
   }
 
   return res;
 }
 
 bool
-nsLookAndFeel::GetFontImpl(FontID aID, nsString &aFontName,
-                           gfxFontStyle &aFontStyle,
-                           float aDevPixPerCSSPixel)
+nsLookAndFeel::GetFontImpl(FontID aID, nsFont& aFont)
 {
     // hack for now
     if (aID == eFont_Window || aID == eFont_Document) {
-        aFontStyle.style      = NS_FONT_STYLE_NORMAL;
-        aFontStyle.weight     = NS_FONT_WEIGHT_NORMAL;
-        aFontStyle.stretch    = NS_FONT_STRETCH_NORMAL;
-        aFontStyle.size       = 14 * aDevPixPerCSSPixel;
-        aFontStyle.systemFont = true;
-
-        aFontName.AssignLiteral("sans-serif");
+        aFont.fontlist   = FontFamilyList("sans-serif", eUnquotedName);
+        aFont.style      = NS_FONT_STYLE_NORMAL;
+        aFont.weight     = NS_FONT_WEIGHT_NORMAL;
+        aFont.stretch    = NS_FONT_STRETCH_NORMAL;
+        aFont.size       = nsPresContext::CSSPixelsToAppUnits(14.0f);
+        aFont.systemFont = true;
         return true;
     }
 
     //TODO: implement more here?
     return false;
 }
--- a/widget/windows/nsLookAndFeel.cpp
+++ b/widget/windows/nsLookAndFeel.cpp
@@ -9,16 +9,17 @@
 #include "nsStyleConsts.h"
 #include "nsUXThemeData.h"
 #include "nsUXThemeConstants.h"
 #include "gfxFont.h"
 #include "WinUtils.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/WindowsVersion.h"
 #include "gfxFontConstants.h"
+#include "nsPresContext.h"
 
 using namespace mozilla;
 using namespace mozilla::widget;
 
 //static
 LookAndFeel::OperatingSystemVersion
 nsLookAndFeel::GetOperatingSystemVersion()
 {
@@ -521,19 +522,17 @@ nsLookAndFeel::GetFloatImpl(FloatID aID,
     default:
         aResult = -1.0;
         res = NS_ERROR_FAILURE;
     }
   return res;
 }
 
 static bool
-GetSysFontInfo(HDC aHDC, LookAndFeel::FontID anID,
-               nsString &aFontName,
-               gfxFontStyle &aFontStyle)
+GetSysFontInfo(HDC aHDC, LookAndFeel::FontID anID, nsFont& aFont)
 {
   LOGFONTW* ptrLogFont = nullptr;
   LOGFONTW logFont;
   NONCLIENTMETRICSW ncm;
   char16_t name[LF_FACESIZE];
   bool useShellDlg = false;
 
   // Depending on which stock font we want, there are a couple of
@@ -632,52 +631,51 @@ GetSysFontInfo(HDC aHDC, LookAndFeel::Fo
     // Fields (text fields)
     // Button and Selects (listboxes/comboboxes)
     // We use whatever font is defined by the system, but explicitly use
     // 10 points (13.33px) for consistency with our existing default behavior
     // as well as other browsers on Windows.
     pixelHeight = 96.0f / 72.0f * 10;
   }
 
-  aFontStyle.size = pixelHeight;
+  aFont.size = nsPresContext::CSSPixelsToAppUnits(pixelHeight);
 
   // FIXME: What about oblique?
-  aFontStyle.style =
+  aFont.style =
     (ptrLogFont->lfItalic) ? NS_FONT_STYLE_ITALIC : NS_FONT_STYLE_NORMAL;
 
   // FIXME: Other weights?
-  aFontStyle.weight =
+  aFont.weight =
     (ptrLogFont->lfWeight == FW_BOLD ?
         NS_FONT_WEIGHT_BOLD : NS_FONT_WEIGHT_NORMAL);
 
   // FIXME: Set aFontStyle->stretch correctly!
-  aFontStyle.stretch = NS_FONT_STRETCH_NORMAL;
+  aFont.stretch = NS_FONT_STRETCH_NORMAL;
 
-  aFontStyle.systemFont = true;
+  aFont.systemFont = true;
 
   if (useShellDlg) {
-    aFontName = NS_LITERAL_STRING("MS Shell Dlg 2");
+    aFont.fontlist =
+      FontFamilyList(NS_LITERAL_STRING("MS Shell Dlg 2"), eUnquotedName);
   } else {
     memcpy(name, ptrLogFont->lfFaceName, LF_FACESIZE*sizeof(char16_t));
-    aFontName = name;
+    nsDependentString fontName(name);
+    fontName.Trim("\"'");
+    aFont.fontlist = FontFamilyList(fontName, eUnquotedName);
   }
 
   return true;
 }
 
 bool
-nsLookAndFeel::GetFontImpl(FontID anID, nsString &aFontName,
-                           gfxFontStyle &aFontStyle,
-                           float aDevPixPerCSSPixel)
+nsLookAndFeel::GetFontImpl(FontID anID, nsFont& aFont)
 {
   HDC tdc = GetDC(nullptr);
-  bool status = GetSysFontInfo(tdc, anID, aFontName, aFontStyle);
+  bool status = GetSysFontInfo(tdc, anID, aFont);
   ReleaseDC(nullptr, tdc);
-  // now convert the logical font size from GetSysFontInfo into device pixels for layout
-  aFontStyle.size *= aDevPixPerCSSPixel;
   return status;
 }
 
 /* virtual */
 char16_t
 nsLookAndFeel::GetPasswordCharacterImpl()
 {
 #define UNICODE_BLACK_CIRCLE_CHAR 0x25cf
--- a/widget/windows/nsLookAndFeel.h
+++ b/widget/windows/nsLookAndFeel.h
@@ -34,19 +34,17 @@ class nsLookAndFeel: public nsXPLookAndF
   static OperatingSystemVersion GetOperatingSystemVersion();
 public:
   nsLookAndFeel();
   virtual ~nsLookAndFeel();
 
   virtual nsresult NativeGetColor(ColorID aID, nscolor &aResult);
   virtual nsresult GetIntImpl(IntID aID, int32_t &aResult);
   virtual nsresult GetFloatImpl(FloatID aID, float &aResult);
-  virtual bool GetFontImpl(FontID aID, nsString& aFontName,
-                           gfxFontStyle& aFontStyle,
-                           float aDevPixPerCSSPixel);
+  virtual bool GetFontImpl(FontID aID, nsFont& aFont);
   virtual char16_t GetPasswordCharacterImpl();
 
   virtual nsTArray<LookAndFeelInt> GetIntCacheImpl();
   virtual void SetIntCacheImpl(const nsTArray<LookAndFeelInt>& aLookAndFeelIntCache);
 
 private:
   int32_t mUseAccessibilityTheme;
 };