| 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 |