JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
16.3k stars 1.18k forks source link

"Failed to create Typeface" error when loading a font file #1860

Closed alexjpwalker closed 2 years ago

alexjpwalker commented 2 years ago

Environment

OS: Windows Server 2019 Compose version: 1.1.0-alpha04, using Skiko Runtime 0.6.7

Steps to reproduce

Render the following Composable:

@Composable
fun MainWindow() {
  Window {
    androidx.compose.material.Text(text = "Hello World")
  }
}

Result

The application crashes with the following exception:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: ComposeLayer is disposed
        at androidx.compose.ui.awt.ComposeWindowDelegate.getLayer(ComposeWindowDelegate.desktop.kt:51)
        at androidx.compose.ui.awt.ComposeWindowDelegate.access$getLayer(ComposeWindowDelegate.desktop.kt:40)
        at androidx.compose.ui.awt.ComposeWindowDelegate$_pane$1.addNotify(ComposeWindowDelegate.desktop.kt:77)
        at java.desktop/java.awt.Container.addNotify(Container.java:2804)
        at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4839)
        at java.desktop/java.awt.Container.addNotify(Container.java:2804)
        at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4839)
        at java.desktop/java.awt.Container.addNotify(Container.java:2804)
        at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4839)
        at java.desktop/javax.swing.JRootPane.addNotify(JRootPane.java:729)
        at java.desktop/java.awt.Container.addNotify(Container.java:2804)
        at java.desktop/java.awt.Window.addNotify(Window.java:791)
        at java.desktop/java.awt.Frame.addNotify(Frame.java:495)
        at java.desktop/java.awt.Window.pack(Window.java:826)
        at java.desktop/javax.swing.JOptionPane.initDialog(JOptionPane.java:997)
        at java.desktop/javax.swing.JOptionPane.createDialog(JOptionPane.java:978)
        at java.desktop/javax.swing.JOptionPane.showOptionDialog(JOptionPane.java:877)
        at java.desktop/javax.swing.JOptionPane.showMessageDialog(JOptionPane.java:676)
        at java.desktop/javax.swing.JOptionPane.showMessageDialog(JOptionPane.java:647)
        at androidx.compose.ui.window.DefaultWindowExceptionHandlerFactory$exceptionHandler$1.onException$lambda-0(WindowExceptionHandlerFactory.desktop.kt:18)
        at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:741)
        at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: ComposeLayer is disposed
        at androidx.compose.ui.awt.ComposeWindowDelegate.getLayer(ComposeWindowDelegate.desktop.kt:51)
        at androidx.compose.ui.awt.ComposeWindowDelegate.access$getLayer(ComposeWindowDelegate.desktop.kt:40)
        at androidx.compose.ui.awt.ComposeWindowDelegate$_pane$1.addNotify(ComposeWindowDelegate.desktop.kt:77)
        at java.desktop/java.awt.Container.addNotify(Container.java:2804)
        at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4839)
        at java.desktop/java.awt.Container.addNotify(Container.java:2804)
        at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4839)
        at java.desktop/java.awt.Container.addNotify(Container.java:2804)
        at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4839)
        at java.desktop/javax.swing.JRootPane.addNotify(JRootPane.java:729)
        at java.desktop/java.awt.Container.addNotify(Container.java:2804)
        at java.desktop/java.awt.Window.addNotify(Window.java:791)
        at java.desktop/java.awt.Frame.addNotify(Frame.java:495)
        at java.desktop/java.awt.Window.pack(Window.java:826)
        at java.desktop/javax.swing.JOptionPane.initDialog(JOptionPane.java:997)
        at java.desktop/javax.swing.JOptionPane.createDialog(JOptionPane.java:978)
        at java.desktop/javax.swing.JOptionPane.showOptionDialog(JOptionPane.java:877)
        at java.desktop/javax.swing.JOptionPane.showMessageDialog(JOptionPane.java:676)
        at java.desktop/javax.swing.JOptionPane.showMessageDialog(JOptionPane.java:647)
        at androidx.compose.ui.window.DefaultWindowExceptionHandlerFactory$exceptionHandler$1.onException$lambda-0(WindowExceptionHandlerFactory.desktop.kt:18)
        at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:741)
        at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

