Replace SkTypeface::Style with SkFontStyle.

Review URL: https://codereview.chromium.org/488143002
diff --git a/gyp/core.gypi b/gyp/core.gypi
index 5e81116..4f9379f 100644
--- a/gyp/core.gypi
+++ b/gyp/core.gypi
@@ -248,6 +248,7 @@
         '<(skia_include_path)/core/SkFloatBits.h',
         '<(skia_include_path)/core/SkFloatingPoint.h',
         '<(skia_include_path)/core/SkFontHost.h',
+        '<(skia_include_path)/core/SkFontStyle.h',
         '<(skia_include_path)/core/SkGraphics.h',
         '<(skia_include_path)/core/SkImage.h',
         '<(skia_include_path)/core/SkImageDecoder.h',
diff --git a/gyp/ports.gyp b/gyp/ports.gyp
index 268f6fd..78d59df 100644
--- a/gyp/ports.gyp
+++ b/gyp/ports.gyp
@@ -60,7 +60,6 @@
         '../include/ports/SkFontConfigInterface.h',
         '../include/ports/SkFontMgr.h',
         '../include/ports/SkFontMgr_indirect.h',
-        '../include/ports/SkFontStyle.h',
         '../include/ports/SkRemotableFontMgr.h',
       ],
       'conditions': [
diff --git a/include/ports/SkFontStyle.h b/include/core/SkFontStyle.h
similarity index 92%
rename from include/ports/SkFontStyle.h
rename to include/core/SkFontStyle.h
index 9d9a912..f42d7dd 100644
--- a/include/ports/SkFontStyle.h
+++ b/include/core/SkFontStyle.h
@@ -43,6 +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);
 
     bool operator==(const SkFontStyle& rhs) const {
         return fUnion.fU32 == rhs.fUnion.fU32;
diff --git a/include/core/SkTypeface.h b/include/core/SkTypeface.h
index a080d84..f7af5d2 100644
--- a/include/core/SkTypeface.h
+++ b/include/core/SkTypeface.h
@@ -11,6 +11,7 @@
 #define SkTypeface_DEFINED
 
 #include "SkAdvancedTypefaceMetrics.h"
+#include "SkFontStyle.h"
 #include "SkWeakRefCnt.h"
 
 class SkDescriptor;
@@ -49,17 +50,25 @@
         kBoldItalic = 0x03
     };
 
-    /** Returns the typeface's intrinsic style attributes
-    */
-    Style style() const { return fStyle; }
+    /** Returns the typeface's intrinsic style attributes. */
+    SkFontStyle fontStyle() const {
+        return fStyle;
+    }
 
-    /** Returns true if getStyle() has the kBold bit set.
-    */
-    bool isBold() const { return (fStyle & kBold) != 0; }
+    /** Returns the typeface's intrinsic style attributes. 
+     *  @deprecated use fontStyle() instead.
+     */
+    Style style() const {
+        return static_cast<Style>(
+            (fStyle.weight() >= SkFontStyle::kSemiBold_Weight ? kBold : kNormal) |
+            (fStyle.slant()  != SkFontStyle::kUpright_Slant ? kItalic : kNormal));
+    }
 
-    /** Returns true if getStyle() has the kItalic bit set.
-    */
-    bool isItalic() const { return (fStyle & kItalic) != 0; }
+    /** Returns true if style() has the kBold bit set. */
+    bool isBold() const { return fStyle.weight() >= SkFontStyle::kSemiBold_Weight; }
+
+    /** Returns true if style() has the kItalic bit set. */
+    bool isItalic() const { return fStyle.slant() != SkFontStyle::kUpright_Slant; }
 
     /** Returns true if the typeface claims to be fixed-pitch.
      *  This is a style bit, advance widths may vary even if this returns true.
@@ -285,7 +294,7 @@
 protected:
     /** uniqueID must be unique and non-zero
     */
-    SkTypeface(Style style, SkFontID uniqueID, bool isFixedPitch = false);
+    SkTypeface(const SkFontStyle& style, SkFontID uniqueID, bool isFixedPitch = false);
     virtual ~SkTypeface();
 
     /** Sets the fixedPitch bit. If used, must be called in the constructor. */
@@ -351,7 +360,7 @@
     static void        DeleteDefault(SkTypeface*);
 
     SkFontID    fUniqueID;
-    Style       fStyle;
+    SkFontStyle fStyle;
     bool        fIsFixedPitch;
 
     friend class SkPaint;
diff --git a/src/core/SkFontHost.cpp b/src/core/SkFontHost.cpp
index ce73491..77b80e8 100644
--- a/src/core/SkFontHost.cpp
+++ b/src/core/SkFontHost.cpp
@@ -67,6 +67,15 @@
     fUnion.fR.fSlant = SkPin32(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;
+}
+
 #include "SkFontMgr.h"
 
 class SkEmptyFontStyleSet : public SkFontStyleSet {
diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp
index 81038bc..84cbdbf 100644
--- a/src/core/SkTypeface.cpp
+++ b/src/core/SkTypeface.cpp
@@ -14,26 +14,10 @@
 #include "SkStream.h"
 #include "SkTypeface.h"
 
-//#define TRACE_LIFECYCLE
+SkTypeface::SkTypeface(const SkFontStyle& style, SkFontID fontID, bool isFixedPitch)
+    : fUniqueID(fontID), fStyle(style), fIsFixedPitch(isFixedPitch) { }
 
-#ifdef TRACE_LIFECYCLE
-    static int32_t gTypefaceCounter;
-#endif
-
-SkTypeface::SkTypeface(Style style, SkFontID fontID, bool isFixedPitch)
-    : fUniqueID(fontID), fStyle(style), fIsFixedPitch(isFixedPitch) {
-#ifdef TRACE_LIFECYCLE
-    SkDebugf("SkTypeface: create  %p fontID %d total %d\n",
-             this, fontID, ++gTypefaceCounter);
-#endif
-}
-
-SkTypeface::~SkTypeface() {
-#ifdef TRACE_LIFECYCLE
-    SkDebugf("SkTypeface: destroy %p fontID %d total %d\n",
-             this, fUniqueID, --gTypefaceCounter);
-#endif
-}
+SkTypeface::~SkTypeface() { }
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -43,7 +27,7 @@
         return SkNEW(SkEmptyTypeface);
     }
 protected:
