#include "SkEndian.h"
#include "SkFontDescriptor.h"
#include "SkFontHost.h"
-#include "SkFontMgr.h"
#include "SkFontStream.h"
#include "SkGlyph.h"
#include "SkHRESULT.h"
///////////////////////////////////////////////////////////////////////////////
-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) {
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.");
UINT32 faceIndex = fontFace->GetIndex();
if (faceIndex == ttcIndex) {
- return DWriteFontTypeface::Create(fontFace.get(), font.get(), fontFamily.get(),
- autoUnregisterFontFileLoader.detatch(),
- autoUnregisterFontCollectionLoader.detatch());
+ return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily.get(),
+ autoUnregisterFontFileLoader.detatch(),
+ autoUnregisterFontCollectionLoader.detatch());
}
}
}
static SkTypeface* create_typeface(const SkTypeface* familyFace,
const char familyName[],
- unsigned style,
- SkFontMgr_DirectWrite* fontMgr) {
+ unsigned style) {
HRESULT hr;
SkTScopedComPtr<IDWriteFontFamily> fontFamily;
if (familyFace) {
SkTScopedComPtr<IDWriteFontFace> fontFace;
hr = font->CreateFontFace(&fontFace);
- return fontMgr->createTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily.get());
+ return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily.get());
}
SkTypeface* DWriteFontTypeface::onRefMatchingStyle(Style style) const {
- SkFontMgr_DirectWrite* fontMgr = NULL;
- // todo: should each typeface have a ref to its fontmgr/cache?
- return create_typeface(this, NULL, style, fontMgr);
+ return create_typeface(this, NULL, style);
}
///////////////////////////////////////////////////////////////////////////////
+#include "SkFontMgr.h"
+
static void get_locale_string(IDWriteLocalizedStrings* names, const WCHAR* preferedLocale,
SkString* skname) {
UINT32 nameIndex = 0;
HRV(wchar_to_skstring(name.get(), skname));
}
-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);
- }
+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();
}
- return face;
-}
-int SkFontMgr_DirectWrite::onCountFamilies() {
- return fFontCollection->GetFontFamilyCount();
-}
+ virtual void getStyle(int index, SkFontStyle* fs, SkString* styleName);
-void SkFontMgr_DirectWrite::onGetFamilyName(int index, SkString* familyName) {
- SkTScopedComPtr<IDWriteFontFamily> fontFamily;
- HRVM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requested family.");
+ virtual SkTypeface* createTypeface(int index) SK_OVERRIDE {
+ SkTScopedComPtr<IDWriteFont> font;
+ HRNM(fFontFamily->GetFont(index, &font), "Could not get font.");
- SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
- HRVM(fontFamily->GetFamilyNames(&familyNames), "Could not get family names.");
+ SkTScopedComPtr<IDWriteFontFace> fontFace;
+ HRNM(font->CreateFontFace(&fontFace), "Could not create font face.");
- get_locale_string(familyNames.get(), fLocaleName.get(), familyName);
-}
+ return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fFontFamily.get());
+ }
-SkFontStyleSet* SkFontMgr_DirectWrite::onCreateStyleSet(int index) {
- SkTScopedComPtr<IDWriteFontFamily> fontFamily;
- HRNM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requested family.");
+ 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 SkNEW_ARGS(SkFontStyleSet_DirectWrite, (this, fontFamily.get()));
-}
+ DWRITE_FONT_WEIGHT weight = (DWRITE_FONT_WEIGHT)pattern.weight();
+ DWRITE_FONT_STRETCH width = (DWRITE_FONT_STRETCH)pattern.width();
-SkFontStyleSet* SkFontMgr_DirectWrite::onMatchFamily(const char familyName[]) {
- SkSMallocWCHAR dwFamilyName;
- HRN(cstring_to_wchar(familyName, &dwFamilyName));
+ 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.");
- UINT32 index;
- BOOL exists;
- HRNM(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &exists),
- "Failed while finding family by name.");
- if (!exists) {
- return NULL;
- }
+ SkTScopedComPtr<IDWriteFontFace> fontFace;
+ HRNM(font->CreateFontFace(&fontFace), "Could not create font face.");
- return this->onCreateStyleSet(index);
-}
+ return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fFontFamily.get());
+ }
-SkTypeface* SkFontMgr_DirectWrite::onMatchFamilyStyle(const char familyName[],
- const SkFontStyle& fontstyle) {
- SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName));
- return sset->matchStyle(fontstyle);
-}
+private:
+ SkAutoTUnref<const SkFontMgr_DirectWrite> fFontMgr;
+ SkTScopedComPtr<IDWriteFontFamily> fFontFamily;
+};
-SkTypeface* SkFontMgr_DirectWrite::onMatchFaceStyle(const SkTypeface* familyMember,
- const SkFontStyle& fontstyle) {
- SkString familyName;
- SkFontStyleSet_DirectWrite sset(
- this, ((DWriteFontTypeface*)familyMember)->fDWriteFontFamily.get()
- );
- return sset.matchStyle(fontstyle);
-}
+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::onCreateFromStream(SkStream* stream, int ttcIndex) {
- return create_from_stream(stream, ttcIndex);
-}
+private:
+ friend class SkFontStyleSet_DirectWrite;
+ SkTScopedComPtr<IDWriteFontCollection> fFontCollection;
+ SkSMallocWCHAR fLocaleName;
-SkTypeface* SkFontMgr_DirectWrite::onCreateFromData(SkData* data, int ttcIndex) {
- SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, (data)));
- return this->createFromStream(stream, ttcIndex);
-}
+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::onCreateFromFile(const char path[], int ttcIndex) {
- SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
- return this->createFromStream(stream, ttcIndex);
-}
+ SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
+ HRVM(fontFamily->GetFamilyNames(&familyNames), "Could not get family names.");
-SkTypeface* SkFontMgr_DirectWrite::onLegacyCreateTypeface(const char familyName[],
- unsigned styleBits) {
- return create_typeface(NULL, familyName, styleBits, this);
-}
+ 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.");
-///////////////////////////////////////////////////////////////////////////////
+ return SkNEW_ARGS(SkFontStyleSet_DirectWrite, (this, fontFamily.get()));
+ }
+ virtual SkFontStyleSet* onMatchFamily(const char familyName[]) SK_OVERRIDE {
+ SkSMallocWCHAR dwFamilyName;
+ HRN(cstring_to_wchar(familyName, &dwFamilyName));
-int SkFontStyleSet_DirectWrite::count() {
- return fFontFamily->GetFontCount();
-}
+ UINT32 index;
+ BOOL exists;
+ HRNM(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &exists),
+ "Failed while finding family by name.");
+ if (!exists) {
+ return NULL;
+ }
-SkTypeface* SkFontStyleSet_DirectWrite::createTypeface(int index) {
- SkTScopedComPtr<IDWriteFont> font;
- HRNM(fFontFamily->GetFont(index, &font), "Could not get font.");
+ return this->onCreateStyleSet(index);
+ }
- SkTScopedComPtr<IDWriteFontFace> fontFace;
- HRNM(font->CreateFontFace(&fontFace), "Could not create font face.");
+ 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);
+ }
- return fFontMgr->createTypefaceFromDWriteFont(fontFace.get(), font.get(), fFontFamily.get());
-}
+ virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
+ unsigned styleBits) SK_OVERRIDE {
+ return create_typeface(NULL, familyName, styleBits);
+ }
+};
void SkFontStyleSet_DirectWrite::getStyle(int index, SkFontStyle* fs, SkString* styleName) {
SkTScopedComPtr<IDWriteFont> font;
}
}
-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
SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
const char familyName[],
SkTypeface::Style style) {
- return create_typeface(familyFace, familyName, style, NULL);
+ return create_typeface(familyFace, familyName, style);
}
SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
#endif
-extern SkFontMgr* SkFontMgr_New_DirectWrite();
-SkFontMgr* SkFontMgr_New_DirectWrite() {
+SkFontMgr* SkFontMgr::Factory() {
IDWriteFactory* factory;
HRNM(get_dwrite_factory(&factory), "Could not get factory.");