Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/ports/SkFontMgr_win_dw.cpp

Issue 338923003: Clean up DirectWrite typeface cache matching. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "SkFontMgr.h" 10 #include "SkFontMgr.h"
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 /** localeNameLength must include the null terminator. */ 252 /** localeNameLength must include the null terminator. */
253 SkFontMgr_DirectWrite(IDWriteFactory* factory, IDWriteFontCollection* fontCo llection, 253 SkFontMgr_DirectWrite(IDWriteFactory* factory, IDWriteFontCollection* fontCo llection,
254 WCHAR* localeName, int localeNameLength) 254 WCHAR* localeName, int localeNameLength)
255 : fFactory(SkRefComPtr(factory)) 255 : fFactory(SkRefComPtr(factory))
256 , fFontCollection(SkRefComPtr(fontCollection)) 256 , fFontCollection(SkRefComPtr(fontCollection))
257 , fLocaleName(localeNameLength) 257 , fLocaleName(localeNameLength)
258 { 258 {
259 memcpy(fLocaleName.get(), localeName, localeNameLength * sizeof(WCHAR)); 259 memcpy(fLocaleName.get(), localeName, localeNameLength * sizeof(WCHAR));
260 } 260 }
261 261
262 /** Creates a typeface using a typeface cache. */
263 SkTypeface* createTypefaceFromDWriteFont(IDWriteFontFace* fontFace,
264 IDWriteFont* font,
265 IDWriteFontFamily* fontFamily) cons t;
266
267 protected: 262 protected:
268 virtual int onCountFamilies() const SK_OVERRIDE; 263 virtual int onCountFamilies() const SK_OVERRIDE;
269 virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERR IDE; 264 virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERR IDE;
270 virtual SkFontStyleSet* onCreateStyleSet(int index) const SK_OVERRIDE; 265 virtual SkFontStyleSet* onCreateStyleSet(int index) const SK_OVERRIDE;
271 virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVER RIDE; 266 virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVER RIDE;
272 virtual SkTypeface* onMatchFamilyStyle(const char familyName[], 267 virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
273 const SkFontStyle& fontstyle) const S K_OVERRIDE; 268 const SkFontStyle& fontstyle) const S K_OVERRIDE;
274 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember, 269 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
275 const SkFontStyle& fontstyle) const SK_ OVERRIDE; 270 const SkFontStyle& fontstyle) const SK_ OVERRIDE;
276 virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE; 271 virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE;
277 virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OV ERRIDE; 272 virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OV ERRIDE;
278 virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE; 273 virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE;
279 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], 274 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
280 unsigned styleBits) const SK_OVER RIDE; 275 unsigned styleBits) const SK_OVER RIDE;
281 276
282 private: 277 private:
283 HRESULT getByFamilyName(const WCHAR familyName[], IDWriteFontFamily** fontFa mily) const; 278 HRESULT getByFamilyName(const WCHAR familyName[], IDWriteFontFamily** fontFa mily) const;
284 HRESULT getDefaultFontFamily(IDWriteFontFamily** fontFamily) const; 279 HRESULT getDefaultFontFamily(IDWriteFontFamily** fontFamily) const;
285 280
286 void Add(SkTypeface* face, SkTypeface::Style requestedStyle, bool strong) co nst { 281 /** Creates a typeface using a typeface cache. */
287 SkAutoMutexAcquire ama(fTFCacheMutex); 282 SkTypeface* createTypefaceFromDWriteFont(IDWriteFontFace* fontFace,
288 fTFCache.add(face, requestedStyle, strong); 283 IDWriteFont* font,
289 } 284 IDWriteFontFamily* fontFamily) cons t;
290
291 SkTypeface* FindByProcAndRef(SkTypefaceCache::FindProc proc, void* ctx) cons t {
292 SkAutoMutexAcquire ama(fTFCacheMutex);
293 SkTypeface* typeface = fTFCache.findByProcAndRef(proc, ctx);
294 return typeface;
295 }
296 285
297 SkTScopedComPtr<IDWriteFactory> fFactory; 286 SkTScopedComPtr<IDWriteFactory> fFactory;
298 SkTScopedComPtr<IDWriteFontCollection> fFontCollection; 287 SkTScopedComPtr<IDWriteFontCollection> fFontCollection;
299 SkSMallocWCHAR fLocaleName; 288 SkSMallocWCHAR fLocaleName;
300 mutable SkMutex fTFCacheMutex; 289 mutable SkMutex fTFCacheMutex;
301 mutable SkTypefaceCache fTFCache; 290 mutable SkTypefaceCache fTFCache;
302 291
303 friend class SkFontStyleSet_DirectWrite; 292 friend class SkFontStyleSet_DirectWrite;
304 }; 293 };
305 294
306 class SkFontStyleSet_DirectWrite : public SkFontStyleSet { 295 class SkFontStyleSet_DirectWrite : public SkFontStyleSet {
307 public: 296 public:
308 SkFontStyleSet_DirectWrite(const SkFontMgr_DirectWrite* fontMgr, 297 SkFontStyleSet_DirectWrite(const SkFontMgr_DirectWrite* fontMgr,
309 IDWriteFontFamily* fontFamily) 298 IDWriteFontFamily* fontFamily)
310 : fFontMgr(SkRef(fontMgr)) 299 : fFontMgr(SkRef(fontMgr))
311 , fFontFamily(SkRefComPtr(fontFamily)) 300 , fFontFamily(SkRefComPtr(fontFamily))
312 { } 301 { }
313 302
314 virtual int count() SK_OVERRIDE; 303 virtual int count() SK_OVERRIDE;
315 virtual void getStyle(int index, SkFontStyle* fs, SkString* styleName) SK_OV ERRIDE; 304 virtual void getStyle(int index, SkFontStyle* fs, SkString* styleName) SK_OV ERRIDE;
316 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE; 305 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE;
317 virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE; 306 virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE;
318 307
319 private: 308 private:
320 SkAutoTUnref<const SkFontMgr_DirectWrite> fFontMgr; 309 SkAutoTUnref<const SkFontMgr_DirectWrite> fFontMgr;
321 SkTScopedComPtr<IDWriteFontFamily> fFontFamily; 310 SkTScopedComPtr<IDWriteFontFamily> fFontFamily;
322 }; 311 };
323 312
324 static bool are_same(IUnknown* a, IUnknown* b) { 313 static HRESULT are_same(IUnknown* a, IUnknown* b, bool& same) {
325 SkTScopedComPtr<IUnknown> iunkA; 314 SkTScopedComPtr<IUnknown> iunkA;
326 if (FAILED(a->QueryInterface(&iunkA))) { 315 HRM(a->QueryInterface(&iunkA), "Failed to QI<IUnknown> for a.");
327 return false; 316
317 SkTScopedComPtr<IUnknown> iunkB;
318 HRM(b->QueryInterface(&iunkB), "Failed to QI<IUnknown> for b.");
319
320 same = (iunkA.get() == iunkB.get());
321 return S_OK;
322 }
323
324 struct ProtoDWriteTypeface {
325 IDWriteFontFace* fDWriteFontFace;
326 IDWriteFont* fDWriteFont;
327 IDWriteFontFamily* fDWriteFontFamily;
328 };
329
330 static bool FindByDWriteFont(SkTypeface* cached, SkTypeface::Style, void* ctx) {
331 DWriteFontTypeface* cshFace = reinterpret_cast<DWriteFontTypeface*>(cached);
332 ProtoDWriteTypeface* ctxFace = reinterpret_cast<ProtoDWriteTypeface*>(ctx);
333 bool same;
334
335 //Check to see if the two fonts are identical.
336 HRB(are_same(cshFace->fDWriteFont.get(), ctxFace->fDWriteFont, same));
337 if (same) {
338 return true;
328 } 339 }
329 340
330 SkTScopedComPtr<IUnknown> iunkB; 341 HRB(are_same(cshFace->fDWriteFontFace.get(), ctxFace->fDWriteFontFace, same) );
331 if (FAILED(b->QueryInterface(&iunkB))) { 342 if (same) {
332 return false;
333 }
334
335 return iunkA.get() == iunkB.get();
336 }
337
338 static bool FindByDWriteFont(SkTypeface* face, SkTypeface::Style, void* ctx) {
339 //Check to see if the two fonts are identical.
340 DWriteFontTypeface* dwFace = reinterpret_cast<DWriteFontTypeface*>(face);
341 IDWriteFont* dwFont = reinterpret_cast<IDWriteFont*>(ctx);
342 if (are_same(dwFace->fDWriteFont.get(), dwFont)) {
343 return true; 343 return true;
344 } 344 }
345 345
346 //Check if the two fonts share the same loader and have the same key. 346 //Check if the two fonts share the same loader and have the same key.
347 SkTScopedComPtr<IDWriteFontFace> dwFaceFontFace; 347 UINT32 cshNumFiles;
348 SkTScopedComPtr<IDWriteFontFace> dwFontFace; 348 UINT32 ctxNumFiles;
349 HRB(dwFace->fDWriteFont->CreateFontFace(&dwFaceFontFace)); 349 HRB(cshFace->fDWriteFontFace->GetFiles(&cshNumFiles, NULL));
350 HRB(dwFont->CreateFontFace(&dwFontFace)); 350 HRB(ctxFace->fDWriteFontFace->GetFiles(&ctxNumFiles, NULL));
351 if (are_same(dwFaceFontFace.get(), dwFontFace.get())) { 351 if (cshNumFiles != ctxNumFiles) {
352 return true;
353 }
354
355 UINT32 dwFaceNumFiles;
356 UINT32 dwNumFiles;
357 HRB(dwFaceFontFace->GetFiles(&dwFaceNumFiles, NULL));
358 HRB(dwFontFace->GetFiles(&dwNumFiles, NULL));
359 if (dwFaceNumFiles != dwNumFiles) {
360 return false; 352 return false;
361 } 353 }
362 354
363 SkTScopedComPtr<IDWriteFontFile> dwFaceFontFile; 355 SkTScopedComPtr<IDWriteFontFile> cshFontFile;
364 SkTScopedComPtr<IDWriteFontFile> dwFontFile; 356 SkTScopedComPtr<IDWriteFontFile> ctxFontFile;
365 HRB(dwFaceFontFace->GetFiles(&dwFaceNumFiles, &dwFaceFontFile)); 357 HRB(cshFace->fDWriteFontFace->GetFiles(&cshNumFiles, &cshFontFile));
366 HRB(dwFontFace->GetFiles(&dwNumFiles, &dwFontFile)); 358 HRB(ctxFace->fDWriteFontFace->GetFiles(&ctxNumFiles, &ctxFontFile));
367 359
368 //for (each file) { //we currently only admit fonts from one file. 360 //for (each file) { //we currently only admit fonts from one file.
369 SkTScopedComPtr<IDWriteFontFileLoader> dwFaceFontFileLoader; 361 SkTScopedComPtr<IDWriteFontFileLoader> cshFontFileLoader;
370 SkTScopedComPtr<IDWriteFontFileLoader> dwFontFileLoader; 362 SkTScopedComPtr<IDWriteFontFileLoader> ctxFontFileLoader;
371 HRB(dwFaceFontFile->GetLoader(&dwFaceFontFileLoader)); 363 HRB(cshFontFile->GetLoader(&cshFontFileLoader));
372 HRB(dwFontFile->GetLoader(&dwFontFileLoader)); 364 HRB(ctxFontFile->GetLoader(&ctxFontFileLoader));
373 if (!are_same(dwFaceFontFileLoader.get(), dwFontFileLoader.get())) { 365 HRB(are_same(cshFontFileLoader.get(), ctxFontFileLoader.get(), same));
366 if (!same) {
374 return false; 367 return false;
375 } 368 }
376 //} 369 //}
377 370
378 const void* dwFaceFontRefKey; 371 const void* cshRefKey;
379 UINT32 dwFaceFontRefKeySize; 372 UINT32 cshRefKeySize;
380 const void* dwFontRefKey; 373 const void* ctxRefKey;
381 UINT32 dwFontRefKeySize; 374 UINT32 ctxRefKeySize;
382 HRB(dwFaceFontFile->GetReferenceKey(&dwFaceFontRefKey, &dwFaceFontRefKeySize )); 375 HRB(cshFontFile->GetReferenceKey(&cshRefKey, &cshRefKeySize));
383 HRB(dwFontFile->GetReferenceKey(&dwFontRefKey, &dwFontRefKeySize)); 376 HRB(ctxFontFile->GetReferenceKey(&ctxRefKey, &ctxRefKeySize));
384 if (dwFaceFontRefKeySize != dwFontRefKeySize) { 377 if (cshRefKeySize != ctxRefKeySize) {
385 return false; 378 return false;
386 } 379 }
387 if (0 != memcmp(dwFaceFontRefKey, dwFontRefKey, dwFontRefKeySize)) { 380 if (0 != memcmp(cshRefKey, ctxRefKey, ctxRefKeySize)) {
388 return false; 381 return false;
389 } 382 }
390 383
391 //TODO: better means than comparing name strings? 384 //TODO: better means than comparing name strings?
392 //NOTE: .tfc and fake bold/italic will end up here. 385 //NOTE: .ttc and fake bold/italic will end up here.
393 SkTScopedComPtr<IDWriteFontFamily> dwFaceFontFamily; 386 SkTScopedComPtr<IDWriteLocalizedStrings> cshFamilyNames;
394 SkTScopedComPtr<IDWriteFontFamily> dwFontFamily; 387 SkTScopedComPtr<IDWriteLocalizedStrings> cshFaceNames;
395 HRB(dwFace->fDWriteFont->GetFontFamily(&dwFaceFontFamily)); 388 HRB(cshFace->fDWriteFontFamily->GetFamilyNames(&cshFamilyNames));
396 HRB(dwFont->GetFontFamily(&dwFontFamily)); 389 HRB(cshFace->fDWriteFont->GetFaceNames(&cshFaceNames));
390 UINT32 cshFamilyNameLength;
391 UINT32 cshFaceNameLength;
392 HRB(cshFamilyNames->GetStringLength(0, &cshFamilyNameLength));
393 HRB(cshFaceNames->GetStringLength(0, &cshFaceNameLength));
397 394
398 SkTScopedComPtr<IDWriteLocalizedStrings> dwFaceFontFamilyNames; 395 SkTScopedComPtr<IDWriteLocalizedStrings> ctxFamilyNames;
399 SkTScopedComPtr<IDWriteLocalizedStrings> dwFaceFontNames; 396 SkTScopedComPtr<IDWriteLocalizedStrings> ctxFaceNames;
400 HRB(dwFaceFontFamily->GetFamilyNames(&dwFaceFontFamilyNames)); 397 HRB(ctxFace->fDWriteFontFamily->GetFamilyNames(&ctxFamilyNames));
401 HRB(dwFace->fDWriteFont->GetFaceNames(&dwFaceFontNames)); 398 HRB(ctxFace->fDWriteFont->GetFaceNames(&ctxFaceNames));
399 UINT32 ctxFamilyNameLength;
400 UINT32 ctxFaceNameLength;
401 HRB(ctxFamilyNames->GetStringLength(0, &ctxFamilyNameLength));
402 HRB(ctxFaceNames->GetStringLength(0, &ctxFaceNameLength));
402 403
403 SkTScopedComPtr<IDWriteLocalizedStrings> dwFontFamilyNames; 404 if (cshFamilyNameLength != ctxFamilyNameLength ||
404 SkTScopedComPtr<IDWriteLocalizedStrings> dwFontNames; 405 cshFaceNameLength != ctxFaceNameLength)
405 HRB(dwFontFamily->GetFamilyNames(&dwFontFamilyNames));
406 HRB(dwFont->GetFaceNames(&dwFontNames));
407
408 UINT32 dwFaceFontFamilyNameLength;
409 UINT32 dwFaceFontNameLength;
410 HRB(dwFaceFontFamilyNames->GetStringLength(0, &dwFaceFontFamilyNameLength));
411 HRB(dwFaceFontNames->GetStringLength(0, &dwFaceFontNameLength));
412
413 UINT32 dwFontFamilyNameLength;
414 UINT32 dwFontNameLength;
415 HRB(dwFontFamilyNames->GetStringLength(0, &dwFontFamilyNameLength));
416 HRB(dwFontNames->GetStringLength(0, &dwFontNameLength));
417
418 if (dwFaceFontFamilyNameLength != dwFontFamilyNameLength ||
419 dwFaceFontNameLength != dwFontNameLength)
420 { 406 {
421 return false; 407 return false;
422 } 408 }
423 409
424 SkSMallocWCHAR dwFaceFontFamilyNameChar(dwFaceFontFamilyNameLength+1); 410 SkSMallocWCHAR cshFamilyName(cshFamilyNameLength+1);
425 SkSMallocWCHAR dwFaceFontNameChar(dwFaceFontNameLength+1); 411 SkSMallocWCHAR cshFaceName(cshFaceNameLength+1);
426 HRB(dwFaceFontFamilyNames->GetString(0, dwFaceFontFamilyNameChar.get(), dwFa ceFontFamilyNameLength+1)); 412 HRB(cshFamilyNames->GetString(0, cshFamilyName.get(), cshFamilyNameLength+1) );
427 HRB(dwFaceFontNames->GetString(0, dwFaceFontNameChar.get(), dwFaceFontNameLe ngth+1)); 413 HRB(cshFaceNames->GetString(0, cshFaceName.get(), cshFaceNameLength+1));
428 414
429 SkSMallocWCHAR dwFontFamilyNameChar(dwFontFamilyNameLength+1); 415 SkSMallocWCHAR ctxFamilyName(ctxFamilyNameLength+1);
430 SkSMallocWCHAR dwFontNameChar(dwFontNameLength+1); 416 SkSMallocWCHAR ctxFaceName(ctxFaceNameLength+1);
431 HRB(dwFontFamilyNames->GetString(0, dwFontFamilyNameChar.get(), dwFontFamily NameLength+1)); 417 HRB(ctxFamilyNames->GetString(0, ctxFamilyName.get(), ctxFamilyNameLength+1) );
432 HRB(dwFontNames->GetString(0, dwFontNameChar.get(), dwFontNameLength+1)); 418 HRB(ctxFaceNames->GetString(0, ctxFaceName.get(), ctxFaceNameLength+1));
433 419
434 return wcscmp(dwFaceFontFamilyNameChar.get(), dwFontFamilyNameChar.get()) == 0 && 420 return wcscmp(cshFamilyName.get(), ctxFamilyName.get()) == 0 &&
435 wcscmp(dwFaceFontNameChar.get(), dwFontNameChar.get()) == 0; 421 wcscmp(cshFaceName.get(), ctxFaceName.get()) == 0;
436 } 422 }
437 423
438 SkTypeface* SkFontMgr_DirectWrite::createTypefaceFromDWriteFont( 424 SkTypeface* SkFontMgr_DirectWrite::createTypefaceFromDWriteFont(
439 IDWriteFontFace* fontFace, 425 IDWriteFontFace* fontFace,
440 IDWriteFont* font, 426 IDWriteFont* font,
441 IDWriteFontFamily* fontFamily) const { 427 IDWriteFontFamily* fontFamily) const {
442 SkTypeface* face = FindByProcAndRef(FindByDWriteFont, font); 428 SkAutoMutexAcquire ama(fTFCacheMutex);
429 ProtoDWriteTypeface spec = { fontFace, font, fontFamily };
430 SkTypeface* face = fTFCache.findByProcAndRef(FindByDWriteFont, &spec);
443 if (NULL == face) { 431 if (NULL == face) {
444 face = DWriteFontTypeface::Create(fFactory.get(), fontFace, font, fontFa mily); 432 face = DWriteFontTypeface::Create(fFactory.get(), fontFace, font, fontFa mily);
445 if (face) { 433 if (face) {
446 Add(face, get_style(font), true); 434 fTFCache.add(face, get_style(font), true);
447 } 435 }
448 } 436 }
449 return face; 437 return face;
450 } 438 }
451 439
452 int SkFontMgr_DirectWrite::onCountFamilies() const { 440 int SkFontMgr_DirectWrite::onCountFamilies() const {
453 return fFontCollection->GetFontFamilyCount(); 441 return fFontCollection->GetFontFamilyCount();
454 } 442 }
455 443
456 void SkFontMgr_DirectWrite::onGetFamilyName(int index, SkString* familyName) con st { 444 void SkFontMgr_DirectWrite::onGetFamilyName(int index, SkString* familyName) con st {
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 } 751 }
764 752
765 #include "SkFontMgr_indirect.h" 753 #include "SkFontMgr_indirect.h"
766 SK_API SkFontMgr* SkFontMgr_New_DirectWriteRenderer(SkRemotableFontMgr* proxy) { 754 SK_API SkFontMgr* SkFontMgr_New_DirectWriteRenderer(SkRemotableFontMgr* proxy) {
767 SkAutoTUnref<SkFontMgr> impl(SkFontMgr_New_DirectWrite()); 755 SkAutoTUnref<SkFontMgr> impl(SkFontMgr_New_DirectWrite());
768 if (impl.get() == NULL) { 756 if (impl.get() == NULL) {
769 return NULL; 757 return NULL;
770 } 758 }
771 return SkNEW_ARGS(SkFontMgr_Indirect, (impl.get(), proxy)); 759 return SkNEW_ARGS(SkFontMgr_Indirect, (impl.get(), proxy));
772 } 760 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698