allow both GDI and DW fontmgrs at the same time
authorreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 14 Aug 2013 18:59:28 +0000 (18:59 +0000)
committerreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Wed, 14 Aug 2013 18:59:28 +0000 (18:59 +0000)
BUG=
R=bungeman@google.com

Review URL: https://codereview.chromium.org/23058002

git-svn-id: http://skia.googlecode.com/svn/trunk@10718 2bbb7eff-a529-9590-31e7-b0007b416f81

gm/fontmgr.cpp
gyp/ports.gyp
src/ports/SkFontHost_win.cpp
src/ports/SkFontHost_win_dw.cpp
src/ports/SkFontMgr_default_dw.cpp [new file with mode: 0644]
src/ports/SkFontMgr_default_gdi.cpp [new file with mode: 0644]

index 70b9115..9c300ab 100644 (file)
 #include "SkGraphics.h"
 #include "SkTypeface.h"
 
+#ifdef SK_BUILD_FOR_WIN
+    extern SkFontMgr* SkFontMgr_New_GDI();
+    extern SkFontMgr* SkFontMgr_New_DirectWrite();
+#endif
+
 // limit this just so we don't take too long to draw
 #define MAX_FAMILIES    30
 
@@ -22,13 +27,21 @@ static SkScalar drawString(SkCanvas* canvas, const SkString& text, SkScalar x,
 
 class FontMgrGM : public skiagm::GM {
 public:
-    FontMgrGM() {
+    FontMgrGM(SkFontMgr* (*factory)() = NULL) {
         SkGraphics::SetFontCacheLimit(16 * 1024 * 1024);
+
+        fName.set("fontmgr_iter");
+        if (factory) {
+            fName.append("_factory");
+            fFM.reset(factory());
+        } else {
+            fFM.reset(SkFontMgr::RefDefault());
+        }
     }
 
 protected:
     virtual SkString onShortName() {
-        return SkString("fontmgr_iter");
+        return fName;
     }
 
     virtual SkISize onISize() {
@@ -43,7 +56,7 @@ protected:
         paint.setSubpixelText(true);
         paint.setTextSize(17);
 
-        SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
+        SkFontMgr* fm = fFM;
         int count = SkMin32(fm->countFamilies(), MAX_FAMILIES);
 
         for (int i = 0; i < count; ++i) {
@@ -79,6 +92,8 @@ protected:
     }
 
 private:
+    SkAutoTUnref<SkFontMgr> fFM;
+    SkString fName;
     typedef GM INHERITED;
 };
 
@@ -181,3 +196,7 @@ private:
 
 DEF_GM( return SkNEW(FontMgrGM); )
 DEF_GM( return SkNEW(FontMgrMatchGM); )
+
+#ifdef SK_BUILD_FOR_WIN
+    DEF_GM( return SkNEW_ARGS(FontMgrGM, (SkFontMgr_New_DirectWrite)); )
+#endif
index fff368d..1d45fd3 100644 (file)
         '../src/ports/SkDebug_nacl.cpp',
         '../src/ports/SkDebug_stdio.cpp',
         '../src/ports/SkDebug_win.cpp',
+
         '../src/ports/SkFontHost_win.cpp',
         '../src/ports/SkFontHost_win_dw.cpp',
+        '../src/ports/SkFontMgr_default_gdi.cpp',
+        '../src/ports/SkFontMgr_default_dw.cpp',
+
         '../src/ports/SkGlobalInitialization_default.cpp',
         '../src/ports/SkMemory_malloc.cpp',
         '../src/ports/SkOSFile_posix.cpp',
             'config/win',
             '../src/utils/win',
           ],
-          'conditions': [
-            [ 'skia_directwrite', {
-                'sources!': [
-                  '../src/ports/SkFontHost_win.cpp',
-                ],
-              }, { # else !skia_directwrite
-                'sources!': [
-                  '../src/ports/SkFontHost_win_dw.cpp',
-                ],
-              }],
-          ],
           'sources!': [ # these are used everywhere but windows
             '../src/ports/SkDebug_stdio.cpp',
             '../src/ports/SkOSFile_posix.cpp',
             '../src/ports/SkTime_Unix.cpp',
             '../src/ports/SkTLS_pthread.cpp',
           ],
+                 'conditions': [
+            #    when we build for win, we only want one of these default files
+            [ 'skia_directwrite', {
+              'sources!': [
+                '../src/ports/SkFontMgr_default_gdi.cpp',
+              ],
+            }, { # else gdi
+              'sources!': [
+                '../src/ports/SkFontMgr_default_dw.cpp',
+              ],
+            }],
+          ],
         }, { # else !win
           'sources!': [
             '../src/ports/SkDebug_win.cpp',
             '../src/ports/SkFontHost_win.cpp',
             '../src/ports/SkFontHost_win_dw.cpp',
+            '../src/ports/SkFontMgr_default_gdi.cpp',
+            '../src/ports/SkFontMgr_default_dw.cpp',
             '../src/ports/SkOSFile_win.cpp',
             '../src/ports/SkThread_win.cpp',
             '../src/ports/SkTime_win.cpp',
index 017c1ea..68210ba 100755 (executable)
@@ -2371,6 +2371,7 @@ SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
 
 #endif
 
-SkFontMgr* SkFontMgr::Factory() {
+extern SkFontMgr* SkFontMgr_New_GDI();
+SkFontMgr* SkFontMgr_New_GDI() {
     return SkNEW(SkFontMgrGDI);
 }
index e1685e6..b17195d 100644 (file)
@@ -16,6 +16,7 @@
 #include "SkEndian.h"
 #include "SkFontDescriptor.h"
 #include "SkFontHost.h"
+#include "SkFontMgr.h"
 #include "SkFontStream.h"
 #include "SkGlyph.h"
 #include "SkHRESULT.h"
@@ -75,6 +76,68 @@ static HRESULT wchar_to_skstring(WCHAR* name, SkString* skname) {
 
 ///////////////////////////////////////////////////////////////////////////////
 
+class StreamFontFileLoader;
+
+class SkFontMgr_DirectWrite : public SkFontMgr {
+public:
+    /** localeNameLength must include the null terminator. */
+    SkFontMgr_DirectWrite(IDWriteFontCollection* fontCollection,
+                          WCHAR* localeName, int localeNameLength)
+        : fFontCollection(SkRefComPtr(fontCollection))
+        , fLocaleName(localeNameLength)
+    {
+        memcpy(fLocaleName.get(), localeName, localeNameLength * sizeof(WCHAR));
+    }
+
+    SkTypefaceCache* getTypefaceCache() { return &fTFCache; }
+
+    SkTypeface* createTypefaceFromDWriteFont(IDWriteFontFace* fontFace,
+                                             IDWriteFont* font,
+                                             IDWriteFontFamily* fontFamily,
+                                             StreamFontFileLoader* = NULL,
+                                             IDWriteFontCollectionLoader* = NULL);
+
+protected:
+    virtual int onCountFamilies() SK_OVERRIDE;
+    virtual void onGetFamilyName(int index, SkString* familyName) SK_OVERRIDE;
+    virtual SkFontStyleSet* onCreateStyleSet(int index) SK_OVERRIDE;
+    virtual SkFontStyleSet* onMatchFamily(const char familyName[]) SK_OVERRIDE;
+    virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
+                                           const SkFontStyle& fontstyle) SK_OVERRIDE;
+    virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
+                                         const SkFontStyle& fontstyle) SK_OVERRIDE;
+    virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) SK_OVERRIDE;
+    virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) SK_OVERRIDE;
+    virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) SK_OVERRIDE;
+    virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
+                                               unsigned styleBits) SK_OVERRIDE;
+
+private:
+    friend class SkFontStyleSet_DirectWrite;
+    SkTScopedComPtr<IDWriteFontCollection> fFontCollection;
+    SkSMallocWCHAR fLocaleName;
+    SkTypefaceCache fTFCache;
+};
+
+class SkFontStyleSet_DirectWrite : public SkFontStyleSet {
+public:
+    SkFontStyleSet_DirectWrite(SkFontMgr_DirectWrite* fontMgr, IDWriteFontFamily* fontFamily)
+        : fFontMgr(SkRef(fontMgr))
+        , fFontFamily(SkRefComPtr(fontFamily))
+    { }
+
+    virtual int count() SK_OVERRIDE;
+    virtual void getStyle(int index, SkFontStyle* fs, SkString* styleName) SK_OVERRIDE;
+    virtual SkTypeface* createTypeface(int index) SK_OVERRIDE;
+    virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE;
+
+private:
+    SkAutoTUnref<SkFontMgr_DirectWrite> fFontMgr;
+    SkTScopedComPtr<IDWriteFontFamily> fFontFamily;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
 class DWriteOffscreen {
 public:
     DWriteOffscreen() : fWidth(0), fHeight(0) {
@@ -704,20 +767,6 @@ static bool FindByDWriteFont(SkTypeface* face, SkTypeface::Style requestedStyle,
            wcscmp(dwFaceFontNameChar.get(), dwFontNameChar.get()) == 0;
 }
 
-SkTypeface* SkCreateTypefaceFromDWriteFont(IDWriteFontFace* fontFace,
-                                           IDWriteFont* font,
-                                           IDWriteFontFamily* fontFamily,
-                                           StreamFontFileLoader* fontFileLoader = NULL,
-                                           IDWriteFontCollectionLoader* fontCollectionLoader = NULL) {
-    SkTypeface* face = SkTypefaceCache::FindByProcAndRef(FindByDWriteFont, font);
-    if (NULL == face) {
-        face = DWriteFontTypeface::Create(fontFace, font, fontFamily,
-                                          fontFileLoader, fontCollectionLoader);
-        SkTypefaceCache::Add(face, get_style(font), fontCollectionLoader != NULL);
-    }
-    return face;
-}
-
 void SkDWriteFontFromTypeface(const SkTypeface* face, IDWriteFont** font) {
     if (NULL == face) {
         HRVM(get_default_font(font), "Could not get default font.");
@@ -1258,9 +1307,9 @@ static SkTypeface* create_from_stream(SkStream* stream, int ttcIndex) {
 
             UINT32 faceIndex = fontFace->GetIndex();
             if (faceIndex == ttcIndex) {
-                return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily.get(),
-                                                      autoUnregisterFontFileLoader.detatch(),
-                                                      autoUnregisterFontCollectionLoader.detatch());
+                return DWriteFontTypeface::Create(fontFace.get(), font.get(), fontFamily.get(),
+                                                  autoUnregisterFontFileLoader.detatch(),
+                                                  autoUnregisterFontCollectionLoader.detatch());
             }
         }
     }
@@ -1596,7 +1645,8 @@ SkAdvancedTypefaceMetrics* DWriteFontTypeface::onGetAdvancedTypefaceMetrics(
 
 static SkTypeface* create_typeface(const SkTypeface* familyFace,
                                    const char familyName[],
-                                   unsigned style) {
+                                   unsigned style,
+                                   SkFontMgr_DirectWrite* fontMgr) {
     HRESULT hr;
     SkTScopedComPtr<IDWriteFontFamily> fontFamily;
     if (familyFace) {
@@ -1627,17 +1677,17 @@ static SkTypeface* create_typeface(const SkTypeface* familyFace,
     SkTScopedComPtr<IDWriteFontFace> fontFace;
     hr = font->CreateFontFace(&fontFace);
 
-    return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily.get());
+    return fontMgr->createTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily.get());
 }
 
 SkTypeface* DWriteFontTypeface::onRefMatchingStyle(Style style) const {
-    return create_typeface(this, NULL, style);
+    SkFontMgr_DirectWrite* fontMgr = NULL;
+    // todo: should each typeface have a ref to its fontmgr/cache?
+    return create_typeface(this, NULL, style, fontMgr);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-#include "SkFontMgr.h"
-
 static void get_locale_string(IDWriteLocalizedStrings* names, const WCHAR* preferedLocale,
                               SkString* skname) {
     UINT32 nameIndex = 0;
@@ -1660,143 +1710,108 @@ static void get_locale_string(IDWriteLocalizedStrings* names, const WCHAR* prefe
     HRV(wchar_to_skstring(name.get(), skname));
 }
 
-class SkFontMgr_DirectWrite;
-
-class SkFontStyleSet_DirectWrite : public SkFontStyleSet {
-public:
-    SkFontStyleSet_DirectWrite(const SkFontMgr_DirectWrite* fontMgr, IDWriteFontFamily* fontFamily)
-        : fFontMgr(SkRef(fontMgr))
-        , fFontFamily(SkRefComPtr(fontFamily))
-    { }
-
-    virtual int count() SK_OVERRIDE {
-        return fFontFamily->GetFontCount();
+SkTypeface* SkFontMgr_DirectWrite::createTypefaceFromDWriteFont(
+                                           IDWriteFontFace* fontFace,
+                                           IDWriteFont* font,
+                                           IDWriteFontFamily* fontFamily,
+                                           StreamFontFileLoader* fontFileLoader,
+                                           IDWriteFontCollectionLoader* fontCollectionLoader) {
+    SkTypeface* face = fTFCache.findByProcAndRef(FindByDWriteFont, font);
+    if (NULL == face) {
+        face = DWriteFontTypeface::Create(fontFace, font, fontFamily,
+                                          fontFileLoader, fontCollectionLoader);
+        if (face) {
+            fTFCache.add(face, get_style(font), fontCollectionLoader != NULL);
+        }
     }
+    return face;
+}
 
-    virtual void getStyle(int index, SkFontStyle* fs, SkString* styleName);
-
-    virtual SkTypeface* createTypeface(int index) SK_OVERRIDE {
-        SkTScopedComPtr<IDWriteFont> font;
-        HRNM(fFontFamily->GetFont(index, &font), "Could not get font.");
+int SkFontMgr_DirectWrite::onCountFamilies() {
+    return fFontCollection->GetFontFamilyCount();
+}
 
-        SkTScopedComPtr<IDWriteFontFace> fontFace;
-        HRNM(font->CreateFontFace(&fontFace), "Could not create font face.");
+void SkFontMgr_DirectWrite::onGetFamilyName(int index, SkString* familyName) {
+    SkTScopedComPtr<IDWriteFontFamily> fontFamily;
+    HRVM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requested family.");
 
-        return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fFontFamily.get());
-    }
+    SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
+    HRVM(fontFamily->GetFamilyNames(&familyNames), "Could not get family names.");
 
-    virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE {
-        DWRITE_FONT_STYLE slant;
-        switch (pattern.slant()) {
-        case SkFontStyle::kUpright_Slant:
-            slant = DWRITE_FONT_STYLE_NORMAL;
-            break;
-        case SkFontStyle::kItalic_Slant:
-            slant = DWRITE_FONT_STYLE_ITALIC;
-            break;
-        default:
-            SkASSERT(false);
-        }
+    get_locale_string(familyNames.get(), fLocaleName.get(), familyName);
+}
 
-        DWRITE_FONT_WEIGHT weight = (DWRITE_FONT_WEIGHT)pattern.weight();
-        DWRITE_FONT_STRETCH width = (DWRITE_FONT_STRETCH)pattern.width();
+SkFontStyleSet* SkFontMgr_DirectWrite::onCreateStyleSet(int index) {
+    SkTScopedComPtr<IDWriteFontFamily> fontFamily;
+    HRNM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requested family.");
 
-        SkTScopedComPtr<IDWriteFont> font;
-        // TODO: perhaps use GetMatchingFonts and get the least simulated?
-        HRNM(fFontFamily->GetFirstMatchingFont(weight, width, slant, &font),
-             "Could not match font in family.");
+    return SkNEW_ARGS(SkFontStyleSet_DirectWrite, (this, fontFamily.get()));
+}
 
-        SkTScopedComPtr<IDWriteFontFace> fontFace;
-        HRNM(font->CreateFontFace(&fontFace), "Could not create font face.");
+SkFontStyleSet* SkFontMgr_DirectWrite::onMatchFamily(const char familyName[]) {
+    SkSMallocWCHAR dwFamilyName;
+    HRN(cstring_to_wchar(familyName, &dwFamilyName));
 
-        return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fFontFamily.get());
+    UINT32 index;
+    BOOL exists;
+    HRNM(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &exists),
+            "Failed while finding family by name.");
+    if (!exists) {
+        return NULL;
     }
 
-private:
-    SkAutoTUnref<const SkFontMgr_DirectWrite> fFontMgr;
-    SkTScopedComPtr<IDWriteFontFamily> fFontFamily;
-};
+    return this->onCreateStyleSet(index);
+}
 
-class SkFontMgr_DirectWrite : public SkFontMgr {
-public:
-    /** localeNameLength must include the null terminator. */
-    SkFontMgr_DirectWrite(IDWriteFontCollection* fontCollection,
-                          WCHAR* localeName, int localeNameLength)
-        : fFontCollection(SkRefComPtr(fontCollection))
-        , fLocaleName(localeNameLength)
-    {
-        memcpy(fLocaleName.get(), localeName, localeNameLength * sizeof(WCHAR));
-    }
+SkTypeface* SkFontMgr_DirectWrite::onMatchFamilyStyle(const char familyName[],
+                                                      const SkFontStyle& fontstyle) {
+    SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName));
+    return sset->matchStyle(fontstyle);
+}
 
-private:
-    friend class SkFontStyleSet_DirectWrite;
-    SkTScopedComPtr<IDWriteFontCollection> fFontCollection;
-    SkSMallocWCHAR fLocaleName;
+SkTypeface* SkFontMgr_DirectWrite::onMatchFaceStyle(const SkTypeface* familyMember,
+                                                    const SkFontStyle& fontstyle) {
+    SkString familyName;
+    SkFontStyleSet_DirectWrite sset(
+        this, ((DWriteFontTypeface*)familyMember)->fDWriteFontFamily.get()
+    );
+    return sset.matchStyle(fontstyle);
+}
 
-protected:
-    virtual int onCountFamilies() SK_OVERRIDE {
-        return fFontCollection->GetFontFamilyCount();
-    }
-    virtual void onGetFamilyName(int index, SkString* familyName) SK_OVERRIDE {
-        SkTScopedComPtr<IDWriteFontFamily> fontFamily;
-        HRVM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requested family.");
+SkTypeface* SkFontMgr_DirectWrite::onCreateFromStream(SkStream* stream, int ttcIndex) {
+    return create_from_stream(stream, ttcIndex);
+}
 
-        SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
-        HRVM(fontFamily->GetFamilyNames(&familyNames), "Could not get family names.");
+SkTypeface* SkFontMgr_DirectWrite::onCreateFromData(SkData* data, int ttcIndex) {
+    SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, (data)));
+    return this->createFromStream(stream, ttcIndex);
+}
 
-        get_locale_string(familyNames.get(), fLocaleName.get(), familyName);
-    }
-    virtual SkFontStyleSet* onCreateStyleSet(int index) SK_OVERRIDE {
-        SkTScopedComPtr<IDWriteFontFamily> fontFamily;
-        HRNM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requested family.");
+SkTypeface* SkFontMgr_DirectWrite::onCreateFromFile(const char path[], int ttcIndex) {
+    SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
+    return this->createFromStream(stream, ttcIndex);
+}
 
-        return SkNEW_ARGS(SkFontStyleSet_DirectWrite, (this, fontFamily.get()));
-    }
-    virtual SkFontStyleSet* onMatchFamily(const char familyName[]) SK_OVERRIDE {
-        SkSMallocWCHAR dwFamilyName;
-        HRN(cstring_to_wchar(familyName, &dwFamilyName));
+SkTypeface* SkFontMgr_DirectWrite::onLegacyCreateTypeface(const char familyName[],
+                                                          unsigned styleBits) {
+    return create_typeface(NULL, familyName, styleBits, this);
+}
 
-        UINT32 index;
-        BOOL exists;
-        HRNM(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &exists),
-             "Failed while finding family by name.");
-        if (!exists) {
-            return NULL;
-        }
+///////////////////////////////////////////////////////////////////////////////
 
-        return this->onCreateStyleSet(index);
-    }
+int SkFontStyleSet_DirectWrite::count() {
+    return fFontFamily->GetFontCount();
+}
 
-    virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
-                                           const SkFontStyle& fontstyle) SK_OVERRIDE {
-        SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName));
-        return sset->matchStyle(fontstyle);
-    }
-    virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
-                                         const SkFontStyle& fontstyle) SK_OVERRIDE {
-        SkString familyName;
-        SkFontStyleSet_DirectWrite sset(
-            this, ((DWriteFontTypeface*)familyMember)->fDWriteFontFamily.get()
-        );
-        return sset.matchStyle(fontstyle);
-    }
-    virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) SK_OVERRIDE {
-        return create_from_stream(stream, ttcIndex);
-    }
-    virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) SK_OVERRIDE {
-        SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, (data)));
-        return this->createFromStream(stream, ttcIndex);
-    }
-    virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) SK_OVERRIDE {
-        SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
-        return this->createFromStream(stream, ttcIndex);
-    }
+SkTypeface* SkFontStyleSet_DirectWrite::createTypeface(int index) {
+    SkTScopedComPtr<IDWriteFont> font;
+    HRNM(fFontFamily->GetFont(index, &font), "Could not get font.");
 
-    virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
-                                               unsigned styleBits) SK_OVERRIDE {
-        return create_typeface(NULL, familyName, styleBits);
-    }
-};
+    SkTScopedComPtr<IDWriteFontFace> fontFace;
+    HRNM(font->CreateFontFace(&fontFace), "Could not create font face.");
+
+    return fFontMgr->createTypefaceFromDWriteFont(fontFace.get(), font.get(), fFontFamily.get());
+}
 
 void SkFontStyleSet_DirectWrite::getStyle(int index, SkFontStyle* fs, SkString* styleName) {
     SkTScopedComPtr<IDWriteFont> font;
@@ -1826,6 +1841,34 @@ void SkFontStyleSet_DirectWrite::getStyle(int index, SkFontStyle* fs, SkString*
     }
 }
 
