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