aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Bruce Wang <brucewang@google.com>2018-06-05 15:20:52 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-07 15:46:38 +0000
commit73e93f31349a3a59c07488249970567893f15efe (patch)
tree3cdd0586d1a4745238463dd0b0fc0a2d9160caa9 /src
parentfaef51451a81dccffcba50b58d9a323bdd9f150c (diff)
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 <bungeman@google.com> Reviewed-by: Bruce Wang <brucewang@google.com> Commit-Queue: Bruce Wang <brucewang@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/ports/SkFontMgr_win_dw.cpp91
1 files changed, 91 insertions, 0 deletions
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 <dwrite.h>
#include <dwrite_2.h>
+#include <dwrite_3.h>
////////////////////////////////////////////////////////////////////////////////
@@ -296,6 +298,7 @@ protected:
SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
const SkFontStyle& fontstyle) const override;
sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset>, int ttcIndex) const override;
+ sk_sp<SkTypeface> onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset>, const SkFontArguments&) const override;
sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData>, int ttcIndex) const override;
sk_sp<SkTypeface> onMakeFromFile(const char path[], int ttcIndex) const override;
sk_sp<SkTypeface> onLegacyMakeTypeface(const char familyName[], SkFontStyle) const override;
@@ -924,6 +927,94 @@ sk_sp<SkTypeface> SkFontMgr_DirectWrite::onMakeFromStreamIndex(std::unique_ptr<S
return nullptr;
}
+sk_sp<SkTypeface> SkFontMgr_DirectWrite::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset> stream,
+ const SkFontArguments& args) const {
+ SkTScopedComPtr<StreamFontFileLoader> fontFileLoader;
+ // This transfers ownership of stream to the new object.
+ HRN(StreamFontFileLoader::Create(std::move(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));
+
+ // Skip if the current font is simulated
+ if (font->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE) {
+ continue;
+ }
+ SkTScopedComPtr<IDWriteFontFace> 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<IDWriteFontFace5> 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<IDWriteFontResource> 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<IDWriteFontFace5> fontFace5_Out;
+ HRN(fontResource->CreateFontFace(DWRITE_FONT_SIMULATIONS_NONE,
+ fontAxisValues.get(),
+ fontAxisCount,
+ &fontFace5_Out));
+ fontFace.reset();
+ fontFace5_Out->QueryInterface(&fontFace);
+ }
+
+#endif
+
+ return sk_sp<SkTypeface>(DWriteFontTypeface::Create(
+ fFactory.get(), fontFace.get(), font.get(), fontFamily.get(),
+ autoUnregisterFontFileLoader.detatch(),
+ autoUnregisterFontCollectionLoader.detatch()));
+ }
+ }
+
+ return nullptr;
+}
+
sk_sp<SkTypeface> SkFontMgr_DirectWrite::onMakeFromData(sk_sp<SkData> data, int ttcIndex) const {
return this->makeFromStream(skstd::make_unique<SkMemoryStream>(std::move(data)), ttcIndex);
}