+SkTypeface* SkFontStyleSet_DirectWrite::matchStyle(const SkFontStyle& pattern) {
+    DWRITE_FONT_STYLE slant;
+    switch (pattern.slant()) {
+    case SkFontStyle::kUpright_Slant:
+        slant = DWRITE_FONT_STYLE_NORMAL;
+        break;
+    case SkFontStyle::kItalic_Slant:
+        slant = DWRITE_FONT_STYLE_ITALIC;
+        break;
+    default:
+        SkASSERT(false);
+    }
+
+    DWRITE_FONT_WEIGHT weight = (DWRITE_FONT_WEIGHT)pattern.weight();
+    DWRITE_FONT_STRETCH width = (DWRITE_FONT_STRETCH)pattern.width();
+
+    SkTScopedComPtr<IDWriteFont> font;
+    // TODO: perhaps use GetMatchingFonts and get the least simulated?
+    HRNM(fFontFamily->GetFirstMatchingFont(weight, width, slant, &font),
+            "Could not match font in family.");
+
+    SkTScopedComPtr<IDWriteFontFace> fontFace;
+    HRNM(font->CreateFontFace(&fontFace), "Could not create font face.");
+
+    return fFontMgr->createTypefaceFromDWriteFont(fontFace.get(), font.get(),
+                                                  fFontFamily.get());
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 #ifndef SK_FONTHOST_USES_FONTMGR
@@ -1833,7 +1876,7 @@ void SkFontStyleSet_DirectWrite::getStyle(int index, SkFontStyle* fs, SkString*
 SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
                                        const char familyName[],
                                        SkTypeface::Style style) {
-    return create_typeface(familyFace, familyName, style);
+    return create_typeface(familyFace, familyName, style, NULL);
 }
 
 SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
@@ -1847,7 +1890,8 @@ SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
 
 #endif
 
-SkFontMgr* SkFontMgr::Factory() {
+extern SkFontMgr* SkFontMgr_New_DirectWrite();
+SkFontMgr* SkFontMgr_New_DirectWrite() {
     IDWriteFactory* factory;
     HRNM(get_dwrite_factory(&factory), "Could not get factory.");
 
@@ -1864,3 +1908,4 @@ SkFontMgr* SkFontMgr::Factory() {
 
     return SkNEW_ARGS(SkFontMgr_DirectWrite, (sysFontCollection.get(), localeName, localeNameLen));
 }
+
diff --git a/src/ports/SkFontMgr_default_dw.cpp b/src/ports/SkFontMgr_default_dw.cpp
new file mode 100644 (file)
index 0000000..3e09446
--- /dev/null
@@ -0,0 +1,7 @@
+#include "SkFontMgr.h"
+
+extern SkFontMgr* SkFontMgr_New_DirectWrite();
+
+SkFontMgr* SkFontMgr::Factory() {
+    return SkFontMgr_New_DirectWrite();
+}
diff --git a/src/ports/SkFontMgr_default_gdi.cpp b/src/ports/SkFontMgr_default_gdi.cpp
new file mode 100644 (file)
index 0000000..243d0cc
--- /dev/null
@@ -0,0 +1,7 @@
+#include "SkFontMgr.h"
+
+extern SkFontMgr* SkFontMgr_New_GDI();
+
+SkFontMgr* SkFontMgr::Factory() {
+    return SkFontMgr_New_GDI();
+}