Notes

We were able to successfully run our application in an older version of Compose (1.0.0-alpha3, using Skiko Runtime 0.3.9)

haikalpribadi commented 2 years ago

@akurasov this issue is a critical blocker for us to release our software in a week's time. We can't run our platform on Windows at all right now because of this bug. We use material text almost everywhere in the codebase.

igordmn commented 2 years ago

Does it always crash with this reproducer?

import androidx.compose.runtime.Composable
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application

fun main() = application {
    MainWindow()
}
@Composable
fun MainWindow() {
    Window(onCloseRequest = {}) {
        androidx.compose.material.Text(text = "Hello World")
    }
}

I tried it, but it works fine on my PC, Windows 11 Home, 1.1.0-alpha04

igordmn commented 2 years ago

Are there any other exceptions/messages in the log?

akurasov commented 2 years ago

Works perfectly on my Win10 too. Do you have this issue on Win10 or Win 11?

alexjpwalker commented 2 years ago

My apologies - I was trying to put together a minimal reproducible example quickly and didn't investigate thoroughly enough. Indeed, the example I originally posted works fine.

We dug a little deeper and uncovered the underlying cause of the exception we saw in our application:

OS: Windows Server 2019 Compose version: 1.1.0-alpha04, using Skiko Runtime 0.6.7 Minimal reproducible example (requires a font file to be available, either on the classpath or elsewhere on the OS):

import androidx.compose.runtime.Composable
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.platform.Font
import java.nio.file.Path

fun main() = application {
    MainWindow()
}
@Composable
fun MainWindow() {
    Window(onCloseRequest = {}) {
        androidx.compose.material.Text(text = "Hello World", fontFamily = FontFamily(Font(Path.of("resources/fonts/Monaco.ttf").toFile(), FontWeight.Normal, FontStyle.Normal)))
    }
}

