font/shaper: work on new grid APIs

This commit is contained in:
Mitchell Hashimoto
2024-04-05 20:21:13 -07:00
parent 90ea733cbd
commit c88137d254
2 changed files with 24 additions and 7 deletions

View File

@ -232,7 +232,24 @@ pub const Shaper = struct {
// Get our font. We have to apply the font features we want for
// the font here.
const run_font: *macos.text.Font = font: {
const face = try run.group.group.faceFromIndex(run.font_index);
// The CoreText shaper relies on CoreText and CoreText claims
// that CTFonts are threadsafe. See:
// https://developer.apple.com/documentation/coretext/
//
// Quote:
// All individual functions in Core Text are thread-safe. Font
// objects (CTFont, CTFontDescriptor, and associated objects) can
// be used simultaneously by multiple operations, work queues, or
// threads. However, the layout objects (CTTypesetter,
// CTFramesetter, CTRun, CTLine, CTFrame, and associated objects)
// should be used in a single operation, work queue, or thread.
//
// Because of this, we only acquire the read lock to grab the
// face and set it up, then release it.
run.grid.lock.lockShared();
defer run.grid.lock.unlockShared();
const face = try run.grid.resolver.collection.getFace(run.font_index);
const original = face.font;
const attrs = try self.features.attrsDict(face.quirks_disable_default_font_features);

View File

@ -174,7 +174,7 @@ pub const RunIterator = struct {
// Otherwise we need a fallback character. Prefer the
// official replacement character.
if (try self.group.indexForCodepoint(
if (try self.grid.getIndex(
alloc,
0xFFFD, // replacement char
font_style,
@ -182,7 +182,7 @@ pub const RunIterator = struct {
)) |idx| break :font_info .{ .idx = idx, .fallback = 0xFFFD };
// Fallback to space
if (try self.group.indexForCodepoint(
if (try self.grid.getIndex(
alloc,
' ',
font_style,
@ -251,7 +251,7 @@ pub const RunIterator = struct {
) !?font.Collection.Index {
// Get the font index for the primary codepoint.
const primary_cp: u32 = if (cell.isEmpty() or cell.codepoint() == 0) ' ' else cell.codepoint();
const primary = try self.group.indexForCodepoint(
const primary = try self.grid.getIndex(
alloc,
primary_cp,
style,
@ -275,7 +275,7 @@ pub const RunIterator = struct {
// Find a font that supports this codepoint. If none support this
// then the whole grapheme can't be rendered so we return null.
const idx = try self.group.indexForCodepoint(
const idx = try self.grid.getIndex(
alloc,
cp,
style,
@ -286,11 +286,11 @@ pub const RunIterator = struct {
// We need to find a candidate that has ALL of our codepoints
for (candidates.items) |idx| {
if (!self.group.group.hasCodepoint(idx, primary_cp, presentation)) continue;
if (!self.grid.hasCodepoint(idx, primary_cp, presentation)) continue;
for (cps) |cp| {
// Ignore Emoji ZWJs
if (cp == 0xFE0E or cp == 0xFE0F or cp == 0x200D) continue;
if (!self.group.group.hasCodepoint(idx, cp, presentation)) break;
if (!self.grid.hasCodepoint(idx, cp, presentation)) break;
} else {
// If the while completed, then we have a candidate that
// supports all of our codepoints.