allow both GDI and DW fontmgrs at the same time

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
This commit is contained in:
reed@google.com 2013-08-14 18:59:28 +00:00
parent 04507b9fd9
commit 7d65dee189
6 changed files with 245 additions and 159 deletions

View File

@ -11,6 +11,11 @@
#include "SkGraphics.h" #include "SkGraphics.h"
#include "SkTypeface.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 // limit this just so we don't take too long to draw
#define MAX_FAMILIES 30 #define MAX_FAMILIES 30
@ -22,13 +27,21 @@ static SkScalar drawString(SkCanvas* canvas, const SkString& text, SkScalar x,
class FontMgrGM : public skiagm::GM { class FontMgrGM : public skiagm::GM {
public: public:
FontMgrGM() { FontMgrGM(SkFontMgr* (*factory)() = NULL) {
SkGraphics::SetFontCacheLimit(16 * 1024 * 1024); SkGraphics::SetFontCacheLimit(16 * 1024 * 1024);
fName.set("fontmgr_iter");
if (factory) {
fName.append("_factory");
fFM.reset(factory());
} else {
fFM.reset(SkFontMgr::RefDefault());
}
} }
protected: protected:
virtual SkString onShortName() { virtual SkString onShortName() {
return SkString("fontmgr_iter"); return fName;
} }
virtual SkISize onISize() { virtual SkISize onISize() {
@ -43,7 +56,7 @@ protected:
paint.setSubpixelText(true); paint.setSubpixelText(true);
paint.setTextSize(17); paint.setTextSize(17);
SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault()); SkFontMgr* fm = fFM;
int count = SkMin32(fm->countFamilies(), MAX_FAMILIES); int count = SkMin32(fm->countFamilies(), MAX_FAMILIES);
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
@ -79,6 +92,8 @@ protected:
} }
private: private:
SkAutoTUnref<SkFontMgr> fFM;
SkString fName;
typedef GM INHERITED; typedef GM INHERITED;
}; };
@ -181,3 +196,7 @@ private:
DEF_GM( return SkNEW(FontMgrGM); ) DEF_GM( return SkNEW(FontMgrGM); )
DEF_GM( return SkNEW(FontMgrMatchGM); ) DEF_GM( return SkNEW(FontMgrMatchGM); )
#ifdef SK_BUILD_FOR_WIN
DEF_GM( return SkNEW_ARGS(FontMgrGM, (SkFontMgr_New_DirectWrite)); )
#endif

View File

