Begin switch to SkFontStyle for legacy calls.

This adds SK_VERY_LEGACY_CREATE_TYPEFACE which, when defined, provides
only the old interface.

Ideally, everyone would switch directly to SkFontMgr and use one of the
newer calls, but there is currently no path for current users to get
there. This updates all the internals to use SkFontStyle, after
switching these over the higher level APIs can be switched.

The Chromium follow on patch can be seen at https://crrev.com/1877673002

GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1873923002

TBR=reed
This doesn't really change API, just modernizes it.

Review URL: https://codereview.chromium.org/1873923002
diff --git a/gm/fontmgr.cpp b/gm/fontmgr.cpp
index dd8b14d..ee3805c 100644
--- a/gm/fontmgr.cpp
+++ b/gm/fontmgr.cpp
@@ -45,7 +45,11 @@
     // it expects to get the same glyph when following this pattern.
     SkString familyName;
     typeface->getFamilyName(&familyName);
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
     SkTypeface* typefaceCopy = fm->legacyCreateTypeface(familyName.c_str(), typeface->style());
+#else
+    SkTypeface* typefaceCopy = fm->legacyCreateTypeface(familyName.c_str(), typeface->fontStyle());
+#endif
     SkSafeUnref(paint.setTypeface(typefaceCopy));
     return drawString(canvas, ch, x, y, paint) + 20;
 }
diff --git a/include/core/SkFontStyle.h b/include/core/SkFontStyle.h
index f42d7dd..c18f956 100644
--- a/include/core/SkFontStyle.h
+++ b/include/core/SkFontStyle.h
@@ -43,8 +43,8 @@
 
     SkFontStyle();
     SkFontStyle(int weight, int width, Slant);