Exception stack trace:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: ComposeLayer is disposed
        at androidx.compose.ui.awt.ComposeWindowDelegate.getLayer(ComposeWindowDelegate.desktop.kt:51)
        at androidx.compose.ui.awt.ComposeWindowDelegate.access$getLayer(ComposeWindowDelegate.desktop.kt:40)
        at androidx.compose.ui.awt.ComposeWindowDelegate$_pane$1.addNotify(ComposeWindowDelegate.desktop.kt:77)
        at java.desktop/java.awt.Container.addNotify(Container.java:2804)
        at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4839)
        at java.desktop/java.awt.Container.addNotify(Container.java:2804)
        at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4839)
        at java.desktop/java.awt.Container.addNotify(Container.java:2804)
        at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4839)
        at java.desktop/javax.swing.JRootPane.addNotify(JRootPane.java:729)
        at java.desktop/java.awt.Container.addNotify(Container.java:2804)
        at java.desktop/java.awt.Window.addNotify(Window.java:791)
        at java.desktop/java.awt.Frame.addNotify(Frame.java:495)
        at java.desktop/java.awt.Window.pack(Window.java:826)
        at java.desktop/javax.swing.JOptionPane.initDialog(JOptionPane.java:997)
        at java.desktop/javax.swing.JOptionPane.createDialog(JOptionPane.java:978)
        at java.desktop/javax.swing.JOptionPane.showOptionDialog(JOptionPane.java:877)
        at java.desktop/javax.swing.JOptionPane.showMessageDialog(JOptionPane.java:676)
        at java.desktop/javax.swing.JOptionPane.showMessageDialog(JOptionPane.java:647)
        at androidx.compose.ui.window.DefaultWindowExceptionHandlerFactory$exceptionHandler$1.onException$lambda-0(WindowExceptionHandlerFactory.desktop.kt:18)
        at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:741)
        at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Exception in thread "main" java.lang.IllegalArgumentException: Failed to create Typeface from path="resources\fonts\monaco\Monaco.ttf" index=0
        at org.jetbrains.skia.Typeface_jvmKt.makeFromFile(Typeface.jvm.kt:15)
        at org.jetbrains.skia.Typeface_jvmKt.makeFromFile$default(Typeface.jvm.kt:11)
        at androidx.compose.ui.text.platform.DesktopFont_desktopKt$loadFromTypefacesCache$1.invoke(DesktopFont.desktop.kt:213)
        at androidx.compose.ui.text.platform.DesktopFont_desktopKt$loadFromTypefacesCache$1.invoke(DesktopFont.desktop.kt:210)
        at androidx.compose.ui.text.ExpireAfterAccessCache.get(ExpireAfterAccessCache.desktop.kt:98)
        at androidx.compose.ui.text.platform.DesktopFont_desktopKt.loadFromTypefacesCache(DesktopFont.desktop.kt:210)
        at androidx.compose.ui.text.platform.FontLoader.load(PlatformFont.skiko.kt:168)
        at androidx.compose.ui.text.platform.FontLoader.ensureRegistered$ui_text(PlatformFont.skiko.kt:142)
        at androidx.compose.ui.text.platform.ComputedStyle.toSkTextStyle(SkiaParagraph.skiko.kt:443)
        at androidx.compose.ui.text.platform.ParagraphBuilder.makeSkTextStyle(SkiaParagraph.skiko.kt:763)
        at androidx.compose.ui.text.platform.ParagraphBuilder.textStyleToParagraphStyle(SkiaParagraph.skiko.kt:734)
        at androidx.compose.ui.text.platform.ParagraphBuilder.build(SkiaParagraph.skiko.kt:552)
        at androidx.compose.ui.text.platform.ParagraphLayouter.<init>(ParagraphLayouter.skiko.kt:71)
        at androidx.compose.ui.text.platform.SkiaParagraphIntrinsics.newLayouter(SkiaParagraphIntrinsics.skiko.kt:64)
        at androidx.compose.ui.text.platform.SkiaParagraphIntrinsics.<init>(SkiaParagraphIntrinsics.skiko.kt:56)
        at androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt.ActualParagraphIntrinsics(SkiaParagraphIntrinsics.skiko.kt:37)
        at androidx.compose.ui.text.ParagraphIntrinsicsKt.ParagraphIntrinsics(ParagraphIntrinsics.kt:54)
        at androidx.compose.ui.text.MultiParagraphIntrinsics.<init>(MultiParagraphIntrinsics.kt:80)
        at androidx.compose.foundation.text.TextDelegate.layoutIntrinsics(TextDelegate.kt:127)
        at androidx.compose.foundation.text.TextDelegate.layoutText-K40F9xA(TextDelegate.kt:151)
        at androidx.compose.foundation.text.TextDelegate.layout-NN6Ew-U(TextDelegate.kt:230)
        at androidx.compose.foundation.text.TextController$measurePolicy$1.measure-3p2s80s(CoreText.kt:295)
        at androidx.compose.ui.node.InnerPlaceable.measure-BRTryo0(InnerPlaceable.kt:55)
        at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131)
        at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131)
        at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier.measure-3p2s80s(GraphicsLayerModifier.kt:306)
        at androidx.compose.ui.node.ModifiedLayoutNode.measure-BRTryo0(ModifiedLayoutNode.kt:39)
        at androidx.compose.ui.node.OuterMeasurablePlaceable$remeasure$2.invoke(OuterMeasurablePlaceable.kt:99)
        at androidx.compose.ui.node.OuterMeasurablePlaceable$remeasure$2.invoke(OuterMeasurablePlaceable.kt:98)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:126)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui(OwnerSnapshotObserver.kt:88)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui(OwnerSnapshotObserver.kt:76)
        at androidx.compose.ui.node.OuterMeasurablePlaceable.remeasure-BRTryo0(OuterMeasurablePlaceable.kt:98)
        at androidx.compose.ui.node.OuterMeasurablePlaceable.measure-BRTryo0(OuterMeasurablePlaceable.kt:75)
        at androidx.compose.ui.node.LayoutNode.measure-BRTryo0(LayoutNode.kt:1308)
        at androidx.compose.ui.layout.RootMeasurePolicy.measure-3p2s80s(RootMeasurePolicy.kt:38)
        at androidx.compose.ui.node.InnerPlaceable.measure-BRTryo0(InnerPlaceable.kt:55)
        at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131)
        at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131)
        at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131)
        at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131)
        at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131)
        at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131)
        at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131)
        at androidx.compose.ui.node.OuterMeasurablePlaceable$remeasure$2.invoke(OuterMeasurablePlaceable.kt:99)
        at androidx.compose.ui.node.OuterMeasurablePlaceable$remeasure$2.invoke(OuterMeasurablePlaceable.kt:98)
        at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:1798)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:121)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui(OwnerSnapshotObserver.kt:88)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui(OwnerSnapshotObserver.kt:76)
        at androidx.compose.ui.node.OuterMeasurablePlaceable.remeasure-BRTryo0(OuterMeasurablePlaceable.kt:98)
        at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui(LayoutNode.kt:1317)
        at androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure(MeasureAndLayoutDelegate.kt:168)
        at androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureAndRelayoutIfNeeded(MeasureAndLayoutDelegate.kt:228)
        at androidx.compose.ui.node.MeasureAndLayoutDelegate.access$remeasureAndRelayoutIfNeeded(MeasureAndLayoutDelegate.kt:38)
        at androidx.compose.ui.node.MeasureAndLayoutDelegate.measureAndLayout(MeasureAndLayoutDelegate.kt:201)
        at androidx.compose.ui.platform.SkiaBasedOwner.measureAndLayout(SkiaBasedOwner.skiko.kt:266)
        at androidx.compose.ui.node.Owner$DefaultImpls.measureAndLayout$default(Owner.kt:182)
        at androidx.compose.ui.platform.SkiaBasedOwner.render(SkiaBasedOwner.skiko.kt:234)
        at androidx.compose.ui.ComposeScene.render(ComposeScene.skiko.kt:354)
        at androidx.compose.ui.awt.ComposeLayer$1$onRender$1.invoke(ComposeLayer.desktop.kt:229)
        at androidx.compose.ui.awt.ComposeLayer$1$onRender$1.invoke(ComposeLayer.desktop.kt:227)
        at androidx.compose.ui.awt.ComposeLayer.catchExceptions(ComposeLayer.desktop.kt:89)
        at androidx.compose.ui.awt.ComposeLayer.access$catchExceptions(ComposeLayer.desktop.kt:70)
        at androidx.compose.ui.awt.ComposeLayer$1.onRender(ComposeLayer.desktop.kt:227)
        at org.jetbrains.skiko.SkiaLayer.update$skiko(SkiaLayer.awt.kt:438)
        at org.jetbrains.skiko.redrawer.Direct3DRedrawer.redrawImmediately(Direct3DRedrawer.kt:48)
        at org.jetbrains.skiko.SkiaLayer.paint(SkiaLayer.awt.kt:329)
        at androidx.compose.ui.awt.ComposeLayer$ComponentImpl.paint(ComposeLayer.desktop.kt:149)
        at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:952)
        at java.desktop/javax.swing.JComponent.paint(JComponent.java:1128)
        at java.desktop/javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
        at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:952)
        at java.desktop/javax.swing.JComponent.paint(JComponent.java:1128)
        at androidx.compose.ui.window.Window_desktopKt$Window$11$1.invoke(Window.desktop.kt:381)
        at androidx.compose.ui.window.Window_desktopKt$Window$11$1.invoke(Window.desktop.kt:374)
        at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$3.invoke(AwtWindow.desktop.kt:88)
        at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$3.invoke(AwtWindow.desktop.kt:87)
        at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2$performUpdate$2.invoke(UpdateEffect.desktop.kt:58)
        at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2$performUpdate$2.invoke(UpdateEffect.desktop.kt:54)
        at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:1798)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:121)
        at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2.invoke$performUpdate(UpdateEffect.desktop.kt:54)
        at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2.invoke(UpdateEffect.desktop.kt:62)
        at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2.invoke(UpdateEffect.desktop.kt:47)
        at androidx.compose.runtime.DisposableEffectImpl.onRemembered(Effects.kt:81)
        at androidx.compose.runtime.CompositionImpl$RememberEventDispatcher.dispatchRememberObservers(Composition.kt:801)
        at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:647)
        at androidx.compose.runtime.Recomposer.composeInitial$runtime(Recomposer.kt:763)
        at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:433)
        at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2.invokeSuspend(Application.desktop.kt:220)
        (Coroutine boundary)
        at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2.invokeSuspend(Application.desktop.kt:200)
        at androidx.compose.ui.window.Application_desktopKt$application$1.invokeSuspend(Application.desktop.kt:115)
