From 73e93f31349a3a59c07488249970567893f15efe Mon Sep 17 00:00:00 2001 From: Bruce Wang Date: Tue, 5 Jun 2018 15:20:52 -0400 Subject: Implement SkFontMgr_DirectWrite::onMakeFromStreamArgs function. Variable fonts now work on windows 10. Change-Id: I81a90520544e2f4811d54bee1e3b89a83792000d Reviewed-on: https://skia-review.googlesource.com/132221 Reviewed-by: Ben Wagner Reviewed-by: Bruce Wang Commit-Queue: Bruce Wang --- src/ports/SkFontMgr_win_dw.cpp | 91 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) (limited to 'src') diff --git a/src/ports/SkFontMgr_win_dw.cpp b/src/ports/SkFontMgr_win_dw.cpp index e4b9a8ed47..b92ffaf797 100644 --- a/src/ports/SkFontMgr_win_dw.cpp +++ b/src/ports/SkFontMgr_win_dw.cpp @@ -10,6 +10,7 @@ #include "SkDWrite.h" #include "SkDWriteFontFileStream.h" +#include "SkEndian.h" #include "SkFontMgr.h" #include "SkHRESULT.h" #include "SkMakeUnique.h" @@ -24,6 +25,7 @@ #include #include +#include //////////////////////////////////////////////////////////////////////////////// @@ -296,6 +298,7 @@ protected: SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember, const SkFontStyle& fontstyle) const override; sk_sp onMakeFromStreamIndex(std::unique_ptr, int ttcIndex) const override; + sk_sp onMakeFromStreamArgs(std::unique_ptr, const SkFontArguments&) const override; sk_sp onMakeFromData(sk_sp, int ttcIndex) const override; sk_sp onMakeFromFile(const char path[], int ttcIndex) const override; sk_sp onLegacyMakeTypeface(const char familyName[], SkFontStyle) const override; @@ -924,6 +927,94 @@ sk_sp SkFontMgr_DirectWrite::onMakeFromStreamIndex(std::unique_ptr SkFontMgr_DirectWrite::onMakeFromStreamArgs(std::unique_ptr stream, + const SkFontArguments& args) const { + SkTScopedComPtr fontFileLoader; + // This transfers ownership of stream to the new object. + HRN(StreamFontFileLoader::Create(std::move(stream), &fontFileLoader)); + HRN(fFactory->RegisterFontFileLoader(fontFileLoader.get())); + SkAutoIDWriteUnregister autoUnregisterFontFileLoader( + fFactory.get(), fontFileLoader.get()); + + SkTScopedComPtr fontCollectionLoader; + HRN(StreamFontCollectionLoader::Create(fontFileLoader.get(), &fontCollectionLoader)); + HRN(fFactory->RegisterFontCollectionLoader(fontCollectionLoader.get())); + SkAutoIDWriteUnregister autoUnregisterFontCollectionLoader( + fFactory.get(), fontCollectionLoader.get()); + + SkTScopedComPtr 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 fontFamily; + HRN(fontCollection->GetFontFamily(familyIndex, &fontFamily)); + + UINT32 fontCount = fontFamily->GetFontCount(); + for (UINT32 fontIndex = 0; fontIndex < fontCount; ++fontIndex) { + SkTScopedComPtr font; + HRN(fontFamily->GetFont(fontIndex, &font)); + + // Skip if the current font is simulated + if (font->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE) { + continue; + } + SkTScopedComPtr fontFace; + HRN(font->CreateFontFace(&fontFace)); + int faceIndex = fontFace->GetIndex(); + int ttcIndex = args.getCollectionIndex(); + + // Skip if the current face index does not match the ttcIndex + if (faceIndex != ttcIndex) { + continue; + } + +#if defined(NTDDI_WIN10_RS3) && NTDDI_VERSION >= NTDDI_WIN10_RS3 + + SkTScopedComPtr fontFace5; + HRN(fontFace->QueryInterface(&fontFace5)); + if (fontFace5 && fontFace5->HasVariations()) { + UINT32 fontAxisCount = fontFace5->GetFontAxisValueCount(); + UINT32 argsCoordCount = args.getVariationDesignPosition().coordinateCount; + SkAutoSTMalloc<8, DWRITE_FONT_AXIS_VALUE> fontAxisValues(fontAxisCount); + SkTScopedComPtr fontResource; + HRN(fontFace5->GetFontResource(&fontResource)); + // Set all axes by default values + HRN(fontResource->GetDefaultFontAxisValues(fontAxisValues, fontAxisCount)); + + for (UINT32 fontIndex = 0; fontIndex < fontAxisCount; ++fontIndex) { + for (UINT32 argsIndex = 0; argsIndex < argsCoordCount; ++argsIndex) { + if (SkEndian_SwapBE32(fontAxisValues[fontIndex].axisTag) == + args.getVariationDesignPosition().coordinates[argsIndex].axis) { + fontAxisValues[fontIndex].value = + args.getVariationDesignPosition().coordinates[argsIndex].value; + } + } + } + + SkTScopedComPtr fontFace5_Out; + HRN(fontResource->CreateFontFace(DWRITE_FONT_SIMULATIONS_NONE, + fontAxisValues.get(), + fontAxisCount, + &fontFace5_Out)); + fontFace.reset(); + fontFace5_Out->QueryInterface(&fontFace); + } + +#endif + + return sk_sp(DWriteFontTypeface::Create( + fFactory.get(), fontFace.get(), font.get(), fontFamily.get(), + autoUnregisterFontFileLoader.detatch(), + autoUnregisterFontCollectionLoader.detatch())); + } + } + + return nullptr; +} + sk_sp SkFontMgr_DirectWrite::onMakeFromData(sk_sp data, int ttcIndex) const { return this->makeFromStream(skstd::make_unique(std::move(data)), ttcIndex); } -- cgit v1.2.3