@ -26,8 +26,12 @@
'../src/ports/SkDebug_nacl.cpp', '../src/ports/SkDebug_nacl.cpp',
'../src/ports/SkDebug_stdio.cpp', '../src/ports/SkDebug_stdio.cpp',
'../src/ports/SkDebug_win.cpp', '../src/ports/SkDebug_win.cpp',
'../src/ports/SkFontHost_win.cpp', '../src/ports/SkFontHost_win.cpp',
'../src/ports/SkFontHost_win_dw.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/SkGlobalInitialization_default.cpp',
'../src/ports/SkMemory_malloc.cpp', '../src/ports/SkMemory_malloc.cpp',
'../src/ports/SkOSFile_posix.cpp', '../src/ports/SkOSFile_posix.cpp',
@ -113,29 +117,32 @@
'config/win', 'config/win',
'../src/utils/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 'sources!': [ # these are used everywhere but windows
'../src/ports/SkDebug_stdio.cpp', '../src/ports/SkDebug_stdio.cpp',
'../src/ports/SkOSFile_posix.cpp', '../src/ports/SkOSFile_posix.cpp',
'../src/ports/SkThread_pthread.cpp', '../src/ports/SkThread_pthread.cpp',
'../src/ports/SkTime_Unix.cpp', '../src/ports/SkTime_Unix.cpp',
'../src/ports/SkTLS_pthread.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 }, { # else !win
'sources!': [ 'sources!': [
'../src/ports/SkDebug_win.cpp', '../src/ports/SkDebug_win.cpp',
'../src/ports/SkFontHost_win.cpp', '../src/ports/SkFontHost_win.cpp',
'../src/ports/SkFontHost_win_dw.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/SkOSFile_win.cpp',
'../src/ports/SkThread_win.cpp', '../src/ports/SkThread_win.cpp',
'../src/ports/SkTime_win.cpp', '../src/ports/SkTime_win.cpp',

View File

@ -2371,6 +2371,7 @@ SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
#endif #endif
SkFontMgr* SkFontMgr::Factory() { extern SkFontMgr* SkFontMgr_New_GDI();
SkFontMgr* SkFontMgr_New_GDI() {
return SkNEW(SkFontMgrGDI); return SkNEW(SkFontMgrGDI);
} }

View File

@ -16,6 +16,7 @@
#include "SkEndian.h" #include "SkEndian.h"
#include "SkFontDescriptor.h" #include "SkFontDescriptor.h"
#include "SkFontHost.h" #include "SkFontHost.h"
#include "SkFontMgr.h"
#include "SkFontStream.h" #include "SkFontStream.h"
#include "SkGlyph.h" #include "SkGlyph.h"
#include "SkHRESULT.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 { class DWriteOffscreen {
public: public:
DWriteOffscreen() : fWidth(0), fHeight(0) { DWriteOffscreen() : fWidth(0), fHeight(0) {
@ -704,20 +767,6 @@ static bool FindByDWriteFont(SkTypeface* face, SkTypeface::Style requestedStyle,
wcscmp(dwFaceFontNameChar.get(), dwFontNameChar.get()) == 0; 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) { void SkDWriteFontFromTypeface(const SkTypeface* face, IDWriteFont** font) {
if (NULL == face) { if (NULL == face) {
HRVM(get_default_font(font), "Could not get default font."); 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(); UINT32 faceIndex = fontFace->GetIndex();
if (faceIndex == ttcIndex) { if (faceIndex == ttcIndex) {
return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily.get(), return DWriteFontTypeface::Create(fontFace.get(), font.get(), fontFamily.get(),
autoUnregisterFontFileLoader.detatch(), autoUnregisterFontFileLoader.detatch(),
autoUnregisterFontCollectionLoader.detatch()); autoUnregisterFontCollectionLoader.detatch());
} }
} }
} }
@ -1596,7 +1645,8 @@ SkAdvancedTypefaceMetrics* DWriteFontTypeface::onGetAdvancedTypefaceMetrics(
static SkTypeface* create_typeface(const SkTypeface* familyFace, static SkTypeface* create_typeface(const SkTypeface* familyFace,
const char familyName[], const char familyName[],
unsigned style) { unsigned style,
SkFontMgr_DirectWrite* fontMgr) {
HRESULT hr; HRESULT hr;
SkTScopedComPtr<IDWriteFontFamily> fontFamily; SkTScopedComPtr<IDWriteFontFamily> fontFamily;
if (familyFace) { if (familyFace) {
@ -1627,17 +1677,17 @@ static SkTypeface* create_typeface(const SkTypeface* familyFace,
SkTScopedComPtr<IDWriteFontFace> fontFace; SkTScopedComPtr<IDWriteFontFace> fontFace;
hr = font->CreateFontFace(&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 { 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, static void get_locale_string(IDWriteLocalizedStrings* names, const WCHAR* preferedLocale,
SkString* skname) { SkString* skname) {
UINT32 nameIndex = 0; UINT32 nameIndex = 0;
@ -1660,143 +1710,108 @@ static void get_locale_string(IDWriteLocalizedStrings* names, const WCHAR* prefe
HRV(wchar_to_skstring(name.get(), skname)); HRV(wchar_to_skstring(name.get(), skname));
} }
class SkFontMgr_DirectWrite; SkTypeface* SkFontMgr_DirectWrite::createTypefaceFromDWriteFont(
IDWriteFontFace* fontFace,
class SkFontStyleSet_DirectWrite : public SkFontStyleSet { IDWriteFont* font,
public: IDWriteFontFamily* fontFamily,
SkFontStyleSet_DirectWrite(const SkFontMgr_DirectWrite* fontMgr, IDWriteFontFamily* fontFamily) StreamFontFileLoader* fontFileLoader,
: fFontMgr(SkRef(fontMgr)) IDWriteFontCollectionLoader* fontCollectionLoader) {
, fFontFamily(SkRefComPtr(fontFamily)) SkTypeface* face = fTFCache.findByProcAndRef(FindByDWriteFont, font);
{ } if (NULL == face) {
face = DWriteFontTypeface::Create(fontFace, font, fontFamily,
virtual int count() SK_OVERRIDE { fontFileLoader, fontCollectionLoader);
return fFontFamily->GetFontCount(); if (face) {
} fTFCache.add(face, get_style(font), fontCollectionLoader != NULL);
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.");
SkTScopedComPtr<IDWriteFontFace> 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);
} }
}
return face;
}
DWRITE_FONT_WEIGHT weight = (DWRITE_FONT_WEIGHT)pattern.weight(); int SkFontMgr_DirectWrite::onCountFamilies() {
DWRITE_FONT_STRETCH width = (DWRITE_FONT_STRETCH)pattern.width(); return fFontCollection->GetFontFamilyCount();
}
SkTScopedComPtr<IDWriteFont> font; void SkFontMgr_DirectWrite::onGetFamilyName(int index, SkString* familyName) {
// TODO: perhaps use GetMatchingFonts and get the least simulated? SkTScopedComPtr<IDWriteFontFamily> fontFamily;
HRNM(fFontFamily->GetFirstMatchingFont(weight, width, slant, &font), HRVM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requested family.");
"Could not match font in family.");
SkTScopedComPtr<IDWriteFontFace> fontFace; SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
HRNM(font->CreateFontFace(&fontFace), "Could not create font face."); 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<IDWriteFontFamily> 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: return this->onCreateStyleSet(index);
SkAutoTUnref<const SkFontMgr_DirectWrite> fFontMgr; }
SkTScopedComPtr<IDWriteFontFamily> fFontFamily;
};
class SkFontMgr_DirectWrite : public SkFontMgr { SkTypeface* SkFontMgr_DirectWrite::onMatchFamilyStyle(const char familyName[],
public: const SkFontStyle& fontstyle) {
/** localeNameLength must include the null terminator. */ SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName));
SkFontMgr_DirectWrite(IDWriteFontCollection* fontCollection, return sset->matchStyle(fontstyle);
WCHAR* localeName, int localeNameLength) }
: fFontCollection(SkRefComPtr(fontCollection))
, fLocaleName(localeNameLength)
{
memcpy(fLocaleName.get(), localeName, localeNameLength * sizeof(WCHAR));
}
private: SkTypeface* SkFontMgr_DirectWrite::onMatchFaceStyle(const SkTypeface* familyMember,
friend class SkFontStyleSet_DirectWrite; const SkFontStyle& fontstyle) {
SkTScopedComPtr<IDWriteFontCollection> fFontCollection; SkString familyName;
SkSMallocWCHAR fLocaleName; SkFontStyleSet_DirectWrite sset(
this, ((DWriteFontTypeface*)familyMember)->fDWriteFontFamily.get()
);
return sset.matchStyle(fontstyle);
}
protected: SkTypeface* SkFontMgr_DirectWrite::onCreateFromStream(SkStream* stream, int ttcIndex) {
virtual int onCountFamilies() SK_OVERRIDE { return create_from_stream(stream, ttcIndex);
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.");
SkTScopedComPtr<IDWriteLocalizedStrings> familyNames; SkTypeface* SkFontMgr_DirectWrite::onCreateFromData(SkData* data, int ttcIndex) {
HRVM(fontFamily->GetFamilyNames(&familyNames), "Could not get family names."); SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, (data)));
return this->createFromStream(stream, ttcIndex);
}
get_locale_string(familyNames.get(), fLocaleName.get(), familyName); SkTypeface* SkFontMgr_DirectWrite::onCreateFromFile(const char path[], int ttcIndex) {
} SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
virtual SkFontStyleSet* onCreateStyleSet(int index) SK_OVERRIDE { return this->createFromStream(stream, ttcIndex);
SkTScopedComPtr<IDWriteFontFamily> fontFamily; }
HRNM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requested family.");
return SkNEW_ARGS(SkFontStyleSet_DirectWrite, (this, fontFamily.get())); SkTypeface* SkFontMgr_DirectWrite::onLegacyCreateTypeface(const char familyName[],
} unsigned styleBits) {
virtual SkFontStyleSet* onMatchFamily(const char familyName[]) SK_OVERRIDE { return create_typeface(NULL, familyName, styleBits, this);
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;
}
return this->onCreateStyleSet(index); int SkFontStyleSet_DirectWrite::count() {
} return fFontFamily->GetFontCount();
}
virtual SkTypeface* onMatchFamilyStyle(const char familyName[], SkTypeface* SkFontStyleSet_DirectWrite::createTypeface(int index) {
const SkFontStyle& fontstyle) SK_OVERRIDE { SkTScopedComPtr<IDWriteFont> font;
SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName)); HRNM(fFontFamily->GetFont(index, &font), "Could not get font.");
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);
}
virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], SkTScopedComPtr<IDWriteFontFace> fontFace;
unsigned styleBits) SK_OVERRIDE { HRNM(font->CreateFontFace(&fontFace), "Could not create font face.");
return create_typeface(NULL, familyName, styleBits);
} return fFontMgr->createTypefaceFromDWriteFont(fontFace.get(), font.get(), fFontFamily.get());
}; }
void SkFontStyleSet_DirectWrite::getStyle(int index, SkFontStyle* fs, SkString* styleName) { void SkFontStyleSet_DirectWrite::getStyle(int index, SkFontStyle* fs, SkString* styleName) {
SkTScopedComPtr<IDWriteFont> font; 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 #ifndef SK_FONTHOST_USES_FONTMGR
@ -1833,7 +1876,7 @@ void SkFontStyleSet_DirectWrite::getStyle(int index, SkFontStyle* fs, SkString*
SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
const char familyName[], const char familyName[],
SkTypeface::Style style) { SkTypeface::Style style) {
return create_typeface(familyFace, familyName, style); return create_typeface(familyFace, familyName, style, NULL);
} }
SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) { SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
@ -1847,7 +1890,8 @@ SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
#endif #endif
SkFontMgr* SkFontMgr::Factory() { extern SkFontMgr* SkFontMgr_New_DirectWrite();
SkFontMgr* SkFontMgr_New_DirectWrite() {
IDWriteFactory* factory; IDWriteFactory* factory;
HRNM(get_dwrite_factory(&factory), "Could not get 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)); return SkNEW_ARGS(SkFontMgr_DirectWrite, (sysFontCollection.get(), localeName, localeNameLen));
} }

View File

@ -0,0 +1,7 @@
#include "SkFontMgr.h"
extern SkFontMgr* SkFontMgr_New_DirectWrite();
SkFontMgr* SkFontMgr::Factory() {
return SkFontMgr_New_DirectWrite();
}

View File

@ -0,0 +1,7 @@
#include "SkFontMgr.h"
extern SkFontMgr* SkFontMgr_New_GDI();
SkFontMgr* SkFontMgr::Factory() {
return SkFontMgr_New_GDI();
}