Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 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 | |
Louis Pullen-Freilich | ab19475 | 2020-07-21 22:21:22 +0100 | [diff] [blame] | 17 | package androidx.compose.ui.text |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 18 | |
Louis Pullen-Freilich | 1f10a59 | 2020-07-24 16:35:14 +0100 | [diff] [blame] | 19 | import androidx.compose.runtime.Immutable |
| 20 | import androidx.compose.runtime.Stable |
Halil Ozercan | 06becff | 2022-04-13 01:38:27 +0000 | [diff] [blame] | 21 | import androidx.compose.ui.graphics.Brush |
Louis Pullen-Freilich | 4dc4dac | 2020-07-22 14:39:14 +0100 | [diff] [blame] | 22 | import androidx.compose.ui.graphics.Color |
| 23 | import androidx.compose.ui.graphics.Shadow |
| 24 | import androidx.compose.ui.graphics.lerp |
George Mount | c6549b9 | 2020-12-14 10:49:53 -0800 | [diff] [blame] | 25 | import androidx.compose.ui.graphics.takeOrElse |
Louis Pullen-Freilich | ab19475 | 2020-07-21 22:21:22 +0100 | [diff] [blame] | 26 | import androidx.compose.ui.text.font.FontFamily |
| 27 | import androidx.compose.ui.text.font.FontStyle |
| 28 | import androidx.compose.ui.text.font.FontSynthesis |
| 29 | import androidx.compose.ui.text.font.FontWeight |
| 30 | import androidx.compose.ui.text.font.lerp |
Louis Pullen-Freilich | 534385a | 2020-08-14 14:10:12 +0100 | [diff] [blame] | 31 | import androidx.compose.ui.text.intl.LocaleList |
Louis Pullen-Freilich | ab19475 | 2020-07-21 22:21:22 +0100 | [diff] [blame] | 32 | import androidx.compose.ui.text.style.BaselineShift |
| 33 | import androidx.compose.ui.text.style.TextDecoration |
Halil Ozercan | 06e7116 | 2022-07-18 17:24:24 +0100 | [diff] [blame] | 34 | import androidx.compose.ui.text.style.TextForegroundStyle |
Louis Pullen-Freilich | ab19475 | 2020-07-21 22:21:22 +0100 | [diff] [blame] | 35 | import androidx.compose.ui.text.style.TextGeometricTransform |
| 36 | import androidx.compose.ui.text.style.lerp |
Louis Pullen-Freilich | a7eeb10 | 2020-07-22 17:54:24 +0100 | [diff] [blame] | 37 | import androidx.compose.ui.unit.TextUnit |
George Mount | cdd20c9 | 2020-12-10 20:03:46 +0000 | [diff] [blame] | 38 | import androidx.compose.ui.unit.isUnspecified |
Louis Pullen-Freilich | a7eeb10 | 2020-07-22 17:54:24 +0100 | [diff] [blame] | 39 | import androidx.compose.ui.unit.lerp |
Siyamed Sinir | 0ac7068 | 2022-03-27 12:07:36 -0700 | [diff] [blame] | 40 | import androidx.compose.ui.unit.sp |
| 41 | |
| 42 | /** The default font size if none is specified. */ |
| 43 | private val DefaultFontSize = 14.sp |
| 44 | private val DefaultLetterSpacing = 0.sp |
| 45 | private val DefaultBackgroundColor = Color.Transparent |
| 46 | // TODO(nona): Introduce TextUnit.Original for representing "do not change the original result". |
| 47 | // Need to distinguish from Inherit. |
| 48 | private val DefaultColor = Color.Black |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 49 | |
| 50 | /** |
Siyamed Sinir | faa4ac4 | 2019-12-04 09:02:31 -0800 | [diff] [blame] | 51 | * Styling configuration for a text span. This configuration only allows character level styling, |
| 52 | * in order to set paragraph level styling such as line height, or text alignment please see |
| 53 | * [ParagraphStyle]. |
| 54 | * |
Louis Pullen-Freilich | ab19475 | 2020-07-21 22:21:22 +0100 | [diff] [blame] | 55 | * @sample androidx.compose.ui.text.samples.SpanStyleSample |
Siyamed Sinir | faa4ac4 | 2019-12-04 09:02:31 -0800 | [diff] [blame] | 56 | * |
Louis Pullen-Freilich | ab19475 | 2020-07-21 22:21:22 +0100 | [diff] [blame] | 57 | * @sample androidx.compose.ui.text.samples.AnnotatedStringBuilderSample |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 58 | * |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 59 | * @param fontSize The size of glyphs (in logical pixels) to use when painting the text. This |
haoyu | df2e07c | 2020-11-09 17:36:11 -0800 | [diff] [blame] | 60 | * may be [TextUnit.Unspecified] for inheriting from another [SpanStyle]. |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 61 | * @param fontWeight The typeface thickness to use when painting the text (e.g., bold). |
| 62 | * @param fontStyle The typeface variant to use when drawing the letters (e.g., italic). |
| 63 | * @param fontSynthesis Whether to synthesize font weight and/or style when the requested weight or |
Siyamed Sinir | 0ac7068 | 2022-03-27 12:07:36 -0700 | [diff] [blame] | 64 | * style cannot be found in the provided font family. |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 65 | * @param fontFamily The font family to be used when rendering the text. |
| 66 | * @param fontFeatureSettings The advanced typography settings provided by font. The format is the |
| 67 | * same as the CSS font-feature-settings attribute: |
| 68 | * https://www.w3.org/TR/css-fonts-3/#font-feature-settings-prop |
| 69 | * @param letterSpacing The amount of space (in em) to add between each letter. |
| 70 | * @param baselineShift The amount by which the text is shifted up from the current baseline. |
| 71 | * @param textGeometricTransform The geometric transformation applied the text. |
| 72 | * @param localeList The locale list used to select region-specific glyphs. |
| 73 | * @param background The background color for the text. |
Siyamed Sinir | 32fd106 | 2019-12-10 10:54:47 -0800 | [diff] [blame] | 74 | * @param textDecoration The decorations to paint on the text (e.g., an underline). |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 75 | * @param shadow The shadow effect applied on the text. |
Siyamed Sinir | 8e2ae72 | 2022-03-10 08:23:44 -0800 | [diff] [blame] | 76 | * @param platformStyle Platform specific [SpanStyle] parameters. |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 77 | * |
Siyamed Sinir | c8b0132 | 2019-12-05 09:41:00 -0800 | [diff] [blame] | 78 | * @see AnnotatedString |
| 79 | * @see TextStyle |
| 80 | * @see ParagraphStyle |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 81 | */ |
| 82 | @Immutable |
siyamed | bd27255 | 2022-07-29 12:40:43 -0700 | [diff] [blame] | 83 | class SpanStyle internal constructor( |
Halil Ozercan | 06becff | 2022-04-13 01:38:27 +0000 | [diff] [blame] | 84 | // The fill to draw text, a unified representation of Color and Brush. |
Halil Ozercan | 06e7116 | 2022-07-18 17:24:24 +0100 | [diff] [blame] | 85 | internal val textForegroundStyle: TextForegroundStyle, |
haoyu | df2e07c | 2020-11-09 17:36:11 -0800 | [diff] [blame] | 86 | val fontSize: TextUnit = TextUnit.Unspecified, |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 87 | val fontWeight: FontWeight? = null, |
| 88 | val fontStyle: FontStyle? = null, |
| 89 | val fontSynthesis: FontSynthesis? = null, |
| 90 | val fontFamily: FontFamily? = null, |
| 91 | val fontFeatureSettings: String? = null, |
haoyu | df2e07c | 2020-11-09 17:36:11 -0800 | [diff] [blame] | 92 | val letterSpacing: TextUnit = TextUnit.Unspecified, |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 93 | val baselineShift: BaselineShift? = null, |
| 94 | val textGeometricTransform: TextGeometricTransform? = null, |
| 95 | val localeList: LocaleList? = null, |
Nader Jawad | cd46cc3 | 2020-09-30 19:03:45 -0700 | [diff] [blame] | 96 | val background: Color = Color.Unspecified, |
Siyamed Sinir | 32fd106 | 2019-12-10 10:54:47 -0800 | [diff] [blame] | 97 | val textDecoration: TextDecoration? = null, |
Siyamed Sinir | 8e2ae72 | 2022-03-10 08:23:44 -0800 | [diff] [blame] | 98 | val shadow: Shadow? = null, |
siyamed | bd27255 | 2022-07-29 12:40:43 -0700 | [diff] [blame] | 99 | val platformStyle: PlatformSpanStyle? = null |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 100 | ) { |
Siyamed Sinir | 8e2ae72 | 2022-03-10 08:23:44 -0800 | [diff] [blame] | 101 | |
Siyamed Sinir | 0ac7068 | 2022-03-27 12:07:36 -0700 | [diff] [blame] | 102 | /** |
| 103 | * Styling configuration for a text span. This configuration only allows character level styling, |
| 104 | * in order to set paragraph level styling such as line height, or text alignment please see |
| 105 | * [ParagraphStyle]. |
| 106 | * |
| 107 | * @sample androidx.compose.ui.text.samples.SpanStyleSample |
| 108 | * |
| 109 | * @sample androidx.compose.ui.text.samples.AnnotatedStringBuilderSample |
| 110 | * |
| 111 | * @param color The text color. |
| 112 | * @param fontSize The size of glyphs (in logical pixels) to use when painting the text. This |
| 113 | * may be [TextUnit.Unspecified] for inheriting from another [SpanStyle]. |
| 114 | * @param fontWeight The typeface thickness to use when painting the text (e.g., bold). |
| 115 | * @param fontStyle The typeface variant to use when drawing the letters (e.g., italic). |
| 116 | * @param fontSynthesis Whether to synthesize font weight and/or style when the requested weight |
| 117 | * or style cannot be found in the provided font family. |
| 118 | * @param fontFamily The font family to be used when rendering the text. |
| 119 | * @param fontFeatureSettings The advanced typography settings provided by font. The format is |
| 120 | * the same as the CSS font-feature-settings attribute: |
| 121 | * https://www.w3.org/TR/css-fonts-3/#font-feature-settings-prop |
| 122 | * @param letterSpacing The amount of space (in em) to add between each letter. |
| 123 | * @param baselineShift The amount by which the text is shifted up from the current baseline. |
| 124 | * @param textGeometricTransform The geometric transformation applied the text. |
| 125 | * @param localeList The locale list used to select region-specific glyphs. |
| 126 | * @param background The background color for the text. |
| 127 | * @param textDecoration The decorations to paint on the text (e.g., an underline). |
| 128 | * @param shadow The shadow effect applied on the text. |
| 129 | * |
| 130 | * @see AnnotatedString |
| 131 | * @see TextStyle |
| 132 | * @see ParagraphStyle |
| 133 | */ |
Siyamed Sinir | 8e2ae72 | 2022-03-10 08:23:44 -0800 | [diff] [blame] | 134 | constructor( |
| 135 | color: Color = Color.Unspecified, |
| 136 | fontSize: TextUnit = TextUnit.Unspecified, |
| 137 | fontWeight: FontWeight? = null, |
| 138 | fontStyle: FontStyle? = null, |
| 139 | fontSynthesis: FontSynthesis? = null, |
| 140 | fontFamily: FontFamily? = null, |
| 141 | fontFeatureSettings: String? = null, |
| 142 | letterSpacing: TextUnit = TextUnit.Unspecified, |
| 143 | baselineShift: BaselineShift? = null, |
| 144 | textGeometricTransform: TextGeometricTransform? = null, |
| 145 | localeList: LocaleList? = null, |
| 146 | background: Color = Color.Unspecified, |
| 147 | textDecoration: TextDecoration? = null, |
| 148 | shadow: Shadow? = null |
| 149 | ) : this( |
Halil Ozercan | 06e7116 | 2022-07-18 17:24:24 +0100 | [diff] [blame] | 150 | textForegroundStyle = TextForegroundStyle.from(color), |
Siyamed Sinir | 8e2ae72 | 2022-03-10 08:23:44 -0800 | [diff] [blame] | 151 | fontSize = fontSize, |
| 152 | fontWeight = fontWeight, |
| 153 | fontStyle = fontStyle, |
| 154 | fontSynthesis = fontSynthesis, |
| 155 | fontFamily = fontFamily, |
| 156 | fontFeatureSettings = fontFeatureSettings, |
| 157 | letterSpacing = letterSpacing, |
| 158 | baselineShift = baselineShift, |
| 159 | textGeometricTransform = textGeometricTransform, |
| 160 | localeList = localeList, |
| 161 | background = background, |
| 162 | textDecoration = textDecoration, |
| 163 | shadow = shadow, |
| 164 | platformStyle = null |
| 165 | ) |
| 166 | |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 167 | /** |
Halil Ozercan | 06becff | 2022-04-13 01:38:27 +0000 | [diff] [blame] | 168 | * Styling configuration for a text span. This configuration only allows character level styling, |
| 169 | * in order to set paragraph level styling such as line height, or text alignment please see |
| 170 | * [ParagraphStyle]. |
| 171 | * |
| 172 | * @sample androidx.compose.ui.text.samples.SpanStyleSample |
| 173 | * |
| 174 | * @sample androidx.compose.ui.text.samples.AnnotatedStringBuilderSample |
| 175 | * |
| 176 | * @param color The color to draw the text. |
| 177 | * @param fontSize The size of glyphs (in logical pixels) to use when painting the text. This |
| 178 | * may be [TextUnit.Unspecified] for inheriting from another [SpanStyle]. |
| 179 | * @param fontWeight The typeface thickness to use when painting the text (e.g., bold). |
| 180 | * @param fontStyle The typeface variant to use when drawing the letters (e.g., italic). |
| 181 | * @param fontSynthesis Whether to synthesize font weight and/or style when the requested weight |
| 182 | * or style cannot be found in the provided font family. |
| 183 | * @param fontFamily The font family to be used when rendering the text. |
| 184 | * @param fontFeatureSettings The advanced typography settings provided by font. The format is |
| 185 | * the same as the CSS font-feature-settings attribute: |
| 186 | * https://www.w3.org/TR/css-fonts-3/#font-feature-settings-prop |
| 187 | * @param letterSpacing The amount of space (in em) to add between each letter. |
| 188 | * @param baselineShift The amount by which the text is shifted up from the current baseline. |
| 189 | * @param textGeometricTransform The geometric transformation applied the text. |
| 190 | * @param localeList The locale list used to select region-specific glyphs. |
| 191 | * @param background The background color for the text. |
| 192 | * @param textDecoration The decorations to paint on the text (e.g., an underline). |
| 193 | * @param shadow The shadow effect applied on the text. |
| 194 | * @param platformStyle Platform specific [SpanStyle] parameters. |
| 195 | * |
| 196 | * @see AnnotatedString |
| 197 | * @see TextStyle |
| 198 | * @see ParagraphStyle |
| 199 | */ |
Halil Ozercan | 06becff | 2022-04-13 01:38:27 +0000 | [diff] [blame] | 200 | constructor( |
| 201 | color: Color = Color.Unspecified, |
| 202 | fontSize: TextUnit = TextUnit.Unspecified, |
| 203 | fontWeight: FontWeight? = null, |
| 204 | fontStyle: FontStyle? = null, |
| 205 | fontSynthesis: FontSynthesis? = null, |
| 206 | fontFamily: FontFamily? = null, |
| 207 | fontFeatureSettings: String? = null, |
| 208 | letterSpacing: TextUnit = TextUnit.Unspecified, |
| 209 | baselineShift: BaselineShift? = null, |
| 210 | textGeometricTransform: TextGeometricTransform? = null, |
| 211 | localeList: LocaleList? = null, |
| 212 | background: Color = Color.Unspecified, |
| 213 | textDecoration: TextDecoration? = null, |
| 214 | shadow: Shadow? = null, |
| 215 | platformStyle: PlatformSpanStyle? = null |
| 216 | ) : this( |
Halil Ozercan | 06e7116 | 2022-07-18 17:24:24 +0100 | [diff] [blame] | 217 | textForegroundStyle = TextForegroundStyle.from(color), |
Halil Ozercan | 06becff | 2022-04-13 01:38:27 +0000 | [diff] [blame] | 218 | fontSize = fontSize, |
| 219 | fontWeight = fontWeight, |
| 220 | fontStyle = fontStyle, |
| 221 | fontSynthesis = fontSynthesis, |
| 222 | fontFamily = fontFamily, |
| 223 | fontFeatureSettings = fontFeatureSettings, |
| 224 | letterSpacing = letterSpacing, |
| 225 | baselineShift = baselineShift, |
| 226 | textGeometricTransform = textGeometricTransform, |
| 227 | localeList = localeList, |
| 228 | background = background, |
| 229 | textDecoration = textDecoration, |
| 230 | shadow = shadow, |
| 231 | platformStyle = platformStyle |
| 232 | ) |
| 233 | |
| 234 | /** |
| 235 | * Styling configuration for a text span. This configuration only allows character level styling, |
| 236 | * in order to set paragraph level styling such as line height, or text alignment please see |
| 237 | * [ParagraphStyle]. |
| 238 | * |
Halil Ozercan | a868604 | 2022-06-01 15:20:20 +0100 | [diff] [blame] | 239 | * @sample androidx.compose.ui.text.samples.SpanStyleBrushSample |
Halil Ozercan | 06becff | 2022-04-13 01:38:27 +0000 | [diff] [blame] | 240 | * |
| 241 | * @sample androidx.compose.ui.text.samples.AnnotatedStringBuilderSample |
| 242 | * |
| 243 | * @param brush The brush to use when painting the text. If brush is given as null, it will be |
| 244 | * treated as unspecified. It is equivalent to calling the alternative color constructor with |
| 245 | * [Color.Unspecified] |
Halil Ozercan | a868604 | 2022-06-01 15:20:20 +0100 | [diff] [blame] | 246 | * @param alpha Opacity to be applied to [brush] from 0.0f to 1.0f representing fully |
| 247 | * transparent to fully opaque respectively. |
Halil Ozercan | 06becff | 2022-04-13 01:38:27 +0000 | [diff] [blame] | 248 | * @param fontSize The size of glyphs (in logical pixels) to use when painting the text. This |
| 249 | * may be [TextUnit.Unspecified] for inheriting from another [SpanStyle]. |
| 250 | * @param fontWeight The typeface thickness to use when painting the text (e.g., bold). |
| 251 | * @param fontStyle The typeface variant to use when drawing the letters (e.g., italic). |
| 252 | * @param fontSynthesis Whether to synthesize font weight and/or style when the requested weight |
| 253 | * or style cannot be found in the provided font family. |
| 254 | * @param fontFamily The font family to be used when rendering the text. |
| 255 | * @param fontFeatureSettings The advanced typography settings provided by font. The format is |
| 256 | * the same as the CSS font-feature-settings attribute: |
| 257 | * https://www.w3.org/TR/css-fonts-3/#font-feature-settings-prop |
| 258 | * @param letterSpacing The amount of space (in em) to add between each letter. |
| 259 | * @param baselineShift The amount by which the text is shifted up from the current baseline. |
| 260 | * @param textGeometricTransform The geometric transformation applied the text. |
| 261 | * @param localeList The locale list used to select region-specific glyphs. |
| 262 | * @param background The background color for the text. |
| 263 | * @param textDecoration The decorations to paint on the text (e.g., an underline). |
| 264 | * @param shadow The shadow effect applied on the text. |
| 265 | * @param platformStyle Platform specific [SpanStyle] parameters. |
| 266 | * |
| 267 | * @see AnnotatedString |
| 268 | * @see TextStyle |
| 269 | * @see ParagraphStyle |
| 270 | */ |
| 271 | @ExperimentalTextApi |
| 272 | constructor( |
| 273 | brush: Brush?, |
Halil Ozercan | a868604 | 2022-06-01 15:20:20 +0100 | [diff] [blame] | 274 | alpha: Float = Float.NaN, |
Halil Ozercan | 06becff | 2022-04-13 01:38:27 +0000 | [diff] [blame] | 275 | fontSize: TextUnit = TextUnit.Unspecified, |
| 276 | fontWeight: FontWeight? = null, |
| 277 | fontStyle: FontStyle? = null, |
| 278 | fontSynthesis: FontSynthesis? = null, |
| 279 | fontFamily: FontFamily? = null, |
| 280 | fontFeatureSettings: String? = null, |
| 281 | letterSpacing: TextUnit = TextUnit.Unspecified, |
| 282 | baselineShift: BaselineShift? = null, |
| 283 | textGeometricTransform: TextGeometricTransform? = null, |
| 284 | localeList: LocaleList? = null, |
| 285 | background: Color = Color.Unspecified, |
| 286 | textDecoration: TextDecoration? = null, |
| 287 | shadow: Shadow? = null, |
| 288 | platformStyle: PlatformSpanStyle? = null |
| 289 | ) : this( |
Halil Ozercan | 06e7116 | 2022-07-18 17:24:24 +0100 | [diff] [blame] | 290 | textForegroundStyle = TextForegroundStyle.from(brush, alpha), |
Halil Ozercan | 06becff | 2022-04-13 01:38:27 +0000 | [diff] [blame] | 291 | fontSize = fontSize, |
| 292 | fontWeight = fontWeight, |
| 293 | fontStyle = fontStyle, |
| 294 | fontSynthesis = fontSynthesis, |
| 295 | fontFamily = fontFamily, |
| 296 | fontFeatureSettings = fontFeatureSettings, |
| 297 | letterSpacing = letterSpacing, |
| 298 | baselineShift = baselineShift, |
| 299 | textGeometricTransform = textGeometricTransform, |
| 300 | localeList = localeList, |
| 301 | background = background, |
| 302 | textDecoration = textDecoration, |
| 303 | shadow = shadow, |
| 304 | platformStyle = platformStyle |
| 305 | ) |
| 306 | |
| 307 | /** |
| 308 | * Color to draw text. |
| 309 | */ |
Halil Ozercan | 06e7116 | 2022-07-18 17:24:24 +0100 | [diff] [blame] | 310 | val color: Color get() = this.textForegroundStyle.color |
Halil Ozercan | 06becff | 2022-04-13 01:38:27 +0000 | [diff] [blame] | 311 | |
| 312 | /** |
| 313 | * Brush to draw text. If not null, overrides [color]. |
| 314 | */ |
George Mount | aea96e1 | 2022-06-15 16:00:57 -0700 | [diff] [blame] | 315 | @ExperimentalTextApi |
Halil Ozercan | 06becff | 2022-04-13 01:38:27 +0000 | [diff] [blame] | 316 | @Suppress("OPT_IN_MARKER_ON_WRONG_TARGET") |
| 317 | @get:ExperimentalTextApi |
Halil Ozercan | 06e7116 | 2022-07-18 17:24:24 +0100 | [diff] [blame] | 318 | val brush: Brush? get() = this.textForegroundStyle.brush |
Halil Ozercan | 06becff | 2022-04-13 01:38:27 +0000 | [diff] [blame] | 319 | |
| 320 | /** |
Halil Ozercan | a868604 | 2022-06-01 15:20:20 +0100 | [diff] [blame] | 321 | * Opacity of text. This value is either provided along side Brush, or via alpha channel in |
| 322 | * color. |
| 323 | */ |
George Mount | aea96e1 | 2022-06-15 16:00:57 -0700 | [diff] [blame] | 324 | @ExperimentalTextApi |
Halil Ozercan | a868604 | 2022-06-01 15:20:20 +0100 | [diff] [blame] | 325 | @Suppress("OPT_IN_MARKER_ON_WRONG_TARGET") |
| 326 | @get:ExperimentalTextApi |
Halil Ozercan | 06e7116 | 2022-07-18 17:24:24 +0100 | [diff] [blame] | 327 | val alpha: Float get() = this.textForegroundStyle.alpha |
Halil Ozercan | a868604 | 2022-06-01 15:20:20 +0100 | [diff] [blame] | 328 | |
| 329 | /** |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 330 | * Returns a new span style that is a combination of this style and the given [other] style. |
| 331 | * |
| 332 | * [other] span style's null or inherit properties are replaced with the non-null properties of |
| 333 | * this span style. Another way to think of it is that the "missing" properties of the [other] |
| 334 | * style are _filled_ by the properties of this style. |
| 335 | * |
| 336 | * If the given span style is null, returns this span style. |
| 337 | */ |
Leland Richardson | 47df77f | 2020-05-21 09:15:40 -0700 | [diff] [blame] | 338 | @Stable |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 339 | fun merge(other: SpanStyle? = null): SpanStyle { |
| 340 | if (other == null) return this |
| 341 | |
| 342 | return SpanStyle( |
Halil Ozercan | 06e7116 | 2022-07-18 17:24:24 +0100 | [diff] [blame] | 343 | textForegroundStyle = textForegroundStyle.merge(other.textForegroundStyle), |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 344 | fontFamily = other.fontFamily ?: this.fontFamily, |
haoyu | df2e07c | 2020-11-09 17:36:11 -0800 | [diff] [blame] | 345 | fontSize = if (!other.fontSize.isUnspecified) other.fontSize else this.fontSize, |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 346 | fontWeight = other.fontWeight ?: this.fontWeight, |
| 347 | fontStyle = other.fontStyle ?: this.fontStyle, |
| 348 | fontSynthesis = other.fontSynthesis ?: this.fontSynthesis, |
| 349 | fontFeatureSettings = other.fontFeatureSettings ?: this.fontFeatureSettings, |
haoyu | df2e07c | 2020-11-09 17:36:11 -0800 | [diff] [blame] | 350 | letterSpacing = if (!other.letterSpacing.isUnspecified) { |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 351 | other.letterSpacing |
| 352 | } else { |
| 353 | this.letterSpacing |
| 354 | }, |
| 355 | baselineShift = other.baselineShift ?: this.baselineShift, |
| 356 | textGeometricTransform = other.textGeometricTransform ?: this.textGeometricTransform, |
| 357 | localeList = other.localeList ?: this.localeList, |
George Mount | c6549b9 | 2020-12-14 10:49:53 -0800 | [diff] [blame] | 358 | background = other.background.takeOrElse { this.background }, |
Siyamed Sinir | 32fd106 | 2019-12-10 10:54:47 -0800 | [diff] [blame] | 359 | textDecoration = other.textDecoration ?: this.textDecoration, |
Siyamed Sinir | 8e2ae72 | 2022-03-10 08:23:44 -0800 | [diff] [blame] | 360 | shadow = other.shadow ?: this.shadow, |
| 361 | platformStyle = mergePlatformStyle(other.platformStyle) |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 362 | ) |
| 363 | } |
Siyamed Sinir | bc9d882 | 2020-04-21 18:20:59 -0700 | [diff] [blame] | 364 | |
Siyamed Sinir | 8e2ae72 | 2022-03-10 08:23:44 -0800 | [diff] [blame] | 365 | private fun mergePlatformStyle(other: PlatformSpanStyle?): PlatformSpanStyle? { |
| 366 | if (platformStyle == null) return other |
| 367 | if (other == null) return platformStyle |
| 368 | return platformStyle.merge(other) |
| 369 | } |
| 370 | |
Siyamed Sinir | bc9d882 | 2020-04-21 18:20:59 -0700 | [diff] [blame] | 371 | /** |
| 372 | * Plus operator overload that applies a [merge]. |
| 373 | */ |
Leland Richardson | 47df77f | 2020-05-21 09:15:40 -0700 | [diff] [blame] | 374 | @Stable |
Siyamed Sinir | bc9d882 | 2020-04-21 18:20:59 -0700 | [diff] [blame] | 375 | operator fun plus(other: SpanStyle): SpanStyle = this.merge(other) |
Siyamed Sinir | da765cc | 2021-01-09 10:17:35 -0800 | [diff] [blame] | 376 | |
| 377 | fun copy( |
| 378 | color: Color = this.color, |
| 379 | fontSize: TextUnit = this.fontSize, |
| 380 | fontWeight: FontWeight? = this.fontWeight, |
| 381 | fontStyle: FontStyle? = this.fontStyle, |
| 382 | fontSynthesis: FontSynthesis? = this.fontSynthesis, |
| 383 | fontFamily: FontFamily? = this.fontFamily, |
| 384 | fontFeatureSettings: String? = this.fontFeatureSettings, |
| 385 | letterSpacing: TextUnit = this.letterSpacing, |
| 386 | baselineShift: BaselineShift? = this.baselineShift, |
| 387 | textGeometricTransform: TextGeometricTransform? = this.textGeometricTransform, |
| 388 | localeList: LocaleList? = this.localeList, |
Andrey Rudenko | b366001 | 2021-01-18 15:01:15 +0100 | [diff] [blame] | 389 | background: Color = this.background, |
Siyamed Sinir | da765cc | 2021-01-09 10:17:35 -0800 | [diff] [blame] | 390 | textDecoration: TextDecoration? = this.textDecoration, |
| 391 | shadow: Shadow? = this.shadow |
| 392 | ): SpanStyle { |
| 393 | return SpanStyle( |
Halil Ozercan | 06e7116 | 2022-07-18 17:24:24 +0100 | [diff] [blame] | 394 | textForegroundStyle = if (color == this.color) { |
| 395 | textForegroundStyle |
| 396 | } else { |
| 397 | TextForegroundStyle.from(color) |
| 398 | }, |
Siyamed Sinir | da765cc | 2021-01-09 10:17:35 -0800 | [diff] [blame] | 399 | fontSize = fontSize, |
| 400 | fontWeight = fontWeight, |
| 401 | fontStyle = fontStyle, |
| 402 | fontSynthesis = fontSynthesis, |
| 403 | fontFamily = fontFamily, |
| 404 | fontFeatureSettings = fontFeatureSettings, |
| 405 | letterSpacing = letterSpacing, |
| 406 | baselineShift = baselineShift, |
| 407 | textGeometricTransform = textGeometricTransform, |
| 408 | localeList = localeList, |
| 409 | background = background, |
| 410 | textDecoration = textDecoration, |
Siyamed Sinir | 8e2ae72 | 2022-03-10 08:23:44 -0800 | [diff] [blame] | 411 | shadow = shadow, |
Halil Ozercan | 06becff | 2022-04-13 01:38:27 +0000 | [diff] [blame] | 412 | platformStyle = this.platformStyle |
Siyamed Sinir | da765cc | 2021-01-09 10:17:35 -0800 | [diff] [blame] | 413 | ) |
| 414 | } |
| 415 | |
Siyamed Sinir | 8e2ae72 | 2022-03-10 08:23:44 -0800 | [diff] [blame] | 416 | fun copy( |
| 417 | color: Color = this.color, |
| 418 | fontSize: TextUnit = this.fontSize, |
| 419 | fontWeight: FontWeight? = this.fontWeight, |
| 420 | fontStyle: FontStyle? = this.fontStyle, |
| 421 | fontSynthesis: FontSynthesis? = this.fontSynthesis, |
| 422 | fontFamily: FontFamily? = this.fontFamily, |
| 423 | fontFeatureSettings: String? = this.fontFeatureSettings, |
| 424 | letterSpacing: TextUnit = this.letterSpacing, |
| 425 | baselineShift: BaselineShift? = this.baselineShift, |
| 426 | textGeometricTransform: TextGeometricTransform? = this.textGeometricTransform, |
| 427 | localeList: LocaleList? = this.localeList, |
| 428 | background: Color = this.background, |
| 429 | textDecoration: TextDecoration? = this.textDecoration, |
| 430 | shadow: Shadow? = this.shadow, |
| 431 | platformStyle: PlatformSpanStyle? = this.platformStyle |
| 432 | ): SpanStyle { |
| 433 | return SpanStyle( |
Halil Ozercan | 06e7116 | 2022-07-18 17:24:24 +0100 | [diff] [blame] | 434 | textForegroundStyle = if (color == this.color) { |
| 435 | textForegroundStyle |
| 436 | } else { |
| 437 | TextForegroundStyle.from(color) |
| 438 | }, |
Halil Ozercan | 06becff | 2022-04-13 01:38:27 +0000 | [diff] [blame] | 439 | fontSize = fontSize, |
| 440 | fontWeight = fontWeight, |
| 441 | fontStyle = fontStyle, |
| 442 | fontSynthesis = fontSynthesis, |
| 443 | fontFamily = fontFamily, |
| 444 | fontFeatureSettings = fontFeatureSettings, |
| 445 | letterSpacing = letterSpacing, |
| 446 | baselineShift = baselineShift, |
| 447 | textGeometricTransform = textGeometricTransform, |
| 448 | localeList = localeList, |
| 449 | background = background, |
| 450 | textDecoration = textDecoration, |
| 451 | shadow = shadow, |
| 452 | platformStyle = platformStyle |
| 453 | ) |
| 454 | } |
| 455 | |
| 456 | @ExperimentalTextApi |
| 457 | fun copy( |
| 458 | brush: Brush?, |
Halil Ozercan | a868604 | 2022-06-01 15:20:20 +0100 | [diff] [blame] | 459 | alpha: Float = this.alpha, |
Halil Ozercan | 06becff | 2022-04-13 01:38:27 +0000 | [diff] [blame] | 460 | fontSize: TextUnit = this.fontSize, |
| 461 | fontWeight: FontWeight? = this.fontWeight, |
| 462 | fontStyle: FontStyle? = this.fontStyle, |
| 463 | fontSynthesis: FontSynthesis? = this.fontSynthesis, |
| 464 | fontFamily: FontFamily? = this.fontFamily, |
| 465 | fontFeatureSettings: String? = this.fontFeatureSettings, |
| 466 | letterSpacing: TextUnit = this.letterSpacing, |
| 467 | baselineShift: BaselineShift? = this.baselineShift, |
| 468 | textGeometricTransform: TextGeometricTransform? = this.textGeometricTransform, |
| 469 | localeList: LocaleList? = this.localeList, |
| 470 | background: Color = this.background, |
| 471 | textDecoration: TextDecoration? = this.textDecoration, |
| 472 | shadow: Shadow? = this.shadow, |
| 473 | platformStyle: PlatformSpanStyle? = this.platformStyle |
| 474 | ): SpanStyle { |
| 475 | return SpanStyle( |
Halil Ozercan | 06e7116 | 2022-07-18 17:24:24 +0100 | [diff] [blame] | 476 | textForegroundStyle = TextForegroundStyle.from(brush, alpha), |
Siyamed Sinir | 8e2ae72 | 2022-03-10 08:23:44 -0800 | [diff] [blame] | 477 | fontSize = fontSize, |
| 478 | fontWeight = fontWeight, |
| 479 | fontStyle = fontStyle, |
| 480 | fontSynthesis = fontSynthesis, |
| 481 | fontFamily = fontFamily, |
| 482 | fontFeatureSettings = fontFeatureSettings, |
| 483 | letterSpacing = letterSpacing, |
| 484 | baselineShift = baselineShift, |
| 485 | textGeometricTransform = textGeometricTransform, |
| 486 | localeList = localeList, |
| 487 | background = background, |
| 488 | textDecoration = textDecoration, |
| 489 | shadow = shadow, |
| 490 | platformStyle = platformStyle |
| 491 | ) |
| 492 | } |
| 493 | |
Sean McQuillan | cb6d100 | 2022-08-08 15:39:42 -0700 | [diff] [blame] | 494 | override fun equals(other: Any?): Boolean { |
Siyamed Sinir | da765cc | 2021-01-09 10:17:35 -0800 | [diff] [blame] | 495 | if (this === other) return true |
| 496 | if (other !is SpanStyle) return false |
Siyamed Sinir | da5769c | 2022-04-13 23:35:28 -0700 | [diff] [blame] | 497 | return hasSameLayoutAffectingAttributes(other) && |
| 498 | hasSameNonLayoutAttributes(other) |
| 499 | } |
Siyamed Sinir | da765cc | 2021-01-09 10:17:35 -0800 | [diff] [blame] | 500 | |
Siyamed Sinir | da5769c | 2022-04-13 23:35:28 -0700 | [diff] [blame] | 501 | internal fun hasSameLayoutAffectingAttributes(other: SpanStyle): Boolean { |
| 502 | if (this === other) return true |
Siyamed Sinir | da765cc | 2021-01-09 10:17:35 -0800 | [diff] [blame] | 503 | if (fontSize != other.fontSize) return false |
| 504 | if (fontWeight != other.fontWeight) return false |
| 505 | if (fontStyle != other.fontStyle) return false |
| 506 | if (fontSynthesis != other.fontSynthesis) return false |
| 507 | if (fontFamily != other.fontFamily) return false |
| 508 | if (fontFeatureSettings != other.fontFeatureSettings) return false |
| 509 | if (letterSpacing != other.letterSpacing) return false |
| 510 | if (baselineShift != other.baselineShift) return false |
| 511 | if (textGeometricTransform != other.textGeometricTransform) return false |
| 512 | if (localeList != other.localeList) return false |
| 513 | if (background != other.background) return false |
Siyamed Sinir | da5769c | 2022-04-13 23:35:28 -0700 | [diff] [blame] | 514 | if (platformStyle != other.platformStyle) return false |
| 515 | return true |
| 516 | } |
| 517 | |
| 518 | private fun hasSameNonLayoutAttributes(other: SpanStyle): Boolean { |
Halil Ozercan | 06e7116 | 2022-07-18 17:24:24 +0100 | [diff] [blame] | 519 | if (textForegroundStyle != other.textForegroundStyle) return false |
Siyamed Sinir | da765cc | 2021-01-09 10:17:35 -0800 | [diff] [blame] | 520 | if (textDecoration != other.textDecoration) return false |
| 521 | if (shadow != other.shadow) return false |
Siyamed Sinir | da765cc | 2021-01-09 10:17:35 -0800 | [diff] [blame] | 522 | return true |
| 523 | } |
| 524 | |
Siyamed Sinir | 8e2ae72 | 2022-03-10 08:23:44 -0800 | [diff] [blame] | 525 | @OptIn(ExperimentalTextApi::class) |
Siyamed Sinir | da765cc | 2021-01-09 10:17:35 -0800 | [diff] [blame] | 526 | override fun hashCode(): Int { |
| 527 | var result = color.hashCode() |
Halil Ozercan | 06becff | 2022-04-13 01:38:27 +0000 | [diff] [blame] | 528 | result = 31 * result + brush.hashCode() |
Halil Ozercan | a868604 | 2022-06-01 15:20:20 +0100 | [diff] [blame] | 529 | result = 31 * result + alpha.hashCode() |
Siyamed Sinir | da765cc | 2021-01-09 10:17:35 -0800 | [diff] [blame] | 530 | result = 31 * result + fontSize.hashCode() |
| 531 | result = 31 * result + (fontWeight?.hashCode() ?: 0) |
| 532 | result = 31 * result + (fontStyle?.hashCode() ?: 0) |
| 533 | result = 31 * result + (fontSynthesis?.hashCode() ?: 0) |
| 534 | result = 31 * result + (fontFamily?.hashCode() ?: 0) |
| 535 | result = 31 * result + (fontFeatureSettings?.hashCode() ?: 0) |
| 536 | result = 31 * result + letterSpacing.hashCode() |
| 537 | result = 31 * result + (baselineShift?.hashCode() ?: 0) |
| 538 | result = 31 * result + (textGeometricTransform?.hashCode() ?: 0) |
| 539 | result = 31 * result + (localeList?.hashCode() ?: 0) |
| 540 | result = 31 * result + background.hashCode() |
| 541 | result = 31 * result + (textDecoration?.hashCode() ?: 0) |
| 542 | result = 31 * result + (shadow?.hashCode() ?: 0) |
Siyamed Sinir | 8e2ae72 | 2022-03-10 08:23:44 -0800 | [diff] [blame] | 543 | result = 31 * result + (platformStyle?.hashCode() ?: 0) |
Siyamed Sinir | da765cc | 2021-01-09 10:17:35 -0800 | [diff] [blame] | 544 | return result |
| 545 | } |
| 546 | |
Halil Ozercan | a883678 | 2022-06-23 17:17:19 +0100 | [diff] [blame] | 547 | internal fun hashCodeLayoutAffectingAttributes(): Int { |
| 548 | var result = fontSize.hashCode() |
| 549 | result = 31 * result + (fontWeight?.hashCode() ?: 0) |
| 550 | result = 31 * result + (fontStyle?.hashCode() ?: 0) |
| 551 | result = 31 * result + (fontSynthesis?.hashCode() ?: 0) |
| 552 | result = 31 * result + (fontFamily?.hashCode() ?: 0) |
| 553 | result = 31 * result + (fontFeatureSettings?.hashCode() ?: 0) |
| 554 | result = 31 * result + letterSpacing.hashCode() |
| 555 | result = 31 * result + (baselineShift?.hashCode() ?: 0) |
| 556 | result = 31 * result + (textGeometricTransform?.hashCode() ?: 0) |
| 557 | result = 31 * result + (localeList?.hashCode() ?: 0) |
| 558 | result = 31 * result + background.hashCode() |
| 559 | result = 31 * result + (platformStyle?.hashCode() ?: 0) |
| 560 | return result |
| 561 | } |
| 562 | |
| 563 | @OptIn(ExperimentalTextApi::class) |
Siyamed Sinir | da765cc | 2021-01-09 10:17:35 -0800 | [diff] [blame] | 564 | override fun toString(): String { |
| 565 | return "SpanStyle(" + |
| 566 | "color=$color, " + |
Halil Ozercan | 06becff | 2022-04-13 01:38:27 +0000 | [diff] [blame] | 567 | "brush=$brush, " + |
Halil Ozercan | a868604 | 2022-06-01 15:20:20 +0100 | [diff] [blame] | 568 | "alpha=$alpha, " + |
Siyamed Sinir | da765cc | 2021-01-09 10:17:35 -0800 | [diff] [blame] | 569 | "fontSize=$fontSize, " + |
| 570 | "fontWeight=$fontWeight, " + |
| 571 | "fontStyle=$fontStyle, " + |
| 572 | "fontSynthesis=$fontSynthesis, " + |
| 573 | "fontFamily=$fontFamily, " + |
| 574 | "fontFeatureSettings=$fontFeatureSettings, " + |
| 575 | "letterSpacing=$letterSpacing, " + |
| 576 | "baselineShift=$baselineShift, " + |
| 577 | "textGeometricTransform=$textGeometricTransform, " + |
| 578 | "localeList=$localeList, " + |
| 579 | "background=$background, " + |
| 580 | "textDecoration=$textDecoration, " + |
Siyamed Sinir | 8e2ae72 | 2022-03-10 08:23:44 -0800 | [diff] [blame] | 581 | "shadow=$shadow, " + |
| 582 | "platformStyle=$platformStyle" + |
Siyamed Sinir | da765cc | 2021-01-09 10:17:35 -0800 | [diff] [blame] | 583 | ")" |
| 584 | } |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 585 | } |
Siyamed Sinir | bc9d882 | 2020-04-21 18:20:59 -0700 | [diff] [blame] | 586 | |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 587 | /** |
haoyu | df2e07c | 2020-11-09 17:36:11 -0800 | [diff] [blame] | 588 | * @param a An sp value. Maybe [TextUnit.Unspecified] |
| 589 | * @param b An sp value. Maybe [TextUnit.Unspecified] |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 590 | */ |
Siyamed Sinir | c8b0132 | 2019-12-05 09:41:00 -0800 | [diff] [blame] | 591 | internal fun lerpTextUnitInheritable(a: TextUnit, b: TextUnit, t: Float): TextUnit { |
haoyu | df2e07c | 2020-11-09 17:36:11 -0800 | [diff] [blame] | 592 | if (a.isUnspecified || b.isUnspecified) return lerpDiscrete(a, b, t) |
Siyamed Sinir | c8b0132 | 2019-12-05 09:41:00 -0800 | [diff] [blame] | 593 | return lerp(a, b, t) |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 594 | } |
| 595 | |
Siyamed Sinir | c8b0132 | 2019-12-05 09:41:00 -0800 | [diff] [blame] | 596 | /** |
| 597 | * Lerp between two values that cannot be transitioned. Returns [a] if [fraction] is smaller than |
| 598 | * 0.5 otherwise [b]. |
| 599 | */ |
| 600 | internal fun <T> lerpDiscrete(a: T, b: T, fraction: Float): T = if (fraction < 0.5) a else b |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 601 | |
| 602 | /** |
| 603 | * Interpolate between two span styles. |
| 604 | * |
| 605 | * This will not work well if the styles don't set the same fields. |
| 606 | * |
| 607 | * The [fraction] argument represents position on the timeline, with 0.0 meaning |
| 608 | * that the interpolation has not started, returning [start] (or something |
| 609 | * equivalent to [start]), 1.0 meaning that the interpolation has finished, |
| 610 | * returning [stop] (or something equivalent to [stop]), and values in between |
| 611 | * meaning that the interpolation is at the relevant point on the timeline |
| 612 | * between [start] and [stop]. The interpolation can be extrapolated beyond 0.0 and |
| 613 | * 1.0, so negative values and values greater than 1.0 are valid. |
| 614 | */ |
| 615 | fun lerp(start: SpanStyle, stop: SpanStyle, fraction: Float): SpanStyle { |
| 616 | return SpanStyle( |
Halil Ozercan | 06e7116 | 2022-07-18 17:24:24 +0100 | [diff] [blame] | 617 | textForegroundStyle = lerp(start.textForegroundStyle, stop.textForegroundStyle, fraction), |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 618 | fontFamily = lerpDiscrete( |
| 619 | start.fontFamily, |
| 620 | stop.fontFamily, |
| 621 | fraction |
| 622 | ), |
| 623 | fontSize = lerpTextUnitInheritable(start.fontSize, stop.fontSize, fraction), |
| 624 | fontWeight = lerp( |
| 625 | start.fontWeight ?: FontWeight.Normal, |
| 626 | stop.fontWeight ?: FontWeight.Normal, |
| 627 | fraction |
| 628 | ), |
| 629 | fontStyle = lerpDiscrete( |
| 630 | start.fontStyle, |
| 631 | stop.fontStyle, |
| 632 | fraction |
| 633 | ), |
| 634 | fontSynthesis = lerpDiscrete( |
| 635 | start.fontSynthesis, |
| 636 | stop.fontSynthesis, |
| 637 | fraction |
| 638 | ), |
| 639 | fontFeatureSettings = lerpDiscrete( |
| 640 | start.fontFeatureSettings, |
| 641 | stop.fontFeatureSettings, |
| 642 | fraction |
| 643 | ), |
| 644 | letterSpacing = lerpTextUnitInheritable( |
| 645 | start.letterSpacing, |
| 646 | stop.letterSpacing, |
| 647 | fraction |
| 648 | ), |
| 649 | baselineShift = lerp( |
| 650 | start.baselineShift ?: BaselineShift(0f), |
| 651 | stop.baselineShift ?: BaselineShift(0f), |
| 652 | fraction |
| 653 | ), |
| 654 | textGeometricTransform = lerp( |
| 655 | start.textGeometricTransform ?: TextGeometricTransform.None, |
| 656 | stop.textGeometricTransform ?: TextGeometricTransform.None, |
| 657 | fraction |
| 658 | ), |
| 659 | localeList = lerpDiscrete(start.localeList, stop.localeList, fraction), |
Siyamed Sinir | d4b6f66 | 2019-12-04 10:07:56 -0800 | [diff] [blame] | 660 | background = lerp( |
Siyamed Sinir | 36b1ec9 | 2020-04-21 15:58:30 -0700 | [diff] [blame] | 661 | start.background, |
| 662 | stop.background, |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 663 | fraction |
| 664 | ), |
Siyamed Sinir | 32fd106 | 2019-12-10 10:54:47 -0800 | [diff] [blame] | 665 | textDecoration = lerpDiscrete( |
| 666 | start.textDecoration, |
| 667 | stop.textDecoration, |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 668 | fraction |
| 669 | ), |
| 670 | shadow = lerp( |
| 671 | start.shadow ?: Shadow(), |
| 672 | stop.shadow ?: Shadow(), |
| 673 | fraction |
Siyamed Sinir | 8e2ae72 | 2022-03-10 08:23:44 -0800 | [diff] [blame] | 674 | ), |
| 675 | platformStyle = lerpPlatformStyle(start.platformStyle, stop.platformStyle, fraction) |
Siyamed Sinir | f447f2a | 2019-12-03 15:44:51 -0800 | [diff] [blame] | 676 | ) |
Siyamed Sinir | bc9d882 | 2020-04-21 18:20:59 -0700 | [diff] [blame] | 677 | } |
Siyamed Sinir | 8e2ae72 | 2022-03-10 08:23:44 -0800 | [diff] [blame] | 678 | |
Siyamed Sinir | 8e2ae72 | 2022-03-10 08:23:44 -0800 | [diff] [blame] | 679 | private fun lerpPlatformStyle( |
| 680 | start: PlatformSpanStyle?, |
| 681 | stop: PlatformSpanStyle?, |
| 682 | fraction: Float |
| 683 | ): PlatformSpanStyle? { |
| 684 | if (start == null && stop == null) return null |
| 685 | val startNonNull = start ?: PlatformSpanStyle.Default |
| 686 | val stopNonNull = stop ?: PlatformSpanStyle.Default |
Siyamed Sinir | e5b3f74 | 2022-04-15 10:14:40 -0700 | [diff] [blame] | 687 | return lerp(startNonNull, stopNonNull, fraction) |
Siyamed Sinir | 8e2ae72 | 2022-03-10 08:23:44 -0800 | [diff] [blame] | 688 | } |
Siyamed Sinir | 0ac7068 | 2022-03-27 12:07:36 -0700 | [diff] [blame] | 689 | |
Siyamed Sinir | 0ac7068 | 2022-03-27 12:07:36 -0700 | [diff] [blame] | 690 | internal fun resolveSpanStyleDefaults(style: SpanStyle) = SpanStyle( |
Halil Ozercan | 06e7116 | 2022-07-18 17:24:24 +0100 | [diff] [blame] | 691 | textForegroundStyle = style.textForegroundStyle.takeOrElse { |
| 692 | TextForegroundStyle.from(DefaultColor) |
| 693 | }, |
Siyamed Sinir | 0ac7068 | 2022-03-27 12:07:36 -0700 | [diff] [blame] | 694 | fontSize = if (style.fontSize.isUnspecified) DefaultFontSize else style.fontSize, |
| 695 | fontWeight = style.fontWeight ?: FontWeight.Normal, |
| 696 | fontStyle = style.fontStyle ?: FontStyle.Normal, |
| 697 | fontSynthesis = style.fontSynthesis ?: FontSynthesis.All, |
| 698 | fontFamily = style.fontFamily ?: FontFamily.Default, |
| 699 | fontFeatureSettings = style.fontFeatureSettings ?: "", |
| 700 | letterSpacing = if (style.letterSpacing.isUnspecified) { |
| 701 | DefaultLetterSpacing |
| 702 | } else { |
| 703 | style.letterSpacing |
| 704 | }, |
| 705 | baselineShift = style.baselineShift ?: BaselineShift.None, |
| 706 | textGeometricTransform = style.textGeometricTransform ?: TextGeometricTransform.None, |
| 707 | localeList = style.localeList ?: LocaleList.current, |
| 708 | background = style.background.takeOrElse { DefaultBackgroundColor }, |
| 709 | textDecoration = style.textDecoration ?: TextDecoration.None, |
| 710 | shadow = style.shadow ?: Shadow.None, |
| 711 | platformStyle = style.platformStyle |
| 712 | ) |