Add variation support to SkShaper.

Sets the variation position of the SkTypeface on th hb_font. This allows
for correct shaping of variation fonts. This also splits out the
creation of hb_font from SkTypeface for clarity.

Change-Id: I8e3476dea0f18f1f7cb3fe757a04f99f0ab6c0fe
Reviewed-on: https://skia-review.googlesource.com/41742
Reviewed-by: Derek Sollenberger <djsollen@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
diff --git a/tools/shape/SkShaper_harfbuzz.cpp b/tools/shape/SkShaper_harfbuzz.cpp
index 98cf6cc..bdb38b1 100644
--- a/tools/shape/SkShaper_harfbuzz.cpp
+++ b/tools/shape/SkShaper_harfbuzz.cpp
@@ -12,6 +12,7 @@
 
 #include "SkShaper.h"
 #include "SkStream.h"
+#include "SkTemplates.h"
 #include "SkTextBlob.h"
 #include "SkTypeface.h"
 #include "SkUtils.h"
@@ -52,24 +53,40 @@
     sk_sp<SkTypeface> fTypeface;
 };
 
-SkShaper::SkShaper(sk_sp<SkTypeface> tf) : fImpl(new Impl) {
-    fImpl->fTypeface = tf ? std::move(tf) : SkTypeface::MakeDefault();
+static HBFont create_hb_font(SkTypeface* tf) {
     int index;
-    HBBlob blob(stream_to_blob(std::unique_ptr<SkStreamAsset>(
-                               fImpl->fTypeface->openStream(&index))));
+    HBBlob blob(stream_to_blob(std::unique_ptr<SkStreamAsset>(tf->openStream(&index))));
     HBFace face(hb_face_create(blob.get(), (unsigned)index));
     SkASSERT(face);
     if (!face) {
-        return;
+        return nullptr;
     }
     hb_face_set_index(face.get(), (unsigned)index);
-    hb_face_set_upem(face.get(), fImpl->fTypeface->getUnitsPerEm());
+    hb_face_set_upem(face.get(), tf->getUnitsPerEm());
 
-    fImpl->fHarfBuzzFont.reset(hb_font_create(face.get()));
+    HBFont font(hb_font_create(face.get()));
+    SkASSERT(font);
+    if (!font) {
+        return nullptr;
+    }
+    hb_font_set_scale(font.get(), FONT_SIZE_SCALE, FONT_SIZE_SCALE);
+    hb_ot_font_set_funcs(font.get());
+    int axis_count = tf->getVariationDesignPosition(nullptr, 0);
+    if (axis_count > 0) {
+        SkAutoSTMalloc<4, SkFontArguments::VariationPosition::Coordinate> axis_values(axis_count);
+        if (tf->getVariationDesignPosition(axis_values, axis_count) == axis_count) {
+            hb_font_set_variations(font.get(),
+                                   reinterpret_cast<hb_variation_t*>(axis_values.get()),
+                                   axis_count);
+        }
+    }
+    return font;
+}
+
+SkShaper::SkShaper(sk_sp<SkTypeface> tf) : fImpl(new Impl) {
+    fImpl->fTypeface = tf ? std::move(tf) : SkTypeface::MakeDefault();
+    fImpl->fHarfBuzzFont = create_hb_font(fImpl->fTypeface.get());
     SkASSERT(fImpl->fHarfBuzzFont);
-    hb_font_set_scale(fImpl->fHarfBuzzFont.get(), FONT_SIZE_SCALE, FONT_SIZE_SCALE);
-    hb_ot_font_set_funcs(fImpl->fHarfBuzzFont.get());
-
     fImpl->fBuffer.reset(hb_buffer_create());
 }