Skip to content

Intro SkikoFont abstraction for async font loading on all Skiko platforms - #2787

Open
adamglin0 (adamglin0) wants to merge 4 commits into
JetBrains:jb-mainfrom
adamglin0:support-skiko-async-font-load
Open

adamglin0 (adamglin0) wants to merge 4 commits into
JetBrains:jb-mainfrom
adamglin0:support-skiko-async-font-load

Conversation

@adamglin0

@adamglin0 adamglin0 (adamglin0) commented Feb 24, 2026 •

Copy link
Copy Markdown

Previously, Skiko-based platforms lacked a public API for async font loading. While PlatformFont serves as the low-level font representation, it is not designed for extensibility by developers. By introducing SkikoFont, we provide a mechanism similar to AndroidFont on Android, allowing developers to:

  • Load fonts asynchronously from remote sources (e.g., CDN, network)
  • Implement custom font loading strategies
  • Display fallback fonts during loading, with automatic text reflow when fonts arrive

Fixes CMP-8231 Async font loading support for iOS targets

Testing

This should be tested by QA, but because the SkiaParagraphIntrinsics-related items lack a listener for TypefaceResult.Async, you need to resize the window so that the text can reflow and display correctly.
(If #2789 is merged, it will automatically display after loading, with no further action required.)

Release Notes

Features - Multiple Platforms

  • Added a new SkikoFont abstract class to enable developers to implement asynchronously loaded fonts.

@adamglin0
adamglin0 (adamglin0) marked this pull request as ready for review February 24, 2026 14:06
@adamglin0

adamglin0 (adamglin0) commented Feb 24, 2026 •

Copy link
Copy Markdown
Author

Ivan Matkov (@MatkovIvan) Igor Demin (@igordmn) Oleksandr Karpovich (@eymar) Could you assign reviewers for thsi PR, thanks.

Additionally, SkiaParagraphIntrinsics currently lacks support for tracking asynchronous font resolution, so it can’t update once the fonts are ready. I plan to address this in a separate PR. We can now force a recompose by resizing the window, either programmatically or manually.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please update this PR as well and fix these comments?
Feel free to ping me when you are done, I'll continue to review

@adamglin0

Copy link
Copy Markdown
Author

Vladimir Mazunin (@mazunin-v-jb) Thanks, I still need some time to review it. I’ll ping you when I’m done.

Add an AndroidFont-shaped public SkikoFont API in ui-skiko and wire it
through SkiaFontLoader and FontCache.

Cache unvaried typefaces under baseCacheKey = identity only, then apply
weight/style matching metadata and variationSettings under full cacheKey
aliases. TypefaceLoader must select sources from identity, not from weight,
style, or variation settings.
Cover base/full cache keys, two-level unvaried sharing across weight and
variation settings, null-load retry behavior, and FontCache get/put/register.
Single commonMain sample that downloads a remote TTF via Ktor and shows
async FontFamily resolution. Wire platform Ktor engines for desktop,
Darwin, and web.
@adamglin0

adamglin0 (adamglin0) commented Jul 28, 2026 •

Copy link
Copy Markdown
Author

Vladimir Mazunin (@mazunin-v-jb) Updated — removed the Android context docs, rebased onto jb-main / ui-skiko.
Caching is two-level because Skia varies typefaces by clone:

baseCacheKey = identity → unvaried source (load once)

cacheKey = identity|weight|style|variation → cloned face registered in FontCollection
Loaders return unvaried faces; framework applies variation. PTAL when you can.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants