Skip to content

Commit 9d379b9

Browse files
committed
fix(🍏): Add missing system apple fonts in listFontFamilies
1 parent 828a2da commit 9d379b9

File tree

10 files changed

+144
-81
lines changed

10 files changed

+144
-81
lines changed

apps/example/src/Examples/API/FontMgr.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import React from "react";
22
import { ScrollView, useWindowDimensions } from "react-native";
33
import {
44
Canvas,
5-
Skia,
65
Text,
6+
listFontFamilies,
77
matchFont,
88
useFonts,
99
} from "@shopify/react-native-skia";
@@ -16,11 +16,7 @@ const titleText = "Fonts from the System";
1616
const titleY = titleFontSize + PADDING;
1717
const subtitleY = titleY + 14 + PADDING;
1818

19-
const fontMgr = Skia.FontMgr.System();
20-
const familyNames = new Array(fontMgr.countFamilies())
21-
.fill(0)
22-
.map((_, i) => fontMgr.getFamilyName(i));
23-
19+
const familyNames = listFontFamilies();
2420
const title2Y = subtitleY + 16 * familyNames.length + PADDING + titleFontSize;
2521

2622
export const FontMgr = () => {

packages/skia/android/cpp/jni/JniPlatformContext.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ void JniPlatformContext::notifyTaskReadyExternal() {
207207
jni::ThreadScope ts;
208208

209209
static auto method =
210-
javaPart_->getClass()->getMethod<void()>("notifyTaskReady");
210+
javaPart_->getClass()->getMethod<void()>("notifyTaskReady");
211211
method(javaPart_.get());
212212
}
213213

packages/skia/apple/RNSkApplePlatformContext.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ class RNSkApplePlatformContext : public RNSkPlatformContext {
7373

7474
sk_sp<SkFontMgr> createFontMgr() override;
7575

76+
std::vector<std::string> getSystemFontFamilies() override;
77+
7678
private:
7779
ViewScreenshotService *_screenshotService;
7880

packages/skia/apple/RNSkApplePlatformContext.mm

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#import <CoreMedia/CMSampleBuffer.h>
44
#include <Metal/Metal.h>
55
#import <React/RCTUtils.h>
6+
#include <set>
67
#include <thread>
78
#include <utility>
89

@@ -300,6 +301,47 @@
300301
return SkFontMgr_New_CoreText(nullptr);
301302
}
302303

304+
std::vector<std::string> RNSkApplePlatformContext::getSystemFontFamilies() {
305+
std::vector<std::string> families;
306+
307+
// List of system UI font types to check
308+
CTFontUIFontType fontTypes[] = {
309+
kCTFontUIFontUser, kCTFontUIFontUserFixedPitch,
310+
kCTFontUIFontSystem, kCTFontUIFontEmphasizedSystem,
311+
kCTFontUIFontSmallSystem, kCTFontUIFontSmallEmphasizedSystem,
312+
kCTFontUIFontMiniSystem, kCTFontUIFontMiniEmphasizedSystem,
313+
kCTFontUIFontLabel, kCTFontUIFontMessage,
314+
kCTFontUIFontToolTip,
315+
};
316+
317+
std::set<std::string> uniqueFamilies;
318+
319+
for (CTFontUIFontType fontType : fontTypes) {
320+
CTFontRef font = CTFontCreateUIFontForLanguage(fontType, 12.0, nullptr);
321+
if (font) {
322+
CFStringRef familyName = CTFontCopyFamilyName(font);
323+
if (familyName) {
324+
const char *cstr =
325+
CFStringGetCStringPtr(familyName, kCFStringEncodingUTF8);
326+
if (cstr) {
327+
uniqueFamilies.insert(std::string(cstr));
328+
} else {
329+
char buffer[256];
330+
if (CFStringGetCString(familyName, buffer, sizeof(buffer),
331+
kCFStringEncodingUTF8)) {
332+
uniqueFamilies.insert(std::string(buffer));
333+
}
334+
}
335+
CFRelease(familyName);
336+
}
337+
CFRelease(font);
338+
}
339+
}
340+
341+
families.assign(uniqueFamilies.begin(), uniqueFamilies.end());
342+
return families;
343+
}
344+
303345
void RNSkApplePlatformContext::runOnMainThread(std::function<void()> func) {
304346
dispatch_async(dispatch_get_main_queue(), ^{
305347
func();

packages/skia/apple/SkiaCVPixelBufferUtils.mm

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,16 @@
3030
#include <TargetConditionals.h>
3131
#if TARGET_RT_BIG_ENDIAN
3232
#define FourCC2Str(fourcc) \
33-
(const char[]){*((char *)&fourcc), *(((char *)&fourcc) + 1), \
34-
*(((char *)&fourcc) + 2), *(((char *)&fourcc) + 3), 0}
33+
(const char[]) { \
34+
*((char *)&fourcc), *(((char *)&fourcc) + 1), *(((char *)&fourcc) + 2), \
35+
*(((char *)&fourcc) + 3), 0 \
36+
}
3537
#else
3638
#define FourCC2Str(fourcc) \
37-
(const char[]){*(((char *)&fourcc) + 3), *(((char *)&fourcc) + 2), \
38-
*(((char *)&fourcc) + 1), *(((char *)&fourcc) + 0), 0}
39+
(const char[]) { \
40+
*(((char *)&fourcc) + 3), *(((char *)&fourcc) + 2), \
41+
*(((char *)&fourcc) + 1), *(((char *)&fourcc) + 0), 0 \
42+
}
3943
#endif
4044

4145
// pragma MARK: TextureHolder

packages/skia/cpp/api/JsiSkFontMgr.h

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,28 @@ class JsiSkFontMgr : public JsiSkWrappingSkPtrHostObject<SkFontMgr> {
2727

2828
JsiSkFontMgr(std::shared_ptr<RNSkPlatformContext> context,
2929
sk_sp<SkFontMgr> fontMgr)
30-
: JsiSkWrappingSkPtrHostObject(std::move(context), fontMgr) {}
30+
: JsiSkWrappingSkPtrHostObject(context, fontMgr),
31+
_systemFontFamilies(context->getSystemFontFamilies()) {}
3132

32-
JSI_HOST_FUNCTION(countFamilies) { return getObject()->countFamilies(); }
33+
JSI_HOST_FUNCTION(countFamilies) {
34+
return static_cast<int>(getObject()->countFamilies() +
35+
_systemFontFamilies.size());
36+
}
3337

3438
JSI_HOST_FUNCTION(getFamilyName) {
3539
auto i = static_cast<int>(arguments[0].asNumber());
36-
SkString name;
37-
getObject()->getFamilyName(i, &name);
38-
return jsi::String::createFromUtf8(runtime, name.c_str());
40+
auto baseFamilyCount = getObject()->countFamilies();
41+
if (i < baseFamilyCount) {
42+
SkString name;
43+
getObject()->getFamilyName(i, &name);
44+
return jsi::String::createFromUtf8(runtime, name.c_str());
45+
}
46+
auto systemIndex = i - baseFamilyCount;
47+
if (systemIndex < static_cast<int>(_systemFontFamilies.size())) {
48+
return jsi::String::createFromUtf8(runtime,
49+
_systemFontFamilies[systemIndex]);
50+
}
51+
return jsi::String::createFromUtf8(runtime, "");
3952
}
4053

4154
JSI_HOST_FUNCTION(matchFamilyStyle) {
@@ -55,6 +68,9 @@ class JsiSkFontMgr : public JsiSkWrappingSkPtrHostObject<SkFontMgr> {
5568
JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkFontMgr, countFamilies),
5669
JSI_EXPORT_FUNC(JsiSkFontMgr, getFamilyName),
5770
JSI_EXPORT_FUNC(JsiSkFontMgr, matchFamilyStyle))
71+
72+
private:
73+
std::vector<std::string> _systemFontFamilies;
5874
};
5975

6076
} // namespace RNSkia

packages/skia/cpp/api/JsiSkPictureFactory.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,15 @@ class JsiSkPictureFactory : public JsiSkHostObject {
5050
}
5151
}
5252

53-
// Get ArrayBuffer - try buffer property first (Uint8Array, etc.), then direct ArrayBuffer
54-
jsi::ArrayBuffer buffer = obj.hasProperty(runtime, jsi::PropNameID::forAscii(runtime, "buffer"))
55-
? obj.getProperty(runtime, jsi::PropNameID::forAscii(runtime, "buffer"))
56-
.asObject(runtime)
57-
.getArrayBuffer(runtime)
58-
: obj.getArrayBuffer(runtime);
53+
// Get ArrayBuffer - try buffer property first (Uint8Array, etc.), then
54+
// direct ArrayBuffer
55+
jsi::ArrayBuffer buffer =
56+
obj.hasProperty(runtime, jsi::PropNameID::forAscii(runtime, "buffer"))
57+
? obj.getProperty(runtime,
58+
jsi::PropNameID::forAscii(runtime, "buffer"))
59+
.asObject(runtime)
60+
.getArrayBuffer(runtime)
61+
: obj.getArrayBuffer(runtime);
5962

6063
sk_sp<SkData> data =
6164
SkData::MakeWithCopy(buffer.data(runtime), buffer.size(runtime));

0 commit comments

Comments
 (0)