-    /** oldStyle means the style-bits in SkTypeface::Style: bold=1, italic=2 */
-    explicit SkFontStyle(unsigned oldStyle);
+
+    static SkFontStyle FromOldStyle(unsigned oldStyle);
 
     bool operator==(const SkFontStyle& rhs) const {
         return fUnion.fU32 == rhs.fUnion.fU32;
diff --git a/include/ports/SkFontConfigInterface.h b/include/ports/SkFontConfigInterface.h
index 063cb9d..464251b 100644
--- a/include/ports/SkFontConfigInterface.h
+++ b/include/ports/SkFontConfigInterface.h
@@ -80,11 +80,19 @@
      *
      *  If a match is not found, return false, and ignore all out parameters.
      */
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
     virtual bool matchFamilyName(const char familyName[],
                                  SkTypeface::Style requested,
                                  FontIdentity* outFontIdentifier,
                                  SkString* outFamilyName,
                                  SkTypeface::Style* outStyle) = 0;
+#else
+    virtual bool matchFamilyName(const char familyName[],
+                                 SkFontStyle requested,
+                                 FontIdentity* outFontIdentifier,
+                                 SkString* outFamilyName,
+                                 SkFontStyle* outStyle) = 0;
+#endif
 
     /**
      *  Given a FontRef, open a stream to access its data, or return null
diff --git a/include/ports/SkFontMgr.h b/include/ports/SkFontMgr.h
index 3e6c785..a961cd4 100644
--- a/include/ports/SkFontMgr.h
+++ b/include/ports/SkFontMgr.h
@@ -164,8 +164,11 @@
      */
     SkTypeface* createFromFile(const char path[], int ttcIndex = 0) const;
 
-    SkTypeface* legacyCreateTypeface(const char familyName[],
-                                     unsigned typefaceStyleBits) const;
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
+    SkTypeface* legacyCreateTypeface(const char familyName[], unsigned typefaceStyleBits) const;
+#else
+    SkTypeface* legacyCreateTypeface(const char familyName[], SkFontStyle style) const;
+#endif
 
     /**
      *  Return a ref to the default fontmgr. The caller must call unref() on
@@ -196,8 +199,13 @@
     virtual SkTypeface* onCreateFromFontData(SkFontData*) const;
     virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const = 0;
 
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
                                                unsigned styleBits) const = 0;
+#else
+    virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], SkFontStyle) const = 0;
+#endif
+
 private:
     static SkFontMgr* Factory();    // implemented by porting layer
     friend SkFontMgr* sk_fontmgr_create_default();
diff --git a/include/ports/SkFontMgr_indirect.h b/include/ports/SkFontMgr_indirect.h
index 37502d24..b3f31c3 100644
--- a/include/ports/SkFontMgr_indirect.h
+++ b/include/ports/SkFontMgr_indirect.h
@@ -38,24 +38,27 @@
 
     SkFontStyleSet* onMatchFamily(const char familyName[]) const override;
 
-    virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
-                                           const SkFontStyle& fontStyle) const override;
+    SkTypeface* onMatchFamilyStyle(const char familyName[],
+                                   const SkFontStyle& fontStyle) const override;
 
-    virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
-                                                    const SkFontStyle&,
-                                                    const char* bcp47[],
-                                                    int bcp47Count,
-                                                    SkUnichar character) const override;
+    SkTypeface* onMatchFamilyStyleCharacter(const char familyName[],
+                                            const SkFontStyle&,
+                                            const char* bcp47[],
+                                            int bcp47Count,
+                                            SkUnichar character) const override;
 
-    virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
-                                         const SkFontStyle& fontStyle) const override;
+    SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
+                                 const SkFontStyle& fontStyle) const override;
 
     SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const override;
     SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override;
     SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override;
 
-    virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
-                                               unsigned styleBits) const override;
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
+    SkTypeface* onLegacyCreateTypeface(const char familyName[], unsigned styleBits) const override;
+#else
+    SkTypeface* onLegacyCreateTypeface(const char familyName[], SkFontStyle) const override;
+#endif
 
 private:
     SkTypeface* createTypefaceFromFontId(const SkFontIdentity& fontId) const;
diff --git a/src/core/SkFontMgr.cpp b/src/core/SkFontMgr.cpp
index ab04250..68a6c24 100644
--- a/src/core/SkFontMgr.cpp
+++ b/src/core/SkFontMgr.cpp
@@ -74,7 +74,11 @@
     SkTypeface* onCreateFromFile(const char[], int) const override {
         return nullptr;
     }
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
     SkTypeface* onLegacyCreateTypeface(const char [], unsigned) const override {
+#else
+    SkTypeface* onLegacyCreateTypeface(const char [], SkFontStyle) const override {
+#endif
         return nullptr;
     }
 };
@@ -165,9 +169,12 @@
     return this->onCreateFromFile(path, ttcIndex);
 }
 
-SkTypeface* SkFontMgr::legacyCreateTypeface(const char familyName[],
-                                            unsigned styleBits) const {
-    return this->onLegacyCreateTypeface(familyName, styleBits);
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
+SkTypeface* SkFontMgr::legacyCreateTypeface(const char familyName[], unsigned style) const {
+#else
+SkTypeface* SkFontMgr::legacyCreateTypeface(const char familyName[], SkFontStyle style) const {
+#endif
+    return this->onLegacyCreateTypeface(familyName, style);
 }
 
 SK_DECLARE_STATIC_ONCE_PTR(SkFontMgr, singleton);
diff --git a/src/core/SkFontStyle.cpp b/src/core/SkFontStyle.cpp
index badf9d7..c28e721 100644
--- a/src/core/SkFontStyle.cpp
+++ b/src/core/SkFontStyle.cpp
@@ -23,11 +23,10 @@
     fUnion.fR.fSlant = SkTPin<int>(slant, kUpright_Slant, kItalic_Slant);
 }
 
-SkFontStyle::SkFontStyle(unsigned oldStyle) {
-    fUnion.fU32 = 0;
-    fUnion.fR.fWeight = (oldStyle & SkTypeface::kBold) ? SkFontStyle::kBold_Weight
-                                                       : SkFontStyle::kNormal_Weight;
-    fUnion.fR.fWidth = SkFontStyle::kNormal_Width;
-    fUnion.fR.fSlant = (oldStyle & SkTypeface::kItalic) ? SkFontStyle::kItalic_Slant
-                                                        : SkFontStyle::kUpright_Slant;
+/*static*/SkFontStyle SkFontStyle::FromOldStyle(unsigned oldStyle) {
+    return SkFontStyle((oldStyle & SkTypeface::kBold) ? SkFontStyle::kBold_Weight
+                                                      : SkFontStyle::kNormal_Weight,
+                       SkFontStyle::kNormal_Width,
+                       (oldStyle & SkTypeface::kItalic) ? SkFontStyle::kItalic_Slant
+                                                        : SkFontStyle::kUpright_Slant);
 }
diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp
index dc53063..f9e5b5f 100644
--- a/src/core/SkTypeface.cpp
+++ b/src/core/SkTypeface.cpp
@@ -87,7 +87,11 @@
         SkAutoMutexAcquire lock(&gCreateDefaultMutex);
 
         SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
         SkTypeface* t = fm->legacyCreateTypeface(nullptr, style);
+#else
+        SkTypeface* t = fm->legacyCreateTypeface(nullptr, SkFontStyle::FromOldStyle(style));
+#endif
         return t ? t : SkEmptyTypeface::Create();
     });
 }
@@ -120,7 +124,11 @@
         return RefDefault(style);
     }
     SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
     return fm->legacyCreateTypeface(name, style);
+#else
+    return fm->legacyCreateTypeface(name, SkFontStyle::FromOldStyle(style));
+#endif
 }
 
 SkTypeface* SkTypeface::CreateFromTypeface(const SkTypeface* family, Style s) {
diff --git a/src/fonts/SkFontMgr_fontconfig.cpp b/src/fonts/SkFontMgr_fontconfig.cpp
index 50af9b4..60ad862 100644
--- a/src/fonts/SkFontMgr_fontconfig.cpp
+++ b/src/fonts/SkFontMgr_fontconfig.cpp
@@ -318,10 +318,14 @@
         return stream.get() ? this->createFromStream(stream.release(), ttcIndex) : nullptr;
     }
 
