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 "SkDWrite.h" | 8 #include "SkDWrite.h" |
9 #include "SkDWriteFontFileStream.h" | 9 #include "SkDWriteFontFileStream.h" |
10 #include "SkDataTable.h" | 10 #include "SkDataTable.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 IUnknown* fLoader; // In COM only IUnknown pointers may be safely used
for identity. | 27 IUnknown* fLoader; // In COM only IUnknown pointers may be safely used
for identity. |
28 void* fKey; | 28 void* fKey; |
29 UINT32 fKeySize; | 29 UINT32 fKeySize; |
30 | 30 |
31 DataId() { } | 31 DataId() { } |
32 | 32 |
33 // This is actually a move!!! | 33 // This is actually a move!!! |
34 explicit DataId(DataId& that) | 34 explicit DataId(DataId& that) |
35 : fLoader(that.fLoader), fKey(that.fKey), fKeySize(that.fKeySize) | 35 : fLoader(that.fLoader), fKey(that.fKey), fKeySize(that.fKeySize) |
36 { | 36 { |
37 that.fLoader = NULL; | 37 that.fLoader = nullptr; |
38 that.fKey = NULL; | 38 that.fKey = nullptr; |
39 SkDEBUGCODE(that.fKeySize = 0xFFFFFFFF;) | 39 SkDEBUGCODE(that.fKeySize = 0xFFFFFFFF;) |
40 } | 40 } |
41 | 41 |
42 ~DataId() { | 42 ~DataId() { |
43 if (fLoader) { | 43 if (fLoader) { |
44 fLoader->Release(); | 44 fLoader->Release(); |
45 } | 45 } |
46 sk_free(fKey); | 46 sk_free(fKey); |
47 } | 47 } |
48 }; | 48 }; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 names.appendString(familyName); | 109 names.appendString(familyName); |
110 } | 110 } |
111 return names.detachDataTable(); | 111 return names.detachDataTable(); |
112 } | 112 } |
113 | 113 |
114 HRESULT FontToIdentity(IDWriteFont* font, SkFontIdentity* fontId) const { | 114 HRESULT FontToIdentity(IDWriteFont* font, SkFontIdentity* fontId) const { |
115 SkTScopedComPtr<IDWriteFontFace> fontFace; | 115 SkTScopedComPtr<IDWriteFontFace> fontFace; |
116 HRM(font->CreateFontFace(&fontFace), "Could not create font face."); | 116 HRM(font->CreateFontFace(&fontFace), "Could not create font face."); |
117 | 117 |
118 UINT32 numFiles; | 118 UINT32 numFiles; |
119 HR(fontFace->GetFiles(&numFiles, NULL)); | 119 HR(fontFace->GetFiles(&numFiles, nullptr)); |
120 if (numFiles > 1) { | 120 if (numFiles > 1) { |
121 return E_FAIL; | 121 return E_FAIL; |
122 } | 122 } |
123 | 123 |
124 // data id | 124 // data id |
125 SkTScopedComPtr<IDWriteFontFile> fontFile; | 125 SkTScopedComPtr<IDWriteFontFile> fontFile; |
126 HR(fontFace->GetFiles(&numFiles, &fontFile)); | 126 HR(fontFace->GetFiles(&numFiles, &fontFile)); |
127 | 127 |
128 SkTScopedComPtr<IDWriteFontFileLoader> fontFileLoader; | 128 SkTScopedComPtr<IDWriteFontFileLoader> fontFileLoader; |
129 HR(fontFile->GetLoader(&fontFileLoader)); | 129 HR(fontFile->GetLoader(&fontFileLoader)); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 "Could not get requested family.", | 186 "Could not get requested family.", |
187 identity); | 187 identity); |
188 | 188 |
189 const DWriteStyle dwStyle(pattern); | 189 const DWriteStyle dwStyle(pattern); |
190 SkTScopedComPtr<IDWriteFont> font; | 190 SkTScopedComPtr<IDWriteFont> font; |
191 HR_GENERAL(fontFamily->GetFirstMatchingFont(dwStyle.fWeight, dwStyle.fWi
dth, | 191 HR_GENERAL(fontFamily->GetFirstMatchingFont(dwStyle.fWeight, dwStyle.fWi
dth, |
192 dwStyle.fSlant, &font), | 192 dwStyle.fSlant, &font), |
193 "Could not match font in family.", | 193 "Could not match font in family.", |
194 identity); | 194 identity); |
195 | 195 |
196 HR_GENERAL(FontToIdentity(font.get(), &identity), NULL, identity); | 196 HR_GENERAL(FontToIdentity(font.get(), &identity), nullptr, identity); |
197 | 197 |
198 return identity; | 198 return identity; |
199 } | 199 } |
200 | 200 |
201 static HRESULT getDefaultFontFamilyName(SkSMallocWCHAR* name) { | 201 static HRESULT getDefaultFontFamilyName(SkSMallocWCHAR* name) { |
202 NONCLIENTMETRICSW metrics; | 202 NONCLIENTMETRICSW metrics; |
203 metrics.cbSize = sizeof(metrics); | 203 metrics.cbSize = sizeof(metrics); |
204 if (0 == SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, | 204 if (0 == SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, |
205 sizeof(metrics), | 205 sizeof(metrics), |
206 &metrics, | 206 &metrics, |
207 0)) { | 207 0)) { |
208 return E_UNEXPECTED; | 208 return E_UNEXPECTED; |
209 } | 209 } |
210 | 210 |
211 size_t len = wcsnlen_s(metrics.lfMessageFont.lfFaceName, LF_FACESIZE) +
1; | 211 size_t len = wcsnlen_s(metrics.lfMessageFont.lfFaceName, LF_FACESIZE) +
1; |
212 if (0 != wcsncpy_s(name->reset(len), len, metrics.lfMessageFont.lfFaceNa
me, _TRUNCATE)) { | 212 if (0 != wcsncpy_s(name->reset(len), len, metrics.lfMessageFont.lfFaceNa
me, _TRUNCATE)) { |
213 return E_UNEXPECTED; | 213 return E_UNEXPECTED; |
214 } | 214 } |
215 | 215 |
216 return S_OK; | 216 return S_OK; |
217 } | 217 } |
218 | 218 |
219 SkRemotableFontIdentitySet* matchName(const char familyName[]) const overrid
e { | 219 SkRemotableFontIdentitySet* matchName(const char familyName[]) const overrid
e { |
220 SkSMallocWCHAR dwFamilyName; | 220 SkSMallocWCHAR dwFamilyName; |
221 if (NULL == familyName) { | 221 if (nullptr == familyName) { |
222 HR_GENERAL(getDefaultFontFamilyName(&dwFamilyName), | 222 HR_GENERAL(getDefaultFontFamilyName(&dwFamilyName), |
223 NULL, SkRemotableFontIdentitySet::NewEmpty()); | 223 nullptr, SkRemotableFontIdentitySet::NewEmpty()); |
224 } else { | 224 } else { |
225 HR_GENERAL(sk_cstring_to_wchar(familyName, &dwFamilyName), | 225 HR_GENERAL(sk_cstring_to_wchar(familyName, &dwFamilyName), |
226 NULL, SkRemotableFontIdentitySet::NewEmpty()); | 226 nullptr, SkRemotableFontIdentitySet::NewEmpty()); |
227 } | 227 } |
228 | 228 |
229 UINT32 index; | 229 UINT32 index; |
230 BOOL exists; | 230 BOOL exists; |
231 HR_GENERAL(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &
exists), | 231 HR_GENERAL(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &
exists), |
232 "Failed while finding family by name.", | 232 "Failed while finding family by name.", |
233 SkRemotableFontIdentitySet::NewEmpty()); | 233 SkRemotableFontIdentitySet::NewEmpty()); |
234 if (!exists) { | 234 if (!exists) { |
235 return SkRemotableFontIdentitySet::NewEmpty(); | 235 return SkRemotableFontIdentitySet::NewEmpty(); |
236 } | 236 } |
237 | 237 |
238 return this->getIndex(index); | 238 return this->getIndex(index); |
239 } | 239 } |
240 | 240 |
241 virtual SkFontIdentity matchNameStyle(const char familyName[], | 241 virtual SkFontIdentity matchNameStyle(const char familyName[], |
242 const SkFontStyle& style) const overri
de | 242 const SkFontStyle& style) const overri
de |
243 { | 243 { |
244 SkFontIdentity identity = { SkFontIdentity::kInvalidDataId }; | 244 SkFontIdentity identity = { SkFontIdentity::kInvalidDataId }; |
245 | 245 |
246 SkSMallocWCHAR dwFamilyName; | 246 SkSMallocWCHAR dwFamilyName; |
247 if (NULL == familyName) { | 247 if (nullptr == familyName) { |
248 HR_GENERAL(getDefaultFontFamilyName(&dwFamilyName), NULL, identity); | 248 HR_GENERAL(getDefaultFontFamilyName(&dwFamilyName), nullptr, identit
y); |
249 } else { | 249 } else { |
250 HR_GENERAL(sk_cstring_to_wchar(familyName, &dwFamilyName), NULL, ide
ntity); | 250 HR_GENERAL(sk_cstring_to_wchar(familyName, &dwFamilyName), nullptr,
identity); |
251 } | 251 } |
252 | 252 |
253 UINT32 index; | 253 UINT32 index; |
254 BOOL exists; | 254 BOOL exists; |
255 HR_GENERAL(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &
exists), | 255 HR_GENERAL(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &
exists), |
256 "Failed while finding family by name.", | 256 "Failed while finding family by name.", |
257 identity); | 257 identity); |
258 if (!exists) { | 258 if (!exists) { |
259 return identity; | 259 return identity; |
260 } | 260 } |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 IID const& riid, void** ppvObject) override | 367 IID const& riid, void** ppvObject) override |
368 { | 368 { |
369 if (__uuidof(IUnknown) == riid || | 369 if (__uuidof(IUnknown) == riid || |
370 __uuidof(IDWritePixelSnapping) == riid || | 370 __uuidof(IDWritePixelSnapping) == riid || |
371 __uuidof(IDWriteTextRenderer) == riid) | 371 __uuidof(IDWriteTextRenderer) == riid) |
372 { | 372 { |
373 *ppvObject = this; | 373 *ppvObject = this; |
374 this->AddRef(); | 374 this->AddRef(); |
375 return S_OK; | 375 return S_OK; |
376 } | 376 } |
377 *ppvObject = NULL; | 377 *ppvObject = nullptr; |
378 return E_FAIL; | 378 return E_FAIL; |
379 } | 379 } |
380 | 380 |
381 const SkFontIdentity FallbackIdentity() { return fIdentity; } | 381 const SkFontIdentity FallbackIdentity() { return fIdentity; } |
382 | 382 |
383 protected: | 383 protected: |
384 ULONG fRefCount; | 384 ULONG fRefCount; |
385 SkAutoTUnref<const SkRemotableFontMgr_DirectWrite> fOuter; | 385 SkAutoTUnref<const SkRemotableFontMgr_DirectWrite> fOuter; |
386 UINT32 fCharacter; | 386 UINT32 fCharacter; |
387 SkFontIdentity fIdentity; | 387 SkFontIdentity fIdentity; |
388 }; | 388 }; |
389 | 389 |
390 virtual SkFontIdentity matchNameStyleCharacter(const char familyName[], | 390 virtual SkFontIdentity matchNameStyleCharacter(const char familyName[], |
391 const SkFontStyle& pattern, | 391 const SkFontStyle& pattern, |
392 const char* bcp47[], int bcp4
7Count, | 392 const char* bcp47[], int bcp4
7Count, |
393 SkUnichar character) const ov
erride | 393 SkUnichar character) const ov
erride |
394 { | 394 { |
395 SkFontIdentity identity = { SkFontIdentity::kInvalidDataId }; | 395 SkFontIdentity identity = { SkFontIdentity::kInvalidDataId }; |
396 | 396 |
397 IDWriteFactory* dwFactory = sk_get_dwrite_factory(); | 397 IDWriteFactory* dwFactory = sk_get_dwrite_factory(); |
398 if (NULL == dwFactory) { | 398 if (nullptr == dwFactory) { |
399 return identity; | 399 return identity; |
400 } | 400 } |
401 | 401 |
402 // TODO: use IDWriteFactory2::GetSystemFontFallback when available. | 402 // TODO: use IDWriteFactory2::GetSystemFontFallback when available. |
403 | 403 |
404 const DWriteStyle dwStyle(pattern); | 404 const DWriteStyle dwStyle(pattern); |
405 | 405 |
406 SkSMallocWCHAR dwFamilyName; | 406 SkSMallocWCHAR dwFamilyName; |
407 if (NULL == familyName) { | 407 if (nullptr == familyName) { |
408 HR_GENERAL(getDefaultFontFamilyName(&dwFamilyName), NULL, identity); | 408 HR_GENERAL(getDefaultFontFamilyName(&dwFamilyName), nullptr, identit
y); |
409 } else { | 409 } else { |
410 HR_GENERAL(sk_cstring_to_wchar(familyName, &dwFamilyName), NULL, ide
ntity); | 410 HR_GENERAL(sk_cstring_to_wchar(familyName, &dwFamilyName), nullptr,
identity); |
411 } | 411 } |
412 | 412 |
413 const SkSMallocWCHAR* dwBcp47; | 413 const SkSMallocWCHAR* dwBcp47; |
414 SkSMallocWCHAR dwBcp47Local; | 414 SkSMallocWCHAR dwBcp47Local; |
415 if (bcp47Count < 1) { | 415 if (bcp47Count < 1) { |
416 dwBcp47 = &fLocaleName; | 416 dwBcp47 = &fLocaleName; |
417 } else { | 417 } else { |
418 //TODO: support fallback stack. | 418 //TODO: support fallback stack. |
419 HR_GENERAL(sk_cstring_to_wchar(bcp47[bcp47Count-1], &dwBcp47Local),
NULL, identity); | 419 HR_GENERAL(sk_cstring_to_wchar(bcp47[bcp47Count-1], &dwBcp47Local),
nullptr, identity); |
420 dwBcp47 = &dwBcp47Local; | 420 dwBcp47 = &dwBcp47Local; |
421 } | 421 } |
422 | 422 |
423 SkTScopedComPtr<IDWriteTextFormat> fallbackFormat; | 423 SkTScopedComPtr<IDWriteTextFormat> fallbackFormat; |
424 HR_GENERAL(dwFactory->CreateTextFormat(dwFamilyName, | 424 HR_GENERAL(dwFactory->CreateTextFormat(dwFamilyName, |
425 fFontCollection.get(), | 425 fFontCollection.get(), |
426 dwStyle.fWeight, | 426 dwStyle.fWeight, |
427 dwStyle.fSlant, | 427 dwStyle.fSlant, |
428 dwStyle.fWidth, | 428 dwStyle.fWidth, |
429 72.0f, | 429 72.0f, |
430 *dwBcp47, | 430 *dwBcp47, |
431 &fallbackFormat), | 431 &fallbackFormat), |
432 "Could not create text format.", | 432 "Could not create text format.", |
433 identity); | 433 identity); |
434 | 434 |
435 WCHAR str[16]; | 435 WCHAR str[16]; |
436 UINT32 strLen = static_cast<UINT32>( | 436 UINT32 strLen = static_cast<UINT32>( |
437 SkUTF16_FromUnichar(character, reinterpret_cast<uint16_t*>(str))); | 437 SkUTF16_FromUnichar(character, reinterpret_cast<uint16_t*>(str))); |
438 SkTScopedComPtr<IDWriteTextLayout> fallbackLayout; | 438 SkTScopedComPtr<IDWriteTextLayout> fallbackLayout; |
439 HR_GENERAL(dwFactory->CreateTextLayout(str, strLen, fallbackFormat.get()
, | 439 HR_GENERAL(dwFactory->CreateTextLayout(str, strLen, fallbackFormat.get()
, |
440 200.0f, 200.0f, | 440 200.0f, 200.0f, |
441 &fallbackLayout), | 441 &fallbackLayout), |
442 "Could not create text layout.", | 442 "Could not create text layout.", |
443 identity); | 443 identity); |
444 | 444 |
445 SkTScopedComPtr<FontFallbackRenderer> fontFallbackRenderer( | 445 SkTScopedComPtr<FontFallbackRenderer> fontFallbackRenderer( |
446 new FontFallbackRenderer(this, character)); | 446 new FontFallbackRenderer(this, character)); |
447 | 447 |
448 HR_GENERAL(fallbackLayout->Draw(NULL, fontFallbackRenderer.get(), 50.0f,
50.0f), | 448 HR_GENERAL(fallbackLayout->Draw(nullptr, fontFallbackRenderer.get(), 50.
0f, 50.0f), |
449 "Could not draw layout with renderer.", | 449 "Could not draw layout with renderer.", |
450 identity); | 450 identity); |
451 | 451 |
452 return fontFallbackRenderer->FallbackIdentity(); | 452 return fontFallbackRenderer->FallbackIdentity(); |
453 } | 453 } |
454 | 454 |
455 SkStreamAsset* getData(int dataId) const override { | 455 SkStreamAsset* getData(int dataId) const override { |
456 SkAutoMutexAcquire ama(fDataIdCacheMutex); | 456 SkAutoMutexAcquire ama(fDataIdCacheMutex); |
457 if (dataId >= fDataIdCache.count()) { | 457 if (dataId >= fDataIdCache.count()) { |
458 return NULL; | 458 return nullptr; |
459 } | 459 } |
460 const DataId& id = fDataIdCache[dataId]; | 460 const DataId& id = fDataIdCache[dataId]; |
461 | 461 |
462 SkTScopedComPtr<IDWriteFontFileLoader> loader; | 462 SkTScopedComPtr<IDWriteFontFileLoader> loader; |
463 HRNM(id.fLoader->QueryInterface(&loader), "QuerryInterface IDWriteFontFi
leLoader failed"); | 463 HRNM(id.fLoader->QueryInterface(&loader), "QuerryInterface IDWriteFontFi
leLoader failed"); |
464 | 464 |
465 SkTScopedComPtr<IDWriteFontFileStream> fontFileStream; | 465 SkTScopedComPtr<IDWriteFontFileStream> fontFileStream; |
466 HRNM(loader->CreateStreamFromKey(id.fKey, id.fKeySize, &fontFileStream), | 466 HRNM(loader->CreateStreamFromKey(id.fKey, id.fKeySize, &fontFileStream), |
467 "Could not create font file stream."); | 467 "Could not create font file stream."); |
468 | 468 |
469 return new SkDWriteFontFileStream(fontFileStream.get()); | 469 return new SkDWriteFontFileStream(fontFileStream.get()); |
470 } | 470 } |
471 | 471 |
472 private: | 472 private: |
473 SkTScopedComPtr<IDWriteFontCollection> fFontCollection; | 473 SkTScopedComPtr<IDWriteFontCollection> fFontCollection; |
474 SkSMallocWCHAR fLocaleName; | 474 SkSMallocWCHAR fLocaleName; |
475 | 475 |
476 typedef SkRemotableFontMgr INHERITED; | 476 typedef SkRemotableFontMgr INHERITED; |
477 }; | 477 }; |
478 | 478 |
479 SkRemotableFontMgr* SkRemotableFontMgr_New_DirectWrite() { | 479 SkRemotableFontMgr* SkRemotableFontMgr_New_DirectWrite() { |
480 IDWriteFactory* factory = sk_get_dwrite_factory(); | 480 IDWriteFactory* factory = sk_get_dwrite_factory(); |
481 if (NULL == factory) { | 481 if (nullptr == factory) { |
482 return NULL; | 482 return nullptr; |
483 } | 483 } |
484 | 484 |
485 SkTScopedComPtr<IDWriteFontCollection> sysFontCollection; | 485 SkTScopedComPtr<IDWriteFontCollection> sysFontCollection; |
486 HRNM(factory->GetSystemFontCollection(&sysFontCollection, FALSE), | 486 HRNM(factory->GetSystemFontCollection(&sysFontCollection, FALSE), |
487 "Could not get system font collection."); | 487 "Could not get system font collection."); |
488 | 488 |
489 WCHAR localeNameStorage[LOCALE_NAME_MAX_LENGTH]; | 489 WCHAR localeNameStorage[LOCALE_NAME_MAX_LENGTH]; |
490 WCHAR* localeName = NULL; | 490 WCHAR* localeName = nullptr; |
491 int localeNameLen = 0; | 491 int localeNameLen = 0; |
492 | 492 |
493 // Dynamically load GetUserDefaultLocaleName function, as it is not availabl
e on XP. | 493 // Dynamically load GetUserDefaultLocaleName function, as it is not availabl
e on XP. |
494 SkGetUserDefaultLocaleNameProc getUserDefaultLocaleNameProc = NULL; | 494 SkGetUserDefaultLocaleNameProc getUserDefaultLocaleNameProc = nullptr; |
495 HRESULT hr = SkGetGetUserDefaultLocaleNameProc(&getUserDefaultLocaleNameProc
); | 495 HRESULT hr = SkGetGetUserDefaultLocaleNameProc(&getUserDefaultLocaleNameProc
); |
496 if (NULL == getUserDefaultLocaleNameProc) { | 496 if (nullptr == getUserDefaultLocaleNameProc) { |
497 SK_TRACEHR(hr, "Could not get GetUserDefaultLocaleName."); | 497 SK_TRACEHR(hr, "Could not get GetUserDefaultLocaleName."); |
498 } else { | 498 } else { |
499 localeNameLen = getUserDefaultLocaleNameProc(localeNameStorage, LOCALE_N
AME_MAX_LENGTH); | 499 localeNameLen = getUserDefaultLocaleNameProc(localeNameStorage, LOCALE_N
AME_MAX_LENGTH); |
500 if (localeNameLen) { | 500 if (localeNameLen) { |
501 localeName = localeNameStorage; | 501 localeName = localeNameStorage; |
502 }; | 502 }; |
503 } | 503 } |
504 | 504 |
505 return new SkRemotableFontMgr_DirectWrite(sysFontCollection.get(), localeNam
e, localeNameLen); | 505 return new SkRemotableFontMgr_DirectWrite(sysFontCollection.get(), localeNam
e, localeNameLen); |
506 } | 506 } |
OLD | NEW |