-    SkEmptyTypeface() : SkTypeface(SkTypeface::kNormal, 0, true) { }
+    SkEmptyTypeface() : SkTypeface(SkFontStyle(), 0, true) { }
 
     virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE { return NULL; }
     virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK_OVERRIDE {
diff --git a/src/core/SkTypefaceCache.cpp b/src/core/SkTypefaceCache.cpp
index f864e1c..cfa301e 100644
--- a/src/core/SkTypefaceCache.cpp
+++ b/src/core/SkTypefaceCache.cpp
@@ -29,7 +29,7 @@
 }
 
 void SkTypefaceCache::add(SkTypeface* face,
-                          SkTypeface::Style requestedStyle,
+                          const SkFontStyle& requestedStyle,
                           bool strong) {
     if (fArray.count() >= TYPEFACE_CACHE_LIMIT) {
         this->purge(TYPEFACE_CACHE_LIMIT >> 2);
@@ -120,7 +120,7 @@
 SK_DECLARE_STATIC_MUTEX(gMutex);
 
 void SkTypefaceCache::Add(SkTypeface* face,
-                          SkTypeface::Style requestedStyle,
+                          const SkFontStyle& requestedStyle,
                           bool strong) {
     SkAutoMutexAcquire ama(gMutex);
     Get().add(face, requestedStyle, strong);
@@ -145,9 +145,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 #ifdef SK_DEBUG
-static bool DumpProc(SkTypeface* face, SkTypeface::Style style, void* ctx) {
-    SkDebugf("SkTypefaceCache: face %p fontID %d style %d refcnt %d\n",
-             face, face->uniqueID(), style, face->getRefCnt());
+static bool DumpProc(SkTypeface* face, const SkFontStyle& s, void* ctx) {
+    SkDebugf("SkTypefaceCache: face %p fontID %d weight %d width %d style %d refcnt %d\n",
+             face, face->uniqueID(), s.weight(), s.width(), s.slant(), face->getRefCnt());
     return false;
 }
 #endif
diff --git a/src/core/SkTypefaceCache.h b/src/core/SkTypefaceCache.h
index ae37ab7..ba851ee 100644
--- a/src/core/SkTypefaceCache.h
+++ b/src/core/SkTypefaceCache.h
@@ -31,7 +31,7 @@
      * for the given context. The passed typeface is owned by the cache and is
      * not additionally ref()ed. The typeface may be in the disposed state.
      */
-    typedef bool (*FindProc)(SkTypeface*, SkTypeface::Style, void* context);
+    typedef bool(*FindProc)(SkTypeface*, const SkFontStyle&, void* context);
 
     /**
      *  Add a typeface to the cache. This ref()s the typeface, so that the
@@ -39,7 +39,7 @@
      *  whose refcnt is 1 (meaning only the cache is an owner) will be
      *  unref()ed.
      */
-    void add(SkTypeface*, SkTypeface::Style requested, bool strong = true);
+    void add(SkTypeface*, const SkFontStyle& requested, bool strong = true);
 
     /**
      *  Search the cache for a typeface with the specified fontID (uniqueID).
@@ -73,7 +73,7 @@
     // These are static wrappers around a global instance of a cache.
 
     static void Add(SkTypeface*,
-                    SkTypeface::Style requested,
+                    const SkFontStyle& requested,
                     bool strong = true);
     static SkTypeface* FindByID(SkFontID fontID);
     static SkTypeface* FindByProcAndRef(FindProc proc, void* ctx);
@@ -90,9 +90,9 @@
     void purge(int count);
 
     struct Rec {
-        SkTypeface*         fFace;
-        bool                fStrong;
-        SkTypeface::Style   fRequestedStyle;
+        SkTypeface* fFace;
+        bool fStrong;
+        SkFontStyle fRequestedStyle;
     };
     SkTDArray<Rec> fArray;
 };
diff --git a/src/fonts/SkFontMgr_fontconfig.cpp b/src/fonts/SkFontMgr_fontconfig.cpp
index a7f8128..c56e065 100644
--- a/src/fonts/SkFontMgr_fontconfig.cpp
+++ b/src/fonts/SkFontMgr_fontconfig.cpp
@@ -300,7 +300,7 @@
         }
 
         // TODO should the caller give us the style or should we get it from freetype?
-        SkTypeface::Style style = SkTypeface::kNormal;
+        SkFontStyle style;
         bool isFixedWidth = false;
         if (!SkTypeface_FreeType::ScanFont(stream, 0, NULL, &style, &isFixedWidth)) {
             return NULL;
diff --git a/src/fonts/SkGScalerContext.cpp b/src/fonts/SkGScalerContext.cpp
index 34a788a..cacc270 100644
--- a/src/fonts/SkGScalerContext.cpp
+++ b/src/fonts/SkGScalerContext.cpp
@@ -158,7 +158,7 @@
 #include "SkTypefaceCache.h"
 
 SkGTypeface::SkGTypeface(SkTypeface* proxy, const SkPaint& paint)
-    : SkTypeface(proxy->style(), SkTypefaceCache::NewFontID(), false)
+    : SkTypeface(proxy->fontStyle(), SkTypefaceCache::NewFontID(), false)
     , fProxy(SkRef(proxy))
     , fPaint(paint) {}
 
diff --git a/src/fonts/SkTestScalerContext.cpp b/src/fonts/SkTestScalerContext.cpp
index ee379f0..b148375 100644
--- a/src/fonts/SkTestScalerContext.cpp
+++ b/src/fonts/SkTestScalerContext.cpp
@@ -110,8 +110,8 @@
         fPaths[index] = path;
     }
 }
-    
-SkTestTypeface::SkTestTypeface(SkTestFont* testFont, SkTypeface::Style style)
+
+SkTestTypeface::SkTestTypeface(SkTestFont* testFont, const SkFontStyle& style)
     : SkTypeface(style, SkTypefaceCache::NewFontID(), false)
     , fTestFont(testFont) {
 }
diff --git a/src/fonts/SkTestScalerContext.h b/src/fonts/SkTestScalerContext.h
index 42f6049..3e6dc97 100644
--- a/src/fonts/SkTestScalerContext.h
+++ b/src/fonts/SkTestScalerContext.h
@@ -57,7 +57,7 @@
 
 class SkTestTypeface : public SkTypeface {
 public:
-    SkTestTypeface(SkTestFont* , SkTypeface::Style style);
+    SkTestTypeface(SkTestFont*, const SkFontStyle& style);
     virtual ~SkTestTypeface() {
         SkSafeUnref(fTestFont);
     }
diff --git a/src/ports/SkFontConfigTypeface.h b/src/ports/SkFontConfigTypeface.h
index f62d99d..c7d8e26 100644
--- a/src/ports/SkFontConfigTypeface.h
+++ b/src/ports/SkFontConfigTypeface.h
@@ -18,13 +18,14 @@
     SkStream* fLocalStream;
 
 public:
-    static FontConfigTypeface* Create(Style style,
+    static FontConfigTypeface* Create(const SkFontStyle& style,
                                       const SkFontConfigInterface::FontIdentity& fi,
                                       const SkString& familyName) {
         return SkNEW_ARGS(FontConfigTypeface, (style, fi, familyName));
     }
 
-    static FontConfigTypeface* Create(Style style, bool fixedWidth, SkStream* localStream) {
+    static FontConfigTypeface* Create(const SkFontStyle& style, bool fixedWidth,
+                                      SkStream* localStream) {
         return SkNEW_ARGS(FontConfigTypeface, (style, fixedWidth, localStream));
     }
 
@@ -50,7 +51,7 @@
 protected:
     friend class SkFontHost;    // hack until we can make public versions
 
-    FontConfigTypeface(Style style,
+    FontConfigTypeface(const SkFontStyle& style,
                        const SkFontConfigInterface::FontIdentity& fi,
                        const SkString& familyName)
             : INHERITED(style, SkTypefaceCache::NewFontID(), false)
@@ -58,7 +59,7 @@
             , fFamilyName(familyName)
             , fLocalStream(NULL) {}
 
-    FontConfigTypeface(Style style, bool fixedWidth, SkStream* localStream)
+    FontConfigTypeface(const SkFontStyle& style, bool fixedWidth, SkStream* localStream)
             : INHERITED(style, SkTypefaceCache::NewFontID(), fixedWidth) {
         // we default to empty fFamilyName and fIdentity
         fLocalStream = localStream;
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index 85f8ab9..f3a87e5 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -1669,8 +1669,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
+#include "SkTSearch.h"
 /*static*/ bool SkTypeface_FreeType::ScanFont(
-    SkStream* stream, int ttcIndex, SkString* name, SkTypeface::Style* style, bool* isFixedPitch)
+    SkStream* stream, int ttcIndex, SkString* name, SkFontStyle* style, bool* isFixedPitch)
 {
     FT_Library  library;
     if (FT_Init_FreeType(&library)) {
@@ -1704,19 +1705,61 @@
         return false;
     }
 
-    int tempStyle = SkTypeface::kNormal;
+    int weight = SkFontStyle::kNormal_Weight;
+    int width = SkFontStyle::kNormal_Width;
+    SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant;
     if (face->style_flags & FT_STYLE_FLAG_BOLD) {
-        tempStyle |= SkTypeface::kBold;
+        weight = SkFontStyle::kBold_Weight;
     }
     if (face->style_flags & FT_STYLE_FLAG_ITALIC) {
-        tempStyle |= SkTypeface::kItalic;
+        slant = SkFontStyle::kItalic_Slant;
+    }
+
+    PS_FontInfoRec psFontInfo;
+    TT_OS2* os2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(face, ft_sfnt_os2));
+    if (os2 && os2->version != 0xffff) {
+        weight = os2->usWeightClass;
+        width = os2->usWidthClass;
+    } else if (0 == FT_Get_PS_Font_Info(face, &psFontInfo) && psFontInfo.weight) {
+        static const struct {
+            char const * const name;
+            int const weight;
+        } commonWeights [] = {
+            // There are probably more common names, but these are known to exist.
+            { "black", SkFontStyle::kBlack_Weight },
+            { "bold", SkFontStyle::kBold_Weight },
+            { "book", (SkFontStyle::kNormal_Weight + SkFontStyle::kLight_Weight)/2 },
+            { "demi", SkFontStyle::kSemiBold_Weight },
+            { "demibold", SkFontStyle::kSemiBold_Weight },
+            { "extrabold", SkFontStyle::kExtraBold_Weight },
+            { "extralight", SkFontStyle::kExtraLight_Weight },
+            { "heavy", SkFontStyle::kBlack_Weight },
+            { "light", SkFontStyle::kLight_Weight },
+            { "medium", SkFontStyle::kMedium_Weight },
+            { "normal", SkFontStyle::kNormal_Weight },
+            { "regular", SkFontStyle::kNormal_Weight },
+            { "semibold", SkFontStyle::kSemiBold_Weight },
+            { "thin", SkFontStyle::kThin_Weight },
+            { "ultra", SkFontStyle::kExtraBold_Weight },
+            { "ultrablack", 1000 },
+            { "ultrabold", SkFontStyle::kExtraBold_Weight },
+            { "ultraheavy", 1000 },
+            { "ultralight", SkFontStyle::kExtraLight_Weight },
+        };
+        int const index = SkStrLCSearch(&commonWeights[0].name, SK_ARRAY_COUNT(commonWeights),
+                                        psFontInfo.weight, sizeof(commonWeights));
+        if (index >= 0) {
+            weight = commonWeights[index].weight;
+        } else {
+            SkDEBUGF(("Do not know weight for: %s\n", psFontInfo.weight));
+        }
     }
 
     if (name) {
         name->set(face->family_name);
     }
     if (style) {
-        *style = (SkTypeface::Style) tempStyle;
+        *style = SkFontStyle(weight, width, slant);
     }
     if (isFixedPitch) {
         *isFixedPitch = FT_IS_FIXED_WIDTH(face);
diff --git a/src/ports/SkFontHost_FreeType_common.h b/src/ports/SkFontHost_FreeType_common.h
index f093dba..79e6d65 100644
--- a/src/ports/SkFontHost_FreeType_common.h
+++ b/src/ports/SkFontHost_FreeType_common.h
@@ -49,10 +49,10 @@
      *  name and style from a stream, using FreeType's API.
      */
     static bool ScanFont(SkStream* stream, int ttcIndex,
-                         SkString* name, SkTypeface::Style* style, bool* isFixedPitch);
+                         SkString* name, SkFontStyle* style, bool* isFixedPitch);
 
 protected:
-    SkTypeface_FreeType(Style style, SkFontID uniqueID, bool isFixedPitch)
+    SkTypeface_FreeType(const SkFontStyle& style, SkFontID uniqueID, bool isFixedPitch)
         : INHERITED(style, uniqueID, isFixedPitch)
         , fGlyphCount(-1)
     {}
diff --git a/src/ports/SkFontHost_fontconfig.cpp b/src/ports/SkFontHost_fontconfig.cpp
index b3a893e..32e9f80 100644
--- a/src/ports/SkFontHost_fontconfig.cpp
+++ b/src/ports/SkFontHost_fontconfig.cpp
@@ -60,19 +60,20 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 struct FindRec {
-    FindRec(const char* name, SkTypeface::Style style)
+    FindRec(const char* name, const SkFontStyle& style)
         : fFamilyName(name)  // don't need to make a deep copy
         , fStyle(style) {}
 
     const char* fFamilyName;
-    SkTypeface::Style fStyle;
+    SkFontStyle fStyle;
 };
 
-static bool find_proc(SkTypeface* face, SkTypeface::Style style, void* ctx) {
-    FontConfigTypeface* fci = (FontConfigTypeface*)face;
-    const FindRec* rec = (const FindRec*)ctx;
+static bool find_proc(SkTypeface* cachedTypeface, const SkFontStyle& cachedStyle, void* ctx) {
+    FontConfigTypeface* cachedFCTypeface = (FontConfigTypeface*)cachedTypeface;
+    const FindRec* rec = static_cast<const FindRec*>(ctx);
 
-    return rec->fStyle == style && fci->isFamilyName(rec->fFamilyName);
+    return rec->fStyle == cachedStyle &&
+           cachedFCTypeface->isFamilyName(rec->fFamilyName);
 }
 
 SkTypeface* FontConfigTypeface::LegacyCreateTypeface(
@@ -89,34 +90,37 @@
         familyName = fct->getFamilyName();
     }
 
-    FindRec rec(familyName, style);
+    SkFontStyle requestedStyle(style);
+    FindRec rec(familyName, requestedStyle);
     SkTypeface* face = SkTypefaceCache::FindByProcAndRef(find_proc, &rec);
     if (face) {
-//        SkDebugf("found cached face <%s> <%s> %p [%d]\n", familyName, ((FontConfigTypeface*)face)->getFamilyName(), face, face->getRefCnt());
+        //SkDebugf("found cached face <%s> <%s> %p [%d]\n",
+        //         familyName, ((FontConfigTypeface*)face)->getFamilyName(),
+        //         face, face->getRefCnt());
         return face;
     }
 
     SkFontConfigInterface::FontIdentity indentity;
-    SkString                            outFamilyName;
-    SkTypeface::Style                   outStyle;
-
-    if (!fci->matchFamilyName(familyName, style,
-                              &indentity, &outFamilyName, &outStyle)) {
+    SkString outFamilyName;
+    SkTypeface::Style outStyle;
+    if (!fci->matchFamilyName(familyName, style, &indentity, &outFamilyName, &outStyle)) {
         return NULL;
     }
 
     // check if we, in fact, already have this. perhaps fontconfig aliased the
     // requested name to some other name we actually have...
     rec.fFamilyName = outFamilyName.c_str();
-    rec.fStyle = outStyle;
+    rec.fStyle = SkFontStyle(outStyle);
     face = SkTypefaceCache::FindByProcAndRef(find_proc, &rec);
     if (face) {
         return face;
     }
 
-    face = FontConfigTypeface::Create(outStyle, indentity, outFamilyName);
-    SkTypefaceCache::Add(face, style);
-//    SkDebugf("add face <%s> <%s> %p [%d]\n", familyName, outFamilyName.c_str(), face, face->getRefCnt());
+    face = FontConfigTypeface::Create(SkFontStyle(outStyle), indentity, outFamilyName);
+    SkTypefaceCache::Add(face, requestedStyle);
+    //SkDebugf("add face <%s> <%s> %p [%d]\n",
+    //         familyName, outFamilyName.c_str(),
+    //         face, face->getRefCnt());
     return face;
 }
 
diff --git a/src/ports/SkFontHost_linux.cpp b/src/ports/SkFontHost_linux.cpp
index a4202aa..90141f9 100644
--- a/src/ports/SkFontHost_linux.cpp
+++ b/src/ports/SkFontHost_linux.cpp
@@ -30,7 +30,7 @@
 /** The base SkTypeface implementation for the custom font manager. */
 class SkTypeface_Custom : public SkTypeface_FreeType {
 public:
-    SkTypeface_Custom(Style style, bool isFixedPitch,
+    SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch,
                       bool sysFont, const SkString familyName, int index)
         : INHERITED(style, SkTypefaceCache::NewFontID(), isFixedPitch)
         , fIsSysFont(sysFont), fFamilyName(familyName), fIndex(index)
@@ -67,7 +67,7 @@
  */
 class SkTypeface_Empty : public SkTypeface_Custom {
 public:
-    SkTypeface_Empty() : INHERITED(SkTypeface::kNormal, false, true, SkString(), 0) {}
+    SkTypeface_Empty() : INHERITED(SkFontStyle(), false, true, SkString(), 0) {}
 
     virtual const char* getUniqueString() const SK_OVERRIDE { return NULL; }
 
@@ -81,9 +81,9 @@
 /** The stream SkTypeface implementation for the custom font manager. */
 class SkTypeface_Stream : public SkTypeface_Custom {
 public:
-    SkTypeface_Stream(Style style, bool isFixedPitch, bool sysFont, const SkString familyName,
-                      SkStream* stream, int ttcIndex)
-        : INHERITED(style, isFixedPitch, sysFont, familyName, ttcIndex)
+    SkTypeface_Stream(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
+                      const SkString familyName, SkStream* stream, int index)
+        : INHERITED(style, isFixedPitch, sysFont, familyName, index)
         , fStream(SkRef(stream))
     { }
 
@@ -104,8 +104,8 @@
 /** The file SkTypeface implementation for the custom font manager. */
 class SkTypeface_File : public SkTypeface_Custom {
 public:
-    SkTypeface_File(Style style, bool isFixedPitch, bool sysFont, const SkString familyName,
-                    const char path[], int index)
+    SkTypeface_File(const SkFontStyle& style, bool isFixedPitch, bool sysFont,
+                    const SkString familyName, const char path[], int index)
         : INHERITED(style, isFixedPitch, sysFont, familyName, index)
         , fPath(path)
     { }
@@ -273,7 +273,7 @@
         }
 
         bool isFixedPitch;
-        SkTypeface::Style style;
+        SkFontStyle style;
         SkString name;
         if (SkTypeface_FreeType::ScanFont(stream, ttcIndex, &name, &style, &isFixedPitch)) {
             return SkNEW_ARGS(SkTypeface_Stream, (style, isFixedPitch, false, name,
@@ -315,7 +315,7 @@
 private:
 
     static bool get_name_and_style(const char path[], SkString* name,
-                                   SkTypeface::Style* style, bool* isFixedPitch) {
+                                   SkFontStyle* style, bool* isFixedPitch) {
         SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
         if (stream.get()) {
             return SkTypeface_FreeType::ScanFont(stream, 0, name, style, isFixedPitch);
@@ -335,8 +335,7 @@
 
             bool isFixedPitch;
             SkString realname;
-            SkTypeface::Style style = SkTypeface::kNormal; // avoid uninitialized warning
-
+            SkFontStyle style = SkFontStyle(); // avoid uninitialized warning
             if (!get_name_and_style(filename.c_str(), &realname, &style, &isFixedPitch)) {
                 SkDebugf("------ can't load <%s> as a font\n", filename.c_str());
                 continue;
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index aae7464..4e57354 100755
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -6,7 +6,6 @@
  * found in the LICENSE file.
  */
 
-#include <vector>
 #ifdef SK_BUILD_FOR_MAC
 #import <ApplicationServices/ApplicationServices.h>
 #endif
@@ -352,20 +351,70 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkTypeface::Style computeStyleBits(CTFontRef font, bool* isFixedPitch) {
-    unsigned style = SkTypeface::kNormal;
-    CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(font);
+static bool find_dict_traits(CFDictionaryRef dict, CTFontSymbolicTraits* traits) {
+    CFNumberRef num;
+    return CFDictionaryGetValueIfPresent(dict, kCTFontSymbolicTrait, (const void**)&num)
+    && CFNumberIsFloatType(num)
+    && CFNumberGetValue(num, kCFNumberSInt32Type, traits);
+}
 
-    if (traits & kCTFontBoldTrait) {
-        style |= SkTypeface::kBold;
+static bool find_dict_float(CFDictionaryRef dict, CFStringRef name, float* value) {
+    CFNumberRef num;
+    return CFDictionaryGetValueIfPresent(dict, name, (const void**)&num)
+    && CFNumberIsFloatType(num)
+    && CFNumberGetValue(num, kCFNumberFloatType, value);
+}
+
+static int unit_weight_to_fontstyle(float unit) {
+    float value;
+    if (unit < 0) {
+        value = 100 + (1 + unit) * 300;
+    } else {
+        value = 400 + unit * 500;
     }
-    if (traits & kCTFontItalicTrait) {
-        style |= SkTypeface::kItalic;
+    return sk_float_round2int(value);
+}
+
+static int unit_width_to_fontstyle(float unit) {
+    float value;
+    if (unit < 0) {
+        value = 1 + (1 + unit) * 4;
+    } else {
+        value = 5 + unit * 4;
+    }
+    return sk_float_round2int(value);
+}
+
+static SkFontStyle fontstyle_from_descriptor(CTFontDescriptorRef desc, bool* isFixedPitch) {
+    AutoCFRelease<CFDictionaryRef> dict(
+            (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc, kCTFontTraitsAttribute));
+    if (NULL == dict.get()) {
+        return SkFontStyle();
+    }
+
+    CTFontSymbolicTraits traits;
+    if (!find_dict_traits(dict, &traits)) {
+        traits = 0;
     }
     if (isFixedPitch) {
-        *isFixedPitch = (traits & kCTFontMonoSpaceTrait) != 0;
+        *isFixedPitch = SkToBool(traits & kCTFontMonoSpaceTrait);
     }
-    return (SkTypeface::Style)style;
+
+    float weight, width, slant;
+    if (!find_dict_float(dict, kCTFontWeightTrait, &weight)) {
+        weight = (traits & kCTFontBoldTrait) ? 0.5f : 0;
+    }
+    if (!find_dict_float(dict, kCTFontWidthTrait, &width)) {
+        width = 0;
+    }
+    if (!find_dict_float(dict, kCTFontSlantTrait, &slant)) {
+        slant = (traits & kCTFontItalicTrait) ? 0.5f : 0;
+    }
+
+    return SkFontStyle(unit_weight_to_fontstyle(weight),
+                       unit_width_to_fontstyle(width),
+                       slant ? SkFontStyle::kItalic_Slant
+                       : SkFontStyle::kUpright_Slant);
 }
 
 static SkFontID CTFontRef_to_SkFontID(CTFontRef fontRef) {
@@ -396,48 +445,15 @@
     return id;
 }
 
-static SkFontStyle stylebits2fontstyle(SkTypeface::Style styleBits) {
-    return SkFontStyle((styleBits & SkTypeface::kBold)
-                           ? SkFontStyle::kBold_Weight
-                           : SkFontStyle::kNormal_Weight,
-                       SkFontStyle::kNormal_Width,
-                       (styleBits & SkTypeface::kItalic)
-                           ? SkFontStyle::kItalic_Slant
-                           : SkFontStyle::kUpright_Slant);
-}
-
 #define WEIGHT_THRESHOLD    ((SkFontStyle::kNormal_Weight + SkFontStyle::kBold_Weight)/2)
 
-static SkTypeface::Style fontstyle2stylebits(const SkFontStyle& fs) {
-    unsigned style = 0;
-    if (fs.width() >= WEIGHT_THRESHOLD) {
-        style |= SkTypeface::kBold;
-    }
-    if (fs.isItalic()) {
-        style |= SkTypeface::kItalic;
-    }
-    return (SkTypeface::Style)style;
-}
-
 class SkTypeface_Mac : public SkTypeface {
 public:
-    SkTypeface_Mac(SkTypeface::Style style, SkFontID fontID, bool isFixedPitch,
-                   CTFontRef fontRef, const char name[], bool isLocalStream)
-        : SkTypeface(style, fontID, isFixedPitch)
-        , fName(name)
-        , fFontRef(fontRef) // caller has already called CFRetain for us
-        , fFontStyle(stylebits2fontstyle(style))
-        , fIsLocalStream(isLocalStream)
-    {
-        SkASSERT(fontRef);
-    }
-
     SkTypeface_Mac(const SkFontStyle& fs, SkFontID fontID, bool isFixedPitch,
                    CTFontRef fontRef, const char name[], bool isLocalStream)
-        : SkTypeface(fontstyle2stylebits(fs), fontID, isFixedPitch)
+        : SkTypeface(fs, fontID, isFixedPitch)
         , fName(name)
         , fFontRef(fontRef) // caller has already called CFRetain for us
-        , fFontStyle(fs)
         , fIsLocalStream(isLocalStream)
     {
         SkASSERT(fontRef);
@@ -445,7 +461,6 @@
 
     SkString fName;
     AutoCFRelease<CTFontRef> fFontRef;
-    SkFontStyle fFontStyle;
 
 protected:
     friend class SkFontHost;    // to access our protected members for deprecated methods
@@ -476,23 +491,26 @@
 static SkTypeface* NewFromFontRef(CTFontRef fontRef, const char name[], bool isLocalStream) {
     SkASSERT(fontRef);
     bool isFixedPitch;
-    SkTypeface::Style style = computeStyleBits(fontRef, &isFixedPitch);
+    AutoCFRelease<CTFontDescriptorRef> desc(CTFontCopyFontDescriptor(fontRef));
+    SkFontStyle style = fontstyle_from_descriptor(desc, &isFixedPitch);
     SkFontID fontID = CTFontRef_to_SkFontID(fontRef);
 
     return new SkTypeface_Mac(style, fontID, isFixedPitch, fontRef, name, isLocalStream);
 }
 
-static SkTypeface* NewFromName(const char familyName[], SkTypeface::Style theStyle) {
+static SkTypeface* NewFromName(const char familyName[], const SkFontStyle& theStyle) {
     CTFontRef ctFont = NULL;
 
     CTFontSymbolicTraits ctFontTraits = 0;
-    if (theStyle & SkTypeface::kBold) {
+    if (theStyle.weight() >= SkFontStyle::kBold_Weight) {
         ctFontTraits |= kCTFontBoldTrait;
     }
-    if (theStyle & SkTypeface::kItalic) {
+    if (theStyle.slant() != SkFontStyle::kUpright_Slant) {
         ctFontTraits |= kCTFontItalicTrait;
     }
 
+    //TODO: add weight width slant
+
     // Create the font info
     AutoCFRelease<CFStringRef> cfFontName(make_CFString(familyName));
 
@@ -534,8 +552,8 @@
     static SkTypeface* gDefaultFace;
 
     if (NULL == gDefaultFace) {
-        gDefaultFace = NewFromName(FONT_DEFAULT_NAME, SkTypeface::kNormal);
-        SkTypefaceCache::Add(gDefaultFace, SkTypeface::kNormal);
+        gDefaultFace = NewFromName(FONT_DEFAULT_NAME, SkFontStyle());
+        SkTypefaceCache::Add(gDefaultFace, SkFontStyle());
     }
     return gDefaultFace;
 }
@@ -558,7 +576,7 @@
         face->ref();
     } else {
         face = NewFromFontRef(fontRef, NULL, false);
-        SkTypefaceCache::Add(face, face->style());
+        SkTypefaceCache::Add(face, face->fontStyle());
         // NewFromFontRef doesn't retain the parameter, but the typeface it
         // creates does release it in its destructor, so we balance that with
         // a retain call here.
@@ -570,11 +588,10 @@
 
 struct NameStyleRec {
     const char*         fName;
-    SkTypeface::Style   fStyle;
+    SkFontStyle   fStyle;
 };
 
-static bool FindByNameStyle(SkTypeface* face, SkTypeface::Style style,
-                            void* ctx) {
+static bool FindByNameStyle(SkTypeface* face, const SkFontStyle& style, void* ctx) {
     const SkTypeface_Mac* mface = reinterpret_cast<SkTypeface_Mac*>(face);
     const NameStyleRec* rec = reinterpret_cast<const NameStyleRec*>(ctx);
 
@@ -599,39 +616,6 @@
     return name;    // no change
 }
 
-static SkTypeface* create_typeface(const SkTypeface* familyFace,
-                                   const char familyName[],
-                                   SkTypeface::Style style) {
-    if (familyName) {
-        familyName = map_css_names(familyName);
-    }
-
-    // Clone an existing typeface
-    // TODO: only clone if style matches the familyFace's style...
-    if (familyName == NULL && familyFace != NULL) {
-        familyFace->ref();
-        return const_cast<SkTypeface*>(familyFace);
-    }
-
-    if (!familyName || !*familyName) {
-        familyName = FONT_DEFAULT_NAME;
-    }
-
-    NameStyleRec rec = { familyName, style };
-    SkTypeface* face = SkTypefaceCache::FindByProcAndRef(FindByNameStyle, &rec);
-
-    if (NULL == face) {
-        face = NewFromName(familyName, style);
-        if (face) {
-            SkTypefaceCache::Add(face, style);
-        } else {
-            face = GetDefaultFace();
-            face->ref();
-        }
-    }
-    return face;
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 
 /** GlyphRect is in FUnits (em space, y up). */
@@ -2008,7 +1992,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
-#if 1
 
 static bool find_desc_str(CTFontDescriptorRef desc, CFStringRef name, SkString* value) {
     AutoCFRelease<CFStringRef> ref((CFStringRef)CTFontDescriptorCopyAttribute(desc, name));
@@ -2019,35 +2002,8 @@
     return true;
 }
 
-static bool find_dict_float(CFDictionaryRef dict, CFStringRef name, float* value) {
-    CFNumberRef num;
-    return CFDictionaryGetValueIfPresent(dict, name, (const void**)&num)
-    && CFNumberIsFloatType(num)
-    && CFNumberGetValue(num, kCFNumberFloatType, value);
-}
-
 #include "SkFontMgr.h"
 
-static int unit_weight_to_fontstyle(float unit) {
-    float value;
-    if (unit < 0) {
-        value = 100 + (1 + unit) * 300;
-    } else {
-        value = 400 + unit * 500;
-    }
-    return sk_float_round2int(value);
-}
-
-static int unit_width_to_fontstyle(float unit) {
-    float value;
-    if (unit < 0) {
-        value = 1 + (1 + unit) * 4;
-    } else {
-        value = 5 + unit * 4;
-    }
-    return sk_float_round2int(value);
-}
-
 static inline int sqr(int value) {
     SkASSERT(SkAbs32(value) < 0x7FFF);  // check for overflow
     return value * value;
@@ -2060,53 +2016,25 @@
            sqr((a.isItalic() != b.isItalic()) * 900);
 }
 
-static SkFontStyle desc2fontstyle(CTFontDescriptorRef desc) {
-    AutoCFRelease<CFDictionaryRef> dict(
-        (CFDictionaryRef)CTFontDescriptorCopyAttribute(desc,
-                                                       kCTFontTraitsAttribute));
-    if (NULL == dict.get()) {
-        return SkFontStyle();
-    }
-
-    float weight, width, slant;
-    if (!find_dict_float(dict, kCTFontWeightTrait, &weight)) {
-        weight = 0;
-    }
-    if (!find_dict_float(dict, kCTFontWidthTrait, &width)) {
-        width = 0;
-    }
-    if (!find_dict_float(dict, kCTFontSlantTrait, &slant)) {
-        slant = 0;
-    }
-
-    return SkFontStyle(unit_weight_to_fontstyle(weight),
-                       unit_width_to_fontstyle(width),
-                       slant ? SkFontStyle::kItalic_Slant
-                       : SkFontStyle::kUpright_Slant);
-}
-
 struct NameFontStyleRec {
     SkString    fFamilyName;
     SkFontStyle fFontStyle;
 };
 
-static bool nameFontStyleProc(SkTypeface* face, SkTypeface::Style,
-                              void* ctx) {
+static bool nameFontStyleProc(SkTypeface* face, const SkFontStyle&, void* ctx) {
     SkTypeface_Mac* macFace = (SkTypeface_Mac*)face;
     const NameFontStyleRec* rec = (const NameFontStyleRec*)ctx;
 
-    return macFace->fFontStyle == rec->fFontStyle &&
+    return macFace->fontStyle() == rec->fFontStyle &&
            macFace->fName == rec->fFamilyName;
 }
 
-static SkTypeface* createFromDesc(CFStringRef cfFamilyName,
-                                  CTFontDescriptorRef desc) {
+static SkTypeface* createFromDesc(CFStringRef cfFamilyName, CTFontDescriptorRef desc) {
     NameFontStyleRec rec;
     CFStringToSkString(cfFamilyName, &rec.fFamilyName);
-    rec.fFontStyle = desc2fontstyle(desc);
+    rec.fFontStyle = fontstyle_from_descriptor(desc, NULL);
 
-    SkTypeface* face = SkTypefaceCache::FindByProcAndRef(nameFontStyleProc,
-                                                         &rec);
+    SkTypeface* face = SkTypefaceCache::FindByProcAndRef(nameFontStyleProc, &rec);
     if (face) {
         return face;
     }
@@ -2127,12 +2055,13 @@
     CFStringToSkString(cfFamilyName, &str);
 
     bool isFixedPitch;
-    (void)computeStyleBits(ctFont, &isFixedPitch);
+    AutoCFRelease<CTFontDescriptorRef> ctFontDesc(CTFontCopyFontDescriptor(ctFont));
+    (void)fontstyle_from_descriptor(ctFontDesc, &isFixedPitch);
     SkFontID fontID = CTFontRef_to_SkFontID(ctFont);
 
     face = SkNEW_ARGS(SkTypeface_Mac, (rec.fFontStyle, fontID, isFixedPitch,
                                        ctFont, str.c_str(), false));
-    SkTypefaceCache::Add(face, face->style());
+    SkTypefaceCache::Add(face, face->fontStyle());
     return face;
 }
 
@@ -2158,12 +2087,11 @@
         return fCount;
     }
 
-    virtual void getStyle(int index, SkFontStyle* style,
-                          SkString* name) SK_OVERRIDE {
+    virtual void getStyle(int index, SkFontStyle* style, SkString* name) SK_OVERRIDE {
         SkASSERT((unsigned)index < (unsigned)fCount);
         CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray, index);
         if (style) {
-            *style = desc2fontstyle(desc);
+            *style = fontstyle_from_descriptor(desc, NULL);
         }
         if (name) {
             if (!find_desc_str(desc, kCTFontStyleNameAttribute, name)) {
@@ -2197,7 +2125,7 @@
 
         for (int i = 0; i < fCount; ++i) {
             CTFontDescriptorRef desc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fArray, i);
-            int metric = compute_metric(pattern, desc2fontstyle(desc));
+            int metric = compute_metric(pattern, fontstyle_from_descriptor(desc, NULL));
             if (0 == metric) {
                 return desc;
             }
@@ -2277,8 +2205,7 @@
         return NULL;
     }
 
-    virtual SkTypeface* onCreateFromData(SkData* data,
-                                         int ttcIndex) const SK_OVERRIDE {
+    virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE {
         AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromData(data));
         if (NULL == pr) {
             return NULL;
@@ -2286,8 +2213,7 @@
         return create_from_dataProvider(pr);
     }
 
-    virtual SkTypeface* onCreateFromStream(SkStream* stream,
-                                           int ttcIndex) const SK_OVERRIDE {
+    virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE {
         AutoCFRelease<CGDataProviderRef> pr(SkCreateDataProviderFromStream(stream));
         if (NULL == pr) {
             return NULL;
@@ -2295,8 +2221,7 @@
         return create_from_dataProvider(pr);
     }
 
-    virtual SkTypeface* onCreateFromFile(const char path[],
-                                         int ttcIndex) const SK_OVERRIDE {
+    virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE {
         AutoCFRelease<CGDataProviderRef> pr(CGDataProviderCreateWithFilename(path));
         if (NULL == pr) {
             return NULL;
@@ -2306,7 +2231,29 @@
 
     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
                                                unsigned styleBits) const SK_OVERRIDE {
-        return create_typeface(NULL, familyName, (SkTypeface::Style)styleBits);
+
+        SkFontStyle style = SkFontStyle((SkTypeface::Style)styleBits);
+        if (familyName) {
+            familyName = map_css_names(familyName);
+        }
+
+        if (!familyName || !*familyName) {
+            familyName = FONT_DEFAULT_NAME;
+        }
+
+        NameStyleRec rec = { familyName, style };
+        SkTypeface* face = SkTypefaceCache::FindByProcAndRef(FindByNameStyle, &rec);
+
+        if (NULL == face) {
+            face = NewFromName(familyName, style);
+            if (face) {
+                SkTypefaceCache::Add(face, style);
+            } else {
+                face = GetDefaultFace();
+                face->ref();
+            }
+        }
+        return face;
     }
 };
 
@@ -2315,4 +2262,3 @@
 SkFontMgr* SkFontMgr::Factory() {
     return SkNEW(SkFontMgr_Mac);
 }
-#endif
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index 1290c00..348246b 100755
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -126,20 +126,10 @@
 //    lf->lfClipPrecision = 64;
 }
 
-static SkTypeface::Style get_style(const LOGFONT& lf) {
-    unsigned style = 0;
-    if (lf.lfWeight >= FW_BOLD) {
-        style |= SkTypeface::kBold;
-    }
-    if (lf.lfItalic) {
-        style |= SkTypeface::kItalic;
-    }
-    return static_cast<SkTypeface::Style>(style);
-}
-
-static void setStyle(LOGFONT* lf, SkTypeface::Style style) {
-    lf->lfWeight = (style & SkTypeface::kBold) != 0 ? FW_BOLD : FW_NORMAL ;
-    lf->lfItalic = ((style & SkTypeface::kItalic) != 0);
+static SkFontStyle get_style(const LOGFONT& lf) {
+    return SkFontStyle(lf.lfWeight,
+                       lf.lfWidth,
+                       lf.lfItalic ? SkFontStyle::kItalic_Slant : SkFontStyle::kUpright_Slant);
 }
 
 static inline FIXED SkFixedToFIXED(SkFixed x) {
@@ -217,8 +207,11 @@
 
 class LogFontTypeface : public SkTypeface {
 public:
-    LogFontTypeface(SkTypeface::Style style, SkFontID fontID, const LOGFONT& lf, bool serializeAsStream = false) :
-        SkTypeface(style, fontID, false), fLogFont(lf), fSerializeAsStream(serializeAsStream) {
+    LogFontTypeface(const SkFontStyle& style, const LOGFONT& lf, bool serializeAsStream)
+        : SkTypeface(style, SkTypefaceCache::NewFontID(), false)
+        , fLogFont(lf)
+        , fSerializeAsStream(serializeAsStream)
+    {
 
         // If the font has cubic outlines, it will not be rendered with ClearType.
         HFONT font = CreateFontIndirect(&lf);
@@ -255,9 +248,7 @@
     bool fCanBeLCD;
 
     static LogFontTypeface* Create(const LOGFONT& lf) {
-        SkTypeface::Style style = get_style(lf);
-        SkFontID fontID = SkTypefaceCache::NewFontID();
-        return new LogFontTypeface(style, fontID, lf);
+        return new LogFontTypeface(get_style(lf), lf, false);
     }
 
     static void EnsureAccessible(const SkTypeface* face) {
@@ -289,9 +280,7 @@
      *  The created FontMemResourceTypeface takes ownership of fontMemResource.
      */
     static FontMemResourceTypeface* Create(const LOGFONT& lf, HANDLE fontMemResource) {
-        SkTypeface::Style style = get_style(lf);
-        SkFontID fontID = SkTypefaceCache::NewFontID();
-        return new FontMemResourceTypeface(style, fontID, lf, fontMemResource);
+        return new FontMemResourceTypeface(get_style(lf), lf, fontMemResource);
     }
 
 protected:
@@ -305,9 +294,9 @@
     /**
      *  Takes ownership of fontMemResource.
      */
-    FontMemResourceTypeface(SkTypeface::Style style, SkFontID fontID, const LOGFONT& lf, HANDLE fontMemResource) :
-        LogFontTypeface(style, fontID, lf, true), fFontMemResource(fontMemResource) {
-    }
+    FontMemResourceTypeface(const SkFontStyle& style, const LOGFONT& lf, HANDLE fontMemResource)
+        : LogFontTypeface(style, lf, true), fFontMemResource(fontMemResource)
+    { }
 
     HANDLE fFontMemResource;
 
@@ -319,7 +308,7 @@
     return gDefaultFont;
 }
 
-static bool FindByLogFont(SkTypeface* face, SkTypeface::Style requestedStyle, void* ctx) {
+static bool FindByLogFont(SkTypeface* face, const SkFontStyle& requestedStyle, void* ctx) {
     LogFontTypeface* lface = static_cast<LogFontTypeface*>(face);
     const LOGFONT* lf = reinterpret_cast<const LOGFONT*>(ctx);
 
@@ -2457,12 +2446,6 @@
     return 1; // non-zero means continue
 }
 
-static SkFontStyle compute_fontstyle(const LOGFONT& lf) {
-    return SkFontStyle(lf.lfWeight, SkFontStyle::kNormal_Width,
-                       lf.lfItalic ? SkFontStyle::kItalic_Slant
-                                   : SkFontStyle::kUpright_Slant);
-}
-
 class SkFontStyleSetGDI : public SkFontStyleSet {
 public:
     SkFontStyleSetGDI(const TCHAR familyName[]) {
@@ -2482,7 +2465,7 @@
 
     virtual void getStyle(int index, SkFontStyle* fs, SkString* styleName) SK_OVERRIDE {
         if (fs) {
-            *fs = compute_fontstyle(fArray[index].elfLogFont);
+            *fs = get_style(fArray[index].elfLogFont);
         }
         if (styleName) {
             const ENUMLOGFONTEX& ref = fArray[index];
@@ -2585,7 +2568,10 @@
         } else {
             logfont_for_name(familyName, &lf);
         }
-        setStyle(&lf, (SkTypeface::Style)styleBits);
+
+        SkTypeface::Style style = (SkTypeface::Style)styleBits;
+        lf.lfWeight = (style & SkTypeface::kBold) != 0 ? FW_BOLD : FW_NORMAL;
+        lf.lfItalic = ((style & SkTypeface::kItalic) != 0);
         return SkCreateTypefaceFromLOGFONT(lf);
     }
 
diff --git a/src/ports/SkFontMgr_android.cpp b/src/ports/SkFontMgr_android.cpp
index 5e93bf8..15f1d3e 100644
--- a/src/ports/SkFontMgr_android.cpp
+++ b/src/ports/SkFontMgr_android.cpp
@@ -42,7 +42,7 @@
 class SkTypeface_Android : public SkTypeface_FreeType {
 public:
     SkTypeface_Android(int index,
-                       Style style,
+                       const SkFontStyle& style,
                        bool isFixedPitch,
                        const SkString familyName)
         : INHERITED(style, SkTypefaceCache::NewFontID(), isFixedPitch)
@@ -65,7 +65,7 @@
 public:
     SkTypeface_AndroidSystem(const SkString pathName,
                              int index,
-                             Style style,
+                             const SkFontStyle& style,
                              bool isFixedPitch,
                              const SkString familyName,
                              const SkLanguage& lang,
@@ -100,7 +100,7 @@
 public:
     SkTypeface_AndroidStream(SkStream* stream,
                              int index,
-                             Style style,
+                             const SkFontStyle& style,
                              bool isFixedPitch,
                              const SkString familyName)
         : INHERITED(index, style, isFixedPitch, familyName)
@@ -158,7 +158,7 @@
 
             const int ttcIndex = fontFile.fIndex;
             SkString familyName;
-            SkTypeface::Style style;
+            SkFontStyle style;
             bool isFixedWidth;
             if (!SkTypeface_FreeType::ScanFont(stream.get(), ttcIndex,
                                                &familyName, &style, &isFixedWidth)) {
@@ -404,7 +404,7 @@
 
     virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE {
         bool isFixedPitch;
-        SkTypeface::Style style;
+        SkFontStyle style;
         SkString name;
         if (!SkTypeface_FreeType::ScanFont(stream, ttcIndex, &name, &style, &isFixedPitch)) {
             return NULL;
@@ -416,14 +416,7 @@
 
     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
                                                unsigned styleBits) const SK_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(styleBits);
 
         if (familyName) {
             // On Android, we must return NULL when we can't find the requested
diff --git a/src/ports/SkFontMgr_fontconfig.cpp b/src/ports/SkFontMgr_fontconfig.cpp
index 6fc1f28..dbc64b6 100644
--- a/src/ports/SkFontMgr_fontconfig.cpp
+++ b/src/ports/SkFontMgr_fontconfig.cpp
@@ -373,20 +373,13 @@
     FcPatternAddInteger(pattern, FC_SLANT, style.isItalic() ? FC_SLANT_ITALIC : FC_SLANT_ROMAN);
 }
 
-static SkTypeface::Style sktypefacestyle_from_fcpattern(FcPattern* pattern) {
-    int fcweight = get_int(pattern, FC_WEIGHT, FC_WEIGHT_REGULAR);
-    int fcslant = get_int(pattern, FC_SLANT, FC_SLANT_ROMAN);
-    return (SkTypeface::Style)((fcweight >= FC_WEIGHT_BOLD ? SkTypeface::kBold : 0) |
-                                (fcslant > FC_SLANT_ROMAN ? SkTypeface::kItalic : 0));
-}
-
 class SkTypeface_stream : public SkTypeface_FreeType {
 public:
     /** @param stream does not take ownership of the reference, does take ownership of the stream.*/
-    SkTypeface_stream(SkTypeface::Style style, bool fixedWidth, int ttcIndex, SkStreamAsset* stream)
+    SkTypeface_stream(const SkFontStyle& style, bool fixedWidth, int index, SkStreamAsset* stream)
         : INHERITED(style, SkTypefaceCache::NewFontID(), fixedWidth)
         , fStream(SkRef(stream))
-        , fIndex(ttcIndex)
+        , fIndex(index)
     { };
 
     virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE {
@@ -447,7 +440,7 @@
 private:
     /** @param pattern takes ownership of the reference. */
     SkTypeface_fontconfig(FcPattern* pattern)
-        : INHERITED(sktypefacestyle_from_fcpattern(pattern),
+        : INHERITED(skfontstyle_from_fcpattern(pattern),
                     SkTypefaceCache::NewFontID(),
                     FC_PROPORTIONAL != get_int(pattern, FC_SPACING, FC_PROPORTIONAL))
         , fPattern(pattern)
@@ -571,7 +564,7 @@
                                           sizes.begin(), names.count());
     }
 
-    static bool FindByFcPattern(SkTypeface* cached, SkTypeface::Style, void* ctx) {
+    static bool FindByFcPattern(SkTypeface* cached, const SkFontStyle&, void* ctx) {
         SkTypeface_fontconfig* cshFace = static_cast<SkTypeface_fontconfig*>(cached);
         FcPattern* ctxPattern = static_cast<FcPattern*>(ctx);
         return FcTrue == FcPatternEqual(cshFace->fPattern, ctxPattern);
@@ -590,7 +583,7 @@
             FcPatternReference(pattern);
             face = SkTypeface_fontconfig::Create(pattern);
             if (face) {
-                fTFCache.add(face, SkTypeface::kNormal, true);
+                fTFCache.add(face, SkFontStyle(), true);
             }
         }
         return face;
@@ -818,7 +811,7 @@
             return NULL;
         }
 
-        SkTypeface::Style style = SkTypeface::kNormal;
+        SkFontStyle style;
         bool isFixedWidth = false;
         if (!SkTypeface_FreeType::ScanFont(stream, ttcIndex, NULL, &style, &isFixedWidth)) {
             return NULL;
diff --git a/src/ports/SkFontMgr_win_dw.cpp b/src/ports/SkFontMgr_win_dw.cpp
index ecca57f..e9d494f 100644
--- a/src/ports/SkFontMgr_win_dw.cpp
+++ b/src/ports/SkFontMgr_win_dw.cpp
@@ -331,7 +331,7 @@
     IDWriteFontFamily* fDWriteFontFamily;
 };
 
-static bool FindByDWriteFont(SkTypeface* cached, SkTypeface::Style, void* ctx) {
+static bool FindByDWriteFont(SkTypeface* cached, const SkFontStyle&, void* ctx) {
     DWriteFontTypeface* cshFace = reinterpret_cast<DWriteFontTypeface*>(cached);
     ProtoDWriteTypeface* ctxFace = reinterpret_cast<ProtoDWriteTypeface*>(ctx);
     bool same;
diff --git a/src/ports/SkTypeface_win_dw.h b/src/ports/SkTypeface_win_dw.h
index 531dc51..7d72dfd 100644
--- a/src/ports/SkTypeface_win_dw.h
+++ b/src/ports/SkTypeface_win_dw.h
@@ -24,22 +24,19 @@
 class SkFontDescriptor;
 struct SkScalerContextRec;
 
-static SkTypeface::Style get_style(IDWriteFont* font) {
-    int style = SkTypeface::kNormal;
-    DWRITE_FONT_WEIGHT weight = font->GetWeight();
-    if (DWRITE_FONT_WEIGHT_DEMI_BOLD <= weight) {
-        style |= SkTypeface::kBold;
-    }
-    DWRITE_FONT_STYLE angle = font->GetStyle();
-    if (DWRITE_FONT_STYLE_OBLIQUE == angle || DWRITE_FONT_STYLE_ITALIC == angle) {
-        style |= SkTypeface::kItalic;
-    }
-    return static_cast<SkTypeface::Style>(style);
+static SkFontStyle get_style(IDWriteFont* font) {
+    DWRITE_FONT_STYLE dwStyle = font->GetStyle();
+    return SkFontStyle(font->GetWeight(),
+                       font->GetStretch(),
+                       (DWRITE_FONT_STYLE_OBLIQUE == dwStyle ||
+                        DWRITE_FONT_STYLE_ITALIC  == dwStyle)
+                                                   ? SkFontStyle::kItalic_Slant
+                                                   : SkFontStyle::kUpright_Slant);
 }
 
 class DWriteFontTypeface : public SkTypeface {
 private:
-    DWriteFontTypeface(SkTypeface::Style style, SkFontID fontID,
+    DWriteFontTypeface(const SkFontStyle& style, SkFontID fontID,
                        IDWriteFactory* factory,
                        IDWriteFontFace* fontFace,
                        IDWriteFont* font,
@@ -80,9 +77,8 @@
                                       IDWriteFontFamily* fontFamily,
                                       IDWriteFontFileLoader* fontFileLoader = NULL,
                                       IDWriteFontCollectionLoader* fontCollectionLoader = NULL) {
-        SkTypeface::Style style = get_style(font);
         SkFontID fontID = SkTypefaceCache::NewFontID();
-        return SkNEW_ARGS(DWriteFontTypeface, (style, fontID,
+        return SkNEW_ARGS(DWriteFontTypeface, (get_style(font), fontID,
                                                factory, fontFace, font, fontFamily,
                                                fontFileLoader, fontCollectionLoader));
     }
diff --git a/tools/sk_tool_utils_font.cpp b/tools/sk_tool_utils_font.cpp
index 3236f07..7cee944 100644
--- a/tools/sk_tool_utils_font.cpp
+++ b/tools/sk_tool_utils_font.cpp
@@ -63,7 +63,7 @@
             atexit(release_portable_typefaces);
         }
     }
-    return SkNEW_ARGS(SkTestTypeface, (font, style));
+    return SkNEW_ARGS(SkTestTypeface, (font, SkFontStyle(style)));
 }