Caused by: java.lang.IllegalArgumentException: Failed to create Typeface from path="resources\fonts\monaco\Monaco.ttf" index=0
        at org.jetbrains.skia.Typeface_jvmKt.makeFromFile(Typeface.jvm.kt:15)
        at org.jetbrains.skia.Typeface_jvmKt.makeFromFile$default(Typeface.jvm.kt:11)
        at androidx.compose.ui.text.platform.DesktopFont_desktopKt$loadFromTypefacesCache$1.invoke(DesktopFont.desktop.kt:213)
        at androidx.compose.ui.text.platform.DesktopFont_desktopKt$loadFromTypefacesCache$1.invoke(DesktopFont.desktop.kt:210)
        at androidx.compose.ui.text.ExpireAfterAccessCache.get(ExpireAfterAccessCache.desktop.kt:98)
        at androidx.compose.ui.text.platform.DesktopFont_desktopKt.loadFromTypefacesCache(DesktopFont.desktop.kt:210)
        at androidx.compose.ui.text.platform.FontLoader.load(PlatformFont.skiko.kt:168)
        at androidx.compose.ui.text.platform.FontLoader.ensureRegistered$ui_text(PlatformFont.skiko.kt:142)
        at androidx.compose.ui.text.platform.ComputedStyle.toSkTextStyle(SkiaParagraph.skiko.kt:443)
        at androidx.compose.ui.text.platform.ParagraphBuilder.makeSkTextStyle(SkiaParagraph.skiko.kt:763)
        at androidx.compose.ui.text.platform.ParagraphBuilder.textStyleToParagraphStyle(SkiaParagraph.skiko.kt:734)
        at androidx.compose.ui.text.platform.ParagraphBuilder.build(SkiaParagraph.skiko.kt:552)
        at androidx.compose.ui.text.platform.ParagraphLayouter.<init>(ParagraphLayouter.skiko.kt:71)
        at androidx.compose.ui.text.platform.SkiaParagraphIntrinsics.newLayouter(SkiaParagraphIntrinsics.skiko.kt:64)
        at androidx.compose.ui.text.platform.SkiaParagraphIntrinsics.<init>(SkiaParagraphIntrinsics.skiko.kt:56)
        at androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt.ActualParagraphIntrinsics(SkiaParagraphIntrinsics.skiko.kt:37)
        at androidx.compose.ui.text.ParagraphIntrinsicsKt.ParagraphIntrinsics(ParagraphIntrinsics.kt:54)
        at androidx.compose.ui.text.MultiParagraphIntrinsics.<init>(MultiParagraphIntrinsics.kt:80)
        at androidx.compose.foundation.text.TextDelegate.layoutIntrinsics(TextDelegate.kt:127)
        at androidx.compose.foundation.text.TextDelegate.layoutText-K40F9xA(TextDelegate.kt:151)
        at androidx.compose.foundation.text.TextDelegate.layout-NN6Ew-U(TextDelegate.kt:230)
        at androidx.compose.foundation.text.TextController$measurePolicy$1.measure-3p2s80s(CoreText.kt:295)
        at androidx.compose.ui.node.InnerPlaceable.measure-BRTryo0(InnerPlaceable.kt:55)
        at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131)
        at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131)
        at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier.measure-3p2s80s(GraphicsLayerModifier.kt:306)
        at androidx.compose.ui.node.ModifiedLayoutNode.measure-BRTryo0(ModifiedLayoutNode.kt:39)
        at androidx.compose.ui.node.OuterMeasurablePlaceable$remeasure$2.invoke(OuterMeasurablePlaceable.kt:99)
        at androidx.compose.ui.node.OuterMeasurablePlaceable$remeasure$2.invoke(OuterMeasurablePlaceable.kt:98)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:126)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui(OwnerSnapshotObserver.kt:88)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui(OwnerSnapshotObserver.kt:76)
        at androidx.compose.ui.node.OuterMeasurablePlaceable.remeasure-BRTryo0(OuterMeasurablePlaceable.kt:98)
        at androidx.compose.ui.node.OuterMeasurablePlaceable.measure-BRTryo0(OuterMeasurablePlaceable.kt:75)
        at androidx.compose.ui.node.LayoutNode.measure-BRTryo0(LayoutNode.kt:1308)
        at androidx.compose.ui.layout.RootMeasurePolicy.measure-3p2s80s(RootMeasurePolicy.kt:38)
        at androidx.compose.ui.node.InnerPlaceable.measure-BRTryo0(InnerPlaceable.kt:55)
        at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131)
        at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131)
        at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131)
        at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131)
        at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131)
        at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131)
        at androidx.compose.ui.node.DelegatingLayoutNodeWrapper.measure-BRTryo0(DelegatingLayoutNodeWrapper.kt:131)
        at androidx.compose.ui.node.OuterMeasurablePlaceable$remeasure$2.invoke(OuterMeasurablePlaceable.kt:99)
        at androidx.compose.ui.node.OuterMeasurablePlaceable$remeasure$2.invoke(OuterMeasurablePlaceable.kt:98)
        at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:1798)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:121)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui(OwnerSnapshotObserver.kt:88)
        at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui(OwnerSnapshotObserver.kt:76)
        at androidx.compose.ui.node.OuterMeasurablePlaceable.remeasure-BRTryo0(OuterMeasurablePlaceable.kt:98)
        at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui(LayoutNode.kt:1317)
        at androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure(MeasureAndLayoutDelegate.kt:168)
        at androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureAndRelayoutIfNeeded(MeasureAndLayoutDelegate.kt:228)
        at androidx.compose.ui.node.MeasureAndLayoutDelegate.access$remeasureAndRelayoutIfNeeded(MeasureAndLayoutDelegate.kt:38)
        at androidx.compose.ui.node.MeasureAndLayoutDelegate.measureAndLayout(MeasureAndLayoutDelegate.kt:201)
        at androidx.compose.ui.platform.SkiaBasedOwner.measureAndLayout(SkiaBasedOwner.skiko.kt:266)
        at androidx.compose.ui.node.Owner$DefaultImpls.measureAndLayout$default(Owner.kt:182)
        at androidx.compose.ui.platform.SkiaBasedOwner.render(SkiaBasedOwner.skiko.kt:234)
        at androidx.compose.ui.ComposeScene.render(ComposeScene.skiko.kt:354)
        at androidx.compose.ui.awt.ComposeLayer$1$onRender$1.invoke(ComposeLayer.desktop.kt:229)
        at androidx.compose.ui.awt.ComposeLayer$1$onRender$1.invoke(ComposeLayer.desktop.kt:227)
        at androidx.compose.ui.awt.ComposeLayer.catchExceptions(ComposeLayer.desktop.kt:89)
        at androidx.compose.ui.awt.ComposeLayer.access$catchExceptions(ComposeLayer.desktop.kt:70)
        at androidx.compose.ui.awt.ComposeLayer$1.onRender(ComposeLayer.desktop.kt:227)
        at org.jetbrains.skiko.SkiaLayer.update$skiko(SkiaLayer.awt.kt:438)
        at org.jetbrains.skiko.redrawer.Direct3DRedrawer.redrawImmediately(Direct3DRedrawer.kt:48)
        at org.jetbrains.skiko.SkiaLayer.paint(SkiaLayer.awt.kt:329)
        at androidx.compose.ui.awt.ComposeLayer$ComponentImpl.paint(ComposeLayer.desktop.kt:149)
        at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:952)
        at java.desktop/javax.swing.JComponent.paint(JComponent.java:1128)
        at java.desktop/javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
        at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:952)
        at java.desktop/javax.swing.JComponent.paint(JComponent.java:1128)
        at androidx.compose.ui.window.Window_desktopKt$Window$11$1.invoke(Window.desktop.kt:381)
        at androidx.compose.ui.window.Window_desktopKt$Window$11$1.invoke(Window.desktop.kt:374)
        at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$3.invoke(AwtWindow.desktop.kt:88)
        at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$3.invoke(AwtWindow.desktop.kt:87)
        at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2$performUpdate$2.invoke(UpdateEffect.desktop.kt:58)
        at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2$performUpdate$2.invoke(UpdateEffect.desktop.kt:54)
        at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:1798)
        at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:121)
        at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2.invoke$performUpdate(UpdateEffect.desktop.kt:54)
        at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2.invoke(UpdateEffect.desktop.kt:62)
        at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2.invoke(UpdateEffect.desktop.kt:47)
        at androidx.compose.runtime.DisposableEffectImpl.onRemembered(Effects.kt:81)
        at androidx.compose.runtime.CompositionImpl$RememberEventDispatcher.dispatchRememberObservers(Composition.kt:801)
        at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:647)
        at androidx.compose.runtime.Recomposer.composeInitial$runtime(Recomposer.kt:763)
        at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:433)
        at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2.invokeSuspend(Application.desktop.kt:220)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:741)
        at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
        at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
        at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

