Skip to content

Commit 5665baa

Browse files
authored
fix(🐛): Fix parameter handling in SkTypefaceFontProvider.matchFamilyStyle() (#2518)
1 parent cda67f3 commit 5665baa

File tree

4 files changed

+68
-8
lines changed

4 files changed

+68
-8
lines changed

docs/docs/text/text.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ export const HelloWorld = () => {
4343

4444
Once the fonts are loaded, we provide a `matchFont` function that given a font style will return a font object that you can use directly.
4545

46+
:::info
47+
48+
For font matching we recommend using the [Paragraph API](/docs/text/paragraph/) instead.
49+
The APIs belows were made available before the Paragraph API was released.
50+
51+
:::
52+
4653
```tsx twoslash
4754
import {useFonts, Text, matchFont} from "@shopify/react-native-skia";
4855

package/cpp/api/JsiSkTypefaceFontProvider.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,20 @@ class JsiSkTypefaceFontProvider
4545
}
4646

4747
JSI_HOST_FUNCTION(matchFamilyStyle) {
48-
auto name = arguments[0].asString(runtime).utf8(runtime);
49-
auto fontStyle = JsiSkFontStyle::fromValue(runtime, arguments[1]);
50-
sk_sp<SkFontStyleSet> set(getObject()->onMatchFamily(name.c_str()));
51-
sk_sp<SkTypeface> typeface(set->matchStyle(*fontStyle));
48+
auto name = count > 0 ? arguments[0].asString(runtime).utf8(runtime) : "";
49+
auto fontStyle =
50+
count > 1 ? JsiSkFontStyle::fromValue(runtime, arguments[1]) : nullptr;
51+
if (name == "" || fontStyle == nullptr) {
52+
throw std::runtime_error("matchFamilyStyle requires a name and a style");
53+
}
54+
auto set = getObject()->onMatchFamily(name.c_str());
55+
if (!set) {
56+
throw std::runtime_error("Could not find font family " + name);
57+
}
58+
auto typeface = set->matchStyle(*fontStyle);
59+
if (!typeface) {
60+
throw std::runtime_error("Could not find font style for " + name);
61+
}
5262
return jsi::Object::createFromHostObject(
5363
runtime, std::make_shared<JsiSkTypeface>(getContext(), typeface));
5464
}

package/src/renderer/__tests__/e2e/FontMgr.spec.tsx

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,50 @@ describe("FontMgr", () => {
101101
expect(width).not.toEqual([0, 0]);
102102
}
103103
});
104-
// Add test
105-
// * Passing |nullptr| as the parameter for |familyName| will return the
106-
// * default system font.
104+
itRunsE2eOnly("Shouldn't crash the font cannot be resolved", async () => {
105+
const result = await surface.eval(
106+
(Skia, { fonts }) => {
107+
const fontMgr = Skia.TypefaceFontProvider.Make();
108+
(Object.keys(fonts) as (keyof typeof fonts)[]).flatMap((familyName) => {
109+
const typefaces = fonts[familyName];
110+
typefaces.forEach((typeface) => {
111+
const data = Skia.Data.fromBytes(new Uint8Array(typeface));
112+
fontMgr.registerFont(
113+
Skia.Typeface.MakeFreeTypeFaceFromData(data)!,
114+
familyName
115+
);
116+
});
117+
});
118+
let exists1 = true;
119+
let exists2 = true;
120+
let exists3 = true;
121+
try {
122+
fontMgr.matchFamilyStyle("Robot", {
123+
weight: 400,
124+
});
125+
} catch {
126+
exists1 = false;
127+
}
128+
try {
129+
fontMgr.matchFamilyStyle("Roboto", {
130+
weight: 100,
131+
});
132+
} catch {
133+
exists2 = false;
134+
}
135+
try {
136+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
137+
// @ts-expect-error
138+
fontMgr.matchFamilyStyle();
139+
} catch {
140+
exists3 = false;
141+
}
142+
return { exists1, exists2, exists3 };
143+
},
144+
{ fonts: testingFonts }
145+
);
146+
expect(result.exists1).toBe(false);
147+
expect(result.exists2).toBe(true);
148+
expect(result.exists3).toBe(false);
149+
});
107150
});

package/src/skia/types/Font/FontMgr.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ import type { FontStyle } from "./Font";
66
export interface SkFontMgr extends SkJSIInstance<"FontMgr"> {
77
countFamilies(): number;
88
getFamilyName(index: number): string;
9-
matchFamilyStyle(name?: string, style?: FontStyle): SkTypeface;
9+
matchFamilyStyle(name: string, style: FontStyle): SkTypeface;
1010
}

0 commit comments

Comments
 (0)