🚀 Variable fonts

* Replaced all fonts with variable versions
* Allows more weight/italic options (and more)
* Increased overall app size on release build by ~8mb (sadly, not much I can do here..)
This commit is contained in:
Acclorite 2025-01-19 16:57:59 +02:00
parent d9f8448de8
commit 5cf333d3d2
107 changed files with 117 additions and 118 deletions

View file

@ -34,7 +34,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import ua.acclorite.book_story.R import ua.acclorite.book_story.R
@ -177,7 +176,6 @@ private fun SegmentedButton(
Text( Text(
text = button.title, text = button.title,
style = button.textStyle, style = button.textStyle,
fontWeight = FontWeight.Medium,
color = if (button.selected) colors.activeContentColor color = if (button.selected) colors.activeContentColor
else colors.inactiveContentColor else colors.inactiveContentColor
) )

View file

@ -1,14 +1,18 @@
package ua.acclorite.book_story.presentation.core.constants package ua.acclorite.book_story.presentation.core.constants
import androidx.annotation.FontRes
import androidx.compose.ui.text.ExperimentalTextApi
import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontVariation
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import ua.acclorite.book_story.R import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.reader.FontWithName import ua.acclorite.book_story.domain.reader.FontWithName
import ua.acclorite.book_story.domain.ui.UIText import ua.acclorite.book_story.domain.ui.UIText
fun Constants.provideFonts(withRandom: Boolean): List<FontWithName> { @OptIn(ExperimentalTextApi::class)
fun Constants.provideFonts(): List<FontWithName> {
return mutableListOf( return mutableListOf(
FontWithName( FontWithName(
"default", "default",
@ -18,175 +22,163 @@ fun Constants.provideFonts(withRandom: Boolean): List<FontWithName> {
FontWithName( FontWithName(
"raleway", "raleway",
UIText.StringValue("Raleway"), UIText.StringValue("Raleway"),
FontFamily( provideVariableFontFamily(
Font(R.font.raleway_regular), normalResId = R.font.raleway_variable,
Font(R.font.raleway_regular_italic, style = FontStyle.Italic), italicResId = R.font.raleway_variable_italic
Font(R.font.raleway_medium, weight = FontWeight.Medium),
Font(R.font.raleway_semibold, weight = FontWeight.SemiBold),
Font(R.font.raleway_bold, weight = FontWeight.Bold),
) )
), ),
FontWithName( FontWithName(
"open_sans", "open_sans",
UIText.StringValue("Open Sans"), UIText.StringValue("Open Sans"),
FontFamily( provideVariableFontFamily(
Font(R.font.opensans_regular), normalResId = R.font.opensans_variable,
Font(R.font.opensans_regular_italic, style = FontStyle.Italic), italicResId = R.font.opensans_variable_italic
Font(R.font.opensans_medium, weight = FontWeight.Medium),
Font(R.font.opensans_semibold, weight = FontWeight.SemiBold),
Font(R.font.opensans_bold, weight = FontWeight.Bold),
) )
), ),
FontWithName( FontWithName(
"mulish", "mulish",
UIText.StringValue("Mulish"), UIText.StringValue("Mulish"),
FontFamily( provideVariableFontFamily(
Font(R.font.mulish_regular), normalResId = R.font.mulish_variable,
Font(R.font.mulish_regular_italic, style = FontStyle.Italic), italicResId = R.font.mulish_variable_italic
Font(R.font.mulish_medium, weight = FontWeight.Medium),
Font(R.font.mulish_semibold, weight = FontWeight.SemiBold),
Font(R.font.mulish_bold, weight = FontWeight.Bold),
) )
), ),
FontWithName( FontWithName(
"arimo", "arimo",
UIText.StringValue("Arimo"), UIText.StringValue("Arimo"),
FontFamily( provideVariableFontFamily(
Font(R.font.arimo_regular), normalResId = R.font.arimo_variable,
Font(R.font.arimo_regular_italic, style = FontStyle.Italic), italicResId = R.font.arimo_variable_italic
Font(R.font.arimo_medium, weight = FontWeight.Medium),
Font(R.font.arimo_semibold, weight = FontWeight.SemiBold),
Font(R.font.arimo_bold, weight = FontWeight.Bold),
) )
), ),
FontWithName( FontWithName(
"garamond", "garamond",
UIText.StringValue("Garamond"), UIText.StringValue("Garamond"),
FontFamily( provideVariableFontFamily(
Font(R.font.garamond_regular), normalResId = R.font.garamond_variable,
Font(R.font.garamond_regular_italic, style = FontStyle.Italic), italicResId = R.font.garamond_variable_italic
Font(R.font.garamond_medium, weight = FontWeight.Medium),
Font(R.font.garamond_semibold, weight = FontWeight.SemiBold),
Font(R.font.garamond_bold, weight = FontWeight.Bold),
) )
), ),
FontWithName( FontWithName(
"roboto_serif", "roboto_serif",
UIText.StringValue("Roboto Serif"), UIText.StringValue("Roboto Serif"),
FontFamily( provideVariableFontFamily(
Font(R.font.robotoserif_regular), normalResId = R.font.robotoserif_variable,
Font(R.font.robotoserif_regular_italic, style = FontStyle.Italic), italicResId = R.font.robotoserif_variable_italic
Font(R.font.robotoserif_medium, weight = FontWeight.Medium),
Font(R.font.robotoserif_semibold, weight = FontWeight.SemiBold),
Font(R.font.robotoserif_bold, weight = FontWeight.Bold),
) )
), ),
FontWithName( FontWithName(
"noto_serif", "noto_serif",
UIText.StringValue("Noto Serif"), UIText.StringValue("Noto Serif"),
FontFamily( provideVariableFontFamily(
Font(R.font.notoserif_regular), normalResId = R.font.notoserif_variable,
Font(R.font.notoserif_regular_italic, style = FontStyle.Italic), italicResId = R.font.notoserif_variable_italic
Font(R.font.notoserif_medium, weight = FontWeight.Medium),
Font(R.font.notoserif_semibold, weight = FontWeight.SemiBold),
Font(R.font.notoserif_bold, weight = FontWeight.Bold),
) )
), ),
FontWithName( FontWithName(
"noto_sans", "noto_sans",
UIText.StringValue("Noto Sans"), UIText.StringValue("Noto Sans"),
FontFamily( provideVariableFontFamily(
Font(R.font.notosans_regular), normalResId = R.font.notosans_variable,
Font(R.font.notosans_regular_italic, style = FontStyle.Italic), italicResId = R.font.notosans_variable_italic
Font(R.font.notosans_medium, weight = FontWeight.Medium),
Font(R.font.notosans_semibold, weight = FontWeight.SemiBold),
Font(R.font.notosans_bold, weight = FontWeight.Bold),
) )
), ),
FontWithName( FontWithName(
"roboto", "roboto",
UIText.StringValue("Roboto"), UIText.StringValue("Roboto"),
FontFamily( provideVariableFontFamily(
Font(R.font.roboto_regular), normalResId = R.font.roboto_variable_with_italic,
Font(R.font.roboto_regular_italic, style = FontStyle.Italic), italicResId = R.font.roboto_variable_with_italic
Font(R.font.roboto_medium, weight = FontWeight.Medium),
Font(R.font.roboto_bold, weight = FontWeight.Bold),
) )
), ),
FontWithName( FontWithName(
"jost", "jost",
UIText.StringValue("Jost"), UIText.StringValue("Jost"),
FontFamily( provideVariableFontFamily(
Font(R.font.jost_regular), normalResId = R.font.jost_variable,
Font(R.font.jost_regular_italic, style = FontStyle.Italic), italicResId = R.font.jost_variable_italic
Font(R.font.jost_medium, weight = FontWeight.Medium),
Font(R.font.jost_semibold, weight = FontWeight.SemiBold),
Font(R.font.jost_bold, weight = FontWeight.Bold),
) )
), ),
FontWithName( FontWithName(
"merriweather", "merriweather",
UIText.StringValue("Merriweather"), UIText.StringValue("Merriweather"),
FontFamily( provideVariableFontFamily(
Font(R.font.merriweather_regular), normalResId = R.font.merriweather_variable,
Font(R.font.merriweather_regular_italic, style = FontStyle.Italic), italicResId = R.font.merriweather_variable_italic
Font(R.font.merriweather_medium, weight = FontWeight.Medium),
Font(R.font.merriweather_bold, weight = FontWeight.Bold),
) )
), ),
FontWithName( FontWithName(
"montserrat", "montserrat",
UIText.StringValue("Montserrat"), UIText.StringValue("Montserrat"),
FontFamily( provideVariableFontFamily(
Font(R.font.montserrat_regular), normalResId = R.font.montserrat_variable,
Font(R.font.montserrat_regular_italic, style = FontStyle.Italic), italicResId = R.font.montserrat_variable_italic
Font(R.font.montserrat_medium, weight = FontWeight.Medium),
Font(R.font.montserrat_semibold, weight = FontWeight.SemiBold),
Font(R.font.montserrat_bold, weight = FontWeight.Bold),
) )
), ),
FontWithName( FontWithName(
"nunito", "nunito",
UIText.StringValue("Nunito"), UIText.StringValue("Nunito"),
FontFamily( provideVariableFontFamily(
Font(R.font.nunito_regular), normalResId = R.font.nunito_variable,
Font(R.font.nunito_regular_italic, style = FontStyle.Italic), italicResId = R.font.nunito_variable_italic
Font(R.font.nunito_medium, weight = FontWeight.Medium),
Font(R.font.nunito_semibold, weight = FontWeight.SemiBold),
Font(R.font.nunito_bold, weight = FontWeight.Bold),
) )
), ),
FontWithName( FontWithName(
"roboto_slab", "roboto_slab",
UIText.StringValue("Roboto Slab"), UIText.StringValue("Roboto Slab"),
FontFamily( provideVariableFontFamily(
Font(R.font.robotoslab_regular), normalResId = R.font.robotoslab_variable_with_italic,
Font(R.font.robotoslab_medium, weight = FontWeight.Medium), italicResId = R.font.robotoslab_variable_with_italic
Font(R.font.robotoslab_semibold, weight = FontWeight.SemiBold),
Font(R.font.robotoslab_bold, weight = FontWeight.Bold),
) )
), ),
FontWithName( FontWithName(
"lora", "lora",
UIText.StringValue("Lora"), UIText.StringValue("Lora"),
FontFamily( provideVariableFontFamily(
Font(R.font.lora_regular), normalResId = R.font.lora_variable,
Font(R.font.lora_regular_italic, style = FontStyle.Italic), italicResId = R.font.lora_variable_italic
Font(R.font.lora_medium, weight = FontWeight.Medium),
Font(R.font.lora_semibold, weight = FontWeight.SemiBold),
Font(R.font.lora_bold, weight = FontWeight.Bold),
) )
) )
).apply {
if (withRandom) {
add(
1,
FontWithName(
"random",
UIText.StringResource(R.string.random_string),
provideFonts(withRandom = false).random().font
) )
) }
}
} @OptIn(ExperimentalTextApi::class)
private fun provideVariableFontFamily(
@FontRes normalResId: Int,
@FontRes italicResId: Int
): FontFamily {
fun provideVariableFont(weight: FontWeight): Array<Font> {
return arrayOf(
Font(
resId = normalResId,
weight = weight,
style = FontStyle.Normal,
variationSettings = FontVariation.Settings(
weight = weight,
style = FontStyle.Normal
)
),
Font(
resId = italicResId,
weight = weight,
style = FontStyle.Italic,
variationSettings = FontVariation.Settings(
weight = weight,
style = FontStyle.Italic
)
)
)
}
return FontFamily(
*provideVariableFont(weight = FontWeight.W100),
*provideVariableFont(weight = FontWeight.W200),
*provideVariableFont(weight = FontWeight.W300),
*provideVariableFont(weight = FontWeight.W400),
*provideVariableFont(weight = FontWeight.W500),
*provideVariableFont(weight = FontWeight.W600),
*provideVariableFont(weight = FontWeight.W700),
*provideVariableFont(weight = FontWeight.W800),
*provideVariableFont(weight = FontWeight.W900)
)
} }

View file

@ -4,7 +4,6 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import ua.acclorite.book_story.R import ua.acclorite.book_story.R
@ -21,29 +20,32 @@ fun FontFamilyOption() {
val state = mainModel.state.collectAsStateWithLifecycle() val state = mainModel.state.collectAsStateWithLifecycle()
val fontFamily = remember(state.value.fontFamily) { val fontFamily = remember(state.value.fontFamily) {
Constants.provideFonts(withRandom = true).find { Constants.provideFonts().run {
find {
it.id == state.value.fontFamily it.id == state.value.fontFamily
} ?: Constants.provideFonts(withRandom = false)[0] } ?: get(0)
}
} }
ChipsWithTitle( ChipsWithTitle(
title = stringResource(id = R.string.font_family_option), title = stringResource(id = R.string.font_family_option),
chips = Constants.provideFonts(withRandom = true) chips = Constants.provideFonts()
.map { .map {
ButtonItem( ButtonItem(
id = it.id, id = it.id,
title = it.fontName.asString(), title = it.fontName.asString(),
textStyle = MaterialTheme.typography.labelLarge.copy( textStyle = MaterialTheme.typography.labelLarge.copy(
fontFamily = when (it.id) { fontFamily = it.font
"random" -> FontFamily.Default
else -> it.font
}
), ),
selected = it.id == fontFamily.id selected = it.id == fontFamily.id
) )
}, },
onClick = { onClick = {
mainModel.onEvent(MainEvent.OnChangeFontFamily(it.id)) mainModel.onEvent(
MainEvent.OnChangeFontFamily(
it.id
)
)
} }
) )
} }

View file

@ -21,9 +21,11 @@ fun FontStyleOption() {
val state = mainModel.state.collectAsStateWithLifecycle() val state = mainModel.state.collectAsStateWithLifecycle()
val fontFamily = remember(state.value.fontFamily) { val fontFamily = remember(state.value.fontFamily) {
Constants.provideFonts(withRandom = false).find { Constants.provideFonts().run {
find {
it.id == state.value.fontFamily it.id == state.value.fontFamily
} ?: Constants.provideFonts(withRandom = false)[0] } ?: get(0)
}
} }
SegmentedButtonWithTitle( SegmentedButtonWithTitle(

View file

@ -101,9 +101,11 @@ class MainModel @Inject constructor(
value = event.value, value = event.value,
updateState = { updateState = {
it.copy( it.copy(
fontFamily = Constants.provideFonts(withRandom = true) fontFamily = Constants.provideFonts().run {
.find { font -> font.id == event.value }?.id find { font ->
?: Constants.provideFonts(withRandom = false)[0].id font.id == event.value
}?.id ?: get(0).id
}
) )
} }
) )

View file

@ -63,6 +63,7 @@ data class MainState(
// Reader Settings // Reader Settings
val fontFamily: String = provideDefaultValue { Constants.provideFonts(withRandom = false)[0].id }, val fontFamily: String = provideDefaultValue { Constants.provideFonts(withRandom = false)[0].id },
val fontFamily: String = provideDefaultValue { Constants.provideFonts()[0].id },
val isItalic: Boolean = provideDefaultValue { false }, val isItalic: Boolean = provideDefaultValue { false },
val fontSize: Int = provideDefaultValue { 16 }, val fontSize: Int = provideDefaultValue { 16 },
val lineHeight: Int = provideDefaultValue { 4 }, val lineHeight: Int = provideDefaultValue { 4 },

View file

@ -110,9 +110,11 @@ data class ReaderScreen(val bookId: Int) : Screen, Parcelable {
} }
val fontFamily = remember(mainState.value.fontFamily) { val fontFamily = remember(mainState.value.fontFamily) {
Constants.provideFonts(withRandom = true).find { Constants.provideFonts().run {
find {
it.id == mainState.value.fontFamily it.id == mainState.value.fontFamily
} ?: Constants.provideFonts(withRandom = false)[0] } ?: get(0)
}
} }
val backgroundColor = animateColorAsState( val backgroundColor = animateColorAsState(
targetValue = settingsState.value.selectedColorPreset.backgroundColor targetValue = settingsState.value.selectedColorPreset.backgroundColor

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more