We tried 3 other TTF fonts and an OTF font - they all fail to load with this error.

To help reproduce the issue, I've uploaded the Monaco font file, but as far as I know, any font file will reproduce the issue: Monaco.ttf.zip

I can test on a Windows 10 machine later today if necessary.

igordmn commented 2 years ago

I have the same exception, if path is incorrect. And don't have an exception, if the path is correct:

import androidx.compose.runtime.Composable
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.platform.Font
import java.nio.file.Path

fun main() = application {
    MainWindow()
}
@Composable
fun MainWindow() {
    Window(onCloseRequest = {}) {
        androidx.compose.material.Text(text = "Hello World", fontFamily = FontFamily(Font(Path.of("D:\\Development\\Work\\compose-jb\\templates\\desktop-template\\src\\main\\resources\\Monaco.ttf").toFile(), FontWeight.Normal, FontStyle.Normal)))
    }
}

(if you need to distribute the font with application as a file, see this, it will help to get the right path)

Or if Monaco.ttf in desktop-template\src\main\resources folder:

import androidx.compose.runtime.Composable
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.platform.Font

fun main() = application {
    MainWindow()
}
@Composable
fun MainWindow() {
    Window(onCloseRequest = {}) {
        androidx.compose.material.Text(text = "Hello World", fontFamily = FontFamily(Font("Monaco.ttf", FontWeight.Normal, FontStyle.Normal)))
    }
}
akurasov commented 2 years ago

