
Article • Reading 1 mins
Article • Reading 3 mins
A font is a particular size, weight and style of a typeface. Each font is a matched set of type, with a piece (a “sort”) for each glyph.
Contents

This article is the first part of the series that will introduce the topic of fonts to you.
Do you remember Fun with Flags in The Big Bang Theory? Let’s have some Fun with Fonts.

Jim Parsons and Will Wheaton in The Big Bang Theory || www.filmweb.pl
First of all, to avoid confusion, let’s define what is what. According to wiki:
A single font family can exponentially have many fonts and scales by adding more weights or slopes. This approach has a few flaws in development. When adding a typeface to our project, we need to include about 12 fonts, which also increases the app size.
private val fonts = listOf(
Font(R.font.roboto_thin, weight = FontWeight.Thin),
Font(R.font.roboto_thin_italic, weight = FontWeight.Thin, style = FontStyle.Italic),
Font(R.font.roboto_light, weight = FontWeight.Light),
Font(R.font.roboto_light_italic, weight = FontWeight.Light, style = FontStyle.Italic),
Font(R.font.roboto_regular),
Font(R.font.roboto_italic, style = FontStyle.Italic),
Font(R.font.roboto_medium, weight = FontWeight.Medium),
Font(R.font.roboto_medium_italic, weight = FontWeight.Medium, style = FontStyle.Italic),
Font(R.font.roboto_bold, weight = FontWeight.Bold),
Font(R.font.roboto_bold_italic, weight = FontWeight.Bold, style = FontStyle.Italic),
Font(R.font.roboto_black, weight = FontWeight.Black),
Font(R.font.roboto_black_italic, weight = FontWeight.Black, style = FontStyle.Italic),
)We need to assign each font the proper weight and style. Let’s render it.
@Composable
fun AllFonts() = Column {
fonts.forEach { font ->
Text(
text = demoText,
fontFamily = FontFamily(font),
)
}
}
We have all fonts required for possible design, but this is not the way how you use Font Family is supposed to be used, let’s achieve this again.
private val robotoFontFamily = FontFamily(fonts)
@Composable
fun FontFamily() = Column {
val weights = listOf(
FontWeight.Thin,
FontWeight.Light,
FontWeight.Normal,
FontWeight.Medium,
FontWeight.Bold,
FontWeight.Black,
)
weights.forEach { weight ->
Text(
text = demoText,
fontFamily = robotoFontFamily,
fontWeight = weight,
)
Text(
text = demoText,
fontFamily = robotoFontFamily,
fontWeight = weight,
fontStyle = FontStyle.Italic,
)
}
}
To my eyes, it looks the same. Now we might start to think if we really need italic fonts. Let’s check what would happen if we use an italic style without having italic font.
@Composable
fun NotEverythingItalicIsItalic() = Column {
val fontsNormal = fonts.filter { it.style == FontStyle.Normal }
val fontsItalic = fonts.filter { it.style == FontStyle.Italic }
fontsNormal.forEach { font ->
Text(
text = demoText,
fontFamily = FontFamily(font),
fontStyle = FontStyle.Italic,
)
}
fontsItalic.forEach { font ->
Text(
text = demoText,
fontFamily = FontFamily(font),
)
}
}
Again we see that text is actually slanted. So, it worked, italic fonts are not needed? Well, kind of, it depends on how lenient your designer is. If we look closely, we will see that the angle is different in the font slanted by Android Framework (HarfBuzz library most likely) than the original font.
@Composable
fun NotEverythingBoldIsBold() = Column {
val regularFont = fonts.first { it.weight == FontWeight.Normal }
val boldFont = fonts.first { it.weight == FontWeight.Bold }
Text(
text = "$demoText regular",
fontFamily = FontFamily(regularFont),
)
Text(
text = "$demoText regular bolded",
fontFamily = FontFamily(regularFont),
fontWeight = FontWeight.Bold,
)
Text(
text = "$demoText bold",
fontFamily = FontFamily(boldFont),
)
}
The same thing happened for bolding text. We can see that framework tried to make the font bolded, but it is not exactly what we would get using the correct font.
That was easy. Now you know how to correctly define fonts and use them in the app. Next, we will check how we can make this process less cumbersome.
Do you want to know more? Check the second part of the article.
You may also like