Merge "Introduce set/getFontVariationSettings."
This commit is contained in:
committed by
Android (Google) Code Review
commit
cf45c85297
@@ -12740,6 +12740,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();
|
||||
@@ -12797,6 +12798,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);
|
||||
@@ -50036,6 +50038,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();
|
||||
@@ -50145,6 +50148,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);
|
||||
|
||||
@@ -13303,6 +13303,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();
|
||||
@@ -13360,6 +13361,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);
|
||||
@@ -53803,6 +53805,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();
|
||||
@@ -53912,6 +53915,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);
|
||||
|
||||
@@ -12774,6 +12774,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();
|
||||
@@ -12831,6 +12832,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);
|
||||
@@ -50356,6 +50358,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();
|
||||
@@ -50465,6 +50468,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);
|
||||
|
||||
@@ -3457,6 +3457,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
|
||||
@@ -3563,6 +3577,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.
|
||||
*
|
||||
|
||||
@@ -32,6 +32,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;
|
||||
|
||||
@@ -406,6 +407,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
|
||||
*
|
||||
@@ -682,6 +692,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