Could you clarify, why do you use Compose 1.1.0-alpha04 with skiko 0.6.7?

akurasov commented 2 years ago

According to the exception, SkTypeFace tries to find font in resources\fonts\monaco\Monaco.ttf and couldn't How do you run the application?

alexjpwalker commented 2 years ago

Could you clarify, why do you use Compose 1.1.0-alpha04 with skiko 0.6.7?

We've been meaning to ask about this! We use Bazel as our build system (not Gradle) which requires us to explicitly specify each dependency version.

When picking a Compose version (e.g. 1.1.0-alpha04) we set all of its components to v1.1.0-alpha04 (ui-graphics-desktop, foundation-layout-desktop and so on), but as for the Skiko version, this is not aligned with the Compose version so we are stuck with using guesswork.

How can we find out the correct Skiko version to use with any given Compose version?

igordmn commented 2 years ago

How can we find out the correct Skiko version to use with any given Compose version?

You can look at the dependencies of ui-graphics-desktop:

https://maven.pkg.jetbrains.space/public/p/compose/dev/org/jetbrains/compose/ui/ui-graphics-desktop/1.1.0-alpha04/ui-graphics-desktop-1.1.0-alpha04.pom

(replace by the needed version, and find "skiko" in the file)

alexjpwalker commented 2 years ago

