blob: bfbcfd828114a4897b964093b322c6dfcee76041 [file] [log] [blame]
/*
* Copyright (C) 2021 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.IntRange;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import com.android.internal.util.Preconditions;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
/**
* Request for updating or adding a font family on the system.
*
* <p>You can update or add a font family with custom style parameters. The following example
* defines a font family called "roboto" using "Roboto-Regular" font file that is already available
* on the system by preloading or {@link FontManager#updateFontFile}.
* <pre>
* FontManager fm = getContext().getSystemService(FontManager.class);
* fm.updateFontFamily(new FontFamilyUpdateRequest.Builder()
* .addFontFamily(new FontFamilyUpdateRequest.FontFamily("roboto", Arrays.asList(
* new FontFamilyUpdateRequest.Font(
* "Roboto-Regular",
* new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
* Collections.emptyList()),
* new FontFamilyUpdateRequest.Font(
* "Roboto-Regular",
* new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_ITALIC),
* Collections.emptyList()))))
* .build(), fm.getFontConfig().getConfigVersion());
* </pre>
*
* <p>You can update or add font files in the same request by calling
* {@link FontFamilyUpdateRequest.Builder#addFontFileUpdateRequest(FontFileUpdateRequest)}.
* The following example adds "YourFont" font file and defines "your-font" font family in the same
* request. In this case, the font file represented by {@code yourFontFd} should be an OpenType
* compliant font file and have "YourFont" as PostScript name (ID=6) in 'name' table.
* <pre>
* FontManager fm = getContext().getSystemService(FontManager.class);
* fm.updateFontFamily(new FontFamilyUpdateRequest.Builder()
* .addFontFileUpdateRequest(new FontFileUpdateRequest(yourFontFd, signature))
* .addFontFamily(new FontFamilyUpdateRequest.FontFamily("your-font", Arrays.asList(
* new FontFamilyUpdateRequest.Font(
* "YourFont",
* new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT),
* Collections.emptyList()))))
* .build(), fm.getFontConfig().getConfigVersion());
* </pre>
*
* @hide
*/
@SystemApi
public final class FontFamilyUpdateRequest {
/**
* A font family definition.
*/
public static final class FontFamily {
/**
* Builds a {@link FontFamily}.
*/
public static final class Builder {
@NonNull private final String mName;
@NonNull private final List<Font> mFonts;
/**
* Constructs a {@link FontFamily.Builder}.
*/
public Builder(@NonNull String name, @NonNull List<Font> fonts) {
Objects.requireNonNull(name);
Preconditions.checkStringNotEmpty(name);
Objects.requireNonNull(fonts);
Preconditions.checkCollectionElementsNotNull(fonts, "fonts");
Preconditions.checkCollectionNotEmpty(fonts, "fonts");
mName = name;
mFonts = new ArrayList<>(fonts);
}
/**
* Adds a {@link Font} to the builder.
*
* @return This builder object.
*/
public @NonNull Builder addFont(@NonNull Font font) {
mFonts.add(font);
return this;
}
/**
* Builds a {@link FontFamily}.
*/
public @NonNull FontFamily build() {
return new FontFamily(mName, mFonts);
}
}
@NonNull
private final String mName;
@NonNull
private final List<Font> mFonts;
/**
* Constructs a FontFamily.
*
* <p>A font family has a name to identify the font family. Apps can use
* {@link android.graphics.Typeface#create(String, int)} or XML resources to use a specific
* font family.
*
* <p>A font family consists of multiple fonts with different styles. The style information
* can be specified by {@link Font}.
*
* @see android.graphics.Typeface#create(String, int)
* @see Font
*/
private FontFamily(@NonNull String name, @NonNull List<Font> fonts) {
mName = name;
mFonts = fonts;
}
/**
* Returns the name of this family.
*/
@NonNull
public String getName() {
return mName;
}
/**
* Returns the fonts in this family.
*/
@NonNull
public List<Font> getFonts() {
return mFonts;
}
}
/**
* A single entry in a font family representing a font.
*/
public static final class Font {
/**
* Builds a {@link Font}.
*/
public static final class Builder {
private final@NonNull String mPostScriptName;
private final @NonNull FontStyle mStyle;
private @NonNull List<FontVariationAxis> mAxes = Collections.emptyList();
private @IntRange(from = 0) int mIndex = 0;
/**
* Construct a {@link Font.Builder}
*
* @param postScriptName The PostScript name of the font file to use. PostScript name is
* in Name ID 6 field in 'name' table, as specified by OpenType
* specification.
* @param style The style for this font.
*/
public Builder(@NonNull String postScriptName, @NonNull FontStyle style) {
Objects.requireNonNull(postScriptName);
Preconditions.checkStringNotEmpty(postScriptName);
Objects.requireNonNull(style);
mPostScriptName = postScriptName;
mStyle = style;
}
/**
* A list of {@link FontVariationAxis} to specify axis tags and values for variable
* fonts.
*/
public @NonNull Builder setAxes(@NonNull List<FontVariationAxis> axes) {
Objects.requireNonNull(axes);
Preconditions.checkCollectionElementsNotNull(axes, "axes");
mAxes = axes;
return this;
}
/**
* Sets font collection index for the Font.
*
* @see {@link android.R.attr#ttcIndex}.
*/
public @NonNull Builder setIndex(@IntRange(from = 0) int index) {
Preconditions.checkArgumentNonnegative(index);
mIndex = index;
return this;
}
/**
* Build a {@link Font} instance.
*/
public @NonNull Font build() {
return new Font(mPostScriptName, mStyle, mIndex, mAxes);
}
}
@NonNull
private final String mPostScriptName;
@NonNull
private final FontStyle mStyle;
@NonNull
private final List<FontVariationAxis> mAxes;
private final @IntRange(from = 0) int mIndex;
/**
* Constructs a FontStyleVariation.
*
* <p>A font has a PostScript name to identify the font file to use, a {@link FontStyle}
* to specify the style, and a list of {@link FontVariationAxis} to specify axis tags and
* values for variable fonts. If the font file identified by {@code postScriptName} is not a
* variable font, {@code axes} must be empty.
*
* @param postScriptName The PostScript name of the font file to use. PostScript name is in
* Name ID 6 field in 'name' table, as specified by OpenType
* specification.
* @param style The style for this font.
* @param index The index of the font in the collection.
* @param axes A list of {@link FontVariationAxis} to specify axis tags and values
* for variable fonts.
*/
private Font(@NonNull String postScriptName, @NonNull FontStyle style,
@IntRange(from = 0) int index, @NonNull List<FontVariationAxis> axes) {
mPostScriptName = postScriptName;
mStyle = style;
mIndex = index;
mAxes = axes;
}
/**
* Returns PostScript name of the font file to use.
*/
@NonNull
public String getPostScriptName() {
return mPostScriptName;
}
/**
* Returns the style.
*/
@NonNull
public FontStyle getStyle() {
return mStyle;
}
/**
* Returns the list of {@link FontVariationAxis}.
*/
@NonNull
public List<FontVariationAxis> getAxes() {
return mAxes;
}
/**
* Returns the index of collection
*/
public @IntRange(from = 0) int getIndex() {
return mIndex;
}
}
/**
* Builds a {@link FontFamilyUpdateRequest}.
*/
public static final class Builder {
@NonNull
private final List<FontFileUpdateRequest> mFontFileUpdateRequests = new ArrayList<>();
@NonNull
private final List<FontFamily> mFontFamilies = new ArrayList<>();
/**
* Constructs a FontFamilyUpdateRequest.Builder.
*/
public Builder() {
}
/**
* Adds a {@link FontFileUpdateRequest} to execute as a part of the constructed
* {@link FontFamilyUpdateRequest}.
*
* @param request A font file update request.
* @return This builder object.
*/
@NonNull
public Builder addFontFileUpdateRequest(@NonNull FontFileUpdateRequest request) {
Objects.requireNonNull(request);
mFontFileUpdateRequests.add(request);
return this;
}
/**
* Adds a font family to update an existing font family in the system font config or
* add as a new font family to the system font config.
*
* @param fontFamily An font family definition to add or update.
* @return This builder object.
*/
@NonNull
public Builder addFontFamily(@NonNull FontFamily fontFamily) {
Objects.requireNonNull(fontFamily);
mFontFamilies.add(fontFamily);
return this;
}
/**
* Builds a {@link FontFamilyUpdateRequest}.
*/
@NonNull
public FontFamilyUpdateRequest build() {
return new FontFamilyUpdateRequest(mFontFileUpdateRequests, mFontFamilies);
}
}
@NonNull
private final List<FontFileUpdateRequest> mFontFiles;
@NonNull
private final List<FontFamily> mFontFamilies;
private FontFamilyUpdateRequest(@NonNull List<FontFileUpdateRequest> fontFiles,
@NonNull List<FontFamily> fontFamilies) {
mFontFiles = fontFiles;
mFontFamilies = fontFamilies;
}
/**
* Returns the list of {@link FontFileUpdateRequest} that will be executed as a part of this
* request.
*/
@NonNull
public List<FontFileUpdateRequest> getFontFileUpdateRequests() {
return mFontFiles;
}
/**
* Returns the list of {@link FontFamily} that will be updated in this request.
*/
@NonNull
public List<FontFamily> getFontFamilies() {
return mFontFamilies;
}
}