diff --git a/gm/fontmgr.cpp b/gm/fontmgr.cpp index 70b91150d0..9c300ab502 100644 --- a/gm/fontmgr.cpp +++ b/gm/fontmgr.cpp @@ -11,6 +11,11 @@ #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 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 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 diff --git a/gyp/ports.gyp b/gyp/ports.gyp index fff368df6a..1d45fd370a 100644 --- a/gyp/ports.gyp +++ b/gyp/ports.gyp @@ -26,8 +26,12 @@ '../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', @@ -113,29 +117,32 @@ '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/SkThread_pthread.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', diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp index 017c1eab76..68210ba46a 100755 --- a/src/ports/SkFontHost_win.cpp +++ b/src/ports/SkFontHost_win.cpp @@ -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); } diff --git a/src/ports/SkFontHost_win_dw.cpp b/src/ports/SkFontHost_win_dw.cpp index e1685e63b0..b17195d0c4 100644 --- a/src/ports/SkFontHost_win_dw.cpp +++ b/src/ports/SkFontHost_win_dw.cpp @@ -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 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 fFontMgr; + SkTScopedComPtr 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 fontFamily; if (familyFace) { @@ -1627,17 +1677,17 @@ static SkTypeface* create_typeface(const SkTypeface* familyFace, SkTScopedComPtr 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(); - } - - virtual void getStyle(int index, SkFontStyle* fs, SkString* styleName); - - virtual SkTypeface* createTypeface(int index) SK_OVERRIDE { - SkTScopedComPtr font; - HRNM(fFontFamily->GetFont(index, &font), "Could not get font."); - - SkTScopedComPtr fontFace; - HRNM(font->CreateFontFace(&fontFace), "Could not create font face."); - - return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fFontFamily.get()); - } - - 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); +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; +} - DWRITE_FONT_WEIGHT weight = (DWRITE_FONT_WEIGHT)pattern.weight(); - DWRITE_FONT_STRETCH width = (DWRITE_FONT_STRETCH)pattern.width(); +int SkFontMgr_DirectWrite::onCountFamilies() { + return fFontCollection->GetFontFamilyCount(); +} - SkTScopedComPtr font; - // TODO: perhaps use GetMatchingFonts and get the least simulated? - HRNM(fFontFamily->GetFirstMatchingFont(weight, width, slant, &font), - "Could not match font in family."); +void SkFontMgr_DirectWrite::onGetFamilyName(int index, SkString* familyName) { + SkTScopedComPtr fontFamily; + HRVM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requested family."); - SkTScopedComPtr fontFace; - HRNM(font->CreateFontFace(&fontFace), "Could not create font face."); + SkTScopedComPtr familyNames; + HRVM(fontFamily->GetFamilyNames(&familyNames), "Could not get family names."); - return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fFontFamily.get()); + get_locale_string(familyNames.get(), fLocaleName.get(), familyName); +} + +SkFontStyleSet* SkFontMgr_DirectWrite::onCreateStyleSet(int index) { + SkTScopedComPtr fontFamily; + HRNM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requested family."); + + return SkNEW_ARGS(SkFontStyleSet_DirectWrite, (this, fontFamily.get())); +} + +SkFontStyleSet* SkFontMgr_DirectWrite::onMatchFamily(const char familyName[]) { + SkSMallocWCHAR dwFamilyName; + HRN(cstring_to_wchar(familyName, &dwFamilyName)); + + UINT32 index; + BOOL exists; + HRNM(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &exists), + "Failed while finding family by name."); + if (!exists) { + return NULL; } -private: - SkAutoTUnref fFontMgr; - SkTScopedComPtr 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 sset(this->matchFamily(familyName)); + return sset->matchStyle(fontstyle); +} -private: - friend class SkFontStyleSet_DirectWrite; - SkTScopedComPtr 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 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 familyNames; - HRVM(fontFamily->GetFamilyNames(&familyNames), "Could not get family names."); +SkTypeface* SkFontMgr_DirectWrite::onCreateFromData(SkData* data, int ttcIndex) { + SkAutoTUnref 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 fontFamily; - HRNM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requested family."); +SkTypeface* SkFontMgr_DirectWrite::onCreateFromFile(const char path[], int ttcIndex) { + SkAutoTUnref 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 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 stream(SkNEW_ARGS(SkMemoryStream, (data))); - return this->createFromStream(stream, ttcIndex); - } - virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) SK_OVERRIDE { - SkAutoTUnref stream(SkStream::NewFromFile(path)); - return this->createFromStream(stream, ttcIndex); - } +SkTypeface* SkFontStyleSet_DirectWrite::createTypeface(int index) { + SkTScopedComPtr 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 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 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 font; + // TODO: perhaps use GetMatchingFonts and get the least simulated? + HRNM(fFontFamily->GetFirstMatchingFont(weight, width, slant, &font), + "Could not match font in family."); + + SkTScopedComPtr 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 index 0000000000..3e09446e48 --- /dev/null +++ b/src/ports/SkFontMgr_default_dw.cpp @@ -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 index 0000000000..243d0cc983 --- /dev/null +++ b/src/ports/SkFontMgr_default_gdi.cpp @@ -0,0 +1,7 @@ +#include "SkFontMgr.h" + +extern SkFontMgr* SkFontMgr_New_GDI(); + +SkFontMgr* SkFontMgr::Factory() { + return SkFontMgr_New_GDI(); +}