SkTypeface* SkFontMgr_DirectWrite::onLegacyCreateTypeface(const char familyName[], SkFontStyle style) const { SkTScopedComPtr<IDWriteFontFamily> fontFamily; if (familyName) { SkSMallocWCHAR wideFamilyName; if (SUCCEEDED(sk_cstring_to_wchar(familyName, &wideFamilyName))) { this->getByFamilyName(wideFamilyName, &fontFamily); } } if (nullptr == fontFamily.get()) { // No family with given name, try default. this->getDefaultFontFamily(&fontFamily); } if (nullptr == fontFamily.get()) { // Could not obtain the default font. HRNM(fFontCollection->GetFontFamily(0, &fontFamily), "Could not get default-default font family."); } SkTScopedComPtr<IDWriteFont> font; DWriteStyle dwStyle(style); HRNM(fontFamily->GetFirstMatchingFont(dwStyle.fWeight, dwStyle.fWidth, dwStyle.fSlant, &font), "Could not get matching font."); SkTScopedComPtr<IDWriteFontFace> fontFace; HRNM(font->CreateFontFace(&fontFace), "Could not create font face."); return this->createTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily.get()); }
// IDWriteTextRenderer methods virtual HRESULT STDMETHODCALLTYPE DrawGlyphRun( void* clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, DWRITE_MEASURING_MODE measuringMode, DWRITE_GLYPH_RUN const* glyphRun, DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription, IUnknown* clientDrawingEffect) override { SkTScopedComPtr<IDWriteFont> font; HRM(fOuter->fFontCollection->GetFontFromFontFace(glyphRun->fontFace, &font), "Could not get font from font face."); // It is possible that the font passed does not actually have the requested character, // due to no font being found and getting the fallback font. // Check that the font actually contains the requested character. BOOL exists; HRM(font->HasCharacter(fCharacter, &exists), "Could not find character."); if (exists) { SkTScopedComPtr<IDWriteFontFamily> fontFamily; HRM(font->GetFontFamily(&fontFamily), "Could not get family."); fResolvedTypeface = fOuter->createTypefaceFromDWriteFont(glyphRun->fontFace, font.get(), fontFamily.get()); } return S_OK; }
void SkFontMgr_DirectWrite::onGetFamilyName(int index, SkString* familyName) const { SkTScopedComPtr<IDWriteFontFamily> fontFamily; HRVM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requested family."); SkTScopedComPtr<IDWriteLocalizedStrings> familyNames; HRVM(fontFamily->GetFamilyNames(&familyNames), "Could not get family names."); sk_get_locale_string(familyNames.get(), fLocaleName.get(), familyName); }
HRESULT SkFontMgr_DirectWrite::getByFamilyName(const WCHAR wideFamilyName[], IDWriteFontFamily** fontFamily) const { UINT32 index; BOOL exists; HR(fFontCollection->FindFamilyName(wideFamilyName, &index, &exists)); if (exists) { HR(fFontCollection->GetFontFamily(index, fontFamily)); } return S_OK; }
SkTypeface* SkFontMgr_DirectWrite::onCreateFromStream(SkStreamAsset* stream, int ttcIndex) const { SkTScopedComPtr<StreamFontFileLoader> fontFileLoader; // This transfers ownership of stream to the new object. HRN(StreamFontFileLoader::Create(stream, &fontFileLoader)); HRN(fFactory->RegisterFontFileLoader(fontFileLoader.get())); SkAutoIDWriteUnregister<StreamFontFileLoader> autoUnregisterFontFileLoader( fFactory.get(), fontFileLoader.get()); SkTScopedComPtr<StreamFontCollectionLoader> fontCollectionLoader; HRN(StreamFontCollectionLoader::Create(fontFileLoader.get(), &fontCollectionLoader)); HRN(fFactory->RegisterFontCollectionLoader(fontCollectionLoader.get())); SkAutoIDWriteUnregister<StreamFontCollectionLoader> autoUnregisterFontCollectionLoader( fFactory.get(), fontCollectionLoader.get()); SkTScopedComPtr<IDWriteFontCollection> fontCollection; HRN(fFactory->CreateCustomFontCollection(fontCollectionLoader.get(), nullptr, 0, &fontCollection)); // Find the first non-simulated font which has the given ttc index. UINT32 familyCount = fontCollection->GetFontFamilyCount(); for (UINT32 familyIndex = 0; familyIndex < familyCount; ++familyIndex) { SkTScopedComPtr<IDWriteFontFamily> fontFamily; HRN(fontCollection->GetFontFamily(familyIndex, &fontFamily)); UINT32 fontCount = fontFamily->GetFontCount(); for (UINT32 fontIndex = 0; fontIndex < fontCount; ++fontIndex) { SkTScopedComPtr<IDWriteFont> font; HRN(fontFamily->GetFont(fontIndex, &font)); if (font->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE) { continue; } SkTScopedComPtr<IDWriteFontFace> fontFace; HRN(font->CreateFontFace(&fontFace)); UINT32 faceIndex = fontFace->GetIndex(); if (faceIndex == ttcIndex) { return DWriteFontTypeface::Create(fFactory.get(), fontFace.get(), font.get(), fontFamily.get(), autoUnregisterFontFileLoader.detatch(), autoUnregisterFontCollectionLoader.detatch()); } } } return nullptr; }
SkTypeface* SkFontMgr_DirectWrite::onLegacyCreateTypeface(const char familyName[], unsigned styleBits) const { SkTScopedComPtr<IDWriteFontFamily> fontFamily; if (familyName) { SkSMallocWCHAR wideFamilyName; if (SUCCEEDED(sk_cstring_to_wchar(familyName, &wideFamilyName))) { this->getByFamilyName(wideFamilyName, &fontFamily); } } if (NULL == fontFamily.get()) { // No family with given name, try default. HRNM(this->getDefaultFontFamily(&fontFamily), "Could not get default font family."); } if (NULL == fontFamily.get()) { // Could not obtain the default font. HRNM(fFontCollection->GetFontFamily(0, &fontFamily), "Could not get default-default font family."); } SkTScopedComPtr<IDWriteFont> font; DWRITE_FONT_WEIGHT weight = (styleBits & SkTypeface::kBold) ? DWRITE_FONT_WEIGHT_BOLD : DWRITE_FONT_WEIGHT_NORMAL; DWRITE_FONT_STRETCH stretch = DWRITE_FONT_STRETCH_NORMAL; DWRITE_FONT_STYLE italic = (styleBits & SkTypeface::kItalic) ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL; HRNM(fontFamily->GetFirstMatchingFont(weight, stretch, italic, &font), "Could not get matching font."); SkTScopedComPtr<IDWriteFontFace> fontFace; HRNM(font->CreateFontFace(&fontFace), "Could not create font face."); return this->createTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily.get()); }
SkTypeface* SkFontMgr_DirectWrite::onMatchFamilyStyleCharacter(const char familyName[], const SkFontStyle& style, const char* bcp47[], int bcp47Count, SkUnichar character) const { const DWriteStyle dwStyle(style); const WCHAR* dwFamilyName = nullptr; SkSMallocWCHAR dwFamilyNameLocal; if (familyName) { HRN(sk_cstring_to_wchar(familyName, &dwFamilyNameLocal)); dwFamilyName = dwFamilyNameLocal; } WCHAR str[16]; UINT32 strLen = static_cast<UINT32>( SkUTF16_FromUnichar(character, reinterpret_cast<uint16_t*>(str))); const SkSMallocWCHAR* dwBcp47; SkSMallocWCHAR dwBcp47Local; if (bcp47Count < 1) { dwBcp47 = &fLocaleName; } else { // TODO: support fallback stack. // TODO: DirectWrite supports 'zh-CN' or 'zh-Hans', but 'zh' misses completely // and may produce a Japanese font. HRN(sk_cstring_to_wchar(bcp47[bcp47Count - 1], &dwBcp47Local)); dwBcp47 = &dwBcp47Local; } if (fFactory2.get()) { SkTScopedComPtr<IDWriteFontFallback> systemFontFallback; IDWriteFontFallback* fontFallback = fFontFallback.get(); if (!fontFallback) { HRNM(fFactory2->GetSystemFontFallback(&systemFontFallback), "Could not get system fallback."); fontFallback = systemFontFallback.get(); } SkTScopedComPtr<IDWriteNumberSubstitution> numberSubstitution; HRNM(fFactory2->CreateNumberSubstitution(DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE, nullptr, TRUE, &numberSubstitution), "Could not create number substitution."); SkTScopedComPtr<FontFallbackSource> fontFallbackSource( new FontFallbackSource(str, strLen, *dwBcp47, numberSubstitution.get())); UINT32 mappedLength; SkTScopedComPtr<IDWriteFont> font; FLOAT scale; HRNM(fontFallback->MapCharacters(fontFallbackSource.get(), 0, // textPosition, strLen, fFontCollection.get(), dwFamilyName, dwStyle.fWeight, dwStyle.fSlant, dwStyle.fWidth, &mappedLength, &font, &scale), "Could not map characters"); if (!font.get()) { return nullptr; } SkTScopedComPtr<IDWriteFontFace> fontFace; HRNM(font->CreateFontFace(&fontFace), "Could not get font face from font."); SkTScopedComPtr<IDWriteFontFamily> fontFamily; HRNM(font->GetFontFamily(&fontFamily), "Could not get family from font."); return this->createTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily.get()); } SkTScopedComPtr<IDWriteTextFormat> fallbackFormat; HRNM(fFactory->CreateTextFormat(dwFamilyName ? dwFamilyName : L"", fFontCollection.get(), dwStyle.fWeight, dwStyle.fSlant, dwStyle.fWidth, 72.0f, *dwBcp47, &fallbackFormat), "Could not create text format."); SkTScopedComPtr<IDWriteTextLayout> fallbackLayout; HRNM(fFactory->CreateTextLayout(str, strLen, fallbackFormat.get(), 200.0f, 200.0f, &fallbackLayout), "Could not create text layout."); SkTScopedComPtr<FontFallbackRenderer> fontFallbackRenderer( new FontFallbackRenderer(this, character)); HRNM(fallbackLayout->Draw(nullptr, fontFallbackRenderer.get(), 50.0f, 50.0f), "Could not draw layout with renderer."); return fontFallbackRenderer->FallbackTypeface(); }
SkFontStyleSet* SkFontMgr_DirectWrite::onCreateStyleSet(int index) const { SkTScopedComPtr<IDWriteFontFamily> fontFamily; HRNM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requested family."); return new SkFontStyleSet_DirectWrite(this, fontFamily.get()); }