Add SkTypeface::getVariationDesignPosition.

Allow users to query a typeface's position in variation design space.

Change-Id: Id7cae439e795b8c9586394f11359fb7fe55e1c0b
Reviewed-on: https://skia-review.googlesource.com/8861
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
diff --git a/tests/FontMgrAndroidParserTest.cpp b/tests/FontMgrAndroidParserTest.cpp
index 92dbd95..cbcfb3b 100644
--- a/tests/FontMgrAndroidParserTest.cpp
+++ b/tests/FontMgrAndroidParserTest.cpp
@@ -90,13 +90,13 @@
         for (int j = 0; j < fontFamilies[i]->fFonts.count(); ++j) {
             const FontFileInfo& ffi = fontFamilies[i]->fFonts[j];
             SkDebugf("  file (%d) %s#%d", ffi.fWeight, ffi.fFileName.c_str(), ffi.fIndex);
-            for (const auto& axis : ffi.fAxes) {
+            for (const auto& coordinate : ffi.fVariationDesignPosition) {
                 SkDebugf(" @'%c%c%c%c'=%f",
-                         (axis.fTag >> 24) & 0xFF,
-                         (axis.fTag >> 16) & 0xFF,
-                         (axis.fTag >>  8) & 0xFF,
-                         (axis.fTag      ) & 0xFF,
-                         axis.fStyleValue);
+                         (coordinate.axis >> 24) & 0xFF,
+                         (coordinate.axis >> 16) & 0xFF,
+                         (coordinate.axis >>  8) & 0xFF,
+                         (coordinate.axis      ) & 0xFF,
+                         coordinate.value);
             }
             SkDebugf("\n");
         }
diff --git a/tests/FontMgrTest.cpp b/tests/FontMgrTest.cpp
index 50e2d5a..b6a0cc5 100644
--- a/tests/FontMgrTest.cpp
+++ b/tests/FontMgrTest.cpp
@@ -150,6 +150,12 @@
         SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override {
             return new EmptyLocalizedStrings;
         }
+        int onGetVariationDesignPosition(
+                SkFontArguments::VariationPosition::Coordinate coordinates[],
+                int coordinateCount) const override
+        {
+            return 0;
+        }
         int onGetTableTags(SkFontTableTag tags[]) const override { return 0; }
         size_t onGetTableData(SkFontTableTag, size_t, size_t, void*) const override {
             return 0;
diff --git a/tests/TypefaceTest.cpp b/tests/TypefaceTest.cpp
index 2a3b32d..4786cc2 100644
--- a/tests/TypefaceTest.cpp
+++ b/tests/TypefaceTest.cpp
@@ -6,6 +6,9 @@
  */
 
 #include "SkData.h"
+#include "SkFixed.h"
+#include "SkFontMgr.h"
+#include "SkMakeUnique.h"
 #include "SkOTTable_OS_2.h"
 #include "SkSFNTHeader.h"
 #include "SkStream.h"
@@ -87,6 +90,77 @@
     }
 }
 
+DEF_TEST(TypefaceAxes, reporter) {
+    std::unique_ptr<SkStreamAsset> distortable(GetResourceAsStream("/fonts/Distortable.ttf"));
+    if (!distortable) {
+        REPORT_FAILURE(reporter, "distortable", SkString());
+        return;
+    }
+
+    sk_sp<SkFontMgr> fm = SkFontMgr::RefDefault();
+    const SkFontArguments::VariationPosition::Coordinate position[] = {
+        { SkSetFourByteTag('w','g','h','t'), SK_ScalarSqrt2 }
+    };
+    SkFontArguments params;
+    params.setVariationDesignPosition({position, SK_ARRAY_COUNT(position)});
+    // TODO: if axes are set and the back-end doesn't support them, should we create the typeface?
+    sk_sp<SkTypeface> typeface(fm->createFromStream(distortable.release(), params));
+
+    int count = typeface->getVariationDesignPosition(nullptr, 0);
+    if (count == -1) {
+        return;
+    }
+    REPORTER_ASSERT(reporter, count == SK_ARRAY_COUNT(position));
+
+    SkFontArguments::VariationPosition::Coordinate positionRead[SK_ARRAY_COUNT(position)];
+    count = typeface->getVariationDesignPosition(positionRead, SK_ARRAY_COUNT(positionRead));
+    REPORTER_ASSERT(reporter, count == SK_ARRAY_COUNT(position));
+
+    REPORTER_ASSERT(reporter, positionRead[0].axis == position[0].axis);
+
+    // Convert to fixed for "almost equal".
+    SkFixed fixedRead = SkScalarToFixed(positionRead[0].value);
+    SkFixed fixedOriginal = SkScalarToFixed(position[0].value);
+    REPORTER_ASSERT(reporter, fixedRead == fixedOriginal);
+}
+
+DEF_TEST(TypefaceVariationIndex, reporter) {
+    std::unique_ptr<SkStreamAsset> distortable(GetResourceAsStream("/fonts/Distortable.ttf"));
+    if (!distortable) {
+        REPORT_FAILURE(reporter, "distortable", SkString());
+        return;
+    }
+
+    sk_sp<SkFontMgr> fm = SkFontMgr::RefDefault();
+    SkFontArguments params;
+    // The first named variation position in Distortable is 'Thin'.
+    params.setCollectionIndex(0x00010000);
+    sk_sp<SkTypeface> typeface(fm->createFromStream(distortable.release(), params));
+    if (!typeface) {
+        // FreeType is the only weird thing that supports this, Skia just needs to make sure if it
+        // gets one of these things make sense.
+        return;
+    }
+
+    int count = typeface->getVariationDesignPosition(nullptr, 0);
+    if (!(count == 1)) {
+        REPORT_FAILURE(reporter, "count == 1", SkString());
+        return;
+    }
+
+    SkFontArguments::VariationPosition::Coordinate positionRead[1];
+    count = typeface->getVariationDesignPosition(positionRead, SK_ARRAY_COUNT(positionRead));
+    if (count == -1) {
+        return;
+    }
+    if (!(count == 1)) {
+        REPORT_FAILURE(reporter, "count == 1", SkString());
+        return;
+    }
+    REPORTER_ASSERT(reporter, positionRead[0].axis == SkSetFourByteTag('w','g','h','t'));
+    REPORTER_ASSERT(reporter, positionRead[0].value == 0.5);
+}
+
 DEF_TEST(Typeface, reporter) {
 
     sk_sp<SkTypeface> t1(SkTypeface::MakeFromName(nullptr, SkFontStyle()));
@@ -134,6 +208,11 @@
         SK_ABORT("unimplemented");
         return nullptr;
     }
+    int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
+                                     int coordinateCount) const override
+    {
+        return 0;
+    }
     int onGetTableTags(SkFontTableTag tags[]) const override { return 0; }
     size_t onGetTableData(SkFontTableTag, size_t, size_t, void*) const override { return 0; }
 };