You can look at the dependencies of ui-graphics-desktop

Thank you for the info - this will be very helpful.

According to the exception, SkTypeFace tries to find font in resources\fonts\monaco\Monaco.ttf and couldn't

After further investigation, it does indeed look like this is the underlying cause - there was a bug in our application so the file actually didn't exist at the path we were trying to load from! So I suppose this issue can be closed.

Would it be possible to make the error message clearer when the file couldn't be found?

igordmn commented 2 years ago

So I suppose this issue can be closed

Ok, glad the issue is solved :)

Would it be possible to make the error message clearer when the file couldn't be found?

We use native Skia API (If the file does not exist, or is not a valid font file, returns nullptr), which doesn't tell the reason of the error. We can probably use Java API instead (load file into bytes first), but we need to investigate if that won't cause any unexpected errors and performance issues.

alexjpwalker commented 2 years ago

@igordmn I just checked the ui-graphics-desktop POM file and it gives the version of org.jetbrains.skiko:skiko-awt used to compile ui-graphics-desktop, which is 0.7.5.

The Skiko version I'm talking about is the JVM runtime Skiko library version (https://mvnrepository.com/artifact/org.jetbrains.skiko/skiko-jvm-runtime-macos-x64, https://mvnrepository.com/artifact/org.jetbrains.skiko/skiko-jvm-runtime-linux-x64 or https://mvnrepository.com/artifact/org.jetbrains.skiko/skiko-jvm-runtime-windows-x64 depending on OS)

There doesn't appear to be a runtime version 0.7.5. How can we find out which Skiko JVM runtime version we need to use?

igordmn commented 2 years ago

The runtime version should be the same. The right link now is https://mvnrepository.com/artifact/org.jetbrains.skiko/skiko-awt-runtime-macos-x64

haikalpribadi commented 2 years ago

Well, first of all, we apologise for the panic on the bug above. We'll be more careful next time in parsing our stack trace logs!

Second of all, these two links are extremely useful for us to know what is the accurate Skiko version to use with Compose. Perhaps you'd want to put this somewhere easy to find in the your docs?

We didn't know where and which POM was the source of truth, and we didn't even know the artifact had changed from skiko-jvm-runtime-<os> to skiko-awt-runtime-<os>! :)

igordmn commented 2 years ago

I have added info about it into CLI script. It is hidden, but there no any other place for it now. The majority uses Gradle, and it is hard to justify a new tutorial/chapter just for that.

okushnikov commented 2 months ago

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.