Index: src/ports/SkFontMgr_win_dw.cpp |
diff --git a/src/ports/SkFontMgr_win_dw.cpp b/src/ports/SkFontMgr_win_dw.cpp |
index 863377564a7f5fbf49d6c6ff5c2c0c0526030349..eb0989a8295a92349dbad43f8b631827c4973eef 100644 |
--- a/src/ports/SkFontMgr_win_dw.cpp |
+++ b/src/ports/SkFontMgr_win_dw.cpp |
@@ -259,11 +259,6 @@ public: |
memcpy(fLocaleName.get(), localeName, localeNameLength * sizeof(WCHAR)); |
} |
- /** Creates a typeface using a typeface cache. */ |
- SkTypeface* createTypefaceFromDWriteFont(IDWriteFontFace* fontFace, |
- IDWriteFont* font, |
- IDWriteFontFamily* fontFamily) const; |
- |
protected: |
virtual int onCountFamilies() const SK_OVERRIDE; |
virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERRIDE; |
@@ -283,16 +278,10 @@ private: |
HRESULT getByFamilyName(const WCHAR familyName[], IDWriteFontFamily** fontFamily) const; |
HRESULT getDefaultFontFamily(IDWriteFontFamily** fontFamily) const; |
- void Add(SkTypeface* face, SkTypeface::Style requestedStyle, bool strong) const { |
- SkAutoMutexAcquire ama(fTFCacheMutex); |
- fTFCache.add(face, requestedStyle, strong); |
- } |
- |
- SkTypeface* FindByProcAndRef(SkTypefaceCache::FindProc proc, void* ctx) const { |
- SkAutoMutexAcquire ama(fTFCacheMutex); |
- SkTypeface* typeface = fTFCache.findByProcAndRef(proc, ctx); |
- return typeface; |
- } |
+ /** Creates a typeface using a typeface cache. */ |
+ SkTypeface* createTypefaceFromDWriteFont(IDWriteFontFace* fontFace, |
+ IDWriteFont* font, |
+ IDWriteFontFamily* fontFamily) const; |
SkTScopedComPtr<IDWriteFactory> fFactory; |
SkTScopedComPtr<IDWriteFontCollection> fFontCollection; |
@@ -321,129 +310,128 @@ private: |
SkTScopedComPtr<IDWriteFontFamily> fFontFamily; |
}; |
-static bool are_same(IUnknown* a, IUnknown* b) { |
+static HRESULT are_same(IUnknown* a, IUnknown* b, bool& same) { |
SkTScopedComPtr<IUnknown> iunkA; |
- if (FAILED(a->QueryInterface(&iunkA))) { |
- return false; |
- } |
+ HRM(a->QueryInterface(&iunkA), "Failed to QI<IUnknown> for a."); |
SkTScopedComPtr<IUnknown> iunkB; |
- if (FAILED(b->QueryInterface(&iunkB))) { |
- return false; |
- } |
+ HRM(b->QueryInterface(&iunkB), "Failed to QI<IUnknown> for b."); |
- return iunkA.get() == iunkB.get(); |
+ same = (iunkA.get() == iunkB.get()); |
+ return S_OK; |
} |
-static bool FindByDWriteFont(SkTypeface* face, SkTypeface::Style, void* ctx) { |
+struct ProtoDWriteTypeface { |
+ IDWriteFontFace* fDWriteFontFace; |
+ IDWriteFont* fDWriteFont; |
+ IDWriteFontFamily* fDWriteFontFamily; |
+}; |
+ |
+static bool FindByDWriteFont(SkTypeface* cached, SkTypeface::Style, void* ctx) { |
+ DWriteFontTypeface* cshFace = reinterpret_cast<DWriteFontTypeface*>(cached); |
+ ProtoDWriteTypeface* ctxFace = reinterpret_cast<ProtoDWriteTypeface*>(ctx); |
+ bool same; |
+ |
//Check to see if the two fonts are identical. |
- DWriteFontTypeface* dwFace = reinterpret_cast<DWriteFontTypeface*>(face); |
- IDWriteFont* dwFont = reinterpret_cast<IDWriteFont*>(ctx); |
- if (are_same(dwFace->fDWriteFont.get(), dwFont)) { |
+ HRB(are_same(cshFace->fDWriteFont.get(), ctxFace->fDWriteFont, same)); |
+ if (same) { |
return true; |
} |
- //Check if the two fonts share the same loader and have the same key. |
- SkTScopedComPtr<IDWriteFontFace> dwFaceFontFace; |
- SkTScopedComPtr<IDWriteFontFace> dwFontFace; |
- HRB(dwFace->fDWriteFont->CreateFontFace(&dwFaceFontFace)); |
- HRB(dwFont->CreateFontFace(&dwFontFace)); |
- if (are_same(dwFaceFontFace.get(), dwFontFace.get())) { |
+ HRB(are_same(cshFace->fDWriteFontFace.get(), ctxFace->fDWriteFontFace, same)); |
+ if (same) { |
return true; |
} |
- UINT32 dwFaceNumFiles; |
- UINT32 dwNumFiles; |
- HRB(dwFaceFontFace->GetFiles(&dwFaceNumFiles, NULL)); |
- HRB(dwFontFace->GetFiles(&dwNumFiles, NULL)); |
- if (dwFaceNumFiles != dwNumFiles) { |
+ //Check if the two fonts share the same loader and have the same key. |
+ UINT32 cshNumFiles; |
+ UINT32 ctxNumFiles; |
+ HRB(cshFace->fDWriteFontFace->GetFiles(&cshNumFiles, NULL)); |
+ HRB(ctxFace->fDWriteFontFace->GetFiles(&ctxNumFiles, NULL)); |
+ if (cshNumFiles != ctxNumFiles) { |
return false; |
} |
- SkTScopedComPtr<IDWriteFontFile> dwFaceFontFile; |
- SkTScopedComPtr<IDWriteFontFile> dwFontFile; |
- HRB(dwFaceFontFace->GetFiles(&dwFaceNumFiles, &dwFaceFontFile)); |
- HRB(dwFontFace->GetFiles(&dwNumFiles, &dwFontFile)); |
+ SkTScopedComPtr<IDWriteFontFile> cshFontFile; |
+ SkTScopedComPtr<IDWriteFontFile> ctxFontFile; |
+ HRB(cshFace->fDWriteFontFace->GetFiles(&cshNumFiles, &cshFontFile)); |
+ HRB(ctxFace->fDWriteFontFace->GetFiles(&ctxNumFiles, &ctxFontFile)); |
//for (each file) { //we currently only admit fonts from one file. |
- SkTScopedComPtr<IDWriteFontFileLoader> dwFaceFontFileLoader; |
- SkTScopedComPtr<IDWriteFontFileLoader> dwFontFileLoader; |
- HRB(dwFaceFontFile->GetLoader(&dwFaceFontFileLoader)); |
- HRB(dwFontFile->GetLoader(&dwFontFileLoader)); |
- if (!are_same(dwFaceFontFileLoader.get(), dwFontFileLoader.get())) { |
+ SkTScopedComPtr<IDWriteFontFileLoader> cshFontFileLoader; |
+ SkTScopedComPtr<IDWriteFontFileLoader> ctxFontFileLoader; |
+ HRB(cshFontFile->GetLoader(&cshFontFileLoader)); |
+ HRB(ctxFontFile->GetLoader(&ctxFontFileLoader)); |
+ HRB(are_same(cshFontFileLoader.get(), ctxFontFileLoader.get(), same)); |
+ if (!same) { |
return false; |
} |
//} |
- const void* dwFaceFontRefKey; |
- UINT32 dwFaceFontRefKeySize; |
- const void* dwFontRefKey; |
- UINT32 dwFontRefKeySize; |
- HRB(dwFaceFontFile->GetReferenceKey(&dwFaceFontRefKey, &dwFaceFontRefKeySize)); |
- HRB(dwFontFile->GetReferenceKey(&dwFontRefKey, &dwFontRefKeySize)); |
- if (dwFaceFontRefKeySize != dwFontRefKeySize) { |
+ const void* cshRefKey; |
+ UINT32 cshRefKeySize; |
+ const void* ctxRefKey; |
+ UINT32 ctxRefKeySize; |
+ HRB(cshFontFile->GetReferenceKey(&cshRefKey, &cshRefKeySize)); |
+ HRB(ctxFontFile->GetReferenceKey(&ctxRefKey, &ctxRefKeySize)); |
+ if (cshRefKeySize != ctxRefKeySize) { |
return false; |
} |
- if (0 != memcmp(dwFaceFontRefKey, dwFontRefKey, dwFontRefKeySize)) { |
+ if (0 != memcmp(cshRefKey, ctxRefKey, ctxRefKeySize)) { |
return false; |
} |
//TODO: better means than comparing name strings? |
- //NOTE: .tfc and fake bold/italic will end up here. |
- SkTScopedComPtr<IDWriteFontFamily> dwFaceFontFamily; |
- SkTScopedComPtr<IDWriteFontFamily> dwFontFamily; |
- HRB(dwFace->fDWriteFont->GetFontFamily(&dwFaceFontFamily)); |
- HRB(dwFont->GetFontFamily(&dwFontFamily)); |
- |
- SkTScopedComPtr<IDWriteLocalizedStrings> dwFaceFontFamilyNames; |
- SkTScopedComPtr<IDWriteLocalizedStrings> dwFaceFontNames; |
- HRB(dwFaceFontFamily->GetFamilyNames(&dwFaceFontFamilyNames)); |
- HRB(dwFace->fDWriteFont->GetFaceNames(&dwFaceFontNames)); |
- |
- SkTScopedComPtr<IDWriteLocalizedStrings> dwFontFamilyNames; |
- SkTScopedComPtr<IDWriteLocalizedStrings> dwFontNames; |
- HRB(dwFontFamily->GetFamilyNames(&dwFontFamilyNames)); |
- HRB(dwFont->GetFaceNames(&dwFontNames)); |
- |
- UINT32 dwFaceFontFamilyNameLength; |
- UINT32 dwFaceFontNameLength; |
- HRB(dwFaceFontFamilyNames->GetStringLength(0, &dwFaceFontFamilyNameLength)); |
- HRB(dwFaceFontNames->GetStringLength(0, &dwFaceFontNameLength)); |
- |
- UINT32 dwFontFamilyNameLength; |
- UINT32 dwFontNameLength; |
- HRB(dwFontFamilyNames->GetStringLength(0, &dwFontFamilyNameLength)); |
- HRB(dwFontNames->GetStringLength(0, &dwFontNameLength)); |
- |
- if (dwFaceFontFamilyNameLength != dwFontFamilyNameLength || |
- dwFaceFontNameLength != dwFontNameLength) |
+ //NOTE: .ttc and fake bold/italic will end up here. |
+ SkTScopedComPtr<IDWriteLocalizedStrings> cshFamilyNames; |
+ SkTScopedComPtr<IDWriteLocalizedStrings> cshFaceNames; |
+ HRB(cshFace->fDWriteFontFamily->GetFamilyNames(&cshFamilyNames)); |
+ HRB(cshFace->fDWriteFont->GetFaceNames(&cshFaceNames)); |
+ UINT32 cshFamilyNameLength; |
+ UINT32 cshFaceNameLength; |
+ HRB(cshFamilyNames->GetStringLength(0, &cshFamilyNameLength)); |
+ HRB(cshFaceNames->GetStringLength(0, &cshFaceNameLength)); |
+ |
+ SkTScopedComPtr<IDWriteLocalizedStrings> ctxFamilyNames; |
+ SkTScopedComPtr<IDWriteLocalizedStrings> ctxFaceNames; |
+ HRB(ctxFace->fDWriteFontFamily->GetFamilyNames(&ctxFamilyNames)); |
+ HRB(ctxFace->fDWriteFont->GetFaceNames(&ctxFaceNames)); |
+ UINT32 ctxFamilyNameLength; |
+ UINT32 ctxFaceNameLength; |
+ HRB(ctxFamilyNames->GetStringLength(0, &ctxFamilyNameLength)); |
+ HRB(ctxFaceNames->GetStringLength(0, &ctxFaceNameLength)); |
+ |
+ if (cshFamilyNameLength != ctxFamilyNameLength || |
+ cshFaceNameLength != ctxFaceNameLength) |
{ |
return false; |
} |
- SkSMallocWCHAR dwFaceFontFamilyNameChar(dwFaceFontFamilyNameLength+1); |
- SkSMallocWCHAR dwFaceFontNameChar(dwFaceFontNameLength+1); |
- HRB(dwFaceFontFamilyNames->GetString(0, dwFaceFontFamilyNameChar.get(), dwFaceFontFamilyNameLength+1)); |
- HRB(dwFaceFontNames->GetString(0, dwFaceFontNameChar.get(), dwFaceFontNameLength+1)); |
+ SkSMallocWCHAR cshFamilyName(cshFamilyNameLength+1); |
+ SkSMallocWCHAR cshFaceName(cshFaceNameLength+1); |
+ HRB(cshFamilyNames->GetString(0, cshFamilyName.get(), cshFamilyNameLength+1)); |
+ HRB(cshFaceNames->GetString(0, cshFaceName.get(), cshFaceNameLength+1)); |
- SkSMallocWCHAR dwFontFamilyNameChar(dwFontFamilyNameLength+1); |
- SkSMallocWCHAR dwFontNameChar(dwFontNameLength+1); |
- HRB(dwFontFamilyNames->GetString(0, dwFontFamilyNameChar.get(), dwFontFamilyNameLength+1)); |
- HRB(dwFontNames->GetString(0, dwFontNameChar.get(), dwFontNameLength+1)); |
+ SkSMallocWCHAR ctxFamilyName(ctxFamilyNameLength+1); |
+ SkSMallocWCHAR ctxFaceName(ctxFaceNameLength+1); |
+ HRB(ctxFamilyNames->GetString(0, ctxFamilyName.get(), ctxFamilyNameLength+1)); |
+ HRB(ctxFaceNames->GetString(0, ctxFaceName.get(), ctxFaceNameLength+1)); |
- return wcscmp(dwFaceFontFamilyNameChar.get(), dwFontFamilyNameChar.get()) == 0 && |
- wcscmp(dwFaceFontNameChar.get(), dwFontNameChar.get()) == 0; |
+ return wcscmp(cshFamilyName.get(), ctxFamilyName.get()) == 0 && |
+ wcscmp(cshFaceName.get(), ctxFaceName.get()) == 0; |
} |
SkTypeface* SkFontMgr_DirectWrite::createTypefaceFromDWriteFont( |
IDWriteFontFace* fontFace, |
IDWriteFont* font, |
IDWriteFontFamily* fontFamily) const { |
- SkTypeface* face = FindByProcAndRef(FindByDWriteFont, font); |
+ SkAutoMutexAcquire ama(fTFCacheMutex); |
+ ProtoDWriteTypeface spec = { fontFace, font, fontFamily }; |
+ SkTypeface* face = fTFCache.findByProcAndRef(FindByDWriteFont, &spec); |
if (NULL == face) { |
face = DWriteFontTypeface::Create(fFactory.get(), fontFace, font, fontFamily); |
if (face) { |
- Add(face, get_style(font), true); |
+ fTFCache.add(face, get_style(font), true); |
} |
} |
return face; |