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:
parent
04507b9fd9
commit
7d65dee189
@ -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
|
||||||
|
@ -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',
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
7
src/ports/SkFontMgr_default_dw.cpp
Normal file
7
src/ports/SkFontMgr_default_dw.cpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "SkFontMgr.h"
|
||||||
|
|
||||||
|
extern SkFontMgr* SkFontMgr_New_DirectWrite();
|
||||||
|
|
||||||
|
SkFontMgr* SkFontMgr::Factory() {
|
||||||
|
return SkFontMgr_New_DirectWrite();
|
||||||
|
}
|
7
src/ports/SkFontMgr_default_gdi.cpp
Normal file
7
src/ports/SkFontMgr_default_gdi.cpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "SkFontMgr.h"
|
||||||
|
|
||||||
|
extern SkFontMgr* SkFontMgr_New_GDI();
|
||||||
|
|
||||||
|
SkFontMgr* SkFontMgr::Factory() {
|
||||||
|
return SkFontMgr_New_GDI();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user