Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions apps/example/src/Examples/API/FontMgr.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import React from "react";
import { ScrollView, useWindowDimensions } from "react-native";
import {
Canvas,
Skia,
Text,
listFontFamilies,
matchFont,
useFonts,
} from "@shopify/react-native-skia";
Expand All @@ -16,11 +16,7 @@ const titleText = "Fonts from the System";
const titleY = titleFontSize + PADDING;
const subtitleY = titleY + 14 + PADDING;

const fontMgr = Skia.FontMgr.System();
const familyNames = new Array(fontMgr.countFamilies())
.fill(0)
.map((_, i) => fontMgr.getFamilyName(i));

const familyNames = listFontFamilies();
const title2Y = subtitleY + 16 * familyNames.length + PADDING + titleFontSize;

export const FontMgr = () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/skia/android/cpp/jni/JniPlatformContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ void JniPlatformContext::notifyTaskReadyExternal() {
jni::ThreadScope ts;

static auto method =
javaPart_->getClass()->getMethod<void()>("notifyTaskReady");
javaPart_->getClass()->getMethod<void()>("notifyTaskReady");
method(javaPart_.get());
}

Expand Down
2 changes: 2 additions & 0 deletions packages/skia/apple/RNSkApplePlatformContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class RNSkApplePlatformContext : public RNSkPlatformContext {

sk_sp<SkFontMgr> createFontMgr() override;

std::vector<std::string> getSystemFontFamilies() override;

private:
ViewScreenshotService *_screenshotService;

Expand Down
46 changes: 46 additions & 0 deletions packages/skia/apple/RNSkApplePlatformContext.mm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#import <CoreMedia/CMSampleBuffer.h>
#include <Metal/Metal.h>
#import <React/RCTUtils.h>
#include <set>
#include <thread>
#include <utility>

Expand Down Expand Up @@ -300,6 +301,51 @@
return SkFontMgr_New_CoreText(nullptr);
}

std::vector<std::string> RNSkApplePlatformContext::getSystemFontFamilies() {
std::vector<std::string> families;

// System UI fonts (e.g., .AppleSystemUIFont) are not enumerated by Skia's
// font manager. We retrieve them via Core Text's CTFontUIFontType constants.
// This list covers common system font types as of iOS 17 / macOS 14.
// Apple may add new CTFontUIFontType values in future OS versions,
// so this list may need to be updated periodically.
CTFontUIFontType fontTypes[] = {
kCTFontUIFontUser, kCTFontUIFontUserFixedPitch,
kCTFontUIFontSystem, kCTFontUIFontEmphasizedSystem,
kCTFontUIFontSmallSystem, kCTFontUIFontSmallEmphasizedSystem,
kCTFontUIFontMiniSystem, kCTFontUIFontMiniEmphasizedSystem,
kCTFontUIFontLabel, kCTFontUIFontMessage,
kCTFontUIFontToolTip,
};

std::set<std::string> uniqueFamilies;

for (CTFontUIFontType fontType : fontTypes) {
CTFontRef font = CTFontCreateUIFontForLanguage(fontType, 12.0, nullptr);
if (font) {
CFStringRef familyName = CTFontCopyFamilyName(font);
if (familyName) {
const char *cstr =
CFStringGetCStringPtr(familyName, kCFStringEncodingUTF8);
if (cstr) {
uniqueFamilies.insert(std::string(cstr));
} else {
char buffer[256];
if (CFStringGetCString(familyName, buffer, sizeof(buffer),
kCFStringEncodingUTF8)) {
uniqueFamilies.insert(std::string(buffer));
}
}
CFRelease(familyName);
}
CFRelease(font);
}
}

families.assign(uniqueFamilies.begin(), uniqueFamilies.end());
return families;
}

