aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Bruce Wang <brucewang@google.com>2018-06-07 17:19:14 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-08 19:13:13 +0000
commitf0aacafe9e7a74475493c71c4c3679e80a8b2a82 (patch)
tree066042fd81bb3ec2e451a9396c95ec71987a542a
parent17ee85597a09757d1bdd31c4452bafcc430332f8 (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.cpp18
-rw-r--r--src/ports/SkTypeface_win_dw.cpp48
-rw-r--r--src/ports/SkTypeface_win_dw.h2
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;