| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkTypes.h" | 8 #include "SkTypes.h" |
| 9 #if defined(SK_BUILD_FOR_WIN32) | 9 #if defined(SK_BUILD_FOR_WIN32) |
| 10 | 10 |
| 11 #include "SkDWrite.h" | 11 #include "SkDWrite.h" |
| 12 #include "SkDWriteFontFileStream.h" | 12 #include "SkDWriteFontFileStream.h" |
| 13 #include "SkFontMgr.h" | 13 #include "SkFontMgr.h" |
| 14 #include "SkHRESULT.h" | 14 #include "SkHRESULT.h" |
| 15 #include "SkMutex.h" | 15 #include "SkMutex.h" |
| 16 #include "SkStream.h" | 16 #include "SkStream.h" |
| 17 #include "SkTScopedComPtr.h" | 17 #include "SkTScopedComPtr.h" |
| 18 #include "SkTypeface.h" | 18 #include "SkTypeface.h" |
| 19 #include "SkTypefaceCache.h" | 19 #include "SkTypefaceCache.h" |
| 20 #include "SkTypeface_win_dw.h" | 20 #include "SkTypeface_win_dw.h" |
| 21 #include "SkTypes.h" | 21 #include "SkTypes.h" |
| 22 #include "SkUtils.h" | 22 #include "SkUtils.h" |
| 23 | 23 |
| 24 #include <dwrite.h> | 24 #include <dwrite.h> |
| 25 | 25 |
| 26 #if SK_HAS_DWRITE_2_H | 26 #if SK_HAS_DWRITE_2_H |
| 27 #include <dwrite_2.h> | 27 #include <dwrite_2.h> |
| 28 #else | |
| 29 struct IDWriteFontFallback; | |
| 30 #endif | 28 #endif |
| 31 | 29 |
| 32 //////////////////////////////////////////////////////////////////////////////// | 30 //////////////////////////////////////////////////////////////////////////////// |
| 33 | 31 |
| 34 class StreamFontFileLoader : public IDWriteFontFileLoader { | 32 class StreamFontFileLoader : public IDWriteFontFileLoader { |
| 35 public: | 33 public: |
| 36 // IUnknown methods | 34 // IUnknown methods |
| 37 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObjec
t); | 35 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObjec
t); |
| 38 virtual ULONG STDMETHODCALLTYPE AddRef(); | 36 virtual ULONG STDMETHODCALLTYPE AddRef(); |
| 39 virtual ULONG STDMETHODCALLTYPE Release(); | 37 virtual ULONG STDMETHODCALLTYPE Release(); |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 *fontFileEnumerator = enumerator.release(); | 257 *fontFileEnumerator = enumerator.release(); |
| 260 return S_OK; | 258 return S_OK; |
| 261 } | 259 } |
| 262 | 260 |
| 263 //////////////////////////////////////////////////////////////////////////////// | 261 //////////////////////////////////////////////////////////////////////////////// |
| 264 | 262 |
| 265 class SkFontMgr_DirectWrite : public SkFontMgr { | 263 class SkFontMgr_DirectWrite : public SkFontMgr { |
| 266 public: | 264 public: |
| 267 /** localeNameLength must include the null terminator. */ | 265 /** localeNameLength must include the null terminator. */ |
| 268 SkFontMgr_DirectWrite(IDWriteFactory* factory, IDWriteFontCollection* fontCo
llection, | 266 SkFontMgr_DirectWrite(IDWriteFactory* factory, IDWriteFontCollection* fontCo
llection, |
| 269 WCHAR* localeName, int localeNameLength, IDWriteFontFa
llback* fallback) | 267 WCHAR* localeName, int localeNameLength) |
| 270 : fFactory(SkRefComPtr(factory)) | 268 : fFactory(SkRefComPtr(factory)) |
| 271 #if SK_HAS_DWRITE_2_H | |
| 272 , fFontFallback(SkSafeRefComPtr(fallback)) | |
| 273 #endif | |
| 274 , fFontCollection(SkRefComPtr(fontCollection)) | 269 , fFontCollection(SkRefComPtr(fontCollection)) |
| 275 , fLocaleName(localeNameLength) | 270 , fLocaleName(localeNameLength) |
| 276 { | 271 { |
| 277 #if SK_HAS_DWRITE_2_H | 272 #if SK_HAS_DWRITE_2_H |
| 278 if (!SUCCEEDED(fFactory->QueryInterface(&fFactory2))) { | 273 if (!SUCCEEDED(fFactory->QueryInterface(&fFactory2))) { |
| 279 // IUnknown::QueryInterface states that if it fails, punk will be se
t to nullptr. | 274 // IUnknown::QueryInterface states that if it fails, punk will be se
t to nullptr. |
| 280 // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/26/96777.aspx | 275 // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/26/96777.aspx |
| 281 SkASSERT_RELEASE(nullptr == fFactory2.get()); | 276 SkASSERT_RELEASE(nullptr == fFactory2.get()); |
| 282 } | 277 } |
| 283 #endif | 278 #endif |
| (...skipping 23 matching lines...) Expand all Loading... |
| 307 HRESULT getDefaultFontFamily(IDWriteFontFamily** fontFamily) const; | 302 HRESULT getDefaultFontFamily(IDWriteFontFamily** fontFamily) const; |
| 308 | 303 |
| 309 /** Creates a typeface using a typeface cache. */ | 304 /** Creates a typeface using a typeface cache. */ |
| 310 SkTypeface* createTypefaceFromDWriteFont(IDWriteFontFace* fontFace, | 305 SkTypeface* createTypefaceFromDWriteFont(IDWriteFontFace* fontFace, |
| 311 IDWriteFont* font, | 306 IDWriteFont* font, |
| 312 IDWriteFontFamily* fontFamily) cons
t; | 307 IDWriteFontFamily* fontFamily) cons
t; |
| 313 | 308 |
| 314 SkTScopedComPtr<IDWriteFactory> fFactory; | 309 SkTScopedComPtr<IDWriteFactory> fFactory; |
| 315 #if SK_HAS_DWRITE_2_H | 310 #if SK_HAS_DWRITE_2_H |
| 316 SkTScopedComPtr<IDWriteFactory2> fFactory2; | 311 SkTScopedComPtr<IDWriteFactory2> fFactory2; |
| 317 SkTScopedComPtr<IDWriteFontFallback> fFontFallback; | |
| 318 #endif | 312 #endif |
| 319 SkTScopedComPtr<IDWriteFontCollection> fFontCollection; | 313 SkTScopedComPtr<IDWriteFontCollection> fFontCollection; |
| 320 SkSMallocWCHAR fLocaleName; | 314 SkSMallocWCHAR fLocaleName; |
| 321 mutable SkMutex fTFCacheMutex; | 315 mutable SkMutex fTFCacheMutex; |
| 322 mutable SkTypefaceCache fTFCache; | 316 mutable SkTypefaceCache fTFCache; |
| 323 | 317 |
| 324 friend class SkFontStyleSet_DirectWrite; | 318 friend class SkFontStyleSet_DirectWrite; |
| 325 friend class FontFallbackRenderer; | 319 friend class FontFallbackRenderer; |
| 326 }; | 320 }; |
| 327 | 321 |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 dwBcp47 = &fLocaleName; | 755 dwBcp47 = &fLocaleName; |
| 762 } else { | 756 } else { |
| 763 // TODO: support fallback stack. | 757 // TODO: support fallback stack. |
| 764 // TODO: DirectWrite supports 'zh-CN' or 'zh-Hans', but 'zh' misses comp
letely | 758 // TODO: DirectWrite supports 'zh-CN' or 'zh-Hans', but 'zh' misses comp
letely |
| 765 // and may produce a Japanese font. | 759 // and may produce a Japanese font. |
| 766 HRN(sk_cstring_to_wchar(bcp47[bcp47Count - 1], &dwBcp47Local)); | 760 HRN(sk_cstring_to_wchar(bcp47[bcp47Count - 1], &dwBcp47Local)); |
| 767 dwBcp47 = &dwBcp47Local; | 761 dwBcp47 = &dwBcp47Local; |
| 768 } | 762 } |
| 769 | 763 |
| 770 #if SK_HAS_DWRITE_2_H | 764 #if SK_HAS_DWRITE_2_H |
| 771 if (fFactory2.get() && fFontFallback.get()) { | 765 if (fFactory2.get()) { |
| 766 SkTScopedComPtr<IDWriteFontFallback> fontFallback; |
| 767 HRNM(fFactory2->GetSystemFontFallback(&fontFallback), "Could not get sys
tem fallback."); |
| 768 |
| 772 SkTScopedComPtr<IDWriteNumberSubstitution> numberSubstitution; | 769 SkTScopedComPtr<IDWriteNumberSubstitution> numberSubstitution; |
| 773 HRNM(fFactory2->CreateNumberSubstitution(DWRITE_NUMBER_SUBSTITUTION_METH
OD_NONE, nullptr, TRUE, | 770 HRNM(fFactory2->CreateNumberSubstitution(DWRITE_NUMBER_SUBSTITUTION_METH
OD_NONE, nullptr, TRUE, |
| 774 &numberSubstitution), | 771 &numberSubstitution), |
| 775 "Could not create number substitution."); | 772 "Could not create number substitution."); |
| 776 SkTScopedComPtr<FontFallbackSource> fontFallbackSource( | 773 SkTScopedComPtr<FontFallbackSource> fontFallbackSource( |
| 777 new FontFallbackSource(str, strLen, *dwBcp47, numberSubstitution.get
())); | 774 new FontFallbackSource(str, strLen, *dwBcp47, numberSubstitution.get
())); |
| 778 | 775 |
| 779 UINT32 mappedLength; | 776 UINT32 mappedLength; |
| 780 SkTScopedComPtr<IDWriteFont> font; | 777 SkTScopedComPtr<IDWriteFont> font; |
| 781 FLOAT scale; | 778 FLOAT scale; |
| 782 HRNM(fFontFallback->MapCharacters(fontFallbackSource.get(), | 779 HRNM(fontFallback->MapCharacters(fontFallbackSource.get(), |
| 783 0, // textPosition, | 780 0, // textPosition, |
| 784 strLen, | 781 strLen, |
| 785 fFontCollection.get(), | 782 fFontCollection.get(), |
| 786 dwFamilyName, | 783 dwFamilyName, |
| 787 dwStyle.fWeight, | 784 dwStyle.fWeight, |
| 788 dwStyle.fSlant, | 785 dwStyle.fSlant, |
| 789 dwStyle.fWidth, | 786 dwStyle.fWidth, |
| 790 &mappedLength, | 787 &mappedLength, |
| 791 &font, | 788 &font, |
| 792 &scale), | 789 &scale), |
| 793 "Could not map characters"); | 790 "Could not map characters"); |
| 794 if (!font.get()) { | 791 if (!font.get()) { |
| 795 return nullptr; | 792 return nullptr; |
| 796 } | 793 } |
| 797 | 794 |
| 798 SkTScopedComPtr<IDWriteFontFace> fontFace; | 795 SkTScopedComPtr<IDWriteFontFace> fontFace; |
| 799 HRNM(font->CreateFontFace(&fontFace), "Could not get font face from font
."); | 796 HRNM(font->CreateFontFace(&fontFace), "Could not get font face from font
."); |
| 800 | 797 |
| 801 SkTScopedComPtr<IDWriteFontFamily> fontFamily; | 798 SkTScopedComPtr<IDWriteFontFamily> fontFamily; |
| 802 HRNM(font->GetFontFamily(&fontFamily), "Could not get family from font."
); | 799 HRNM(font->GetFontFamily(&fontFamily), "Could not get family from font."
); |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1079 } | 1076 } |
| 1080 } | 1077 } |
| 1081 | 1078 |
| 1082 SkTScopedComPtr<IDWriteFontCollection> systemFontCollection; | 1079 SkTScopedComPtr<IDWriteFontCollection> systemFontCollection; |
| 1083 if (nullptr == collection) { | 1080 if (nullptr == collection) { |
| 1084 HRNM(factory->GetSystemFontCollection(&systemFontCollection, FALSE), | 1081 HRNM(factory->GetSystemFontCollection(&systemFontCollection, FALSE), |
| 1085 "Could not get system font collection."); | 1082 "Could not get system font collection."); |
| 1086 collection = systemFontCollection.get(); | 1083 collection = systemFontCollection.get(); |
| 1087 } | 1084 } |
| 1088 | 1085 |
| 1089 IDWriteFontFallback *fontFallback = nullptr; | |
| 1090 #if SK_HAS_DWRITE_2_H | |
| 1091 SkTScopedComPtr<IDWriteFontFallback> systemFontFallback; | |
| 1092 SkTScopedComPtr<IDWriteFactory2> fFactory2; | |
| 1093 factory->QueryInterface(&fFactory2); | |
| 1094 if (fFactory2.get()) { | |
| 1095 HRNM(fFactory2->GetSystemFontFallback(&systemFontFallback), | |
| 1096 "Could not get system fallback."); | |
| 1097 fontFallback = systemFontFallback.get(); | |
| 1098 } | |
| 1099 #endif | |
| 1100 | |
| 1101 WCHAR localeNameStorage[LOCALE_NAME_MAX_LENGTH]; | 1086 WCHAR localeNameStorage[LOCALE_NAME_MAX_LENGTH]; |
| 1102 WCHAR* localeName = nullptr; | 1087 WCHAR* localeName = nullptr; |
| 1103 int localeNameLen = 0; | 1088 int localeNameLen = 0; |
| 1104 | 1089 |
| 1105 // Dynamically load GetUserDefaultLocaleName function, as it is not availabl
e on XP. | 1090 // Dynamically load GetUserDefaultLocaleName function, as it is not availabl
e on XP. |
| 1106 SkGetUserDefaultLocaleNameProc getUserDefaultLocaleNameProc = nullptr; | 1091 SkGetUserDefaultLocaleNameProc getUserDefaultLocaleNameProc = nullptr; |
| 1107 HRESULT hr = SkGetGetUserDefaultLocaleNameProc(&getUserDefaultLocaleNameProc
); | 1092 HRESULT hr = SkGetGetUserDefaultLocaleNameProc(&getUserDefaultLocaleNameProc
); |
| 1108 if (nullptr == getUserDefaultLocaleNameProc) { | 1093 if (nullptr == getUserDefaultLocaleNameProc) { |
| 1109 SK_TRACEHR(hr, "Could not get GetUserDefaultLocaleName."); | 1094 SK_TRACEHR(hr, "Could not get GetUserDefaultLocaleName."); |
| 1110 } else { | 1095 } else { |
| 1111 localeNameLen = getUserDefaultLocaleNameProc(localeNameStorage, LOCALE_N
AME_MAX_LENGTH); | 1096 localeNameLen = getUserDefaultLocaleNameProc(localeNameStorage, LOCALE_N
AME_MAX_LENGTH); |
| 1112 if (localeNameLen) { | 1097 if (localeNameLen) { |
| 1113 localeName = localeNameStorage; | 1098 localeName = localeNameStorage; |
| 1114 }; | 1099 }; |
| 1115 } | 1100 } |
| 1116 | 1101 |
| 1117 return new SkFontMgr_DirectWrite( | 1102 return new SkFontMgr_DirectWrite(factory, collection, localeName, localeName
Len); |
| 1118 factory, collection, localeName, localeNameLen, fontFallback); | |
| 1119 } | 1103 } |
| 1120 | 1104 |
| 1121 #include "SkFontMgr_indirect.h" | 1105 #include "SkFontMgr_indirect.h" |
| 1122 SK_API SkFontMgr* SkFontMgr_New_DirectWriteRenderer(SkRemotableFontMgr* proxy) { | 1106 SK_API SkFontMgr* SkFontMgr_New_DirectWriteRenderer(SkRemotableFontMgr* proxy) { |
| 1123 SkAutoTUnref<SkFontMgr> impl(SkFontMgr_New_DirectWrite()); | 1107 SkAutoTUnref<SkFontMgr> impl(SkFontMgr_New_DirectWrite()); |
| 1124 if (impl.get() == nullptr) { | 1108 if (impl.get() == nullptr) { |
| 1125 return nullptr; | 1109 return nullptr; |
| 1126 } | 1110 } |
| 1127 return new SkFontMgr_Indirect(impl.get(), proxy); | 1111 return new SkFontMgr_Indirect(impl.get(), proxy); |
| 1128 } | 1112 } |
| 1129 #endif//defined(SK_BUILD_FOR_WIN32) | 1113 #endif//defined(SK_BUILD_FOR_WIN32) |
| OLD | NEW |