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 public final class FontStyle { 48 private static final String TAG = "FontStyle"; 49 50 /** 51 * A default value when font weight is unspecified 52 */ 53 public static final int FONT_WEIGHT_UNSPECIFIED = -1; 54 /** 55 * A minimum weight value for the font 56 */ 57 public static final int FONT_WEIGHT_MIN = 1; 58 59 /** 60 * A font weight value for the thin weight 61 */ 62 public static final int FONT_WEIGHT_THIN = 100; 63 64 /** 65 * A font weight value for the extra-light weight 66 */ 67 public static final int FONT_WEIGHT_EXTRA_LIGHT = 200; 68 69 /** 70 * A font weight value for the light weight 71 */ 72 public static final int FONT_WEIGHT_LIGHT = 300; 73 74 /** 75 * A font weight value for the normal weight 76 */ 77 public static final int FONT_WEIGHT_NORMAL = 400; 78 79 /** 80 * A font weight value for the medium weight 81 */ 82 public static final int FONT_WEIGHT_MEDIUM = 500; 83 84 /** 85 * A font weight value for the semi-bold weight 86 */ 87 public static final int FONT_WEIGHT_SEMI_BOLD = 600; 88 89 /** 90 * A font weight value for the bold weight. 91 */ 92 public static final int FONT_WEIGHT_BOLD = 700; 93 94 /** 95 * A font weight value for the extra-bold weight 96 */ 97 public static final int FONT_WEIGHT_EXTRA_BOLD = 800; 98 99 /** 100 * A font weight value for the black weight 101 */ 102 public static final int FONT_WEIGHT_BLACK = 900; 103 104 /** 105 * A maximum weight value for the font 106 */ 107 public static final int FONT_WEIGHT_MAX = 1000; 108 109 /** 110 * A font slant value for upright 111 */ 112 public static final int FONT_SLANT_UPRIGHT = 0; 113 114 /** 115 * A font slant value for italic 116 */ 117 public static final int FONT_SLANT_ITALIC = 1; 118 119 // TODO: Support FONT_SLANT_OBLIQUE 120 121 /** @hide */ 122 @IntDef(prefix = { "FONT_SLANT_" }, value = { 123 FONT_SLANT_UPRIGHT, 124 FONT_SLANT_ITALIC 125 }) 126 @Retention(RetentionPolicy.SOURCE) 127 public @interface FontSlant {} 128 129 private final @IntRange(from = 0, to = 1000) int mWeight; 130 private final @FontSlant int mSlant; 131 // TODO: Support width 132 FontStyle()133 public FontStyle() { 134 mWeight = FONT_WEIGHT_NORMAL; 135 mSlant = FONT_SLANT_UPRIGHT; 136 } 137 138 /** 139 * Create FontStyle with specific weight and italic 140 * 141 * <p> 142 * <table> 143 * <thead> 144 * <tr> 145 * <th align="center">Value</th> 146 * <th align="center">Name</th> 147 * <th align="center">Android Definition</th> 148 * </tr> 149 * </thead> 150 * <tbody> 151 * <tr> 152 * <td align="center">100</td> 153 * <td align="center">Thin</td> 154 * <td align="center">{@link FontStyle#FONT_WEIGHT_THIN}</td> 155 * </tr> 156 * <tr> 157 * <td align="center">200</td> 158 * <td align="center">Extra Light (Ultra Light)</td> 159 * <td align="center">{@link FontStyle#FONT_WEIGHT_EXTRA_LIGHT}</td> 160 * </tr> 161 * <tr> 162 * <td align="center">300</td> 163 * <td align="center">Light</td> 164 * <td align="center">{@link FontStyle#FONT_WEIGHT_LIGHT}</td> 165 * </tr> 166 * <tr> 167 * <td align="center">400</td> 168 * <td align="center">Normal (Regular)</td> 169 * <td align="center">{@link FontStyle#FONT_WEIGHT_NORMAL}</td> 170 * </tr> 171 * <tr> 172 * <td align="center">500</td> 173 * <td align="center">Medium</td> 174 * <td align="center">{@link FontStyle#FONT_WEIGHT_MEDIUM}</td> 175 * </tr> 176 * <tr> 177 * <td align="center">600</td> 178 * <td align="center">Semi Bold (Demi Bold)</td> 179 * <td align="center">{@link FontStyle#FONT_WEIGHT_SEMI_BOLD}</td> 180 * </tr> 181 * <tr> 182 * <td align="center">700</td> 183 * <td align="center">Bold</td> 184 * <td align="center">{@link FontStyle#FONT_WEIGHT_BOLD}</td> 185 * </tr> 186 * <tr> 187 * <td align="center">800</td> 188 * <td align="center">Extra Bold (Ultra Bold)</td> 189 * <td align="center">{@link FontStyle#FONT_WEIGHT_EXTRA_BOLD}</td> 190 * </tr> 191 * <tr> 192 * <td align="center">900</td> 193 * <td align="center">Black (Heavy)</td> 194 * <td align="center">{@link FontStyle#FONT_WEIGHT_BLACK}</td> 195 * </tr> 196 * </tbody> 197 * </p> 198 * 199 * @see FontStyle#FONT_WEIGHT_THIN 200 * @see FontStyle#FONT_WEIGHT_EXTRA_LIGHT 201 * @see FontStyle#FONT_WEIGHT_LIGHT 202 * @see FontStyle#FONT_WEIGHT_NORMAL 203 * @see FontStyle#FONT_WEIGHT_MEDIUM 204 * @see FontStyle#FONT_WEIGHT_SEMI_BOLD 205 * @see FontStyle#FONT_WEIGHT_BOLD 206 * @see FontStyle#FONT_WEIGHT_EXTRA_BOLD 207 * @see FontStyle#FONT_WEIGHT_BLACK 208 * @param weight a weight value 209 * @param slant a slant value 210 */ FontStyle(int weight, @FontSlant int slant)211 public FontStyle(int weight, @FontSlant int slant) { 212 Preconditions.checkArgument(FONT_WEIGHT_MIN <= weight && weight <= FONT_WEIGHT_MAX, 213 "weight value must be [" + FONT_WEIGHT_MIN + ", " + FONT_WEIGHT_MAX + "]"); 214 Preconditions.checkArgument(slant == FONT_SLANT_UPRIGHT || slant == FONT_SLANT_ITALIC, 215 "slant value must be FONT_SLANT_UPRIGHT or FONT_SLANT_UPRIGHT"); 216 mWeight = weight; 217 mSlant = slant; 218 } 219 220 221 /** 222 * Gets the weight value 223 * 224 * @see #FontStyle(int, int) 225 * @return a weight value 226 */ getWeight()227 public @IntRange(from = 0, to = 1000) int getWeight() { 228 return mWeight; 229 } 230 231 /** 232 * Gets the slant value 233 * 234 * @return a slant value 235 */ getSlant()236 public @FontSlant int getSlant() { 237 return mSlant; 238 } 239 240 /** 241 * Compute the matching score for another style. 242 * 243 * The smaller is better. 244 * @hide 245 */ getMatchScore(@onNull FontStyle o)246 public int getMatchScore(@NonNull FontStyle o) { 247 return Math.abs((getWeight() - o.getWeight())) / 100 + (getSlant() == o.getSlant() ? 0 : 2); 248 } 249 250 @Override equals(@ullable Object o)251 public boolean equals(@Nullable Object o) { 252 if (o == this) { 253 return true; 254 } 255 if (o == null || !(o instanceof FontStyle)) { 256 return false; 257 } 258 FontStyle fontStyle = (FontStyle) o; 259 return fontStyle.mWeight == mWeight && fontStyle.mSlant == mSlant; 260 } 261 262 @Override hashCode()263 public int hashCode() { 264 return Objects.hash(mWeight, mSlant); 265 } 266 267 @Override toString()268 public String toString() { 269 return "FontStyle { weight=" + mWeight + ", slant=" + mSlant + "}"; 270 } 271 } 272