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