| Index: src/ports/SkFontHost_win_dw.cpp
|
| diff --git a/src/ports/SkFontHost_win_dw.cpp b/src/ports/SkFontHost_win_dw.cpp
|
| index e1685e63b0750cbc2afe20657d6e5bd2bfc1b9b2..b17195d0c4d150e45ab15c6e74be866da640c82f 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<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));
|
| }
|
| +
|
|
|