SkStreamAsset* DWriteFontTypeface::onOpenStream(int* ttcIndex) const { *ttcIndex = fDWriteFontFace->GetIndex(); UINT32 numFiles; HRNM(fDWriteFontFace->GetFiles(&numFiles, nullptr), "Could not get number of font files."); if (numFiles != 1) { return nullptr; } SkTScopedComPtr<IDWriteFontFile> fontFile; HRNM(fDWriteFontFace->GetFiles(&numFiles, &fontFile), "Could not get font files."); const void* fontFileKey; UINT32 fontFileKeySize; HRNM(fontFile->GetReferenceKey(&fontFileKey, &fontFileKeySize), "Could not get font file reference key."); SkTScopedComPtr<IDWriteFontFileLoader> fontFileLoader; HRNM(fontFile->GetLoader(&fontFileLoader), "Could not get font file loader."); SkTScopedComPtr<IDWriteFontFileStream> fontFileStream; HRNM(fontFileLoader->CreateStreamFromKey(fontFileKey, fontFileKeySize, &fontFileStream), "Could not create font file stream."); return new SkDWriteFontFileStream(fontFileStream.get()); }
static bool FindByDWriteFont(SkTypeface* cached, 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. HRB(are_same(cshFace->fDWriteFont.get(), ctxFace->fDWriteFont, same)); if (same) { return true; } HRB(are_same(cshFace->fDWriteFontFace.get(), ctxFace->fDWriteFontFace, same)); if (same) { return true; } //Check if the two fonts share the same loader and have the same key. UINT32 cshNumFiles; UINT32 ctxNumFiles; HRB(cshFace->fDWriteFontFace->GetFiles(&cshNumFiles, nullptr)); HRB(ctxFace->fDWriteFontFace->GetFiles(&ctxNumFiles, nullptr)); if (cshNumFiles != ctxNumFiles) { return false; } 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> 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* 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(cshRefKey, ctxRefKey, ctxRefKeySize)) { return false; } //TODO: better means than comparing name strings? //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 cshFamilyName(cshFamilyNameLength+1); SkSMallocWCHAR cshFaceName(cshFaceNameLength+1); HRB(cshFamilyNames->GetString(0, cshFamilyName.get(), cshFamilyNameLength+1)); HRB(cshFaceNames->GetString(0, cshFaceName.get(), cshFaceNameLength+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(cshFamilyName.get(), ctxFamilyName.get()) == 0 && wcscmp(cshFaceName.get(), ctxFaceName.get()) == 0; }