Skip to content

Compose font integration for multiple languages #416

@sebastian-gallese-speak

Description

Problem

  • On iOS, we intercept Rive font loads and return system-styled fonts from our design system, so Rive text matches app typography.
  • On Android (Compose), there’s no easy hook to resolve Rive text via Compose Typography/TextStyle or FontFamily. This makes it hard to render multiple locales/scripts in Rive using our existing Compose font syles.

Why this matters

  • Typography parity: ideally Rive text should match our app UI text.
  • Platform parity: this mirrors iOS’s seamless asset-loader mapping to system-styled fonts, especially for loading fonts from various languages.

Question

  • Is there an existing hook we can use today to take our Compose Font style and support all locales?
  • If not, could rive-android expose a solution for this?
    • So when Rive requests a font (family/weight/italic) that supports all device languages, we can return:
      • A Compose FontFamily/TextStyle (with weight/style mapping) or
      • A Typeface
    • Alternatively, provide an API to set a default Compose TextStyle/FontFamily for all Rive text.

Details

On iOS, Rive lets us intercept font loads and return a system-styled font from our design system, so Rive text automatically matches app typography.

iOS example (asset loader intercepting RiveFontAsset → UIFont built from our design system “body” font):

riveViewModel = RiveRuntime.RiveViewModel(
    fileName: fileName,
    ...
) { asset, _, factory in
    switch asset {
    case let asset as RiveFontAsset:
        if let font = factory.decodeFont(.appFont(.body)) {
            asset.font(font)
            return true
        }
        return false
    default:
        return false
    }
}

Our iOS design-system helper that bridges to system fonts:

public struct CustomTextStyle {
    let size: CGFloat
    let weight: Font.Weight
    public static let body = Self.init(size: 16, weight: .medium)
}

public extension UIFont {
    static func appFont(_ style: CustomTextStyle) -> UIFont {
        let weight: UIFont.Weight = switch style.weight {
        case .medium: .medium
        case .semibold: .semibold
        case .bold: .bold
        default: .regular
        }
        return systemFont(ofSize: style.size, weight: weight)
    }
}

On Android (Compose), we render via RiveAnimationView, but we don’t see a hook to resolve Rive text through Compose Typography/TextStyle. We’d like a similar mapping to our Compose styles.

Our Android text styles (simplified):

object CustomTextStyle {
    val Body1 = TextStyle(
        fontFamily = FontFamily.SansSerif,
        fontWeight = FontWeight.Medium,
        fontSize = 16.sp,
        lineHeight = 20.sp,
        letterSpacing = 0.32.sp
    )
    // ...other styles
}

We are interested in something like this that supports fonts for all languages (doesn’t need to match this exact syntax, just an example of how it could look):

RiveAnimationView.Builder(context)
    .setFontResolver { request ->
        // request.family?: String?, request.weight: Int, request.italic: Boolean
        // Return Typeface or a Compose FontFamily/TextStyle mapping.
        composeTypefaceFrom(CustomTextStyle.Body1) // or MaterialTheme.typography.bodyMedium
    }
    .build()

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions