/* * Copyright 2019 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.material import androidx.compose.runtime.Immutable import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.sp /** * Material Design type scale. * * The Material Design type scale includes a range of contrasting styles that support the needs of * your product and its content. * * The type scale is a combination of thirteen styles that are supported by the type system. It * contains reusable categories of text, each with an intended application and meaning. * * ![Typography image](https://developer.android.com/images/reference/androidx/compose/material/typography.png) * * @property h1 h1 is the largest headline, reserved for short, important text or numerals. * For headlines, you can choose an expressive font, such as a display, handwritten, or script * style. These unconventional font designs have details and intricacy that help attract the eye. * @property h2 h2 is the second largest headline, reserved for short, important text or numerals. * For headlines, you can choose an expressive font, such as a display, handwritten, or script * style. These unconventional font designs have details and intricacy that help attract the eye. * @property h3 h3 is the third largest headline, reserved for short, important text or numerals. * For headlines, you can choose an expressive font, such as a display, handwritten, or script * style. These unconventional font designs have details and intricacy that help attract the eye. * @property h4 h4 is the fourth largest headline, reserved for short, important text or numerals. * For headlines, you can choose an expressive font, such as a display, handwritten, or script * style. These unconventional font designs have details and intricacy that help attract the eye. * @property h5 h5 is the fifth largest headline, reserved for short, important text or numerals. * For headlines, you can choose an expressive font, such as a display, handwritten, or script * style. These unconventional font designs have details and intricacy that help attract the eye. * @property h6 h6 is the sixth largest headline, reserved for short, important text or numerals. * For headlines, you can choose an expressive font, such as a display, handwritten, or script * style. These unconventional font designs have details and intricacy that help attract the eye. * @property subtitle1 subtitle1 is the largest subtitle, and is typically reserved for * medium-emphasis text that is shorter in length. Serif or sans serif typefaces work well for * subtitles. * @property subtitle2 subtitle2 is the smallest subtitle, and is typically reserved for * medium-emphasis text that is shorter in length. Serif or sans serif typefaces work well for * subtitles. * @property body1 body1 is the largest body, and is typically used for long-form writing as it * works well for small text sizes. For longer sections of text, a serif or sans serif typeface * is recommended. * @property body2 body2 is the smallest body, and is typically used for long-form writing as it * works well for small text sizes. For longer sections of text, a serif or sans serif typeface * is recommended. * @property button button text is a call to action used in different types of buttons (such as * text, outlined and contained buttons) and in tabs, dialogs, and cards. Button text is * typically sans serif, using all caps text. * @property caption caption is one of the smallest font sizes. It is used sparingly to * annotate imagery or to introduce a headline. * @property overline overline is one of the smallest font sizes. It is used sparingly to * annotate imagery or to introduce a headline. */ @Immutable class Typography internal constructor( val h1: TextStyle, val h2: TextStyle, val h3: TextStyle, val h4: TextStyle, val h5: TextStyle, val h6: TextStyle, val subtitle1: TextStyle, val subtitle2: TextStyle, val body1: TextStyle, val body2: TextStyle, val button: TextStyle, val caption: TextStyle, val overline: TextStyle ) { /** * Constructor to create a [Typography]. For information on the types of style defined in * this constructor, see the property documentation for [Typography]. * * @param defaultFontFamily the default [FontFamily] to be used for [TextStyle]s provided in * this constructor. This default will be used if the [FontFamily] on the [TextStyle] is `null`. * @param h1 h1 is the largest headline, reserved for short, important text or numerals. * @param h2 h2 is the second largest headline, reserved for short, important text or numerals. * @param h3 h3 is the third largest headline, reserved for short, important text or numerals. * @param h4 h4 is the fourth largest headline, reserved for short, important text or numerals. * @param h5 h5 is the fifth largest headline, reserved for short, important text or numerals. * @param h6 h6 is the sixth largest headline, reserved for short, important text or numerals. * @param subtitle1 subtitle1 is the largest subtitle, and is typically reserved for * medium-emphasis text that is shorter in length. * @param subtitle2 subtitle2 is the smallest subtitle, and is typically reserved for * medium-emphasis text that is shorter in length. * @param body1 body1 is the largest body, and is typically used for long-form writing as it * works well for small text sizes. * @param body2 body2 is the smallest body, and is typically used for long-form writing as it * works well for small text sizes. * @param button button text is a call to action used in different types of buttons (such as * text, outlined and contained buttons) and in tabs, dialogs, and cards. * @param caption caption is one of the smallest font sizes. It is used sparingly to annotate * imagery or to introduce a headline. * @param overline overline is one of the smallest font sizes. It is used sparingly to annotate * imagery or to introduce a headline. */ constructor( defaultFontFamily: FontFamily = FontFamily.Default, h1: TextStyle = TextStyle( fontWeight = FontWeight.Light, fontSize = 96.sp, letterSpacing = (-1.5).sp ), h2: TextStyle = TextStyle( fontWeight = FontWeight.Light, fontSize = 60.sp, letterSpacing = (-0.5).sp ), h3: TextStyle = TextStyle( fontWeight = FontWeight.Normal, fontSize = 48.sp, letterSpacing = 0.sp ), h4: TextStyle = TextStyle( fontWeight = FontWeight.Normal, fontSize = 34.sp, letterSpacing = 0.25.sp ), h5: TextStyle = TextStyle( fontWeight = FontWeight.Normal, fontSize = 24.sp, letterSpacing = 0.sp ), h6: TextStyle = TextStyle( fontWeight = FontWeight.Medium, fontSize = 20.sp, letterSpacing = 0.15.sp ), subtitle1: TextStyle = TextStyle( fontWeight = FontWeight.Normal, fontSize = 16.sp, letterSpacing = 0.15.sp ), subtitle2: TextStyle = TextStyle( fontWeight = FontWeight.Medium, fontSize = 14.sp, letterSpacing = 0.1.sp ), body1: TextStyle = TextStyle( fontWeight = FontWeight.Normal, fontSize = 16.sp, letterSpacing = 0.5.sp ), body2: TextStyle = TextStyle( fontWeight = FontWeight.Normal, fontSize = 14.sp, letterSpacing = 0.25.sp ), button: TextStyle = TextStyle( fontWeight = FontWeight.Medium, fontSize = 14.sp, letterSpacing = 1.25.sp ), caption: TextStyle = TextStyle( fontWeight = FontWeight.Normal, fontSize = 12.sp, letterSpacing = 0.4.sp ), overline: TextStyle = TextStyle( fontWeight = FontWeight.Normal, fontSize = 10.sp, letterSpacing = 1.5.sp ) ) : this( h1 = h1.withDefaultFontFamily(defaultFontFamily), h2 = h2.withDefaultFontFamily(defaultFontFamily), h3 = h3.withDefaultFontFamily(defaultFontFamily), h4 = h4.withDefaultFontFamily(defaultFontFamily), h5 = h5.withDefaultFontFamily(defaultFontFamily), h6 = h6.withDefaultFontFamily(defaultFontFamily), subtitle1 = subtitle1.withDefaultFontFamily(defaultFontFamily), subtitle2 = subtitle2.withDefaultFontFamily(defaultFontFamily), body1 = body1.withDefaultFontFamily(defaultFontFamily), body2 = body2.withDefaultFontFamily(defaultFontFamily), button = button.withDefaultFontFamily(defaultFontFamily), caption = caption.withDefaultFontFamily(defaultFontFamily), overline = overline.withDefaultFontFamily(defaultFontFamily) ) /** * Returns a copy of this Typography, optionally overriding some of the values. */ fun copy( h1: TextStyle = this.h1, h2: TextStyle = this.h2, h3: TextStyle = this.h3, h4: TextStyle = this.h4, h5: TextStyle = this.h5, h6: TextStyle = this.h6, subtitle1: TextStyle = this.subtitle1, subtitle2: TextStyle = this.subtitle2, body1: TextStyle = this.body1, body2: TextStyle = this.body2, button: TextStyle = this.button, caption: TextStyle = this.caption, overline: TextStyle = this.overline ): Typography = Typography( h1 = h1, h2 = h2, h3 = h3, h4 = h4, h5 = h5, h6 = h6, subtitle1 = subtitle1, subtitle2 = subtitle2, body1 = body1, body2 = body2, button = button, caption = caption, overline = overline ) override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is Typography) return false if (h1 != other.h1) return false if (h2 != other.h2) return false if (h3 != other.h3) return false if (h4 != other.h4) return false if (h5 != other.h5) return false if (h6 != other.h6) return false if (subtitle1 != other.subtitle1) return false if (subtitle2 != other.subtitle2) return false if (body1 != other.body1) return false if (body2 != other.body2) return false if (button != other.button) return false if (caption != other.caption) return false if (overline != other.overline) return false return true } override fun hashCode(): Int { var result = h1.hashCode() result = 31 * result + h2.hashCode() result = 31 * result + h3.hashCode() result = 31 * result + h4.hashCode() result = 31 * result + h5.hashCode() result = 31 * result + h6.hashCode() result = 31 * result + subtitle1.hashCode() result = 31 * result + subtitle2.hashCode() result = 31 * result + body1.hashCode() result = 31 * result + body2.hashCode() result = 31 * result + button.hashCode() result = 31 * result + caption.hashCode() result = 31 * result + overline.hashCode() return result } override fun toString(): String { return "Typography(h1=$h1, h2=$h2, h3=$h3, h4=$h4, h5=$h5, h6=$h6, " + "subtitle1=$subtitle1, subtitle2=$subtitle2, body1=$body1, " + "body2=$body2, button=$button, caption=$caption, overline=$overline)" } } /** * @return [this] if there is a [FontFamily] defined, otherwise copies [this] with [default] as * the [FontFamily]. */ private fun TextStyle.withDefaultFontFamily(default: FontFamily): TextStyle { return if (fontFamily != null) this else copy(fontFamily = default) } /** * This CompositionLocal holds on to the current definition of typography for this application as * described by the Material spec. You can read the values in it when creating custom components * that want to use Material types, as well as override the values when you want to re-style a * part of your hierarchy. Material components related to text such as [Button] will use this * CompositionLocal to set values with which to style children text components. * * To access values within this CompositionLocal, use [MaterialTheme.typography]. */ internal val LocalTypography = staticCompositionLocalOf { Typography() }