/*
 * 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.
 */

package android.graphics.fonts;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.text.TextUtils;

import java.util.ArrayList;
import java.util.regex.Pattern;

Class that holds information about single font variation axis.
/** * Class that holds information about single font variation axis. */
public final class FontVariationAxis { private final int mTag; private final String mTagString; private final float mStyleValue;
Construct FontVariationAxis. The axis tag must contain four ASCII characters. Tag string that are longer or shorter than four characters, or contains characters outside of U+0020..U+007E are invalid.
Throws:
  • IllegalArgumentException – If given tag string is invalid.
/** * Construct FontVariationAxis. * * The axis tag must contain four ASCII characters. Tag string that are longer or shorter than * four characters, or contains characters outside of U+0020..U+007E are invalid. * * @throws IllegalArgumentException If given tag string is invalid. */
public FontVariationAxis(@NonNull String tagString, float styleValue) { if (!isValidTag(tagString)) { throw new IllegalArgumentException("Illegal tag pattern: " + tagString); } mTag = makeTag(tagString); mTagString = tagString; mStyleValue = styleValue; }
Returns the OpenType style tag value.
@hide
/** * Returns the OpenType style tag value. * @hide */
public int getOpenTypeTagValue() { return mTag; }
Returns the variable font axis tag associated to this axis.
/** * Returns the variable font axis tag associated to this axis. */
public String getTag() { return mTagString; }
Returns the style value associated to the given axis for this font.
/** * Returns the style value associated to the given axis for this font. */
public float getStyleValue() { return mStyleValue; }
Returns a valid font variation setting string for this object.
/** * Returns a valid font variation setting string for this object. */
@Override public @NonNull String toString() { return "'" + mTagString + "' " + Float.toString(mStyleValue); }
The 'tag' attribute value is read as four character values between U+0020 and U+007E inclusive.
/** * The 'tag' attribute value is read as four character values between U+0020 and U+007E * inclusive. */
private static final Pattern TAG_PATTERN = Pattern.compile("[\u0020-\u007E]{4}");
Returns true if 'tagString' is valid for font variation axis tag.
/** * Returns true if 'tagString' is valid for font variation axis tag. */
private static boolean isValidTag(String tagString) { return tagString != null && TAG_PATTERN.matcher(tagString).matches(); }
The 'styleValue' attribute has an optional leading '-', followed by '', '.', or '.' where '' is one or more of [0-9].
/** * The 'styleValue' attribute has an optional leading '-', followed by '<digits>', * '<digits>.<digits>', or '.<digits>' where '<digits>' is one or more of [0-9]. */
private static final Pattern STYLE_VALUE_PATTERN = Pattern.compile("-?(([0-9]+(\\.[0-9]+)?)|(\\.[0-9]+))"); private static boolean isValidValueFormat(String valueString) { return valueString != null && STYLE_VALUE_PATTERN.matcher(valueString).matches(); }
@hide
/** @hide */
public static int makeTag(String tagString) { final char c1 = tagString.charAt(0); final char c2 = tagString.charAt(1); final char c3 = tagString.charAt(2); final char c4 = tagString.charAt(3); return (c1 << 24) | (c2 << 16) | (c3 << 8) | c4; }
Construct FontVariationAxis array from 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.
  FontVariationAxis.fromFontVariationSettings("'wdth' 1.0");
  FontVariationAxis.fromFontVariationSettings("'AX  ' 1.0, 'FB  ' 2.0");
Params:
  • settings – font variation settings.
Throws:
Returns:FontVariationAxis[] the array of parsed font variation axis. null if settings has no font variation settings.
/** * Construct FontVariationAxis array from 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> * FontVariationAxis.fromFontVariationSettings("'wdth' 1.0"); * FontVariationAxis.fromFontVariationSettings("'AX ' 1.0, 'FB ' 2.0"); * </pre> * * @param settings font variation settings. * @return FontVariationAxis[] the array of parsed font variation axis. {@code null} if settings * has no font variation settings. * @throws IllegalArgumentException If given string is not a valid font variation settings * format. */
public static @Nullable FontVariationAxis[] fromFontVariationSettings( @Nullable String settings) { if (settings == null || settings.isEmpty()) { return null; } final ArrayList<FontVariationAxis> axisList = new ArrayList<>(); final int length = settings.length(); for (int i = 0; i < length; i++) { final char c = settings.charAt(i); if (Character.isWhitespace(c)) { continue; } if (!(c == '\'' || c == '"') || length < i + 6 || settings.charAt(i + 5) != c) { throw new IllegalArgumentException( "Tag should be wrapped with double or single quote: " + settings); } final String tagString = settings.substring(i + 1, i + 5); i += 6; // Move to end of tag. int endOfValueString = settings.indexOf(',', i); if (endOfValueString == -1) { endOfValueString = length; } final float value; try { // Float.parseFloat ignores leading/trailing whitespaces. value = Float.parseFloat(settings.substring(i, endOfValueString)); } catch (NumberFormatException e) { throw new IllegalArgumentException( "Failed to parse float string: " + e.getMessage()); } axisList.add(new FontVariationAxis(tagString, value)); i = endOfValueString; } if (axisList.isEmpty()) { return null; } return axisList.toArray(new FontVariationAxis[0]); }
Stringify the array of FontVariationAxis.
Params:
  • axes – an array of FontVariationAxis.
Returns:String a valid font variation settings string.
/** * Stringify the array of FontVariationAxis. * * @param axes an array of FontVariationAxis. * @return String a valid font variation settings string. */
public static @NonNull String toFontVariationSettings(@Nullable FontVariationAxis[] axes) { if (axes == null) { return ""; } return TextUtils.join(",", axes); } }