1 /*
2  * Copyright 2019 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 package androidx.compose.ui.text.font
17 
18 import androidx.compose.runtime.Immutable
19 import androidx.compose.runtime.Stable
20 import androidx.compose.ui.text.internal.requirePrecondition
21 import androidx.compose.ui.util.lerp
22 
23 /**
24  * The thickness of the glyphs, in a range of [1, 1000].
25  *
26  * @param weight Font weight value in the range of [1, 1000]
27  * @see Font
28  * @see FontFamily
29  */
30 @Immutable
31 class FontWeight(val weight: Int) : Comparable<FontWeight> {
32 
33     companion object {
34         /** [Thin] */
35         @Stable val W100 = FontWeight(100)
36         /** [ExtraLight] */
37         @Stable val W200 = FontWeight(200)
38         /** [Light] */
39         @Stable val W300 = FontWeight(300)
40         /** [Normal] / regular / plain */
41         @Stable val W400 = FontWeight(400)
42         /** [Medium] */
43         @Stable val W500 = FontWeight(500)
44         /** [SemiBold] */
45         @Stable val W600 = FontWeight(600)
46         /** [Bold] */
47         @Stable val W700 = FontWeight(700)
48         /** [ExtraBold] */
49         @Stable val W800 = FontWeight(800)
50         /** [Black] */
51         @Stable val W900 = FontWeight(900)
52 
53         /** Alias for [W100] */
54         @Stable val Thin = W100
55         /** Alias for [W200] */
56         @Stable val ExtraLight = W200
57         /** Alias for [W300] */
58         @Stable val Light = W300
59         /** The default font weight - alias for [W400] */
60         @Stable val Normal = W400
61         /** Alias for [W500] */
62         @Stable val Medium = W500
63         /** Alias for [W600] */
64         @Stable val SemiBold = W600
65         /** A commonly used font weight that is heavier than normal - alias for [W700] */
66         @Stable val Bold = W700
67         /** Alias for [W800] */
68         @Stable val ExtraBold = W800
69         /** Alias for [W900] */
70         @Stable val Black = W900
71 
72         /** A list of all the font weights. */
73         internal val values: List<FontWeight> =
74             listOf(W100, W200, W300, W400, W500, W600, W700, W800, W900)
75     }
76 
77     init {
<lambda>null78         requirePrecondition(weight in 1..1000) {
79             "Font weight can be in range [1, 1000]. Current value: $weight"
80         }
81     }
82 
compareTonull83     override operator fun compareTo(other: FontWeight): Int {
84         return weight.compareTo(other.weight)
85     }
86 
equalsnull87     override fun equals(other: Any?): Boolean {
88         if (this === other) return true
89         if (other !is FontWeight) return false
90         if (weight != other.weight) return false
91         return true
92     }
93 
hashCodenull94     override fun hashCode(): Int {
95         return weight
96     }
97 
toStringnull98     override fun toString(): String {
99         return "FontWeight(weight=$weight)"
100     }
101 }
102 
103 /**
104  * Linearly interpolate between two font weights.
105  *
106  * The [fraction] argument represents position on the timeline, with 0.0 meaning that the
107  * interpolation has not started, returning [start] (or something equivalent to [start]), 1.0
108  * meaning that the interpolation has finished, returning [stop] (or something equivalent to
109  * [stop]), and values in between meaning that the interpolation is at the relevant point on the
110  * timeline between [start] and [stop]. The interpolation can be extrapolated beyond 0.0 and 1.0, so
111  * negative values and values greater than 1.0 are valid (and can easily be generated by curves).
112  *
113  * Values for [fraction] are usually obtained from an [Animation<Float>], such as an
114  * `AnimationController`.
115  */
lerpnull116 fun lerp(start: FontWeight, stop: FontWeight, fraction: Float): FontWeight {
117     val weight = lerp(start.weight, stop.weight, fraction).coerceIn(1, 1000)
118     return FontWeight(weight)
119 }
120