Skip to content

Commit 8e00956

Browse files
fonts: fix CJK fallback font loading
Clearing font charset restrictions by copying a font descriptor's attributes and re-creating it sometimes doesn't work; for example, with 'PingFang SC Regular' (derived from '.AppleSystemUIFontMonospaced' in `CoreText.discoverCodepoint(...)`), `face.hasCodepoint(cp, p_mode)` will erroneously return false after copying, and the font will be rejected. This causes fallback font lookup to fail for CJK characters when using '.AppleSystemUIFontMonospaced' (the non-CJK path queries system fonts instead of deriving a font from the current one, so doesn't seem to hit the broken font). If you first render a non-CJK character that loads a font that contains CJK characters, everything will work fine as the CJK fallback path is never hit. I'm fixing this by only clearing charset restrictions if we know that we've applied them to the font (using `CoreText.discover(...)`, not hitting the special CJK path), but I'm not sure how fragile the charset restriction clearing is for other scenarios.
1 parent e7c1b4d commit 8e00956

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

src/font/discovery.zig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ pub const CoreText = struct {
372372
.alloc = alloc,
373373
.list = zig_list,
374374
.variations = desc.variations,
375+
.charset_restriction = true,
375376
.i = 0,
376377
};
377378
}
@@ -409,6 +410,7 @@ pub const CoreText = struct {
409410
.alloc = alloc,
410411
.list = list,
411412
.variations = desc.variations,
413+
.charset_restriction = false,
412414
.i = 0,
413415
};
414416
}
@@ -433,6 +435,7 @@ pub const CoreText = struct {
433435
.alloc = alloc,
434436
.list = list,
435437
.variations = desc.variations,
438+
.charset_restriction = false,
436439
.i = 0,
437440
};
438441
}
@@ -828,6 +831,8 @@ pub const CoreText = struct {
828831
alloc: Allocator,
829832
list: []const *macos.text.FontDescriptor,
830833
variations: []const Variation,
834+
// We used a charset restriction to filter, and need to remove it
835+
charset_restriction: bool,
831836
i: usize,
832837

833838
pub fn deinit(self: *DiscoverIterator) void {
@@ -849,6 +854,10 @@ pub const CoreText = struct {
849854
const desc = desc: {
850855
const original = self.list[self.i];
851856

857+
if (!self.charset_restriction) {
858+
break :desc original;
859+
}
860+
852861
// For some reason simply copying the attributes and recreating
853862
// the descriptor removes the charset restriction. This is tested.
854863
const attrs = original.copyAttributes();

0 commit comments

Comments
 (0)