void RNSkApplePlatformContext::runOnMainThread(std::function<void()> func) {
dispatch_async(dispatch_get_main_queue(), ^{
func();
Expand Down
12 changes: 8 additions & 4 deletions packages/skia/apple/SkiaCVPixelBufferUtils.mm
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,16 @@
#include <TargetConditionals.h>
#if TARGET_RT_BIG_ENDIAN
#define FourCC2Str(fourcc) \
(const char[]){*((char *)&fourcc), *(((char *)&fourcc) + 1), \
*(((char *)&fourcc) + 2), *(((char *)&fourcc) + 3), 0}
(const char[]) { \
*((char *)&fourcc), *(((char *)&fourcc) + 1), *(((char *)&fourcc) + 2), \
*(((char *)&fourcc) + 3), 0 \
}
#else
#define FourCC2Str(fourcc) \
(const char[]){*(((char *)&fourcc) + 3), *(((char *)&fourcc) + 2), \
*(((char *)&fourcc) + 1), *(((char *)&fourcc) + 0), 0}
(const char[]) { \
*(((char *)&fourcc) + 3), *(((char *)&fourcc) + 2), \
*(((char *)&fourcc) + 1), *(((char *)&fourcc) + 0), 0 \
}
#endif

// pragma MARK: TextureHolder
Expand Down
30 changes: 25 additions & 5 deletions packages/skia/cpp/api/JsiSkFontMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,32 @@ class JsiSkFontMgr : public JsiSkWrappingSkPtrHostObject<SkFontMgr> {

JsiSkFontMgr(std::shared_ptr<RNSkPlatformContext> context,
sk_sp<SkFontMgr> fontMgr)
: JsiSkWrappingSkPtrHostObject(std::move(context), fontMgr) {}
: JsiSkWrappingSkPtrHostObject(context, fontMgr),
_systemFontFamilies(context->getSystemFontFamilies()) {}

JSI_HOST_FUNCTION(countFamilies) { return getObject()->countFamilies(); }
JSI_HOST_FUNCTION(countFamilies) {
return static_cast<int>(getObject()->countFamilies() +
_systemFontFamilies.size());
}

JSI_HOST_FUNCTION(getFamilyName) {
auto i = static_cast<int>(arguments[0].asNumber());
SkString name;
getObject()->getFamilyName(i, &name);
return jsi::String::createFromUtf8(runtime, name.c_str());
auto baseFamilyCount = getObject()->countFamilies();
if (i < baseFamilyCount) {
SkString name;
getObject()->getFamilyName(i, &name);
return jsi::String::createFromUtf8(runtime, name.c_str());
}
auto systemIndex = i - baseFamilyCount;
if (systemIndex < static_cast<int>(_systemFontFamilies.size())) {
return jsi::String::createFromUtf8(runtime,
_systemFontFamilies[systemIndex]);
}
throw jsi::JSError(runtime, "Font family index out of bounds: " +
std::to_string(i) + " (total families: " +
std::to_string(baseFamilyCount +
_systemFontFamilies.size()) +
")");
}

JSI_HOST_FUNCTION(matchFamilyStyle) {
Expand All @@ -55,6 +72,9 @@ class JsiSkFontMgr : public JsiSkWrappingSkPtrHostObject<SkFontMgr> {
JSI_EXPORT_FUNCTIONS(JSI_EXPORT_FUNC(JsiSkFontMgr, countFamilies),
JSI_EXPORT_FUNC(JsiSkFontMgr, getFamilyName),
JSI_EXPORT_FUNC(JsiSkFontMgr, matchFamilyStyle))

private:
std::vector<std::string> _systemFontFamilies;
};

} // namespace RNSkia
15 changes: 9 additions & 6 deletions packages/skia/cpp/api/JsiSkPictureFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,15 @@ class JsiSkPictureFactory : public JsiSkHostObject {
}
}

// Get ArrayBuffer - try buffer property first (Uint8Array, etc.), then direct ArrayBuffer
jsi::ArrayBuffer buffer = obj.hasProperty(runtime, jsi::PropNameID::forAscii(runtime, "buffer"))
? obj.getProperty(runtime, jsi::PropNameID::forAscii(runtime, "buffer"))
.asObject(runtime)
.getArrayBuffer(runtime)
: obj.getArrayBuffer(runtime);
// Get ArrayBuffer - try buffer property first (Uint8Array, etc.), then
// direct ArrayBuffer
jsi::ArrayBuffer buffer =
obj.hasProperty(runtime, jsi::PropNameID::forAscii(runtime, "buffer"))
? obj.getProperty(runtime,
jsi::PropNameID::forAscii(runtime, "buffer"))
.asObject(runtime)
.getArrayBuffer(runtime)
: obj.getArrayBuffer(runtime);

sk_sp<SkData> data =
SkData::MakeWithCopy(buffer.data(runtime), buffer.size(runtime));
Expand Down
Loading
Loading