1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.graphics.fonts; 18 19 import android.annotation.IntDef; 20 import android.annotation.IntRange; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 24 import com.android.internal.util.Preconditions; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.util.Objects; 29 30 /** 31 * A font style object. 32 * 33 * This class represents a single font style which is a pair of weight value and slant value. 34 * Here are common font styles examples: 35 * <p> 36 * <pre> 37 * <code> 38 * final FontStyle NORMAL = new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT); 39 * final FontStyle BOLD = new FontStyle(FONT_WEIGHT_BOLD, FONT_SLANT_UPRIGHT); 40 * final FontStyle ITALIC = new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_ITALIC); 41 * final FontStyle BOLD_ITALIC = new FontStyle(FONT_WEIGHT_BOLD, FONT_SLANT_ITALIC); 42 * </code> 43 * </pre> 44 * </p> 45 * 46 */ 47 @android.ravenwood.annotation.RavenwoodKeepWholeClass 48 public final class FontStyle { 49 private static final String TAG = "FontStyle"; 50 51 /** 52 * A default value when font weight is unspecified 53 */ 54 public static final int FONT_WEIGHT_UNSPECIFIED = -1; 55 /** 56 * A minimum weight value for the font 57 */ 58 public static final int FONT_WEIGHT_MIN = 1; 59 60 /** 61 * A font weight value for the thin weight 62 */ 63 public static final int FONT_WEIGHT_THIN = 100; 64 65 /** 66 * A font weight value for the extra-light weight 67 */ 68 public static final int FONT_WEIGHT_EXTRA_LIGHT = 200; 69 70 /** 71 * A font weight value for the light weight 72 */ 73 public static final int FONT_WEIGHT_LIGHT = 300; 74 75 /** 76 * A font weight value for the normal weight 77 */ 78 public static final int FONT_WEIGHT_NORMAL = 400; 79 80 /** 81 * A font weight value for the medium weight 82 */ 83 public static final int FONT_WEIGHT_MEDIUM = 500; 84 85 /** 86 * A font weight value for the semi-bold weight 87 */ 88 public static final int FONT_WEIGHT_SEMI_BOLD = 600; 89 90 /** 91 * A font weight value for the bold weight. 92 */ 93 public static final int FONT_WEIGHT_BOLD = 700; 94 95 /** 96 * A font weight value for the extra-bold weight 97 */ 98 public static final int FONT_WEIGHT_EXTRA_BOLD = 800; 99 100 /** 101 * A font weight value for the black weight 102 */ 103 public static final int FONT_WEIGHT_BLACK = 900; 104 105 /** 106 * A maximum weight value for the font 107 */ 108 public static final int FONT_WEIGHT_MAX = 1000; 109 110 /** 111 * A font slant value for upright 112 */ 113 public static final int FONT_SLANT_UPRIGHT = 0; 114 115 /** 116 * A font slant value for italic 117 */ 118 public static final int FONT_SLANT_ITALIC = 1; 119 120 // TODO: Support FONT_SLANT_OBLIQUE 121 122 /** @hide */ 123 @IntDef(prefix = { "FONT_SLANT_" }, value = { 124 FONT_SLANT_UPRIGHT, 125 FONT_SLANT_ITALIC 126 }) 127 @Retention(RetentionPolicy.SOURCE) 128 public @interface FontSlant {} 129 130 private final @IntRange(from = 0, to = 1000) int mWeight; 131 private final @FontSlant int mSlant; 132 // TODO: Support width 133 FontStyle()134 public FontStyle() { 135 mWeight = FONT_WEIGHT_NORMAL; 136 mSlant = FONT_SLANT_UPRIGHT; 137 } 138 139 /** 140 * Create FontStyle with specific weight and italic 141 * 142 * <p> 143 * <table> 144 * <thead> 145 * <tr> 146 * <th align="center">Value</th> 147 * <th align="center">Name</th> 148 * <th align="center">Android Definition</th> 149 * </tr> 150 * </thead> 151 * <tbody> 152 * <tr> 153 * <td align="center">100</td> 154 * <td align="center">Thin</td> 155 * <td align="center">{@link FontStyle#FONT_WEIGHT_THIN}</td> 156 * </tr> 157 * <tr> 158 * <td align="center">200</td> 159 * <td align="center">Extra Light (Ultra Light)</td> 160 * <td align="center">{@link FontStyle#FONT_WEIGHT_EXTRA_LIGHT}</td> 161 * </tr> 162 * <tr> 163 * <td align="center">300</td> 164 * <td align="center">Light</td> 165 * <td align="center">{@link FontStyle#FONT_WEIGHT_LIGHT}</td> 166 * </tr> 167 * <tr> 168 * <td align="center">400</td> 169 * <td align="center">Normal (Regular)</td> 170 * <td align="center">{@link FontStyle#FONT_WEIGHT_NORMAL}</td> 171 * </tr> 172 * <tr> 173 * <td align="center">500</td> 174 * <td align="center">Medium</td> 175 * <td align="center">{@link FontStyle#FONT_WEIGHT_MEDIUM}</td> 176 * </tr> 177 * <tr> 178 * <td align="center">600</td> 179 * <td align="center">Semi Bold (Demi Bold)</td> 180 * <td align="center">{@link FontStyle#FONT_WEIGHT_SEMI_BOLD}</td> 181 * </tr> 182 * <tr> 183 * <td align="center">700</td> 184 * <td align="center">Bold</td> 185 * <td align="center">{@link FontStyle#FONT_WEIGHT_BOLD}</td> 186 * </tr> 187 * <tr> 188 * <td align="center">800</td> 189 * <td align="center">Extra Bold (Ultra Bold)</td> 190 * <td align="center">{@link FontStyle#FONT_WEIGHT_EXTRA_BOLD}</td> 191 * </tr> 192 * <tr> 193 * <td align="center">900</td> 194 * <td align="center">Black (Heavy)</td> 195 * <td align="center">{@link FontStyle#FONT_WEIGHT_BLACK}</td> 196 * </tr> 197 * </tbody> 198 * </p> 199 * 200 * @see FontStyle#FONT_WEIGHT_THIN 201 * @see FontStyle#FONT_WEIGHT_EXTRA_LIGHT 202 * @see FontStyle#FONT_WEIGHT_LIGHT 203 * @see FontStyle#FONT_WEIGHT_NORMAL 204 * @see FontStyle#FONT_WEIGHT_MEDIUM 205 * @see FontStyle#FONT_WEIGHT_SEMI_BOLD 206 * @see FontStyle#FONT_WEIGHT_BOLD 207 * @see FontStyle#FONT_WEIGHT_EXTRA_BOLD 208 * @see FontStyle#FONT_WEIGHT_BLACK 209 * @param weight a weight value 210 * @param slant a slant value 211 */ FontStyle(int weight, @FontSlant int slant)212 public FontStyle(int weight, @FontSlant int slant) { 213 Preconditions.checkArgument(FONT_WEIGHT_MIN <= weight && weight <= FONT_WEIGHT_MAX, 214 "weight value must be [" + FONT_WEIGHT_MIN + ", " + FONT_WEIGHT_MAX + "]"); 215 Preconditions.checkArgument(slant == FONT_SLANT_UPRIGHT || slant == FONT_SLANT_ITALIC, 216 "slant value must be FONT_SLANT_UPRIGHT or FONT_SLANT_UPRIGHT"); 217 mWeight = weight; 218 mSlant = slant; 219 } 220 221 222 /** 223 * Gets the weight value 224 * 225 * @see #FontStyle(int, int) 226 * @return a weight value 227 */ getWeight()228 public @IntRange(from = 0, to = 1000) int getWeight() { 229 return mWeight; 230 } 231 232 /** 233 * Gets the slant value 234 * 235 * @return a slant value 236 */ getSlant()237 public @FontSlant int getSlant() { 238 return mSlant; 239 } 240 241 /** 242 * Compute the matching score for another style. 243 * 244 * The smaller is better. 245 * @hide 246 */ getMatchScore(@onNull FontStyle o)247 public int getMatchScore(@NonNull FontStyle o) { 248 return Math.abs((getWeight() - o.getWeight())) / 100 + (getSlant() == o.getSlant() ? 0 : 2); 249 } 250 251 @Override equals(@ullable Object o)252 public boolean equals(@Nullable Object o) { 253 if (o == this) { 254 return true; 255 } 256 if (o == null || !(o instanceof FontStyle)) { 257 return false; 258 } 259 FontStyle fontStyle = (FontStyle) o; 260 return fontStyle.mWeight == mWeight && fontStyle.mSlant == mSlant; 261 } 262 263 @Override hashCode()264 public int hashCode() { 265 return Objects.hash(mWeight, mSlant); 266 } 267 268 @Override toString()269 public String toString() { 270 return "FontStyle { weight=" + mWeight + ", slant=" + mSlant + "}"; 271 } 272 } 273