Support FontFeatureSettings in Paint

New API is hidden.

Bug: 15246510
Change-Id: Idefca06a366de0d87f53d123b5291788448de4d0
diff --git a/core/jni/android/graphics/MinikinUtils.cpp b/core/jni/android/graphics/MinikinUtils.cpp
index 47f72c4..b00e1ab 100644
--- a/core/jni/android/graphics/MinikinUtils.cpp
+++ b/core/jni/android/graphics/MinikinUtils.cpp
@@ -59,6 +59,7 @@
     minikinPaint.skewX = paint->getTextSkewX();
     minikinPaint.letterSpacing = paint->getLetterSpacing();
     minikinPaint.paintFlags = MinikinFontSkia::packPaintFlags(paint);
+    minikinPaint.fontFeatureSettings = paint->getFontFeatureSettings();
 
     layout->doLayout(buf, start, count, bufSize, bidiFlags, minikinStyle, minikinPaint);
 }
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 2b0d68c..235e4f2 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -428,6 +428,16 @@
         paint->setLetterSpacing(letterSpacing);
     }
 
+    static void setFontFeatureSettings(JNIEnv* env, jobject clazz, jlong paintHandle, jstring settings) {
+        Paint* paint = reinterpret_cast<Paint*>(paintHandle);
+        if (!settings)
+            paint->setFontFeatureSettings(std::string());
+        else {
+            ScopedUtfChars settingsChars(env, settings);
+            paint->setFontFeatureSettings(std::string(settingsChars.c_str(), settingsChars.size()));
+        }
+    }
+
     static SkScalar getMetricsInternal(JNIEnv* env, jobject jpaint, Paint::FontMetrics *metrics) {
         const int kElegantTop = 2500;
         const int kElegantBottom = -1000;
@@ -987,6 +997,7 @@
     {"setTextSkewX","(F)V", (void*) PaintGlue::setTextSkewX},
     {"native_getLetterSpacing","(J)F", (void*) PaintGlue::getLetterSpacing},
     {"native_setLetterSpacing","(JF)V", (void*) PaintGlue::setLetterSpacing},
+    {"native_setFontFeatureSettings","(JLjava/lang/String;)V", (void*) PaintGlue::setFontFeatureSettings},
     {"ascent","()F", (void*) PaintGlue::ascent},
     {"descent","()F", (void*) PaintGlue::descent},
     {"getFontMetrics", "(Landroid/graphics/Paint$FontMetrics;)F", (void*)PaintGlue::getFontMetrics},
diff --git a/core/jni/android/graphics/Paint.h b/core/jni/android/graphics/Paint.h
index 7235cc4..efc65be 100644
--- a/core/jni/android/graphics/Paint.h
+++ b/core/jni/android/graphics/Paint.h
@@ -18,6 +18,7 @@
 #define ANDROID_GRAPHICS_PAINT_H
 
 #include <SkPaint.h>
+#include <string>
 
 namespace android {
 
@@ -42,8 +43,17 @@
         return mLetterSpacing;
     }
 
+    void setFontFeatureSettings(const std::string &fontFeatureSettings) {
+        mFontFeatureSettings = fontFeatureSettings;
+    }
+
+    std::string getFontFeatureSettings() const {
+        return mFontFeatureSettings;
+    }
+
 private:
     float mLetterSpacing;
+    std::string mFontFeatureSettings;
 };
 
 }  // namespace android
diff --git a/core/jni/android/graphics/PaintImpl.cpp b/core/jni/android/graphics/PaintImpl.cpp
index ff2bbc5..05020d2 100644
--- a/core/jni/android/graphics/PaintImpl.cpp
+++ b/core/jni/android/graphics/PaintImpl.cpp
@@ -23,11 +23,11 @@
 namespace android {
 
 Paint::Paint() : SkPaint(),
-        mLetterSpacing(0) {
+        mLetterSpacing(0), mFontFeatureSettings() {
 }
 
 Paint::Paint(const Paint& paint) : SkPaint(paint),
-        mLetterSpacing(0) {
+        mLetterSpacing(0), mFontFeatureSettings() {
 }
 
 Paint::~Paint() {
@@ -36,12 +36,14 @@
 Paint& Paint::operator=(const Paint& other) {
     SkPaint::operator=(other);
     mLetterSpacing = other.mLetterSpacing;
+    mFontFeatureSettings = other.mFontFeatureSettings;
     return *this;
 }
 
 bool operator==(const Paint& a, const Paint& b) {
     return static_cast<const SkPaint&>(a) == static_cast<const SkPaint&>(b)
-            && a.mLetterSpacing == b.mLetterSpacing;
+            && a.mLetterSpacing == b.mLetterSpacing
+            && a.mFontFeatureSettings == b.mFontFeatureSettings;
 }
 
 }
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 58a1bf2..ec862f8 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -51,6 +51,7 @@
     private float       mInvCompatScaling;
 
     private Locale      mLocale;
+    private String      mFontFeatureSettings;
 
     /**
      * @hide
@@ -474,6 +475,7 @@
         mBidiFlags = BIDI_DEFAULT_LTR;
         setTextLocale(Locale.getDefault());
         setElegantTextHeight(false);
+        mFontFeatureSettings = null;
     }
 
     /**
@@ -513,6 +515,7 @@
 
         mBidiFlags = paint.mBidiFlags;
         mLocale = paint.mLocale;
+        mFontFeatureSettings = paint.mFontFeatureSettings;
     }
 
     /** @hide */
@@ -1283,6 +1286,34 @@
     }
 
     /**
+     * Get font feature settings.  Default is null.
+     *
+     * @return the paint's currently set font feature settings.
+     * @hide
+     */
+    public String getFontFeatureSettings() {
+        return mFontFeatureSettings;
+    }
+
+    /**
+     * Set font feature settings.
+     *
+     * The format is the same as the CSS font-feature-settings attribute:
+     * http://dev.w3.org/csswg/css-fonts/#propdef-font-feature-settings
+     *
+     * @param settings the font feature settings string to use, may be null.
+     * @hide
+     */
+    public void setFontFeatureSettings(String settings) {
+        if (settings != null && settings.equals(""))
+            settings = null;
+        if ((settings == null && mFontFeatureSettings == null)
+                || (settings != null && settings.equals(mFontFeatureSettings))) return;
+        mFontFeatureSettings = settings;
+        native_setFontFeatureSettings(mNativePaint, settings);
+    }
+
+    /**
      * Return the distance above (negative) the baseline (ascent) based on the
      * current typeface and text size.
      *
@@ -2259,4 +2290,6 @@
     private static native float native_getLetterSpacing(long native_object);
     private static native void native_setLetterSpacing(long native_object,
                                                        float letterSpacing);
+    private static native void native_setFontFeatureSettings(long native_object,
+                                                             String settings);
 }