mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
font/coretext: respect quirks fonts for shaper
This commit is contained in:
@ -71,6 +71,10 @@ pub const MutableArray = opaque {
|
|||||||
CFArrayAppendValue(self, @constCast(@ptrCast(value)));
|
CFArrayAppendValue(self, @constCast(@ptrCast(value)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn removeValue(self: *MutableArray, idx: usize) void {
|
||||||
|
CFArrayRemoveValueAtIndex(self, idx);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn sortValues(
|
pub fn sortValues(
|
||||||
self: *MutableArray,
|
self: *MutableArray,
|
||||||
comptime Elem: type,
|
comptime Elem: type,
|
||||||
@ -104,6 +108,10 @@ pub const MutableArray = opaque {
|
|||||||
*MutableArray,
|
*MutableArray,
|
||||||
*anyopaque,
|
*anyopaque,
|
||||||
) void;
|
) void;
|
||||||
|
extern "c" fn CFArrayRemoveValueAtIndex(
|
||||||
|
*MutableArray,
|
||||||
|
usize,
|
||||||
|
) void;
|
||||||
extern "c" fn CFArraySortValues(
|
extern "c" fn CFArraySortValues(
|
||||||
array: *MutableArray,
|
array: *MutableArray,
|
||||||
range: Range,
|
range: Range,
|
||||||
|
@ -74,11 +74,20 @@ pub const Shaper = struct {
|
|||||||
self.list.release();
|
self.list.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Append the given feature to the list. The feature syntax is
|
||||||
|
/// the same as Harfbuzz: "feat" enables it and "-feat" disables it.
|
||||||
pub fn append(self: *FeatureList, name_raw: []const u8) !void {
|
pub fn append(self: *FeatureList, name_raw: []const u8) !void {
|
||||||
// If the name is `-name` then we are disabling the feature,
|
// If the name is `-name` then we are disabling the feature,
|
||||||
// otherwise we are enabling it, so we need to parse this out.
|
// otherwise we are enabling it, so we need to parse this out.
|
||||||
const name = if (name_raw[0] == '-') name_raw[1..] else name_raw;
|
const name = if (name_raw[0] == '-') name_raw[1..] else name_raw;
|
||||||
const value_num: c_int = if (name_raw[0] == '-') 0 else 1;
|
const dict = try featureDict(name, name_raw[0] != '-');
|
||||||
|
defer dict.release();
|
||||||
|
self.list.appendValue(macos.foundation.Dictionary, dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create the dictionary for the given feature and value.
|
||||||
|
fn featureDict(name: []const u8, v: bool) !*macos.foundation.Dictionary {
|
||||||
|
const value_num: c_int = @intFromBool(v);
|
||||||
|
|
||||||
// Keys can only be ASCII.
|
// Keys can only be ASCII.
|
||||||
var key = try macos.foundation.String.createWithBytes(name, .ascii, false);
|
var key = try macos.foundation.String.createWithBytes(name, .ascii, false);
|
||||||
@ -96,17 +105,28 @@ pub const Shaper = struct {
|
|||||||
value,
|
value,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
defer dict.release();
|
errdefer dict.release();
|
||||||
|
return dict;
|
||||||
self.list.appendValue(macos.foundation.Dictionary, dict);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the dictionary to use with the font API to set the
|
/// Returns the dictionary to use with the font API to set the
|
||||||
/// features. This should be released by the caller.
|
/// features. This should be released by the caller.
|
||||||
pub fn attrsDict(self: FeatureList) !*macos.foundation.Dictionary {
|
pub fn attrsDict(
|
||||||
|
self: FeatureList,
|
||||||
|
omit_defaults: bool,
|
||||||
|
) !*macos.foundation.Dictionary {
|
||||||
|
// Get our feature list. If we're omitting defaults then we
|
||||||
|
// slice off the hardcoded features.
|
||||||
|
const list = if (!omit_defaults) self.list else list: {
|
||||||
|
const list = try macos.foundation.MutableArray.createCopy(@ptrCast(self.list));
|
||||||
|
for (hardcoded_features) |_| list.removeValue(0);
|
||||||
|
break :list list;
|
||||||
|
};
|
||||||
|
defer if (omit_defaults) list.release();
|
||||||
|
|
||||||
var dict = try macos.foundation.Dictionary.create(
|
var dict = try macos.foundation.Dictionary.create(
|
||||||
&[_]?*const anyopaque{macos.text.c.kCTFontFeatureSettingsAttribute},
|
&[_]?*const anyopaque{macos.text.c.kCTFontFeatureSettingsAttribute},
|
||||||
&[_]?*const anyopaque{self.list},
|
&[_]?*const anyopaque{list},
|
||||||
);
|
);
|
||||||
errdefer dict.release();
|
errdefer dict.release();
|
||||||
return dict;
|
return dict;
|
||||||
@ -157,8 +177,6 @@ pub const Shaper = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn shape(self: *Shaper, run: font.shape.TextRun) ![]const font.shape.Cell {
|
pub fn shape(self: *Shaper, run: font.shape.TextRun) ![]const font.shape.Cell {
|
||||||
// TODO: quirks fonts
|
|
||||||
|
|
||||||
// Special fonts aren't shaped and their codepoint == glyph so we
|
// Special fonts aren't shaped and their codepoint == glyph so we
|
||||||
// can just return the codepoints as-is.
|
// can just return the codepoints as-is.
|
||||||
if (run.font_index.special() != null) {
|
if (run.font_index.special() != null) {
|
||||||
@ -184,7 +202,7 @@ pub const Shaper = struct {
|
|||||||
const face = try run.group.group.faceFromIndex(run.font_index);
|
const face = try run.group.group.faceFromIndex(run.font_index);
|
||||||
const original = face.font;
|
const original = face.font;
|
||||||
|
|
||||||
const attrs = try self.features.attrsDict();
|
const attrs = try self.features.attrsDict(face.quirks_disable_default_font_features);
|
||||||
defer attrs.release();
|
defer attrs.release();
|
||||||
|
|
||||||
const desc = try macos.text.FontDescriptor.createWithAttributes(attrs);
|
const desc = try macos.text.FontDescriptor.createWithAttributes(attrs);
|
||||||
|
Reference in New Issue
Block a user