diff options
author | Bruce Wang <brucewang@google.com> | 2018-06-07 17:19:14 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-06-08 19:13:13 +0000 |
commit | f0aacafe9e7a74475493c71c4c3679e80a8b2a82 (patch) | |
tree | 066042fd81bb3ec2e451a9396c95ec71987a542a | |
parent | 17ee85597a09757d1bdd31c4452bafcc430332f8 (diff) |
Add SkTypeface::makeClone.
This adds an method to typeface to allow users to create a copy of the
typeface with different arguments for its parameters. This is far more
efficient when animating a variation font.
Change-Id: Ie41a5b76bef8eaf05b56b65774eaf38aad0dc4cf
Reviewed-on: https://skia-review.googlesource.com/132934
Commit-Queue: Bruce Wang <brucewang@google.com>
Reviewed-by: Bruce Wang <brucewang@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
-rw-r--r-- | gm/fontscalerdistortable.cpp | 18 | ||||
-rw-r--r-- | src/ports/SkTypeface_win_dw.cpp | 48 | ||||
-rw-r--r-- | src/ports/SkTypeface_win_dw.h | 2 |
3 files changed, 63 insertions, 5 deletions
diff --git a/gm/fontscalerdistortable.cpp b/gm/fontscalerdistortable.cpp index 49d254de36..5778ce0200 100644 --- a/gm/fontscalerdistortable.cpp +++ b/gm/fontscalerdistortable.cpp @@ -35,8 +35,10 @@ protected: paint.setLCDRenderText(true); sk_sp<SkFontMgr> fontMgr(SkFontMgr::RefDefault()); - std::unique_ptr<SkStreamAsset> distortable(GetResourceAsStream("fonts/Distortable.ttf")); - if (!distortable) { + std::unique_ptr<SkStreamAsset> distortableStream(GetResourceAsStream("fonts/Distortable.ttf")); + sk_sp<SkTypeface> distortable(MakeResourceAsTypeface("fonts/Distortable.ttf")); + + if (!distortableStream) { return; } const char* text = "abc"; @@ -48,13 +50,19 @@ protected: SkScalar y = SkIntToScalar(20); SkFourByteTag tag = SkSetFourByteTag('w','g','h','t'); - SkScalar styleValue = SkDoubleToScalar(0.5 + (5*j + i) * ((2.0 - 0.5) / (2 * 5))); + SkScalar styleValue = SkDoubleToScalar(0.5 + (5 * j + i) * ((2.0 - 0.5) / (2 * 5))); SkFontArguments::VariationPosition::Coordinate coordinates[] = {{tag, styleValue}}; SkFontArguments::VariationPosition position = { coordinates, SK_ARRAY_COUNT(coordinates) }; - paint.setTypeface(sk_sp<SkTypeface>(fontMgr->makeFromStream( - distortable->duplicate(), + if (j == 0 && distortable) { + paint.setTypeface(sk_sp<SkTypeface>( + distortable->makeClone( + SkFontArguments().setVariationDesignPosition(position)))); + } else { + paint.setTypeface(sk_sp<SkTypeface>(fontMgr->makeFromStream( + distortableStream->duplicate(), SkFontArguments().setVariationDesignPosition(position)))); + } SkAutoCanvasRestore acr(canvas, true); canvas->translate(SkIntToScalar(30 + i * 100), SkIntToScalar(20)); diff --git a/src/ports/SkTypeface_win_dw.cpp b/src/ports/SkTypeface_win_dw.cpp index 38e68dccca..281355e6a0 100644 --- a/src/ports/SkTypeface_win_dw.cpp +++ b/src/ports/SkTypeface_win_dw.cpp @@ -217,6 +217,54 @@ size_t DWriteFontTypeface::onGetTableData(SkFontTableTag tag, size_t offset, return size; } +sk_sp<SkTypeface> DWriteFontTypeface::onMakeClone(const SkFontArguments& args) const { + // Skip if the current face index does not match the ttcIndex + if (fDWriteFontFace->GetIndex() != SkTo<UINT32>(args.getCollectionIndex())) { + return sk_ref_sp(this); + } + +#if defined(NTDDI_WIN10_RS3) && NTDDI_VERSION >= NTDDI_WIN10_RS3 + + SkTScopedComPtr<IDWriteFontFace5> fontFace5; + + if (SUCCEEDED(fDWriteFontFace->QueryInterface(&fontFace5)) && fontFace5->HasVariations()) { + UINT32 fontAxisCount = fontFace5->GetFontAxisValueCount(); + UINT32 argsCoordCount = args.getVariationDesignPosition().coordinateCount; + SkAutoSTMalloc<8, DWRITE_FONT_AXIS_VALUE> fontAxisValue(fontAxisCount); + HRN(fontFace5->GetFontAxisValues(fontAxisValue.get(), fontAxisCount)); + + for (UINT32 fontIndex = 0; fontIndex < fontAxisCount; ++fontIndex) { + for (UINT32 argsIndex = 0; argsIndex < argsCoordCount; ++argsIndex) { + if (SkEndian_SwapBE32(fontAxisValue[fontIndex].axisTag) == + args.getVariationDesignPosition().coordinates[argsIndex].axis) { + fontAxisValue[fontIndex].value = + args.getVariationDesignPosition().coordinates[argsIndex].value; + } + } + } + SkTScopedComPtr<IDWriteFontResource> fontResource; + HRN(fontFace5->GetFontResource(&fontResource)); + SkTScopedComPtr<IDWriteFontFace5> newFontFace5; + HRN(fontResource->CreateFontFace(fDWriteFont->GetSimulations(), + fontAxisValue.get(), + fontAxisCount, + &newFontFace5)); + + SkTScopedComPtr<IDWriteFontFace> newFontFace; + HRN(newFontFace5->QueryInterface(&newFontFace)); + return sk_sp<SkTypeface>(DWriteFontTypeface::Create(fFactory.get(), + newFontFace.get(), + fDWriteFont.get(), + fDWriteFontFamily.get(), + fDWriteFontFileLoader.get(), + fDWriteFontCollectionLoader.get())); + } + +#endif + + return sk_ref_sp(this); +} + SkStreamAsset* DWriteFontTypeface::onOpenStream(int* ttcIndex) const { *ttcIndex = fDWriteFontFace->GetIndex(); diff --git a/src/ports/SkTypeface_win_dw.h b/src/ports/SkTypeface_win_dw.h index 75be040fd4..b443c28efe 100644 --- a/src/ports/SkTypeface_win_dw.h +++ b/src/ports/SkTypeface_win_dw.h @@ -19,6 +19,7 @@ #include <dwrite.h> #include <dwrite_1.h> #include <dwrite_2.h> +#include <dwrite_3.h> class SkFontDescriptor; struct SkScalerContextRec; @@ -100,6 +101,7 @@ protected: INHERITED::weak_dispose(); } + sk_sp<SkTypeface> onMakeClone(const SkFontArguments&) const override; SkStreamAsset* onOpenStream(int* ttcIndex) const override; SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&, const SkDescriptor*) const override; |