[Web] Error: Couldn't create typeface for
Hi,
I am currently upgrading from expo 51 to 52 and noticed that after the upgrade no fonts are rendered in my skia canvas due to an error:
Font.js:67 Uncaught (in promise) Error: Couldn't create typeface for Inter-Regular
at Font.js:67:17
at async Promise.all (index 0)
I am adding inter fonts like this in all skia components and it used to work just fine
const fonts = useFonts({
'Inter-Regular': [require('@tamagui/font-inter/otf/Inter-Regular.otf')],
});
After then I'm using them in the styles for paragraph
Skia.ParagraphBuilder.Make({}, fonts).pushStyle({
fontFamilies: ['Inter-Regular'],
}).addText(text).build()
It works fine in iOS (even after upgrade to expo 52) but not in Web anymore.
Tested with react-native-skia 1.5.0 and 1.6.0
can you share a reproduction?
@wcandillon Sure, I added a skia paragraph using inter font to a fresh expo 52 create-expo-app. https://github.com/tlow92/react-native-skia-typeface-issue
Let me know if you need more
I found something, but I am not sure about the root cause and the consequences (I'm sure resolveAsset is used for a purpose), maybe you can help understanding this.
For some reason
Platform.resolveAsset(typefaceToLoad) is undefined on web
when removing the resolveAsset call and just passing typefaceToLoad typefaces are created and displayed correctly.
https://github.com/Shopify/react-native-skia/blob/42f81f05a66c6e083eb232ad9cc55b8e72405413/packages/skia/src/skia/core/Font.ts#L106
Patch used:
diff --git a/node_modules/@shopify/react-native-skia/lib/module/skia/core/Font.js b/node_modules/@shopify/react-native-skia/lib/module/skia/core/Font.js
index 25896be..58085c1 100644
--- a/node_modules/@shopify/react-native-skia/lib/module/skia/core/Font.js
+++ b/node_modules/@shopify/react-native-skia/lib/module/skia/core/Font.js
@@ -61,7 +61,7 @@ export const listFontFamilies = (fontMgr = Skia.FontMgr.System()) => new Array(f
const loadTypefaces = typefacesToLoad => {
const promises = Object.keys(typefacesToLoad).flatMap(familyName => {
return typefacesToLoad[familyName].map(typefaceToLoad => {
- return Skia.Data.fromURI(Platform.resolveAsset(typefaceToLoad)).then(data => {
+ return Skia.Data.fromURI(typefaceToLoad).then(data => {
const tf = Skia.Typeface.MakeFreeTypeFaceFromData(data);
if (tf === null) {
throw new Error(`Couldn't create typeface for ${familyName}`);
same for me (in expo web)
as a workaround for developing I am using
Noto: [{ default: require("../assets/fonts/NotoColorEmoji.ttf") }],
instead of
Noto: [require("../assets/fonts/NotoColorEmoji.ttf")],
typescript is complaining and it is definitely not a right solution, but I can proceed with my explorations
same for me (in expo web)
as a workaround for developing I am using
Noto: [{ default: require("../assets/fonts/NotoColorEmoji.ttf") }],instead ofNoto: [require("../assets/fonts/NotoColorEmoji.ttf")],typescript is complaining and it is definitely not a right solution, but I can proceed with my explorations
I'm having the same issues as well on skia 1.11.7
your workaround works for me
same for me (in expo web)
as a workaround for developing I am using
Noto: [{ default: require("../assets/fonts/NotoColorEmoji.ttf") }],instead ofNoto: [require("../assets/fonts/NotoColorEmoji.ttf")],typescript is complaining and it is definitely not a right solution, but I can proceed with my explorations
This works for me in web, but on iOS I'm getting
ERROR Warning: Error: Value is a number, expected a String
with this workaround.
This works to me
const customFontMgr = useFonts({
OrbitronBold: [
Platform.OS === 'web'
? { default: require('./YourFont.ttf') }
: require('./YourFont.ttf') ,
],
});