Introduce set/getFontVariationSettings.
This is 2nd attempt of I249d464f8cdaa56017a987588b94ed685aadeb58.
The original CL was reverted due to conflicting with another CL submitted
before.
Nothing has changed except for following class name changes.
Here is the original commit message of reverted change.
This CL enables developers to specify axis values to the underlying
font collection. The specification of the font variation settings is
the same as the CSS font-variation-settings attribute in CSS working
draft as of 2016-11-30.
Code example: Here is an example to set width 100 and weight 1.5.
TextView tv = (TextView) findViewById(R.id.textView);
tv.setFontVariationSettings("'wdth' 100, 'wght' 1.5");
Bug: 33062398
Test: Manually done. Ran FrameworksGraphicsTests, CtsGraphicsTestCases
and CtsWidgetTestCases
Change-Id: I9cdfbdecc87c995d805096883ef2652768c6c21e
This commit is contained in:
@@ -12731,6 +12731,7 @@ package android.graphics {
|
||||
method public int getFontMetricsInt(android.graphics.Paint.FontMetricsInt);
|
||||
method public android.graphics.Paint.FontMetricsInt getFontMetricsInt();
|
||||
method public float getFontSpacing();
|
||||
method public java.lang.String getFontVariationSettings();
|
||||
method public int getHinting();
|
||||
method public float getLetterSpacing();
|
||||
method public android.graphics.MaskFilter getMaskFilter();
|
||||
@@ -12788,6 +12789,7 @@ package android.graphics {
|
||||
method public void setFilterBitmap(boolean);
|
||||
method public void setFlags(int);
|
||||
method public void setFontFeatureSettings(java.lang.String);
|
||||
method public void setFontVariationSettings(java.lang.String);
|
||||
method public void setHinting(int);
|
||||
method public void setLetterSpacing(float);
|
||||
method public void setLinearText(boolean);
|
||||
@@ -49983,6 +49985,7 @@ package android.widget {
|
||||
method public int getExtendedPaddingTop();
|
||||
method public android.text.InputFilter[] getFilters();
|
||||
method public java.lang.String getFontFeatureSettings();
|
||||
method public java.lang.String getFontVariationSettings();
|
||||
method public boolean getFreezesText();
|
||||
method public int getGravity();
|
||||
method public int getHighlightColor();
|
||||
@@ -50092,6 +50095,7 @@ package android.widget {
|
||||
method public void setExtractedText(android.view.inputmethod.ExtractedText);
|
||||
method public void setFilters(android.text.InputFilter[]);
|
||||
method public void setFontFeatureSettings(java.lang.String);
|
||||
method public void setFontVariationSettings(java.lang.String);
|
||||
method protected boolean setFrame(int, int, int, int);
|
||||
method public void setFreezesText(boolean);
|
||||
method public void setGravity(int);
|
||||
|
||||
@@ -13293,6 +13293,7 @@ package android.graphics {
|
||||
method public int getFontMetricsInt(android.graphics.Paint.FontMetricsInt);
|
||||
method public android.graphics.Paint.FontMetricsInt getFontMetricsInt();
|
||||
method public float getFontSpacing();
|
||||
method public java.lang.String getFontVariationSettings();
|
||||
method public int getHinting();
|
||||
method public float getLetterSpacing();
|
||||
method public android.graphics.MaskFilter getMaskFilter();
|
||||
@@ -13350,6 +13351,7 @@ package android.graphics {
|
||||
method public void setFilterBitmap(boolean);
|
||||
method public void setFlags(int);
|
||||
method public void setFontFeatureSettings(java.lang.String);
|
||||
method public void setFontVariationSettings(java.lang.String);
|
||||
method public void setHinting(int);
|
||||
method public void setLetterSpacing(float);
|
||||
method public void setLinearText(boolean);
|
||||
@@ -53749,6 +53751,7 @@ package android.widget {
|
||||
method public int getExtendedPaddingTop();
|
||||
method public android.text.InputFilter[] getFilters();
|
||||
method public java.lang.String getFontFeatureSettings();
|
||||
method public java.lang.String getFontVariationSettings();
|
||||
method public boolean getFreezesText();
|
||||
method public int getGravity();
|
||||
method public int getHighlightColor();
|
||||
@@ -53858,6 +53861,7 @@ package android.widget {
|
||||
method public void setExtractedText(android.view.inputmethod.ExtractedText);
|
||||
method public void setFilters(android.text.InputFilter[]);
|
||||
method public void setFontFeatureSettings(java.lang.String);
|
||||
method public void setFontVariationSettings(java.lang.String);
|
||||
method protected boolean setFrame(int, int, int, int);
|
||||
method public void setFreezesText(boolean);
|
||||
method public void setGravity(int);
|
||||
|
||||
@@ -12765,6 +12765,7 @@ package android.graphics {
|
||||
method public int getFontMetricsInt(android.graphics.Paint.FontMetricsInt);
|
||||
method public android.graphics.Paint.FontMetricsInt getFontMetricsInt();
|
||||
method public float getFontSpacing();
|
||||
method public java.lang.String getFontVariationSettings();
|
||||
method public int getHinting();
|
||||
method public float getLetterSpacing();
|
||||
method public android.graphics.MaskFilter getMaskFilter();
|
||||
@@ -12822,6 +12823,7 @@ package android.graphics {
|
||||
method public void setFilterBitmap(boolean);
|
||||
method public void setFlags(int);
|
||||
method public void setFontFeatureSettings(java.lang.String);
|
||||
method public void setFontVariationSettings(java.lang.String);
|
||||
method public void setHinting(int);
|
||||
method public void setLetterSpacing(float);
|
||||
method public void setLinearText(boolean);
|
||||
@@ -50303,6 +50305,7 @@ package android.widget {
|
||||
method public int getExtendedPaddingTop();
|
||||
method public android.text.InputFilter[] getFilters();
|
||||
method public java.lang.String getFontFeatureSettings();
|
||||
method public java.lang.String getFontVariationSettings();
|
||||
method public boolean getFreezesText();
|
||||
method public int getGravity();
|
||||
method public int getHighlightColor();
|
||||
@@ -50412,6 +50415,7 @@ package android.widget {
|
||||
method public void setExtractedText(android.view.inputmethod.ExtractedText);
|
||||
method public void setFilters(android.text.InputFilter[]);
|
||||
method public void setFontFeatureSettings(java.lang.String);
|
||||
method public void setFontVariationSettings(java.lang.String);
|
||||
method protected boolean setFrame(int, int, int, int);
|
||||
method public void setFreezesText(boolean);
|
||||
method public void setGravity(int);
|
||||
|
||||
@@ -3432,6 +3432,20 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
return mTextPaint.getFontFeatureSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the font variation settings.
|
||||
*
|
||||
* @return the currently set font variation settings. Returns null if no variation is
|
||||
* specified.
|
||||
*
|
||||
* @see #setFontVariationSettings(String)
|
||||
* @see Paint#setFontVariationSettings(String) Paint.setFontVariationSettings(String)
|
||||
*/
|
||||
@Nullable
|
||||
public String getFontVariationSettings() {
|
||||
return mTextPaint.getFontVariationSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the break strategy for breaking paragraphs into lines. The default value for
|
||||
* TextView is {@link Layout#BREAK_STRATEGY_HIGH_QUALITY}, and the default value for
|
||||
@@ -3538,6 +3552,41 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets TrueType or OpenType font variation settings. The settings string is constructed from
|
||||
* multiple pairs of axis tag and style values. The axis tag must contain four ASCII characters
|
||||
* and must be wrapped with single quotes (U+0027) or double quotes (U+0022). Axis strings that
|
||||
* are longer or shorter than four characters, or contain characters outside of U+0020..U+007E
|
||||
* are invalid. If a specified axis name is not defined in the font, the settings will be
|
||||
* ignored.
|
||||
*
|
||||
* <pre>
|
||||
* textView.setFontVariationSettings("'wdth' 1.0");
|
||||
* textView.setFontVariationSettings("'AX ' 1.8, 'FB ' 2.0");
|
||||
* </pre>
|
||||
*
|
||||
* @param fontVariationSettings font variation settings. You can pass null or empty string as
|
||||
* no variation settings.
|
||||
*
|
||||
* @see #getFontVariationSettings()
|
||||
* @see Paint#getFontVariationSettings() Paint.getFontVariationSettings()
|
||||
*/
|
||||
public void setFontVariationSettings(@Nullable String fontVariationSettings) {
|
||||
final String existingSettings = mTextPaint.getFontVariationSettings();
|
||||
if (fontVariationSettings == existingSettings
|
||||
|| (fontVariationSettings != null
|
||||
&& fontVariationSettings.equals(existingSettings))) {
|
||||
return;
|
||||
}
|
||||
mTextPaint.setFontVariationSettings(fontVariationSettings);
|
||||
|
||||
if (mLayout != null) {
|
||||
nullLayouts();
|
||||
requestLayout();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text color for all the states (normal, selected,
|
||||
* focused) to be this color.
|
||||
|
||||
@@ -118,6 +118,7 @@ LOCAL_SRC_FILES:= \
|
||||
android/graphics/ColorFilter.cpp \
|
||||
android/graphics/DrawFilter.cpp \
|
||||
android/graphics/FontFamily.cpp \
|
||||
android/graphics/FontUtils.cpp \
|
||||
android/graphics/CreateJavaOutputStreamAdaptor.cpp \
|
||||
android/graphics/GIFMovie.cpp \
|
||||
android/graphics/GraphicBuffer.cpp \
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <android_runtime/android_util_AssetManager.h>
|
||||
#include <androidfw/AssetManager.h>
|
||||
#include "Utils.h"
|
||||
#include "FontUtils.h"
|
||||
|
||||
#include <hwui/MinikinSkia.h>
|
||||
#include <hwui/Typeface.h>
|
||||
@@ -149,16 +150,6 @@ static jboolean FontFamily_addFont(JNIEnv* env, jobject clazz, jlong builderPtr,
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct {
|
||||
jmethodID mGet;
|
||||
jmethodID mSize;
|
||||
} gListClassInfo;
|
||||
|
||||
static struct {
|
||||
jfieldID mTag;
|
||||
jfieldID mStyleValue;
|
||||
} gAxisClassInfo;
|
||||
|
||||
static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong builderPtr,
|
||||
jobject font, jint ttcIndex, jobject listOfAxis, jint weight, jboolean isItalic) {
|
||||
NPE_CHECK_RETURN_ZERO(env, font);
|
||||
@@ -167,20 +158,22 @@ static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong
|
||||
std::unique_ptr<SkFontMgr::FontParameters::Axis[]> skiaAxes;
|
||||
int skiaAxesLength = 0;
|
||||
if (listOfAxis) {
|
||||
jint listSize = env->CallIntMethod(listOfAxis, gListClassInfo.mSize);
|
||||
ListHelper list(env, listOfAxis);
|
||||
jint listSize = list.size();
|
||||
|
||||
skiaAxes.reset(new SkFontMgr::FontParameters::Axis[listSize]);
|
||||
skiaAxesLength = listSize;
|
||||
for (jint i = 0; i < listSize; ++i) {
|
||||
jobject axisObject = env->CallObjectMethod(listOfAxis, gListClassInfo.mGet, i);
|
||||
jobject axisObject = list.get(i);
|
||||
if (!axisObject) {
|
||||
skiaAxes[i].fTag = 0;
|
||||
skiaAxes[i].fStyleValue = 0;
|
||||
continue;
|
||||
}
|
||||
AxisHelper axis(env, axisObject);
|
||||
|
||||
jint tag = env->GetIntField(axisObject, gAxisClassInfo.mTag);
|
||||
jfloat stylevalue = env->GetFloatField(axisObject, gAxisClassInfo.mStyleValue);
|
||||
jint tag = axis.getTag();
|
||||
jfloat stylevalue = axis.getStyleValue();
|
||||
skiaAxes[i].fTag = tag;
|
||||
skiaAxes[i].fStyleValue = SkFloatToScalar(stylevalue);
|
||||
}
|
||||
@@ -291,14 +284,7 @@ int register_android_graphics_FontFamily(JNIEnv* env)
|
||||
int err = RegisterMethodsOrDie(env, "android/graphics/FontFamily", gFontFamilyMethods,
|
||||
NELEM(gFontFamilyMethods));
|
||||
|
||||
jclass listClass = FindClassOrDie(env, "java/util/List");
|
||||
gListClassInfo.mGet = GetMethodIDOrDie(env, listClass, "get", "(I)Ljava/lang/Object;");
|
||||
gListClassInfo.mSize = GetMethodIDOrDie(env, listClass, "size", "()I");
|
||||
|
||||
jclass axisClass = FindClassOrDie(env, "android/text/FontConfig$Axis");
|
||||
gAxisClassInfo.mTag = GetFieldIDOrDie(env, axisClass, "mTag", "I");
|
||||
gAxisClassInfo.mStyleValue = GetFieldIDOrDie(env, axisClass, "mStyleValue", "F");
|
||||
|
||||
init_FontUtils(env);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
54
core/jni/android/graphics/FontUtils.h
Normal file
54
core/jni/android/graphics/FontUtils.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _ANDROID_GRAPHICS_FONT_UTILS_H_
|
||||
#define _ANDROID_GRAPHICS_FONT_UTILS_H_
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
// Utility wrapper for java.util.List
|
||||
class ListHelper {
|
||||
public:
|
||||
ListHelper(JNIEnv* env, jobject list) : mEnv(env), mList(list) {}
|
||||
|
||||
jint size() const;
|
||||
jobject get(jint index) const;
|
||||
|
||||
private:
|
||||
JNIEnv* mEnv;
|
||||
jobject mList;
|
||||
};
|
||||
|
||||
// Utility wrapper for android.graphics.FontConfig$Axis
|
||||
class AxisHelper {
|
||||
public:
|
||||
AxisHelper(JNIEnv* env, jobject axis) : mEnv(env), mAxis(axis) {}
|
||||
|
||||
jint getTag() const;
|
||||
jfloat getStyleValue() const;
|
||||
|
||||
private:
|
||||
JNIEnv* mEnv;
|
||||
jobject mAxis;
|
||||
};
|
||||
|
||||
void init_FontUtils(JNIEnv* env);
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // _ANDROID_GRAPHICS_FONT_UTILS_H_
|
||||
@@ -17,12 +17,14 @@
|
||||
#include "jni.h"
|
||||
#include "core_jni_helpers.h"
|
||||
|
||||
#include "FontUtils.h"
|
||||
#include "GraphicsJNI.h"
|
||||
#include "ScopedPrimitiveArray.h"
|
||||
#include "SkTypeface.h"
|
||||
#include <android_runtime/android_util_AssetManager.h>
|
||||
#include <androidfw/AssetManager.h>
|
||||
#include <hwui/Typeface.h>
|
||||
#include <minikin/FontFamily.h>
|
||||
|
||||
using namespace android;
|
||||
|
||||
@@ -40,6 +42,23 @@ static jlong Typeface_createFromTypeface(JNIEnv* env, jobject, jlong familyHandl
|
||||
return reinterpret_cast<jlong>(face);
|
||||
}
|
||||
|
||||
static jlong Typeface_createFromTypefaceWithVariation(JNIEnv* env, jobject, jlong familyHandle,
|
||||
jobject listOfAxis) {
|
||||
std::vector<minikin::FontVariation> variations;
|
||||
ListHelper list(env, listOfAxis);
|
||||
for (jint i = 0; i < list.size(); i++) {
|
||||
jobject axisObject = list.get(i);
|
||||
if (axisObject == nullptr) {
|
||||
continue;
|
||||
}
|
||||
AxisHelper axis(env, axisObject);
|
||||
variations.push_back(minikin::FontVariation(axis.getTag(), axis.getStyleValue()));
|
||||
}
|
||||
Typeface* baseTypeface = reinterpret_cast<Typeface*>(familyHandle);
|
||||
Typeface* result = Typeface::createFromTypefaceWithVariation(baseTypeface, variations);
|
||||
return reinterpret_cast<jlong>(result);
|
||||
}
|
||||
|
||||
static jlong Typeface_createWeightAlias(JNIEnv* env, jobject, jlong familyHandle, jint weight) {
|
||||
Typeface* family = reinterpret_cast<Typeface*>(familyHandle);
|
||||
Typeface* face = Typeface::createWeightAlias(family, weight);
|
||||
@@ -77,6 +96,8 @@ static void Typeface_setDefault(JNIEnv *env, jobject, jlong faceHandle) {
|
||||
|
||||
static const JNINativeMethod gTypefaceMethods[] = {
|
||||
{ "nativeCreateFromTypeface", "(JI)J", (void*)Typeface_createFromTypeface },
|
||||
{ "nativeCreateFromTypefaceWithVariation", "(JLjava/util/List;)J",
|
||||
(void*)Typeface_createFromTypefaceWithVariation },
|
||||
{ "nativeCreateWeightAlias", "(JI)J", (void*)Typeface_createWeightAlias },
|
||||
{ "nativeUnref", "(J)V", (void*)Typeface_unref },
|
||||
{ "nativeGetStyle", "(J)I", (void*)Typeface_getStyle },
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.util.Xml;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -52,9 +53,12 @@ public class FontListParser {
|
||||
// Note that a well-formed variation contains a four-character tag and a float as styleValue,
|
||||
// with spacers in between. The tag is enclosd either by double quotes or single quotes.
|
||||
@VisibleForTesting
|
||||
public static FontConfig.Axis[] parseFontVariationSettings(String settings) {
|
||||
String[] settingList = settings.split(",");
|
||||
public static ArrayList<FontConfig.Axis> parseFontVariationSettings(@Nullable String settings) {
|
||||
ArrayList<FontConfig.Axis> axisList = new ArrayList<>();
|
||||
if (settings == null) {
|
||||
return axisList;
|
||||
}
|
||||
String[] settingList = settings.split(",");
|
||||
settingLoop:
|
||||
for (String setting : settingList) {
|
||||
int pos = 0;
|
||||
@@ -98,7 +102,7 @@ public class FontListParser {
|
||||
tagString.charAt(3));
|
||||
axisList.add(new FontConfig.Axis(tag, styleValue));
|
||||
}
|
||||
return axisList.toArray(new FontConfig.Axis[axisList.size()]);
|
||||
return axisList;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
||||
@@ -71,6 +71,7 @@ public class Paint {
|
||||
|
||||
private LocaleList mLocales;
|
||||
private String mFontFeatureSettings;
|
||||
private String mFontVariationSettings;
|
||||
|
||||
private static final Object sCacheLock = new Object();
|
||||
|
||||
@@ -1493,6 +1494,37 @@ public class Paint {
|
||||
nSetFontFeatureSettings(mNativePaint, settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the font variation settings.
|
||||
*
|
||||
* @return the paint's currently set font variation settings. Default is null.
|
||||
*
|
||||
* @see #setFontVariationSettings(String)
|
||||
*/
|
||||
public String getFontVariationSettings() {
|
||||
return mFontVariationSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set font variation settings.
|
||||
*
|
||||
* @param settings font variation settings, e.g. "'wdth' 300, 'wght' 1.8"
|
||||
*
|
||||
* @see #getFontVariationSettings()
|
||||
*
|
||||
* @param settings the font variation settings. You can pass null or empty string as no
|
||||
* variation settings.
|
||||
*/
|
||||
public void setFontVariationSettings(String settings) {
|
||||
settings = TextUtils.nullIfEmpty(settings);
|
||||
if (settings == mFontVariationSettings
|
||||
|| (settings != null && settings.equals(mFontVariationSettings))) {
|
||||
return;
|
||||
}
|
||||
mFontVariationSettings = settings;
|
||||
setTypeface(Typeface.createFromTypefaceWithVariation(mTypeface, settings));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current value of hyphen edit.
|
||||
*
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.util.Log;
|
||||
import android.util.LongSparseArray;
|
||||
import android.util.LruCache;
|
||||
import android.util.SparseArray;
|
||||
import android.graphics.FontListParser;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
|
||||
@@ -349,6 +350,15 @@ public class Typeface {
|
||||
return typeface;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static Typeface createFromTypefaceWithVariation(Typeface family,
|
||||
String fontVariationSettings) {
|
||||
final long ni = family == null ? 0 : family.native_instance;
|
||||
ArrayList<FontConfig.Axis> axes =
|
||||
FontListParser.parseFontVariationSettings(fontVariationSettings);
|
||||
return new Typeface(nativeCreateFromTypefaceWithVariation(ni, axes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns one of the default typeface objects, based on the specified style
|
||||
*
|
||||
@@ -625,6 +635,8 @@ public class Typeface {
|
||||
}
|
||||
|
||||
private static native long nativeCreateFromTypeface(long native_instance, int style);
|
||||
private static native long nativeCreateFromTypefaceWithVariation(
|
||||
long native_instance, List<FontConfig.Axis> axes);
|
||||
private static native long nativeCreateWeightAlias(long native_instance, int weight);
|
||||
private static native void nativeUnref(long native_instance);
|
||||
private static native int nativeGetStyle(long native_instance);
|
||||
|
||||
@@ -18,9 +18,8 @@ package android.graphics;
|
||||
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.text.FontConfig;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.util.List;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
|
||||
public class VariationParserTest extends TestCase {
|
||||
@@ -28,92 +27,92 @@ public class VariationParserTest extends TestCase {
|
||||
@SmallTest
|
||||
public void testParseFontVariationSetting() {
|
||||
int tag = FontListParser.makeTag('w', 'd', 't', 'h');
|
||||
FontConfig.Axis[] axis = FontListParser.parseFontVariationSettings("'wdth' 1");
|
||||
assertEquals(tag, axis[0].getTag());
|
||||
assertEquals(1.0f, axis[0].getStyleValue());
|
||||
List<FontConfig.Axis> axes = FontListParser.parseFontVariationSettings("'wdth' 1");
|
||||
assertEquals(tag, axes.get(0).getTag());
|
||||
assertEquals(1.0f, axes.get(0).getStyleValue());
|
||||
|
||||
axis = FontListParser.parseFontVariationSettings("\"wdth\" 100");
|
||||
assertEquals(tag, axis[0].getTag());
|
||||
assertEquals(100.0f, axis[0].getStyleValue());
|
||||
axes = FontListParser.parseFontVariationSettings("\"wdth\" 100");
|
||||
assertEquals(tag, axes.get(0).getTag());
|
||||
assertEquals(100.0f, axes.get(0).getStyleValue());
|
||||
|
||||
axis = FontListParser.parseFontVariationSettings(" 'wdth' 100");
|
||||
assertEquals(tag, axis[0].getTag());
|
||||
assertEquals(100.0f, axis[0].getStyleValue());
|
||||
axes = FontListParser.parseFontVariationSettings(" 'wdth' 100");
|
||||
assertEquals(tag, axes.get(0).getTag());
|
||||
assertEquals(100.0f, axes.get(0).getStyleValue());
|
||||
|
||||
axis = FontListParser.parseFontVariationSettings("\t'wdth' 0.5");
|
||||
assertEquals(tag, axis[0].getTag());
|
||||
assertEquals(0.5f, axis[0].getStyleValue());
|
||||
axes = FontListParser.parseFontVariationSettings("\t'wdth' 0.5");
|
||||
assertEquals(tag, axes.get(0).getTag());
|
||||
assertEquals(0.5f, axes.get(0).getStyleValue());
|
||||
|
||||
tag = FontListParser.makeTag('A', 'X', ' ', ' ');
|
||||
axis = FontListParser.parseFontVariationSettings("'AX ' 1");
|
||||
assertEquals(tag, axis[0].getTag());
|
||||
assertEquals(1.0f, axis[0].getStyleValue());
|
||||
axes = FontListParser.parseFontVariationSettings("'AX ' 1");
|
||||
assertEquals(tag, axes.get(0).getTag());
|
||||
assertEquals(1.0f, axes.get(0).getStyleValue());
|
||||
|
||||
axis = FontListParser.parseFontVariationSettings("'AX '\t1");
|
||||
assertEquals(tag, axis[0].getTag());
|
||||
assertEquals(1.0f, axis[0].getStyleValue());
|
||||
axes = FontListParser.parseFontVariationSettings("'AX '\t1");
|
||||
assertEquals(tag, axes.get(0).getTag());
|
||||
assertEquals(1.0f, axes.get(0).getStyleValue());
|
||||
|
||||
axis = FontListParser.parseFontVariationSettings("'AX '\n1");
|
||||
assertEquals(tag, axis[0].getTag());
|
||||
assertEquals(1.0f, axis[0].getStyleValue());
|
||||
axes = FontListParser.parseFontVariationSettings("'AX '\n1");
|
||||
assertEquals(tag, axes.get(0).getTag());
|
||||
assertEquals(1.0f, axes.get(0).getStyleValue());
|
||||
|
||||
axis = FontListParser.parseFontVariationSettings("'AX '\r1");
|
||||
assertEquals(tag, axis[0].getTag());
|
||||
assertEquals(1.0f, axis[0].getStyleValue());
|
||||
axes = FontListParser.parseFontVariationSettings("'AX '\r1");
|
||||
assertEquals(tag, axes.get(0).getTag());
|
||||
assertEquals(1.0f, axes.get(0).getStyleValue());
|
||||
|
||||
axis = FontListParser.parseFontVariationSettings("'AX '\r\t\n 1");
|
||||
assertEquals(tag, axis[0].getTag());
|
||||
assertEquals(1.0f, axis[0].getStyleValue());
|
||||
axes = FontListParser.parseFontVariationSettings("'AX '\r\t\n 1");
|
||||
assertEquals(tag, axes.get(0).getTag());
|
||||
assertEquals(1.0f, axes.get(0).getStyleValue());
|
||||
|
||||
// Test for invalid input
|
||||
axis = FontListParser.parseFontVariationSettings("");
|
||||
assertEquals(0, axis.length);
|
||||
axis = FontListParser.parseFontVariationSettings("invalid_form");
|
||||
assertEquals(0, axis.length);
|
||||
axes = FontListParser.parseFontVariationSettings("");
|
||||
assertEquals(0, axes.size());
|
||||
axes = FontListParser.parseFontVariationSettings("invalid_form");
|
||||
assertEquals(0, axes.size());
|
||||
|
||||
// Test with invalid tag
|
||||
axis = FontListParser.parseFontVariationSettings("'' 1");
|
||||
assertEquals(0, axis.length);
|
||||
axis = FontListParser.parseFontVariationSettings("'invalid' 1");
|
||||
assertEquals(0, axis.length);
|
||||
axes = FontListParser.parseFontVariationSettings("'' 1");
|
||||
assertEquals(0, axes.size());
|
||||
axes = FontListParser.parseFontVariationSettings("'invalid' 1");
|
||||
assertEquals(0, axes.size());
|
||||
|
||||
// Test with invalid styleValue
|
||||
axis = FontListParser.parseFontVariationSettings("'wdth' ");
|
||||
assertEquals(0, axis.length);
|
||||
axis = FontListParser.parseFontVariationSettings("'wdth' x");
|
||||
assertEquals(0, axis.length);
|
||||
axis = FontListParser.parseFontVariationSettings("'wdth' \t");
|
||||
assertEquals(0, axis.length);
|
||||
axis = FontListParser.parseFontVariationSettings("'wdth' \n\r");
|
||||
assertEquals(0, axis.length);
|
||||
axes = FontListParser.parseFontVariationSettings("'wdth' ");
|
||||
assertEquals(0, axes.size());
|
||||
axes = FontListParser.parseFontVariationSettings("'wdth' x");
|
||||
assertEquals(0, axes.size());
|
||||
axes = FontListParser.parseFontVariationSettings("'wdth' \t");
|
||||
assertEquals(0, axes.size());
|
||||
axes = FontListParser.parseFontVariationSettings("'wdth' \n\r");
|
||||
assertEquals(0, axes.size());
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testParseFontVariationStyleSettings() {
|
||||
FontConfig.Axis[] axis =
|
||||
List<FontConfig.Axis> axes =
|
||||
FontListParser.parseFontVariationSettings("'wdth' 10,'AX '\r1");
|
||||
int tag1 = FontListParser.makeTag('w', 'd', 't', 'h');
|
||||
int tag2 = FontListParser.makeTag('A', 'X', ' ', ' ');
|
||||
assertEquals(tag1, axis[0].getTag());
|
||||
assertEquals(10.0f, axis[0].getStyleValue());
|
||||
assertEquals(tag2, axis[1].getTag());
|
||||
assertEquals(1.0f, axis[1].getStyleValue());
|
||||
assertEquals(tag1, axes.get(0).getTag());
|
||||
assertEquals(10.0f, axes.get(0).getStyleValue());
|
||||
assertEquals(tag2, axes.get(1).getTag());
|
||||
assertEquals(1.0f, axes.get(1).getStyleValue());
|
||||
|
||||
// Test only spacers are allowed before tag
|
||||
axis = FontListParser.parseFontVariationSettings(" 'wdth' 10,ab'wdth' 1");
|
||||
axes = FontListParser.parseFontVariationSettings(" 'wdth' 10,ab'wdth' 1");
|
||||
tag1 = FontListParser.makeTag('w', 'd', 't', 'h');
|
||||
assertEquals(tag1, axis[0].getTag());
|
||||
assertEquals(10.0f, axis[0].getStyleValue());
|
||||
assertEquals(1, axis.length);
|
||||
assertEquals(tag1, axes.get(0).getTag());
|
||||
assertEquals(10.0f, axes.get(0).getStyleValue());
|
||||
assertEquals(1, axes.size());
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
public void testInvalidTagCharacters() {
|
||||
FontConfig.Axis[] axis =
|
||||
List<FontConfig.Axis> axes =
|
||||
FontListParser.parseFontVariationSettings("'\u0000\u0000\u0000\u0000' 10");
|
||||
assertEquals(0, axis.length);
|
||||
axis = FontListParser.parseFontVariationSettings("'\u3042\u3044\u3046\u3048' 10");
|
||||
assertEquals(0, axis.length);
|
||||
assertEquals(0, axes.size());
|
||||
axes = FontListParser.parseFontVariationSettings("'\u3042\u3044\u3046\u3048' 10");
|
||||
assertEquals(0, axes.size());
|
||||
}
|
||||
|
||||
@SmallTest
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
#include "MinikinSkia.h"
|
||||
|
||||
#include <log/log.h>
|
||||
|
||||
#include <SkFontDescriptor.h>
|
||||
#include <SkFontMgr.h>
|
||||
#include <SkPaint.h>
|
||||
#include <SkTypeface.h>
|
||||
|
||||
@@ -86,6 +87,28 @@ int MinikinFontSkia::GetFontIndex() const {
|
||||
return mTtcIndex;
|
||||
}
|
||||
|
||||
minikin::MinikinFont* MinikinFontSkia::createFontWithVariation(
|
||||
const std::vector<minikin::FontVariation>& variations) const {
|
||||
SkFontMgr::FontParameters params;
|
||||
|
||||
int ttcIndex;
|
||||
SkStreamAsset* stream = mTypeface->openStream(&ttcIndex);
|
||||
LOG_ALWAYS_FATAL_IF(stream == nullptr, "openStream failed");
|
||||
|
||||
params.setCollectionIndex(ttcIndex);
|
||||
std::vector<SkFontMgr::FontParameters::Axis> skAxes;
|
||||
skAxes.resize(variations.size());
|
||||
for (size_t i = 0; i < variations.size(); i++) {
|
||||
skAxes[i].fTag = variations[i].axisTag;
|
||||
skAxes[i].fStyleValue = SkFloatToScalar(variations[i].value);
|
||||
}
|
||||
params.setAxes(skAxes.data(), skAxes.size());
|
||||
sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
|
||||
sk_sp<SkTypeface> face(fm->createFromStream(stream, params));
|
||||
|
||||
return new MinikinFontSkia(std::move(face), mFontData, mFontSize, ttcIndex);
|
||||
}
|
||||
|
||||
uint32_t MinikinFontSkia::packPaintFlags(const SkPaint* paint) {
|
||||
uint32_t flags = paint->getFlags();
|
||||
SkPaint::Hinting hinting = paint->getHinting();
|
||||
|
||||
@@ -44,6 +44,8 @@ public:
|
||||
const void* GetFontData() const;
|
||||
size_t GetFontSize() const;
|
||||
int GetFontIndex() const;
|
||||
minikin::MinikinFont* createFontWithVariation(
|
||||
const std::vector<minikin::FontVariation>&) const;
|
||||
|
||||
static uint32_t packPaintFlags(const SkPaint* paint);
|
||||
static void unpackPaintFlags(SkPaint* paint, uint32_t paintFlags);
|
||||
|
||||
@@ -62,7 +62,7 @@ Typeface* Typeface::resolveDefault(Typeface* src) {
|
||||
Typeface* Typeface::createFromTypeface(Typeface* src, SkTypeface::Style style) {
|
||||
Typeface* resolvedFace = Typeface::resolveDefault(src);
|
||||
Typeface* result = new Typeface;
|
||||
if (result != 0) {
|
||||
if (result != nullptr) {
|
||||
result->fFontCollection = resolvedFace->fFontCollection;
|
||||
result->fFontCollection->Ref();
|
||||
result->fSkiaStyle = style;
|
||||
@@ -72,10 +72,30 @@ Typeface* Typeface::createFromTypeface(Typeface* src, SkTypeface::Style style) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Typeface* Typeface::createFromTypefaceWithVariation(Typeface* src,
|
||||
const std::vector<minikin::FontVariation>& variations) {
|
||||
Typeface* resolvedFace = Typeface::resolveDefault(src);
|
||||
Typeface* result = new Typeface();
|
||||
if (result != nullptr) {
|
||||
result->fFontCollection =
|
||||
resolvedFace->fFontCollection->createCollectionWithVariation(variations);
|
||||
if (result->fFontCollection == nullptr) {
|
||||
// None of passed axes are supported by this collection.
|
||||
// So we will reuse the same collection with incrementing reference count.
|
||||
result->fFontCollection = resolvedFace->fFontCollection;
|
||||
result->fFontCollection->Ref();
|
||||
}
|
||||
result->fSkiaStyle = resolvedFace->fSkiaStyle;
|
||||
result->fBaseWeight = resolvedFace->fBaseWeight;
|
||||
resolveStyle(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Typeface* Typeface::createWeightAlias(Typeface* src, int weight) {
|
||||
Typeface* resolvedFace = Typeface::resolveDefault(src);
|
||||
Typeface* result = new Typeface;
|
||||
if (result != 0) {
|
||||
if (result != nullptr) {
|
||||
result->fFontCollection = resolvedFace->fFontCollection;
|
||||
result->fFontCollection->Ref();
|
||||
result->fSkiaStyle = resolvedFace->fSkiaStyle;
|
||||
|
||||
@@ -43,6 +43,9 @@ struct ANDROID_API Typeface {
|
||||
|
||||
static Typeface* createFromTypeface(Typeface* src, SkTypeface::Style style);
|
||||
|
||||
static Typeface* createFromTypefaceWithVariation(Typeface* src,
|
||||
const std::vector<minikin::FontVariation>& variations);
|
||||
|
||||
static Typeface* createWeightAlias(Typeface* src, int baseweight);
|
||||
|
||||
static Typeface* createFromFamilies(const std::vector<minikin::FontFamily*>& families);
|
||||
|
||||
Reference in New Issue
Block a user