OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 #undef GetGlyphIndices | 9 #undef GetGlyphIndices |
10 | 10 |
11 #include "SkAdvancedTypefaceMetrics.h" | 11 #include "SkAdvancedTypefaceMetrics.h" |
12 #include "SkColorFilter.h" | 12 #include "SkColorFilter.h" |
| 13 #include "SkDWrite.h" |
13 #include "SkDWriteFontFileStream.h" | 14 #include "SkDWriteFontFileStream.h" |
14 #include "SkDWriteGeometrySink.h" | 15 #include "SkDWriteGeometrySink.h" |
15 #include "SkDescriptor.h" | 16 #include "SkDescriptor.h" |
16 #include "SkEndian.h" | 17 #include "SkEndian.h" |
17 #include "SkFontDescriptor.h" | 18 #include "SkFontDescriptor.h" |
18 #include "SkFontHost.h" | 19 #include "SkFontHost.h" |
19 #include "SkFontMgr.h" | 20 #include "SkFontMgr.h" |
20 #include "SkFontStream.h" | 21 #include "SkFontStream.h" |
21 #include "SkGlyph.h" | 22 #include "SkGlyph.h" |
22 #include "SkHRESULT.h" | 23 #include "SkHRESULT.h" |
(...skipping 12 matching lines...) Expand all Loading... |
35 #include "SkTypefaceCache.h" | 36 #include "SkTypefaceCache.h" |
36 #include "SkUtils.h" | 37 #include "SkUtils.h" |
37 | 38 |
38 #include <dwrite.h> | 39 #include <dwrite.h> |
39 | 40 |
40 static bool isLCD(const SkScalerContext::Rec& rec) { | 41 static bool isLCD(const SkScalerContext::Rec& rec) { |
41 return SkMask::kLCD16_Format == rec.fMaskFormat || | 42 return SkMask::kLCD16_Format == rec.fMaskFormat || |
42 SkMask::kLCD32_Format == rec.fMaskFormat; | 43 SkMask::kLCD32_Format == rec.fMaskFormat; |
43 } | 44 } |
44 | 45 |
45 /** Prefer to use this type to prevent template proliferation. */ | |
46 typedef SkAutoSTMalloc<16, WCHAR> SkSMallocWCHAR; | |
47 | |
48 /** Converts a utf8 string to a WCHAR string. */ | |
49 static HRESULT cstring_to_wchar(const char* skname, SkSMallocWCHAR* name) { | |
50 int wlen = MultiByteToWideChar(CP_UTF8, 0, skname, -1, NULL, 0); | |
51 if (0 == wlen) { | |
52 HRM(HRESULT_FROM_WIN32(GetLastError()), | |
53 "Could not get length for wchar to utf-8 conversion."); | |
54 } | |
55 name->reset(wlen); | |
56 wlen = MultiByteToWideChar(CP_UTF8, 0, skname, -1, name->get(), wlen); | |
57 if (0 == wlen) { | |
58 HRM(HRESULT_FROM_WIN32(GetLastError()), "Could not convert wchar to utf-
8."); | |
59 } | |
60 return S_OK; | |
61 } | |
62 | |
63 /** Converts a WCHAR string to a utf8 string. */ | |
64 static HRESULT wchar_to_skstring(WCHAR* name, SkString* skname) { | |
65 int len = WideCharToMultiByte(CP_UTF8, 0, name, -1, NULL, 0, NULL, NULL); | |
66 if (0 == len) { | |
67 HRM(HRESULT_FROM_WIN32(GetLastError()), | |
68 "Could not get length for utf-8 to wchar conversion."); | |
69 } | |
70 skname->resize(len - 1); | |
71 | |
72 // TODO: remove after https://code.google.com/p/skia/issues/detail?id=1989 i
s fixed. | |
73 // If we resize to 0 then the skname points to gEmptyRec (the unique empty S
kString::Rec). | |
74 // gEmptyRec is static const and on Windows this means the value is in a rea
d only page. | |
75 // Writing to it in the following call to WideCharToMultiByte will cause an
access violation. | |
76 if (1 == len) { | |
77 return S_OK; | |
78 } | |
79 | |
80 len = WideCharToMultiByte(CP_UTF8, 0, name, -1, skname->writable_str(), len,
NULL, NULL); | |
81 if (0 == len) { | |
82 HRM(HRESULT_FROM_WIN32(GetLastError()), "Could not convert utf-8 to wcha
r."); | |
83 } | |
84 return S_OK; | |
85 } | |
86 | |
87 /////////////////////////////////////////////////////////////////////////////// | |
88 | |
89 static void create_dwrite_factory(IDWriteFactory** factory) { | |
90 typedef decltype(DWriteCreateFactory)* DWriteCreateFactoryProc; | |
91 DWriteCreateFactoryProc dWriteCreateFactoryProc = reinterpret_cast<DWriteCre
ateFactoryProc>( | |
92 GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory")); | |
93 | |
94 if (!dWriteCreateFactoryProc) { | |
95 HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); | |
96 if (!IS_ERROR(hr)) { | |
97 hr = ERROR_PROC_NOT_FOUND; | |
98 } | |
99 HRVM(hr, "Could not get DWriteCreateFactory proc."); | |
100 } | |
101 | |
102 HRVM(dWriteCreateFactoryProc(DWRITE_FACTORY_TYPE_SHARED, | |
103 __uuidof(IDWriteFactory), | |
104 reinterpret_cast<IUnknown**>(factory)), | |
105 "Could not create DirectWrite factory."); | |
106 } | |
107 | |
108 static IDWriteFactory* get_dwrite_factory() { | |
109 static IDWriteFactory* gDWriteFactory = NULL; | |
110 SK_DECLARE_STATIC_ONCE(once); | |
111 SkOnce(&once, create_dwrite_factory, &gDWriteFactory); | |
112 | |
113 return gDWriteFactory; | |
114 } | |
115 | |
116 /////////////////////////////////////////////////////////////////////////////// | 46 /////////////////////////////////////////////////////////////////////////////// |
117 | 47 |
118 class StreamFontFileLoader; | 48 class StreamFontFileLoader; |
119 | 49 |
120 class SkFontMgr_DirectWrite : public SkFontMgr { | 50 class SkFontMgr_DirectWrite : public SkFontMgr { |
121 public: | 51 public: |
122 /** localeNameLength must include the null terminator. */ | 52 /** localeNameLength must include the null terminator. */ |
123 SkFontMgr_DirectWrite(IDWriteFontCollection* fontCollection, | 53 SkFontMgr_DirectWrite(IDWriteFontCollection* fontCollection, |
124 WCHAR* localeName, int localeNameLength) | 54 WCHAR* localeName, int localeNameLength) |
125 : fFontCollection(SkRefComPtr(fontCollection)) | 55 : fFontCollection(SkRefComPtr(fontCollection)) |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 private: | 138 private: |
209 uint16_t fWidth; | 139 uint16_t fWidth; |
210 uint16_t fHeight; | 140 uint16_t fHeight; |
211 IDWriteFontFace* fFontFace; | 141 IDWriteFontFace* fFontFace; |
212 FLOAT fFontSize; | 142 FLOAT fFontSize; |
213 DWRITE_MATRIX fXform; | 143 DWRITE_MATRIX fXform; |
214 SkTDArray<uint8_t> fBits; | 144 SkTDArray<uint8_t> fBits; |
215 }; | 145 }; |
216 | 146 |
217 const void* DWriteOffscreen::draw(const SkGlyph& glyph, bool isBW) { | 147 const void* DWriteOffscreen::draw(const SkGlyph& glyph, bool isBW) { |
218 IDWriteFactory* factory = get_dwrite_factory(); | 148 IDWriteFactory* factory = sk_get_dwrite_factory(); |
219 SkASSERT(factory != NULL); | 149 SkASSERT(factory != NULL); |
220 | 150 |
221 if (fWidth < glyph.fWidth || fHeight < glyph.fHeight) { | 151 if (fWidth < glyph.fWidth || fHeight < glyph.fHeight) { |
222 fWidth = SkMax32(fWidth, glyph.fWidth); | 152 fWidth = SkMax32(fWidth, glyph.fWidth); |
223 fHeight = SkMax32(fHeight, glyph.fHeight); | 153 fHeight = SkMax32(fHeight, glyph.fHeight); |
224 | 154 |
225 if (isBW) { | 155 if (isBW) { |
226 fBits.setCount(fWidth * fHeight); | 156 fBits.setCount(fWidth * fHeight); |
227 } else { | 157 } else { |
228 fBits.setCount(fWidth * fHeight * 3); | 158 fBits.setCount(fWidth * fHeight * 3); |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 IDWriteFontFamily* fontFamily, | 483 IDWriteFontFamily* fontFamily, |
554 StreamFontFileLoader* fontFileLoader = NUL
L, | 484 StreamFontFileLoader* fontFileLoader = NUL
L, |
555 IDWriteFontCollectionLoader* fontCollectio
nLoader = NULL) { | 485 IDWriteFontCollectionLoader* fontCollectio
nLoader = NULL) { |
556 SkTypeface::Style style = get_style(font); | 486 SkTypeface::Style style = get_style(font); |
557 SkFontID fontID = SkTypefaceCache::NewFontID(); | 487 SkFontID fontID = SkTypefaceCache::NewFontID(); |
558 return SkNEW_ARGS(DWriteFontTypeface, (style, fontID, | 488 return SkNEW_ARGS(DWriteFontTypeface, (style, fontID, |
559 fontFace, font, fontFamily, | 489 fontFace, font, fontFamily, |
560 fontFileLoader, fontCollectionLoa
der)); | 490 fontFileLoader, fontCollectionLoa
der)); |
561 } | 491 } |
562 | 492 |
563 ~DWriteFontTypeface() { | 493 protected: |
| 494 virtual void weak_dispose() const SK_OVERRIDE { |
564 if (fDWriteFontCollectionLoader.get() == NULL) return; | 495 if (fDWriteFontCollectionLoader.get() == NULL) return; |
565 | 496 |
566 IDWriteFactory* factory = get_dwrite_factory(); | 497 IDWriteFactory* factory = sk_get_dwrite_factory(); |
567 SkASSERT(factory != NULL); | 498 SkASSERT(factory != NULL); |
568 HRV(factory->UnregisterFontCollectionLoader(fDWriteFontCollectionLoader.
get())); | 499 HRV(factory->UnregisterFontCollectionLoader(fDWriteFontCollectionLoader.
get())); |
569 HRV(factory->UnregisterFontFileLoader(fDWriteFontFileLoader.get())); | 500 HRV(factory->UnregisterFontFileLoader(fDWriteFontFileLoader.get())); |
| 501 |
| 502 //SkTypefaceCache::Remove(this); |
| 503 INHERITED::weak_dispose(); |
570 } | 504 } |
571 | 505 |
572 protected: | |
573 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE; | 506 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE; |
574 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK
_OVERRIDE; | 507 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK
_OVERRIDE; |
575 virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE; | 508 virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE; |
576 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( | 509 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( |
577 SkAdvancedTypefaceMetrics::PerGlyphInfo, | 510 SkAdvancedTypefaceMetrics::PerGlyphInfo, |
578 const uint32_t*, uint32_t) const SK_OVERRIDE; | 511 const uint32_t*, uint32_t) const SK_OVERRIDE; |
579 virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE
; | 512 virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE
; |
580 virtual int onCharsToGlyphs(const void* chars, Encoding encoding, | 513 virtual int onCharsToGlyphs(const void* chars, Encoding encoding, |
581 uint16_t glyphs[], int glyphCount) const SK_OVER
RIDE; | 514 uint16_t glyphs[], int glyphCount) const SK_OVER
RIDE; |
582 virtual int onCountGlyphs() const SK_OVERRIDE; | 515 virtual int onCountGlyphs() const SK_OVERRIDE; |
583 virtual int onGetUPEM() const SK_OVERRIDE; | 516 virtual int onGetUPEM() const SK_OVERRIDE; |
584 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_
OVERRIDE; | 517 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_
OVERRIDE; |
585 virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; | 518 virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; |
586 virtual size_t onGetTableData(SkFontTableTag, size_t offset, | 519 virtual size_t onGetTableData(SkFontTableTag, size_t offset, |
587 size_t length, void* data) const SK_OVERRIDE; | 520 size_t length, void* data) const SK_OVERRIDE; |
| 521 |
| 522 private: |
| 523 typedef SkTypeface INHERITED; |
588 }; | 524 }; |
589 | 525 |
590 class SkScalerContext_DW : public SkScalerContext { | 526 class SkScalerContext_DW : public SkScalerContext { |
591 public: | 527 public: |
592 SkScalerContext_DW(DWriteFontTypeface*, const SkDescriptor* desc); | 528 SkScalerContext_DW(DWriteFontTypeface*, const SkDescriptor* desc); |
593 virtual ~SkScalerContext_DW(); | 529 virtual ~SkScalerContext_DW(); |
594 | 530 |
595 protected: | 531 protected: |
596 virtual unsigned generateGlyphCount() SK_OVERRIDE; | 532 virtual unsigned generateGlyphCount() SK_OVERRIDE; |
597 virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE; | 533 virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE; |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 DWRITE_GLYPH_RUN run; | 745 DWRITE_GLYPH_RUN run; |
810 run.glyphCount = 1; | 746 run.glyphCount = 1; |
811 run.glyphAdvances = &advance; | 747 run.glyphAdvances = &advance; |
812 run.fontFace = fTypeface->fDWriteFontFace.get(); | 748 run.fontFace = fTypeface->fDWriteFontFace.get(); |
813 run.fontEmSize = SkScalarToFloat(fRec.fTextSize); | 749 run.fontEmSize = SkScalarToFloat(fRec.fTextSize); |
814 run.bidiLevel = 0; | 750 run.bidiLevel = 0; |
815 run.glyphIndices = &glyphId; | 751 run.glyphIndices = &glyphId; |
816 run.isSideways = FALSE; | 752 run.isSideways = FALSE; |
817 run.glyphOffsets = &offset; | 753 run.glyphOffsets = &offset; |
818 | 754 |
819 IDWriteFactory* factory = get_dwrite_factory(); | 755 IDWriteFactory* factory = sk_get_dwrite_factory(); |
820 SkASSERT(factory != NULL); | 756 SkASSERT(factory != NULL); |
821 | 757 |
822 const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat; | 758 const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat; |
823 DWRITE_RENDERING_MODE renderingMode; | 759 DWRITE_RENDERING_MODE renderingMode; |
824 DWRITE_TEXTURE_TYPE textureType; | 760 DWRITE_TEXTURE_TYPE textureType; |
825 if (isBW) { | 761 if (isBW) { |
826 renderingMode = DWRITE_RENDERING_MODE_ALIASED; | 762 renderingMode = DWRITE_RENDERING_MODE_ALIASED; |
827 textureType = DWRITE_TEXTURE_ALIASED_1x1; | 763 textureType = DWRITE_TEXTURE_ALIASED_1x1; |
828 } else { | 764 } else { |
829 renderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC; | 765 renderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC; |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1060 SkTScopedComPtr<IDWriteLocalizedStrings> dwFamilyNames; | 996 SkTScopedComPtr<IDWriteLocalizedStrings> dwFamilyNames; |
1061 HRV(fDWriteFontFamily->GetFamilyNames(&dwFamilyNames)); | 997 HRV(fDWriteFontFamily->GetFamilyNames(&dwFamilyNames)); |
1062 | 998 |
1063 UINT32 dwFamilyNamesLength; | 999 UINT32 dwFamilyNamesLength; |
1064 HRV(dwFamilyNames->GetStringLength(0, &dwFamilyNamesLength)); | 1000 HRV(dwFamilyNames->GetStringLength(0, &dwFamilyNamesLength)); |
1065 | 1001 |
1066 SkSMallocWCHAR dwFamilyNameChar(dwFamilyNamesLength+1); | 1002 SkSMallocWCHAR dwFamilyNameChar(dwFamilyNamesLength+1); |
1067 HRV(dwFamilyNames->GetString(0, dwFamilyNameChar.get(), dwFamilyNamesLength+
1)); | 1003 HRV(dwFamilyNames->GetString(0, dwFamilyNameChar.get(), dwFamilyNamesLength+
1)); |
1068 | 1004 |
1069 SkString utf8FamilyName; | 1005 SkString utf8FamilyName; |
1070 HRV(wchar_to_skstring(dwFamilyNameChar.get(), &utf8FamilyName)); | 1006 HRV(sk_wchar_to_skstring(dwFamilyNameChar.get(), &utf8FamilyName)); |
1071 | 1007 |
1072 desc->setFamilyName(utf8FamilyName.c_str()); | 1008 desc->setFamilyName(utf8FamilyName.c_str()); |
1073 *isLocalStream = SkToBool(fDWriteFontFileLoader.get()); | 1009 *isLocalStream = SkToBool(fDWriteFontFileLoader.get()); |
1074 } | 1010 } |
1075 | 1011 |
1076 static SkUnichar next_utf8(const void** chars) { | 1012 static SkUnichar next_utf8(const void** chars) { |
1077 return SkUTF8_NextUnichar((const char**)chars); | 1013 return SkUTF8_NextUnichar((const char**)chars); |
1078 } | 1014 } |
1079 | 1015 |
1080 static SkUnichar next_utf16(const void** chars) { | 1016 static SkUnichar next_utf16(const void** chars) { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1170 } | 1106 } |
1171 | 1107 |
1172 // String | 1108 // String |
1173 UINT32 stringLength; | 1109 UINT32 stringLength; |
1174 HRBM(fStrings->GetStringLength(fIndex, &stringLength), "Could not get st
ring length."); | 1110 HRBM(fStrings->GetStringLength(fIndex, &stringLength), "Could not get st
ring length."); |
1175 stringLength += 1; | 1111 stringLength += 1; |
1176 | 1112 |
1177 SkSMallocWCHAR wString(stringLength); | 1113 SkSMallocWCHAR wString(stringLength); |
1178 HRBM(fStrings->GetString(fIndex, wString.get(), stringLength), "Could no
t get string."); | 1114 HRBM(fStrings->GetString(fIndex, wString.get(), stringLength), "Could no
t get string."); |
1179 | 1115 |
1180 HRB(wchar_to_skstring(wString.get(), &localizedString->fString)); | 1116 HRB(sk_wchar_to_skstring(wString.get(), &localizedString->fString)); |
1181 | 1117 |
1182 // Locale | 1118 // Locale |
1183 UINT32 localeLength; | 1119 UINT32 localeLength; |
1184 HRBM(fStrings->GetLocaleNameLength(fIndex, &localeLength), "Could not ge
t locale length."); | 1120 HRBM(fStrings->GetLocaleNameLength(fIndex, &localeLength), "Could not ge
t locale length."); |
1185 localeLength += 1; | 1121 localeLength += 1; |
1186 | 1122 |
1187 SkSMallocWCHAR wLocale(localeLength); | 1123 SkSMallocWCHAR wLocale(localeLength); |
1188 HRBM(fStrings->GetLocaleName(fIndex, wLocale.get(), localeLength), "Coul
d not get locale."); | 1124 HRBM(fStrings->GetLocaleName(fIndex, wLocale.get(), localeLength), "Coul
d not get locale."); |
1189 | 1125 |
1190 HRB(wchar_to_skstring(wLocale.get(), &localizedString->fLanguage)); | 1126 HRB(sk_wchar_to_skstring(wLocale.get(), &localizedString->fLanguage)); |
1191 | 1127 |
1192 ++fIndex; | 1128 ++fIndex; |
1193 return true; | 1129 return true; |
1194 } | 1130 } |
1195 | 1131 |
1196 private: | 1132 private: |
1197 UINT32 fIndex; | 1133 UINT32 fIndex; |
1198 SkTScopedComPtr<IDWriteLocalizedStrings> fStrings; | 1134 SkTScopedComPtr<IDWriteLocalizedStrings> fStrings; |
1199 }; | 1135 }; |
1200 | 1136 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1285 | 1221 |
1286 HRESULT unregister(IDWriteFactory* factory, IDWriteFontCollectionLoader* unr
egister) { | 1222 HRESULT unregister(IDWriteFactory* factory, IDWriteFontCollectionLoader* unr
egister) { |
1287 return factory->UnregisterFontCollectionLoader(unregister); | 1223 return factory->UnregisterFontCollectionLoader(unregister); |
1288 } | 1224 } |
1289 | 1225 |
1290 IDWriteFactory* fFactory; | 1226 IDWriteFactory* fFactory; |
1291 T* fUnregister; | 1227 T* fUnregister; |
1292 }; | 1228 }; |
1293 | 1229 |
1294 static SkTypeface* create_from_stream(SkStream* stream, int ttcIndex) { | 1230 static SkTypeface* create_from_stream(SkStream* stream, int ttcIndex) { |
1295 IDWriteFactory* factory = get_dwrite_factory(); | 1231 IDWriteFactory* factory = sk_get_dwrite_factory(); |
1296 if (NULL == factory) { | 1232 if (NULL == factory) { |
1297 return NULL; | 1233 return NULL; |
1298 } | 1234 } |
1299 | 1235 |
1300 SkTScopedComPtr<StreamFontFileLoader> fontFileLoader; | 1236 SkTScopedComPtr<StreamFontFileLoader> fontFileLoader; |
1301 HRN(StreamFontFileLoader::Create(stream, &fontFileLoader)); | 1237 HRN(StreamFontFileLoader::Create(stream, &fontFileLoader)); |
1302 HRN(factory->RegisterFontFileLoader(fontFileLoader.get())); | 1238 HRN(factory->RegisterFontFileLoader(fontFileLoader.get())); |
1303 SkAutoIDWriteUnregister<StreamFontFileLoader> autoUnregisterFontFileLoader( | 1239 SkAutoIDWriteUnregister<StreamFontFileLoader> autoUnregisterFontFileLoader( |
1304 factory, fontFileLoader.get()); | 1240 factory, fontFileLoader.get()); |
1305 | 1241 |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1524 | 1460 |
1525 UINT32 faceNameLength; | 1461 UINT32 faceNameLength; |
1526 hr = faceNames->GetStringLength(0, &faceNameLength); | 1462 hr = faceNames->GetStringLength(0, &faceNameLength); |
1527 | 1463 |
1528 UINT32 size = familyNameLength+1+faceNameLength+1; | 1464 UINT32 size = familyNameLength+1+faceNameLength+1; |
1529 SkSMallocWCHAR wFamilyName(size); | 1465 SkSMallocWCHAR wFamilyName(size); |
1530 hr = familyNames->GetString(0, wFamilyName.get(), size); | 1466 hr = familyNames->GetString(0, wFamilyName.get(), size); |
1531 wFamilyName[familyNameLength] = L' '; | 1467 wFamilyName[familyNameLength] = L' '; |
1532 hr = faceNames->GetString(0, &wFamilyName[familyNameLength+1], size - faceNa
meLength + 1); | 1468 hr = faceNames->GetString(0, &wFamilyName[familyNameLength+1], size - faceNa
meLength + 1); |
1533 | 1469 |
1534 hr = wchar_to_skstring(wFamilyName.get(), &info->fFontName); | 1470 hr = sk_wchar_to_skstring(wFamilyName.get(), &info->fFontName); |
1535 | 1471 |
1536 if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) { | 1472 if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) { |
1537 populate_glyph_to_unicode(fDWriteFontFace.get(), glyphCount, &(info->fGl
yphToUnicode)); | 1473 populate_glyph_to_unicode(fDWriteFontFace.get(), glyphCount, &(info->fGl
yphToUnicode)); |
1538 } | 1474 } |
1539 | 1475 |
1540 DWRITE_FONT_FACE_TYPE fontType = fDWriteFontFace->GetType(); | 1476 DWRITE_FONT_FACE_TYPE fontType = fDWriteFontFace->GetType(); |
1541 if (fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE || | 1477 if (fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE || |
1542 fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION) { | 1478 fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION) { |
1543 info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font; | 1479 info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font; |
1544 } else { | 1480 } else { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1641 glyphIDsCount, | 1577 glyphIDsCount, |
1642 getWidthAdvance)); | 1578 getWidthAdvance)); |
1643 } | 1579 } |
1644 } | 1580 } |
1645 | 1581 |
1646 return info; | 1582 return info; |
1647 } | 1583 } |
1648 | 1584 |
1649 /////////////////////////////////////////////////////////////////////////////// | 1585 /////////////////////////////////////////////////////////////////////////////// |
1650 | 1586 |
1651 static void get_locale_string(IDWriteLocalizedStrings* names, const WCHAR* prefe
redLocale, | |
1652 SkString* skname) { | |
1653 UINT32 nameIndex = 0; | |
1654 if (preferedLocale) { | |
1655 // Ignore any errors and continue with index 0 if there is a problem. | |
1656 BOOL nameExists; | |
1657 names->FindLocaleName(preferedLocale, &nameIndex, &nameExists); | |
1658 if (!nameExists) { | |
1659 nameIndex = 0; | |
1660 } | |
1661 } | |
1662 | |
1663 UINT32 nameLength; | |
1664 HRVM(names->GetStringLength(nameIndex, &nameLength), "Could not get name len
gth."); | |
1665 nameLength += 1; | |
1666 | |
1667 SkSMallocWCHAR name(nameLength); | |
1668 HRVM(names->GetString(nameIndex, name.get(), nameLength), "Could not get str
ing."); | |
1669 | |
1670 HRV(wchar_to_skstring(name.get(), skname)); | |
1671 } | |
1672 | |
1673 SkTypeface* SkFontMgr_DirectWrite::createTypefaceFromDWriteFont( | 1587 SkTypeface* SkFontMgr_DirectWrite::createTypefaceFromDWriteFont( |
1674 IDWriteFontFace* fontFace, | 1588 IDWriteFontFace* fontFace, |
1675 IDWriteFont* font, | 1589 IDWriteFont* font, |
1676 IDWriteFontFamily* fontFamily, | 1590 IDWriteFontFamily* fontFamily, |
1677 StreamFontFileLoader* fontFileLoader, | 1591 StreamFontFileLoader* fontFileLoader, |
1678 IDWriteFontCollectionLoader* fontCollectionLoader) const { | 1592 IDWriteFontCollectionLoader* fontCollectionLoader) const { |
1679 SkTypeface* face = FindByProcAndRef(FindByDWriteFont, font); | 1593 SkTypeface* face = FindByProcAndRef(FindByDWriteFont, font); |
1680 if (NULL == face) { | 1594 if (NULL == face) { |
1681 face = DWriteFontTypeface::Create(fontFace, font, fontFamily, | 1595 face = DWriteFontTypeface::Create(fontFace, font, fontFamily, |
1682 fontFileLoader, fontCollectionLoader); | 1596 fontFileLoader, fontCollectionLoader); |
1683 if (face) { | 1597 if (face) { |
1684 Add(face, get_style(font), fontCollectionLoader != NULL); | 1598 Add(face, get_style(font), fontCollectionLoader != NULL); |
1685 } | 1599 } |
1686 } | 1600 } |
1687 return face; | 1601 return face; |
1688 } | 1602 } |
1689 | 1603 |
1690 int SkFontMgr_DirectWrite::onCountFamilies() const { | 1604 int SkFontMgr_DirectWrite::onCountFamilies() const { |
1691 return fFontCollection->GetFontFamilyCount(); | 1605 return fFontCollection->GetFontFamilyCount(); |
1692 } | 1606 } |
1693 | 1607 |
1694 void SkFontMgr_DirectWrite::onGetFamilyName(int index, SkString* familyName) con
st { | 1608 void SkFontMgr_DirectWrite::onGetFamilyName(int index, SkString* familyName) con
st { |
1695 SkTScopedComPtr<IDWriteFontFamily> fontFamily; | 1609 SkTScopedComPtr<IDWriteFontFamily> fontFamily; |
1696 HRVM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requ
ested family."); | 1610 HRVM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requ
ested family."); |
1697 | 1611 |
1698 SkTScopedComPtr<IDWriteLocalizedStrings> familyNames; | 1612 SkTScopedComPtr<IDWriteLocalizedStrings> familyNames; |
1699 HRVM(fontFamily->GetFamilyNames(&familyNames), "Could not get family names."
); | 1613 HRVM(fontFamily->GetFamilyNames(&familyNames), "Could not get family names."
); |
1700 | 1614 |
1701 get_locale_string(familyNames.get(), fLocaleName.get(), familyName); | 1615 sk_get_locale_string(familyNames.get(), fLocaleName.get(), familyName); |
1702 } | 1616 } |
1703 | 1617 |
1704 SkFontStyleSet* SkFontMgr_DirectWrite::onCreateStyleSet(int index) const { | 1618 SkFontStyleSet* SkFontMgr_DirectWrite::onCreateStyleSet(int index) const { |
1705 SkTScopedComPtr<IDWriteFontFamily> fontFamily; | 1619 SkTScopedComPtr<IDWriteFontFamily> fontFamily; |
1706 HRNM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requ
ested family."); | 1620 HRNM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requ
ested family."); |
1707 | 1621 |
1708 return SkNEW_ARGS(SkFontStyleSet_DirectWrite, (this, fontFamily.get())); | 1622 return SkNEW_ARGS(SkFontStyleSet_DirectWrite, (this, fontFamily.get())); |
1709 } | 1623 } |
1710 | 1624 |
1711 SkFontStyleSet* SkFontMgr_DirectWrite::onMatchFamily(const char familyName[]) co
nst { | 1625 SkFontStyleSet* SkFontMgr_DirectWrite::onMatchFamily(const char familyName[]) co
nst { |
1712 SkSMallocWCHAR dwFamilyName; | 1626 SkSMallocWCHAR dwFamilyName; |
1713 HRN(cstring_to_wchar(familyName, &dwFamilyName)); | 1627 HRN(sk_cstring_to_wchar(familyName, &dwFamilyName)); |
1714 | 1628 |
1715 UINT32 index; | 1629 UINT32 index; |
1716 BOOL exists; | 1630 BOOL exists; |
1717 HRNM(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &exists), | 1631 HRNM(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &exists), |
1718 "Failed while finding family by name."); | 1632 "Failed while finding family by name."); |
1719 if (!exists) { | 1633 if (!exists) { |
1720 return NULL; | 1634 return NULL; |
1721 } | 1635 } |
1722 | 1636 |
1723 return this->onCreateStyleSet(index); | 1637 return this->onCreateStyleSet(index); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1778 "Could not create DWrite font family from LOGFONT."); | 1692 "Could not create DWrite font family from LOGFONT."); |
1779 | 1693 |
1780 return S_OK; | 1694 return S_OK; |
1781 } | 1695 } |
1782 | 1696 |
1783 SkTypeface* SkFontMgr_DirectWrite::onLegacyCreateTypeface(const char familyName[
], | 1697 SkTypeface* SkFontMgr_DirectWrite::onLegacyCreateTypeface(const char familyName[
], |
1784 unsigned styleBits) co
nst { | 1698 unsigned styleBits) co
nst { |
1785 SkTScopedComPtr<IDWriteFontFamily> fontFamily; | 1699 SkTScopedComPtr<IDWriteFontFamily> fontFamily; |
1786 if (familyName) { | 1700 if (familyName) { |
1787 SkSMallocWCHAR wideFamilyName; | 1701 SkSMallocWCHAR wideFamilyName; |
1788 if (SUCCEEDED(cstring_to_wchar(familyName, &wideFamilyName))) { | 1702 if (SUCCEEDED(sk_cstring_to_wchar(familyName, &wideFamilyName))) { |
1789 this->getByFamilyName(wideFamilyName, &fontFamily); | 1703 this->getByFamilyName(wideFamilyName, &fontFamily); |
1790 } | 1704 } |
1791 } | 1705 } |
1792 | 1706 |
1793 if (NULL == fontFamily.get()) { | 1707 if (NULL == fontFamily.get()) { |
1794 // No family with given name, try default. | 1708 // No family with given name, try default. |
1795 HRNM(this->getDefaultFontFamily(&fontFamily), "Could not get default fon
t family."); | 1709 HRNM(this->getDefaultFontFamily(&fontFamily), "Could not get default fon
t family."); |
1796 } | 1710 } |
1797 | 1711 |
1798 SkTScopedComPtr<IDWriteFont> font; | 1712 SkTScopedComPtr<IDWriteFont> font; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1848 | 1762 |
1849 int weight = font->GetWeight(); | 1763 int weight = font->GetWeight(); |
1850 int width = font->GetStretch(); | 1764 int width = font->GetStretch(); |
1851 | 1765 |
1852 *fs = SkFontStyle(weight, width, slant); | 1766 *fs = SkFontStyle(weight, width, slant); |
1853 } | 1767 } |
1854 | 1768 |
1855 if (styleName) { | 1769 if (styleName) { |
1856 SkTScopedComPtr<IDWriteLocalizedStrings> faceNames; | 1770 SkTScopedComPtr<IDWriteLocalizedStrings> faceNames; |
1857 if (SUCCEEDED(font->GetFaceNames(&faceNames))) { | 1771 if (SUCCEEDED(font->GetFaceNames(&faceNames))) { |
1858 get_locale_string(faceNames.get(), fFontMgr->fLocaleName.get(), styl
eName); | 1772 sk_get_locale_string(faceNames.get(), fFontMgr->fLocaleName.get(), s
tyleName); |
1859 } | 1773 } |
1860 } | 1774 } |
1861 } | 1775 } |
1862 | 1776 |
1863 SkTypeface* SkFontStyleSet_DirectWrite::matchStyle(const SkFontStyle& pattern) { | 1777 SkTypeface* SkFontStyleSet_DirectWrite::matchStyle(const SkFontStyle& pattern) { |
1864 DWRITE_FONT_STYLE slant; | 1778 DWRITE_FONT_STYLE slant; |
1865 switch (pattern.slant()) { | 1779 switch (pattern.slant()) { |
1866 case SkFontStyle::kUpright_Slant: | 1780 case SkFontStyle::kUpright_Slant: |
1867 slant = DWRITE_FONT_STYLE_NORMAL; | 1781 slant = DWRITE_FONT_STYLE_NORMAL; |
1868 break; | 1782 break; |
1869 case SkFontStyle::kItalic_Slant: | 1783 case SkFontStyle::kItalic_Slant: |
1870 slant = DWRITE_FONT_STYLE_ITALIC; | 1784 slant = DWRITE_FONT_STYLE_ITALIC; |
1871 break; | 1785 break; |
1872 default: | 1786 default: |
1873 SkASSERT(false); | 1787 SkASSERT(false); |
1874 } | 1788 } |
1875 | 1789 |
1876 DWRITE_FONT_WEIGHT weight = (DWRITE_FONT_WEIGHT)pattern.weight(); | 1790 DWRITE_FONT_WEIGHT weight = (DWRITE_FONT_WEIGHT)pattern.weight(); |
1877 DWRITE_FONT_STRETCH width = (DWRITE_FONT_STRETCH)pattern.width(); | 1791 DWRITE_FONT_STRETCH width = (DWRITE_FONT_STRETCH)pattern.width(); |
1878 | 1792 |
1879 SkTScopedComPtr<IDWriteFont> font; | 1793 SkTScopedComPtr<IDWriteFont> font; |
1880 // TODO: perhaps use GetMatchingFonts and get the least simulated? | 1794 // TODO: perhaps use GetMatchingFonts and get the least simulated? |
1881 HRNM(fFontFamily->GetFirstMatchingFont(weight, width, slant, &font), | 1795 HRNM(fFontFamily->GetFirstMatchingFont(weight, width, slant, &font), |
1882 "Could not match font in family."); | 1796 "Could not match font in family."); |
1883 | 1797 |
1884 SkTScopedComPtr<IDWriteFontFace> fontFace; | 1798 SkTScopedComPtr<IDWriteFontFace> fontFace; |
1885 HRNM(font->CreateFontFace(&fontFace), "Could not create font face."); | 1799 HRNM(font->CreateFontFace(&fontFace), "Could not create font face."); |
1886 | 1800 |
1887 return fFontMgr->createTypefaceFromDWriteFont(fontFace.get(), font.get(), | 1801 return fFontMgr->createTypefaceFromDWriteFont(fontFace.get(), font.get(), |
1888 fFontFamily.get()); | 1802 fFontFamily.get()); |
1889 } | 1803 } |
1890 | 1804 |
1891 /////////////////////////////////////////////////////////////////////////////// | 1805 /////////////////////////////////////////////////////////////////////////////// |
1892 | 1806 |
1893 typedef decltype(GetUserDefaultLocaleName)* GetUserDefaultLocaleNameProc; | |
1894 static HRESULT GetGetUserDefaultLocaleNameProc(GetUserDefaultLocaleNameProc* pro
c) { | |
1895 *proc = reinterpret_cast<GetUserDefaultLocaleNameProc>( | |
1896 GetProcAddress(LoadLibraryW(L"Kernel32.dll"), "GetUserDefaultLocaleName"
) | |
1897 ); | |
1898 if (!*proc) { | |
1899 HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); | |
1900 if (!IS_ERROR(hr)) { | |
1901 hr = ERROR_PROC_NOT_FOUND; | |
1902 } | |
1903 return hr; | |
1904 } | |
1905 return S_OK; | |
1906 } | |
1907 | |
1908 SkFontMgr* SkFontMgr_New_DirectWrite() { | 1807 SkFontMgr* SkFontMgr_New_DirectWrite() { |
1909 IDWriteFactory* factory = get_dwrite_factory(); | 1808 IDWriteFactory* factory = sk_get_dwrite_factory(); |
1910 if (NULL == factory) { | 1809 if (NULL == factory) { |
1911 return NULL; | 1810 return NULL; |
1912 } | 1811 } |
1913 | 1812 |
1914 SkTScopedComPtr<IDWriteFontCollection> sysFontCollection; | 1813 SkTScopedComPtr<IDWriteFontCollection> sysFontCollection; |
1915 HRNM(factory->GetSystemFontCollection(&sysFontCollection, FALSE), | 1814 HRNM(factory->GetSystemFontCollection(&sysFontCollection, FALSE), |
1916 "Could not get system font collection."); | 1815 "Could not get system font collection."); |
1917 | 1816 |
1918 WCHAR localeNameStorage[LOCALE_NAME_MAX_LENGTH]; | 1817 WCHAR localeNameStorage[LOCALE_NAME_MAX_LENGTH]; |
1919 WCHAR* localeName = NULL; | 1818 WCHAR* localeName = NULL; |
1920 int localeNameLen = 0; | 1819 int localeNameLen = 0; |
1921 | 1820 |
1922 // Dynamically load GetUserDefaultLocaleName function, as it is not availabl
e on XP. | 1821 // Dynamically load GetUserDefaultLocaleName function, as it is not availabl
e on XP. |
1923 GetUserDefaultLocaleNameProc getUserDefaultLocaleNameProc = NULL; | 1822 SkGetUserDefaultLocaleNameProc getUserDefaultLocaleNameProc = NULL; |
1924 HRESULT hr = GetGetUserDefaultLocaleNameProc(&getUserDefaultLocaleNameProc); | 1823 HRESULT hr = SkGetGetUserDefaultLocaleNameProc(&getUserDefaultLocaleNameProc
); |
1925 if (NULL == getUserDefaultLocaleNameProc) { | 1824 if (NULL == getUserDefaultLocaleNameProc) { |
1926 SK_TRACEHR(hr, "Could not get GetUserDefaultLocaleName."); | 1825 SK_TRACEHR(hr, "Could not get GetUserDefaultLocaleName."); |
1927 } else { | 1826 } else { |
1928 localeNameLen = getUserDefaultLocaleNameProc(localeNameStorage, LOCALE_N
AME_MAX_LENGTH); | 1827 localeNameLen = getUserDefaultLocaleNameProc(localeNameStorage, LOCALE_N
AME_MAX_LENGTH); |
1929 if (localeNameLen) { | 1828 if (localeNameLen) { |
1930 localeName = localeNameStorage; | 1829 localeName = localeNameStorage; |
1931 }; | 1830 }; |
1932 } | 1831 } |
1933 | 1832 |
1934 return SkNEW_ARGS(SkFontMgr_DirectWrite, (sysFontCollection.get(), localeNam
e, localeNameLen)); | 1833 return SkNEW_ARGS(SkFontMgr_DirectWrite, (sysFontCollection.get(), localeNam
e, localeNameLen)); |
1935 } | 1834 } |
| 1835 |
| 1836 #include "SkFontMgr_indirect.h" |
| 1837 SkFontMgr* SkFontMgr_New_DirectWriteRenderer(SkRemotableFontMgr* proxy) { |
| 1838 SkAutoTUnref<SkFontMgr> impl(SkFontMgr_New_DirectWrite()); |
| 1839 if (impl.get() == NULL) { |
| 1840 return NULL; |
| 1841 } |
| 1842 return SkNEW_ARGS(SkFontMgr_Indirect, (impl.get(), proxy)); |
| 1843 } |
OLD | NEW |