| /* |
| * Copyright 2020 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package androidx.compose.foundation |
| |
| import androidx.compose.Composable |
| import androidx.compose.ExperimentalComposeApi |
| import androidx.compose.Providers |
| import androidx.compose.ambientOf |
| import androidx.compose.structuralEqualityPolicy |
| import androidx.ui.core.Modifier |
| import androidx.ui.core.semantics.semantics |
| import androidx.ui.graphics.Color |
| import androidx.ui.graphics.useOrElse |
| import androidx.ui.semantics.text |
| import androidx.ui.text.AnnotatedString |
| import androidx.compose.foundation.text.CoreText |
| import androidx.compose.foundation.text.InlineTextContent |
| import androidx.ui.text.Paragraph |
| import androidx.ui.text.TextLayoutResult |
| import androidx.ui.text.TextStyle |
| import androidx.ui.text.font.FontFamily |
| import androidx.ui.text.font.FontStyle |
| import androidx.ui.text.font.FontWeight |
| import androidx.ui.text.style.TextAlign |
| import androidx.ui.text.style.TextDecoration |
| import androidx.ui.text.style.TextOverflow |
| import androidx.ui.unit.TextUnit |
| |
| /** |
| * High level element that displays text and provides semantics / accessibility information. |
| * |
| * The default [style] uses the [currentTextStyle] defined by a theme. If you are setting your |
| * own style, you may want to consider first retrieving [currentTextStyle], and using |
| * [TextStyle.copy] to keep any theme defined attributes, only modifying the specific attributes |
| * you want to override. |
| * |
| * For ease of use, commonly used parameters from [TextStyle] are also present here. The order of |
| * precedence is as follows: |
| * - If a parameter is explicitly set here (i.e, it is _not_ `null` or [TextUnit.Inherit]), then |
| * this parameter will always be used. |
| * - If a parameter is _not_ set, (`null` or [TextUnit.Inherit]), then the corresponding value |
| * from [style] will be used instead. |
| * |
| * Additionally, for [color], if [color] is not set, and [style] does not have a color, then |
| * [contentColor] will be used - this allows this [Text] or element containing this [Text] to |
| * adapt to different background colors and still maintain contrast and accessibility. |
| * |
| * @param text The text to be displayed. |
| * @param modifier [Modifier] to apply to this layout node. |
| * @param color [Color] to apply to the text. If [Color.Unset], and [style] has no color set, this |
| * will be [contentColor]. |
| * @param fontSize The size of glyphs to use when painting the text. See [TextStyle.fontSize]. |
| * @param fontStyle The typeface variant to use when drawing the letters (e.g., italic). |
| * See [TextStyle.fontStyle]. |
| * @param fontWeight The typeface thickness to use when painting the text (e.g., [FontWeight.Bold]). |
| * @param fontFamily The font family to be used when rendering the text. See [TextStyle.fontFamily]. |
| * @param letterSpacing The amount of space to add between each letter. |
| * See [TextStyle.letterSpacing]. |
| * @param textDecoration The decorations to paint on the text (e.g., an underline). |
| * See [TextStyle.textDecoration]. |
| * @param textAlign The alignment of the text within the lines of the paragraph. |
| * See [TextStyle.textAlign]. |
| * @param lineHeight Line height for the [Paragraph] in [TextUnit] unit, e.g. SP or EM. |
| * See [TextStyle.lineHeight]. |
| * @param overflow How visual overflow should be handled. |
| * @param softWrap Whether the text should break at soft line breaks. If false, the glyphs in the |
| * text will be positioned as if there was unlimited horizontal space. If [softWrap] is false, |
| * [overflow] and TextAlign may have unexpected effects. |
| * @param maxLines An optional maximum number of lines for the text to span, wrapping if |
| * necessary. If the text exceeds the given number of lines, it will be truncated according to |
| * [overflow] and [softWrap]. If it is not null, then it must be greater than zero. |
| * @param inlineContent A map store composables that replaces certain ranges of the text. It's |
| * used to insert composables into text layout. Check [InlineTextContent] for more information. |
| * @param onTextLayout Callback that is executed when a new text layout is calculated. |
| * @param style Style configuration for the text such as color, font, line height etc. |
| */ |
| @Composable |
| fun Text( |
| text: String, |
| modifier: Modifier = Modifier, |
| color: Color = Color.Unset, |
| fontSize: TextUnit = TextUnit.Inherit, |
| fontStyle: FontStyle? = null, |
| fontWeight: FontWeight? = null, |
| fontFamily: FontFamily? = null, |
| letterSpacing: TextUnit = TextUnit.Inherit, |
| textDecoration: TextDecoration? = null, |
| textAlign: TextAlign? = null, |
| lineHeight: TextUnit = TextUnit.Inherit, |
| overflow: TextOverflow = TextOverflow.Clip, |
| softWrap: Boolean = true, |
| maxLines: Int = Int.MAX_VALUE, |
| inlineContent: Map<String, InlineTextContent> = mapOf(), |
| onTextLayout: (TextLayoutResult) -> Unit = {}, |
| style: TextStyle = currentTextStyle() |
| ) { |
| Text( |
| AnnotatedString(text), |
| modifier, |
| color, |
| fontSize, |
| fontStyle, |
| fontWeight, |
| fontFamily, |
| letterSpacing, |
| textDecoration, |
| textAlign, |
| lineHeight, |
| overflow, |
| softWrap, |
| maxLines, |
| inlineContent, |
| onTextLayout, |
| style |
| ) |
| } |
| |
| /** |
| * High level element that displays text and provides semantics / accessibility information. |
| * |
| * The default [style] uses the [currentTextStyle] defined by a theme. If you are setting your |
| * own style, you may want to consider first retrieving [currentTextStyle], and using |
| * [TextStyle.copy] to keep any theme defined attributes, only modifying the specific attributes |
| * you want to override. |
| * |
| * For ease of use, commonly used parameters from [TextStyle] are also present here. The order of |
| * precedence is as follows: |
| * - If a parameter is explicitly set here (i.e, it is _not_ `null` or [TextUnit.Inherit]), then |
| * this parameter will always be used. |
| * - If a parameter is _not_ set, (`null` or [TextUnit.Inherit]), then the corresponding value |
| * from [style] will be used instead. |
| * |
| * Additionally, for [color], if [color] is not set, and [style] does not have a color, then |
| * [contentColor] will be used - this allows this [Text] or element containing this [Text] to |
| * adapt to different background colors and still maintain contrast and accessibility. |
| * |
| * @param text The text to be displayed. |
| * @param modifier [Modifier] to apply to this layout node. |
| * @param color [Color] to apply to the text. If [Color.Unset], and [style] has no color set, this |
| * will be [contentColor]. |
| * @param fontSize The size of glyphs to use when painting the text. See [TextStyle.fontSize]. |
| * @param fontStyle The typeface variant to use when drawing the letters (e.g., italic). |
| * See [TextStyle.fontStyle]. |
| * @param fontWeight The typeface thickness to use when painting the text (e.g., [FontWeight.Bold]). |
| * @param fontFamily The font family to be used when rendering the text. See [TextStyle.fontFamily]. |
| * @param letterSpacing The amount of space to add between each letter. |
| * See [TextStyle.letterSpacing]. |
| * @param textDecoration The decorations to paint on the text (e.g., an underline). |
| * See [TextStyle.textDecoration]. |
| * @param textAlign The alignment of the text within the lines of the paragraph. |
| * See [TextStyle.textAlign]. |
| * @param lineHeight Line height for the [Paragraph] in [TextUnit] unit, e.g. SP or EM. |
| * See [TextStyle.lineHeight]. |
| * @param overflow How visual overflow should be handled. |
| * @param softWrap Whether the text should break at soft line breaks. If false, the glyphs in the |
| * text will be positioned as if there was unlimited horizontal space. If [softWrap] is false, |
| * [overflow] and TextAlign may have unexpected effects. |
| * @param maxLines An optional maximum number of lines for the text to span, wrapping if |
| * necessary. If the text exceeds the given number of lines, it will be truncated according to |
| * [overflow] and [softWrap]. If it is not null, then it must be greater than zero. |
| * @param inlineContent A map store composables that replaces certain ranges of the text. It's |
| * used to insert composables into text layout. Check [InlineTextContent] for more information. |
| * @param onTextLayout Callback that is executed when a new text layout is calculated. |
| * @param style Style configuration for the text such as color, font, line height etc. |
| */ |
| @Composable |
| fun Text( |
| text: AnnotatedString, |
| modifier: Modifier = Modifier, |
| color: Color = Color.Unset, |
| fontSize: TextUnit = TextUnit.Inherit, |
| fontStyle: FontStyle? = null, |
| fontWeight: FontWeight? = null, |
| fontFamily: FontFamily? = null, |
| letterSpacing: TextUnit = TextUnit.Inherit, |
| textDecoration: TextDecoration? = null, |
| textAlign: TextAlign? = null, |
| lineHeight: TextUnit = TextUnit.Inherit, |
| overflow: TextOverflow = TextOverflow.Clip, |
| softWrap: Boolean = true, |
| maxLines: Int = Int.MAX_VALUE, |
| inlineContent: Map<String, InlineTextContent> = mapOf(), |
| onTextLayout: (TextLayoutResult) -> Unit = {}, |
| style: TextStyle = currentTextStyle() |
| ) { |
| val textColor = color.useOrElse { style.color.useOrElse { contentColor() } } |
| val mergedStyle = style.merge( |
| TextStyle( |
| color = textColor, |
| fontSize = fontSize, |
| fontWeight = fontWeight, |
| textAlign = textAlign, |
| lineHeight = lineHeight, |
| fontFamily = fontFamily, |
| textDecoration = textDecoration, |
| fontStyle = fontStyle, |
| letterSpacing = letterSpacing |
| ) |
| ) |
| // TODO: text could contain composables, should be the final text |
| CoreText( |
| text, |
| modifier.semantics { this.text = text }, |
| mergedStyle, |
| softWrap, |
| overflow, |
| maxLines, |
| inlineContent, |
| onTextLayout |
| ) |
| } |
| |
| private val TextStyleAmbient = ambientOf( |
| @OptIn(ExperimentalComposeApi::class) structuralEqualityPolicy() |
| ) { TextStyle() } |
| |
| /** |
| * This component is used to set the current value of the Text style ambient. The given style will |
| * be merged with the current style values for any missing attributes. Any [Text] |
| * components included in this component's children will be styled with this style unless |
| * styled explicitly. |
| */ |
| @Composable |
| fun ProvideTextStyle(value: TextStyle, children: @Composable () -> Unit) { |
| val mergedStyle = currentTextStyle().merge(value) |
| Providers(TextStyleAmbient provides mergedStyle, children = children) |
| } |
| |
| /** |
| * This effect is used to read the current value of the Text style ambient. Any [Text] |
| * components included in this component's children will be styled with this style unless |
| * styled explicitly. |
| */ |
| @Composable |
| fun currentTextStyle(): TextStyle = TextStyleAmbient.current |