-    SkTypeface* onLegacyCreateTypeface(const char familyName[],
-                                       unsigned styleBits) const override {
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
+    SkTypeface* onLegacyCreateTypeface(const char familyName[], unsigned styleBits) const override {
+        SkTypeface::Style style = static_cast<SkTypeface::Style>(styleBits);
+#else
+    SkTypeface* onLegacyCreateTypeface(const char familyName[], SkFontStyle style) const override {
+#endif
         FCLocker lock;
-        return FontConfigTypeface::LegacyCreateTypeface(familyName, (SkTypeface::Style)styleBits);
+        return FontConfigTypeface::LegacyCreateTypeface(familyName, style);
     }
 };
 
diff --git a/src/fonts/SkFontMgr_indirect.cpp b/src/fonts/SkFontMgr_indirect.cpp
index fc0bd5c..4d226da 100644
--- a/src/fonts/SkFontMgr_indirect.cpp
+++ b/src/fonts/SkFontMgr_indirect.cpp
@@ -184,16 +184,14 @@
     return fImpl->createFromData(data, ttcIndex);
 }
 
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
 SkTypeface* SkFontMgr_Indirect::onLegacyCreateTypeface(const char familyName[],
                                                        unsigned styleBits) const {
-    bool bold = SkToBool(styleBits & SkTypeface::kBold);
-    bool italic = SkToBool(styleBits & SkTypeface::kItalic);
-    SkFontStyle style = SkFontStyle(bold ? SkFontStyle::kBold_Weight
-                                         : SkFontStyle::kNormal_Weight,
-                                    SkFontStyle::kNormal_Width,
-                                    italic ? SkFontStyle::kItalic_Slant
-                                           : SkFontStyle::kUpright_Slant);
-
+    SkFontStyle style = SkFontStyle::FromOldStyle(styleBits);
+#else
+SkTypeface* SkFontMgr_Indirect::onLegacyCreateTypeface(const char familyName[],
+                                                       SkFontStyle style) const {
+#endif
     SkAutoTUnref<SkTypeface> face(this->matchFamilyStyle(familyName, style));
 
     if (nullptr == face.get()) {
diff --git a/src/ports/SkFontConfigInterface_direct.cpp b/src/ports/SkFontConfigInterface_direct.cpp
index f5f4949..1c42e2d 100644
--- a/src/ports/SkFontConfigInterface_direct.cpp
+++ b/src/ports/SkFontConfigInterface_direct.cpp
@@ -9,6 +9,7 @@
 
 #include "SkBuffer.h"
 #include "SkDataTable.h"
+#include "SkFixed.h"
 #include "SkFontConfigInterface_direct.h"
 #include "SkFontStyle.h"
 #include "SkMutex.h"
@@ -304,6 +305,7 @@
 }
 
 // Retrieves |is_bold|, |is_italic| and |font_family| properties from |font|.
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
 SkTypeface::Style GetFontStyle(FcPattern* font) {
     int resulting_bold;
     if (FcPatternGetInteger(font, FC_WEIGHT, 0, &resulting_bold))
@@ -335,6 +337,136 @@
 
     return (SkTypeface::Style)styleBits;
 }
+#else
+
+static int get_int(FcPattern* pattern, const char object[], int missing) {
+    int value;
+    if (FcPatternGetInteger(pattern, object, 0, &value) != FcResultMatch) {
+        return missing;
+    }
+    return value;
+}
+
+static int map_range(SkFixed value,
+                     SkFixed old_min, SkFixed old_max,
+                     SkFixed new_min, SkFixed new_max)
+{
+    SkASSERT(old_min < old_max);
+    SkASSERT(new_min <= new_max);
+    return new_min + SkMulDiv(value - old_min, new_max - new_min, old_max - old_min);
+}
+
+struct MapRanges {
+    SkFixed old_val;
+    SkFixed new_val;
+};
+
+static SkFixed map_ranges_fixed(SkFixed val, MapRanges const ranges[], int rangesCount) {
+    // -Inf to [0]
+    if (val < ranges[0].old_val) {
+        return ranges[0].new_val;
+    }
+
+    // Linear from [i] to [i+1]
+    for (int i = 0; i < rangesCount - 1; ++i) {
+        if (val < ranges[i+1].old_val) {
+            return map_range(val, ranges[i].old_val, ranges[i+1].old_val,
+                                  ranges[i].new_val, ranges[i+1].new_val);
+        }
+    }
+
+    // From [n] to +Inf
+    // if (fcweight < Inf)
+    return ranges[rangesCount-1].new_val;
+}
+
+static int map_ranges(int val, MapRanges const ranges[], int rangesCount) {
+    return SkFixedRoundToInt(map_ranges_fixed(SkIntToFixed(val), ranges, rangesCount));
+}
+
+template<int n> struct SkTFixed {
+    static_assert(-32768 <= n && n <= 32767, "SkTFixed_n_not_in_range");
+    static const SkFixed value = static_cast<SkFixed>(n << 16);
+};
+
+static SkFontStyle skfontstyle_from_fcpattern(FcPattern* pattern) {
+    typedef SkFontStyle SkFS;
+
+    static const MapRanges weightRanges[] = {
+        { SkTFixed<FC_WEIGHT_THIN>::value,       SkTFixed<SkFS::kThin_Weight>::value },
+        { SkTFixed<FC_WEIGHT_EXTRALIGHT>::value, SkTFixed<SkFS::kExtraLight_Weight>::value },
+        { SkTFixed<FC_WEIGHT_LIGHT>::value,      SkTFixed<SkFS::kLight_Weight>::value },
+        { SkTFixed<FC_WEIGHT_REGULAR>::value,    SkTFixed<SkFS::kNormal_Weight>::value },
+        { SkTFixed<FC_WEIGHT_MEDIUM>::value,     SkTFixed<SkFS::kMedium_Weight>::value },
+        { SkTFixed<FC_WEIGHT_DEMIBOLD>::value,   SkTFixed<SkFS::kSemiBold_Weight>::value },
+        { SkTFixed<FC_WEIGHT_BOLD>::value,       SkTFixed<SkFS::kBold_Weight>::value },
+        { SkTFixed<FC_WEIGHT_EXTRABOLD>::value,  SkTFixed<SkFS::kExtraBold_Weight>::value },
+        { SkTFixed<FC_WEIGHT_BLACK>::value,      SkTFixed<SkFS::kBlack_Weight>::value },
+        { SkTFixed<FC_WEIGHT_EXTRABLACK>::value, SkTFixed<1000>::value },
+    };
+    int weight = map_ranges(get_int(pattern, FC_WEIGHT, FC_WEIGHT_REGULAR),
+                            weightRanges, SK_ARRAY_COUNT(weightRanges));
+
+    static const MapRanges widthRanges[] = {
+        { SkTFixed<FC_WIDTH_ULTRACONDENSED>::value, SkTFixed<SkFS::kUltraCondensed_Width>::value },
+        { SkTFixed<FC_WIDTH_EXTRACONDENSED>::value, SkTFixed<SkFS::kExtraCondensed_Width>::value },
+        { SkTFixed<FC_WIDTH_CONDENSED>::value,      SkTFixed<SkFS::kCondensed_Width>::value },
+        { SkTFixed<FC_WIDTH_SEMICONDENSED>::value,  SkTFixed<SkFS::kSemiCondensed_Width>::value },
+        { SkTFixed<FC_WIDTH_NORMAL>::value,         SkTFixed<SkFS::kNormal_Width>::value },
+        { SkTFixed<FC_WIDTH_SEMIEXPANDED>::value,   SkTFixed<SkFS::kSemiExpanded_Width>::value },
+        { SkTFixed<FC_WIDTH_EXPANDED>::value,       SkTFixed<SkFS::kExpanded_Width>::value },
+        { SkTFixed<FC_WIDTH_EXTRAEXPANDED>::value,  SkTFixed<SkFS::kExtraExpanded_Width>::value },
+        { SkTFixed<FC_WIDTH_ULTRAEXPANDED>::value,  SkTFixed<SkFS::kUltaExpanded_Width>::value },
+    };
+    int width = map_ranges(get_int(pattern, FC_WIDTH, FC_WIDTH_NORMAL),
+                           widthRanges, SK_ARRAY_COUNT(widthRanges));
+
+    SkFS::Slant slant = get_int(pattern, FC_SLANT, FC_SLANT_ROMAN) > 0
+                             ? SkFS::kItalic_Slant
+                             : SkFS::kUpright_Slant;
+
+    return SkFontStyle(weight, width, slant);
+}
+
+static void fcpattern_from_skfontstyle(SkFontStyle style, FcPattern* pattern) {
+    typedef SkFontStyle SkFS;
+
+    static const MapRanges weightRanges[] = {
+        { SkTFixed<SkFS::kThin_Weight>::value,       SkTFixed<FC_WEIGHT_THIN>::value },
+        { SkTFixed<SkFS::kExtraLight_Weight>::value, SkTFixed<FC_WEIGHT_EXTRALIGHT>::value },
+        { SkTFixed<SkFS::kLight_Weight>::value,      SkTFixed<FC_WEIGHT_LIGHT>::value },
+        { SkTFixed<SkFS::kNormal_Weight>::value,     SkTFixed<FC_WEIGHT_REGULAR>::value },
+        { SkTFixed<SkFS::kMedium_Weight>::value,     SkTFixed<FC_WEIGHT_MEDIUM>::value },
+        { SkTFixed<SkFS::kSemiBold_Weight>::value,   SkTFixed<FC_WEIGHT_DEMIBOLD>::value },
+        { SkTFixed<SkFS::kBold_Weight>::value,       SkTFixed<FC_WEIGHT_BOLD>::value },
+        { SkTFixed<SkFS::kExtraBold_Weight>::value,  SkTFixed<FC_WEIGHT_EXTRABOLD>::value },
+        { SkTFixed<SkFS::kBlack_Weight>::value,      SkTFixed<FC_WEIGHT_BLACK>::value },
+        { SkTFixed<1000>::value,                     SkTFixed<FC_WEIGHT_EXTRABLACK>::value },
+    };
+    int weight = map_ranges(style.weight(), weightRanges, SK_ARRAY_COUNT(weightRanges));
+
+    static const MapRanges widthRanges[] = {
+        { SkTFixed<SkFS::kUltraCondensed_Width>::value, SkTFixed<FC_WIDTH_ULTRACONDENSED>::value },
+        { SkTFixed<SkFS::kExtraCondensed_Width>::value, SkTFixed<FC_WIDTH_EXTRACONDENSED>::value },
+        { SkTFixed<SkFS::kCondensed_Width>::value,      SkTFixed<FC_WIDTH_CONDENSED>::value },
+        { SkTFixed<SkFS::kSemiCondensed_Width>::value,  SkTFixed<FC_WIDTH_SEMICONDENSED>::value },
+        { SkTFixed<SkFS::kNormal_Width>::value,         SkTFixed<FC_WIDTH_NORMAL>::value },
+        { SkTFixed<SkFS::kSemiExpanded_Width>::value,   SkTFixed<FC_WIDTH_SEMIEXPANDED>::value },
+        { SkTFixed<SkFS::kExpanded_Width>::value,       SkTFixed<FC_WIDTH_EXPANDED>::value },
+        { SkTFixed<SkFS::kExtraExpanded_Width>::value,  SkTFixed<FC_WIDTH_EXTRAEXPANDED>::value },
+        { SkTFixed<SkFS::kUltaExpanded_Width>::value,   SkTFixed<FC_WIDTH_ULTRAEXPANDED>::value },
+    };
+    int width = map_ranges(style.width(), widthRanges, SK_ARRAY_COUNT(widthRanges));
+
+    FcPatternAddInteger(pattern, FC_WEIGHT, weight);
+    FcPatternAddInteger(pattern, FC_WIDTH, width);
+    FcPatternAddInteger(pattern, FC_SLANT, style.isItalic() ? FC_SLANT_ITALIC : FC_SLANT_ROMAN);
+}
+
+SkFontStyle GetFontStyle(FcPattern* font) {
+    return skfontstyle_from_fcpattern(font);
+}
+#endif
 
 }  // anonymous namespace
 
@@ -417,11 +549,19 @@
   return match;
 }
 
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
 bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[],
                                                   SkTypeface::Style style,
                                                   FontIdentity* outIdentity,
                                                   SkString* outFamilyName,
                                                   SkTypeface::Style* outStyle) {
+#else
+bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[],
+                                                  SkFontStyle style,
+                                                  FontIdentity* outIdentity,
+                                                  SkString* outFamilyName,
+                                                  SkFontStyle* outStyle) {
+#endif
     SkString familyStr(familyName ? familyName : "");
     if (familyStr.size() > kMaxFontFamilyLength) {
         return false;
@@ -434,12 +574,17 @@
     if (familyName) {
         FcPatternAddString(pattern, FC_FAMILY, (FcChar8*)familyName);
     }
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
     FcPatternAddInteger(pattern, FC_WEIGHT,
                         (style & SkTypeface::kBold) ? FC_WEIGHT_BOLD
                                                     : FC_WEIGHT_NORMAL);
     FcPatternAddInteger(pattern, FC_SLANT,
                         (style & SkTypeface::kItalic) ? FC_SLANT_ITALIC
                                                       : FC_SLANT_ROMAN);
+#else
+    fcpattern_from_skfontstyle(style, pattern);
+#endif
+
     FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
 
     FcConfigSubstitute(nullptr, pattern, FcMatchPattern);
diff --git a/src/ports/SkFontConfigInterface_direct.h b/src/ports/SkFontConfigInterface_direct.h
index a048aed..22dd9f1 100644
--- a/src/ports/SkFontConfigInterface_direct.h
+++ b/src/ports/SkFontConfigInterface_direct.h
@@ -17,11 +17,20 @@
     SkFontConfigInterfaceDirect();
     ~SkFontConfigInterfaceDirect() override;
 
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
     bool matchFamilyName(const char familyName[],
                          SkTypeface::Style requested,
                          FontIdentity* outFontIdentifier,
                          SkString* outFamilyName,
                          SkTypeface::Style* outStyle) override;
+#else
+    bool matchFamilyName(const char familyName[],
+                         SkFontStyle requested,
+                         FontIdentity* outFontIdentifier,
+                         SkString* outFamilyName,
+                         SkFontStyle* outStyle) override;
+
+#endif
     SkStreamAsset* openStream(const FontIdentity&) override;
 
     // new APIs
diff --git a/src/ports/SkFontConfigTypeface.h b/src/ports/SkFontConfigTypeface.h
index a6dc6ca..68a36e3 100644
--- a/src/ports/SkFontConfigTypeface.h
+++ b/src/ports/SkFontConfigTypeface.h
@@ -39,7 +39,11 @@
         return fFamilyName.equals(name);
     }
 
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
     static SkTypeface* LegacyCreateTypeface(const char familyName[], SkTypeface::Style);
+#else
+    static SkTypeface* LegacyCreateTypeface(const char familyName[], SkFontStyle);
+#endif
 
 protected:
     FontConfigTypeface(const SkFontStyle& style,
diff --git a/src/ports/SkFontHost_fontconfig.cpp b/src/ports/SkFontHost_fontconfig.cpp
index e42929a..207aa72 100644
--- a/src/ports/SkFontHost_fontconfig.cpp
+++ b/src/ports/SkFontHost_fontconfig.cpp
@@ -166,9 +166,16 @@
     }
 };
 
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
 SkTypeface* FontConfigTypeface::LegacyCreateTypeface(const char requestedFamilyName[],
                                                      SkTypeface::Style requestedOldStyle)
 {
+    SkFontStyle requestedStyle = SkFontStyle::FromOldStyle(requestedOldStyle);
+#else
+SkTypeface* FontConfigTypeface::LegacyCreateTypeface(const char requestedFamilyName[],
+                                                     SkFontStyle requestedStyle)
+{
+#endif
     SkAutoTUnref<SkFontConfigInterface> fci(RefFCI());
     if (nullptr == fci.get()) {
         return nullptr;
@@ -176,7 +183,6 @@
 
     // Check if this request is already in the request cache.
     using Request = SkFontHostRequestCache::Request;
-    SkFontStyle requestedStyle(requestedOldStyle);
     SkAutoTDelete<Request> request(Request::Create(requestedFamilyName, requestedStyle));
     SkTypeface* face = SkFontHostRequestCache::FindAndRef(request);
     if (face) {
@@ -185,9 +191,14 @@
 
     SkFontConfigInterface::FontIdentity identity;
     SkString outFamilyName;
-    SkTypeface::Style outOldStyle;
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
+    SkTypeface::Style outStyle;
     if (!fci->matchFamilyName(requestedFamilyName, requestedOldStyle,
-                              &identity, &outFamilyName, &outOldStyle))
+#else
+    SkFontStyle outStyle;
+    if (!fci->matchFamilyName(requestedFamilyName, requestedStyle,
+#endif
+                              &identity, &outFamilyName, &outStyle))
     {
         return nullptr;
     }
@@ -195,9 +206,15 @@
     // Check if a typeface with this FontIdentity is already in the FontIdentity cache.
     face = SkTypefaceCache::FindByProcAndRef(find_by_FontIdentity, &identity);
     if (!face) {
-        face = FontConfigTypeface::Create(SkFontStyle(outOldStyle), identity, outFamilyName);
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
+        face = FontConfigTypeface::Create(SkFontStyle::FromOldStyle(outStyle), identity, outFamilyName);
         // Add this FontIdentity to the FontIdentity cache.
-        SkTypefaceCache::Add(face, SkFontStyle(outOldStyle));
+        SkTypefaceCache::Add(face, SkFontStyle::FromOldStyle(outStyle));
+#else
+        face = FontConfigTypeface::Create(outStyle, identity, outFamilyName);
+        // Add this FontIdentity to the FontIdentity cache.
+        SkTypefaceCache::Add(face, outStyle);
+#endif
     }
     // Add this request to the request cache.
     SkFontHostRequestCache::Add(face, request.release());
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index 8d4a3f8..70693ee 100644
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -420,22 +420,6 @@
                        : SkFontStyle::kUpright_Slant);
 }
 
-static SkTypeface::Style computeStyleBits(CTFontRef font, bool* isFixedPitch) {
-    unsigned style = SkTypeface::kNormal;
-    CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(font);
-
-    if (traits & kCTFontBoldTrait) {
-        style |= SkTypeface::kBold;
-    }
-    if (traits & kCTFontItalicTrait) {
-        style |= SkTypeface::kItalic;
-    }
-    if (isFixedPitch) {
-        *isFixedPitch = (traits & kCTFontMonoSpaceTrait) != 0;
-    }
-    return (SkTypeface::Style)style;
-}
-
 #define WEIGHT_THRESHOLD    ((SkFontStyle::kNormal_Weight + SkFontStyle::kBold_Weight)/2)
 
 // kCTFontColorGlyphsTrait was added in the Mac 10.7 and iPhone 4.3 SDKs.
@@ -493,9 +477,12 @@
 /** Creates a typeface without searching the cache. Takes ownership of the CTFontRef. */
 static SkTypeface* NewFromFontRef(CTFontRef fontRef, CFTypeRef resourceRef, bool isLocalStream) {
     SkASSERT(fontRef);
-    bool isFixedPitch;
-    SkFontStyle style = SkFontStyle(computeStyleBits(fontRef, &isFixedPitch));
 
+    AutoCFRelease<CTFontDescriptorRef> desc(CTFontCopyFontDescriptor(fontRef));
+    SkFontStyle style = fontstyle_from_descriptor(desc);
+
+    CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(fontRef);
+    bool isFixedPitch = SkToBool(traits & kCTFontMonoSpaceTrait);
     return new SkTypeface_Mac(fontRef, resourceRef, style, isFixedPitch, isLocalStream);
 }
 
@@ -2572,10 +2559,12 @@
         return create_from_dataProvider(pr);
     }
 
-    virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
-                                               unsigned styleBits) const override {
-
-        SkFontStyle style = SkFontStyle((SkTypeface::Style)styleBits);
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
+    SkTypeface* onLegacyCreateTypeface(const char familyName[], unsigned styleBits) const override {
+        SkFontStyle style = SkFontStyle::FromOldStyle(styleBits);
+#else
+    SkTypeface* onLegacyCreateTypeface(const char familyName[], SkFontStyle style) const override {
+#endif
         if (familyName) {
             familyName = map_css_names(familyName);
         }
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index 395307c..9ded4f5 100644
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -2501,8 +2501,12 @@
         return this->createFromStream(SkStream::NewFromFile(path));
     }
 
-    virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
-                                               unsigned styleBits) const override {
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
+    SkTypeface* onLegacyCreateTypeface(const char familyName[], unsigned styleBits) const override {
+        SkFontStyle style = SkFontStyle::FromOldStyle(styleBits);
+#else
+    SkTypeface* onLegacyCreateTypeface(const char familyName[], SkFontStyle style) const override {
+#endif
         LOGFONT lf;
         if (nullptr == familyName) {
             lf = get_default_font();
@@ -2510,9 +2514,8 @@
             logfont_for_name(familyName, &lf);
         }
 
-        SkTypeface::Style style = (SkTypeface::Style)styleBits;
-        lf.lfWeight = (style & SkTypeface::kBold) != 0 ? FW_BOLD : FW_NORMAL;
-        lf.lfItalic = ((style & SkTypeface::kItalic) != 0);
+        lf.lfWeight = style.weight();
+        lf.lfItalic = style.isItalic() ? TRUE : FALSE;
         return SkCreateTypefaceFromLOGFONT(lf);
     }
 
diff --git a/src/ports/SkFontMgr_android.cpp b/src/ports/SkFontMgr_android.cpp
index ead0bf0..741d6cc 100644
--- a/src/ports/SkFontMgr_android.cpp
+++ b/src/ports/SkFontMgr_android.cpp
@@ -487,11 +487,12 @@
         return new SkTypeface_AndroidStream(data, style, isFixedPitch, name);
     }
 
-
-    virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
-                                               unsigned styleBits) const override {
-        SkFontStyle style = SkFontStyle(styleBits);
-
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
+    SkTypeface* onLegacyCreateTypeface(const char familyName[], unsigned styleBits) const override {
+        SkFontStyle style = SkFontStyle::FromOldStyle(styleBits);
+#else
+    SkTypeface* onLegacyCreateTypeface(const char familyName[], SkFontStyle style) const override {
+#endif
         if (familyName) {
             // On Android, we must return nullptr when we can't find the requested
             // named typeface so that the system/app can provide their own recovery
diff --git a/src/ports/SkFontMgr_custom.cpp b/src/ports/SkFontMgr_custom.cpp
index c77fe39..6749ced 100644
--- a/src/ports/SkFontMgr_custom.cpp
+++ b/src/ports/SkFontMgr_custom.cpp
@@ -308,15 +308,12 @@
         return stream.get() ? this->createFromStream(stream.release(), ttcIndex) : nullptr;
     }
 
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
     SkTypeface* onLegacyCreateTypeface(const char familyName[], unsigned styleBits) const override {
-        SkTypeface::Style oldStyle = (SkTypeface::Style)styleBits;
-        SkFontStyle style = SkFontStyle(oldStyle & SkTypeface::kBold
-                                                 ? SkFontStyle::kBold_Weight
-                                                 : SkFontStyle::kNormal_Weight,
-                                        SkFontStyle::kNormal_Width,
-                                        oldStyle & SkTypeface::kItalic
-                                                 ? SkFontStyle::kItalic_Slant
-                                                 : SkFontStyle::kUpright_Slant);
+        SkFontStyle style = SkFontStyle::FromOldStyle(styleBits);
+#else
+    SkTypeface* onLegacyCreateTypeface(const char familyName[], SkFontStyle style) const override {
+#endif
         SkTypeface* tf = nullptr;
 
         if (familyName) {
diff --git a/src/ports/SkFontMgr_fontconfig.cpp b/src/ports/SkFontMgr_fontconfig.cpp
index 089be5c..c8b055f 100644
--- a/src/ports/SkFontMgr_fontconfig.cpp
+++ b/src/ports/SkFontMgr_fontconfig.cpp
@@ -264,10 +264,6 @@
     return new_min + SkMulDiv(value - old_min, new_max - new_min, old_max - old_min);
 }
 
-static int ave(SkFixed a, SkFixed b) {
-    return SkFixedAve(a, b);
-}
-
 struct MapRanges {
     SkFixed old_val;
     SkFixed new_val;
@@ -279,15 +275,11 @@
         return ranges[0].new_val;
     }
 
-    // Linear from [i] to ave([i], [i+1]), then from ave([i], [i+1]) to [i+1]
+    // Linear from [i] to [i+1]
     for (int i = 0; i < rangesCount - 1; ++i) {
-        if (val < ave(ranges[i].old_val, ranges[i+1].old_val)) {
-            return map_range(val, ranges[i].old_val, ave(ranges[i].old_val, ranges[i+1].old_val),
-                                  ranges[i].new_val, ave(ranges[i].new_val, ranges[i+1].new_val));
-        }
         if (val < ranges[i+1].old_val) {
-            return map_range(val, ave(ranges[i].old_val, ranges[i+1].old_val), ranges[i+1].old_val,
-                                  ave(ranges[i].new_val, ranges[i+1].new_val), ranges[i+1].new_val);
+            return map_range(val, ranges[i].old_val, ranges[i+1].old_val,
+                                  ranges[i].new_val, ranges[i+1].new_val);
         }
     }
 
@@ -882,15 +874,12 @@
         return new SkTypeface_stream(fontData, style, isFixedWidth);
     }
 
-    virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
-                                               unsigned styleBits) const override {
-        bool bold = styleBits & SkTypeface::kBold;
-        bool italic = styleBits & SkTypeface::kItalic;
-        SkFontStyle style = SkFontStyle(bold ? SkFontStyle::kBold_Weight
-                                             : SkFontStyle::kNormal_Weight,
-                                        SkFontStyle::kNormal_Width,
-                                        italic ? SkFontStyle::kItalic_Slant
-                                               : SkFontStyle::kUpright_Slant);
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
+    SkTypeface* onLegacyCreateTypeface(const char familyName[], unsigned styleBits) const override {
+        SkFontStyle style = SkFontStyle::FromOldStyle(styleBits);
+#else
+    SkTypeface* onLegacyCreateTypeface(const char familyName[], SkFontStyle style) const override {
+#endif
         SkAutoTUnref<SkTypeface> typeface(this->matchFamilyStyle(familyName, style));
         if (typeface.get()) {
             return typeface.release();
diff --git a/src/ports/SkFontMgr_win_dw.cpp b/src/ports/SkFontMgr_win_dw.cpp
index 11afec3..788bb5e 100644
--- a/src/ports/SkFontMgr_win_dw.cpp
+++ b/src/ports/SkFontMgr_win_dw.cpp
@@ -284,18 +284,21 @@
     void onGetFamilyName(int index, SkString* familyName) const override;
     SkFontStyleSet* onCreateStyleSet(int index) const override;
     SkFontStyleSet* onMatchFamily(const char familyName[]) const override;
-    virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
-                                           const SkFontStyle& fontstyle) const override;
-    virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
-                                                    const char* bcp47[], int bcp47Count,
-                                                    SkUnichar character) const override;
-    virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
-                                         const SkFontStyle& fontstyle) const override;
+    SkTypeface* onMatchFamilyStyle(const char familyName[],
+                                   const SkFontStyle& fontstyle) const override;
+    SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle&,
+                                            const char* bcp47[], int bcp47Count,
+                                            SkUnichar character) const override;
+    SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
+                                 const SkFontStyle& fontstyle) const override;
     SkTypeface* onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const override;
     SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const override;
     SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override;
-    virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
-                                               unsigned styleBits) const override;
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
+    SkTypeface* onLegacyCreateTypeface(const char familyName[], unsigned styleBits) const override;
+#else
+    SkTypeface* onLegacyCreateTypeface(const char familyName[], SkFontStyle) const override;
+#endif
 
 private:
     HRESULT getByFamilyName(const WCHAR familyName[], IDWriteFontFamily** fontFamily) const;
@@ -950,8 +953,14 @@
     return S_OK;
 }
 
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
 SkTypeface* SkFontMgr_DirectWrite::onLegacyCreateTypeface(const char familyName[],
                                                           unsigned styleBits) const {
+    SkFontStyle style = SkFontStyle::FromOldStyle(styleBits);
+#else
+SkTypeface* SkFontMgr_DirectWrite::onLegacyCreateTypeface(const char familyName[],
+                                                          SkFontStyle style) const {
+#endif
     SkTScopedComPtr<IDWriteFontFamily> fontFamily;
     if (familyName) {
         SkSMallocWCHAR wideFamilyName;
@@ -972,13 +981,10 @@
     }
 
     SkTScopedComPtr<IDWriteFont> font;
-    DWRITE_FONT_WEIGHT weight = (styleBits & SkTypeface::kBold)
-                              ? DWRITE_FONT_WEIGHT_BOLD
-                              : DWRITE_FONT_WEIGHT_NORMAL;
-    DWRITE_FONT_STRETCH stretch = DWRITE_FONT_STRETCH_NORMAL;
-    DWRITE_FONT_STYLE italic = (styleBits & SkTypeface::kItalic)
-                             ? DWRITE_FONT_STYLE_ITALIC
-                             : DWRITE_FONT_STYLE_NORMAL;
+    DWRITE_FONT_WEIGHT weight = (DWRITE_FONT_WEIGHT)style.weight();
+    DWRITE_FONT_STRETCH stretch = (DWRITE_FONT_STRETCH)style.width();
+    DWRITE_FONT_STYLE italic = style.isItalic() ? DWRITE_FONT_STYLE_ITALIC
+                                                : DWRITE_FONT_STYLE_NORMAL;
     HRNM(fontFamily->GetFirstMatchingFont(weight, stretch, italic, &font),
          "Could not get matching font.");
 
diff --git a/tools/sk_tool_utils_font.cpp b/tools/sk_tool_utils_font.cpp
index 0f8c96f..df47926 100644
--- a/tools/sk_tool_utils_font.cpp
+++ b/tools/sk_tool_utils_font.cpp
@@ -47,7 +47,11 @@
             // If we called SkTypeface::CreateFromName() here we'd recurse infinitely,
             // so we reimplement its core logic here inline without the recursive aspect.
             SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
+#ifdef SK_VERY_LEGACY_CREATE_TYPEFACE
             return fm->legacyCreateTypeface(name, style);
+#else
+            return fm->legacyCreateTypeface(name, SkFontStyle::FromOldStyle(style));
+#endif
         }
     } else {
         sub = &gSubFonts[gDefaultFontIndex];
@@ -65,7 +69,7 @@
             fontData->fFontCache = SkSafeRef(font);
         }
     }
-    return new SkTestTypeface(font, SkFontStyle(style));
+    return new SkTestTypeface(font, SkFontStyle::FromOldStyle(style));
 }
 
 }