Add per-font size adjustment, don't adjust nf symbol font or emoji font; use non-Mono symbols nerd font (#7953)

This adds functionality for choosing different normalization metrics for
each fallback font. It's not exposed as a config option, but could be in
the future, which would probably go a long way towards addressing
concerns like #7929.

The currently available reference metrics are, in priority order:
`ic_width, ex_height, cap_height, line_height, em_size`. The default
value is `ic_width`.

By priority order, I mean that if the chosen metric is not defined in
the fallback font, we move to the next metric in the list---we don't
normalize by an estimated metric from the fallback font (however, we're
happy to use an estimated metric from the primary font, that's how
`ic_width` normalization between CJK and Latin fonts work). This extends
the pattern that was used between `ic_width` and `ex_height` in the
existing hardcoded rule. `line_height` is always defined, so the buck
stops there.

What motivated me to implement this was the fact that, with the existing
hardcoded rule, the embedded symbols-only Nerd Font was always scaled up
by a factor of 1.2, which turned out to be an important reason why it's
been difficult to make icon scaling work to everyone's satisfaction.
Accordingly, the symbols-only font is the first to take advantage of the
new functionality. If this PR is merged, #7917 is no longer needed. (To
limit the scope of this PR, it only includes the minimal changes to let
icon scaling take advantage of this functionality. I may submit a
follow-up PR with some further icon scaling improvement enabled by
this.)
This commit is contained in:
Mitchell Hashimoto
2025-07-26 07:08:44 -07:00
committed by GitHub
15 changed files with 997 additions and 663 deletions

View File

@ -531,7 +531,7 @@ pub fn add(
const nf_symbols = b.dependency("nerd_fonts_symbols_only", .{});
step.root_module.addAnonymousImport(
"nerd_fonts_symbols_only",
.{ .root_source_file = nf_symbols.path("SymbolsNerdFontMono-Regular.ttf") },
.{ .root_source_file = nf_symbols.path("SymbolsNerdFont-Regular.ttf") },
);
}

View File

@ -190,7 +190,10 @@ pub fn getIndex(
// Discovery is supposed to only return faces that have our
// codepoint but we can't search presentation in discovery so
// we have to check it here.
const face: Collection.Entry = .{ .fallback_deferred = deferred_face };
const face: Collection.Entry = .{
.face = .{ .deferred = deferred_face },
.fallback = true,
};
if (!face.hasCodepoint(cp, p_mode)) {
deferred_face.deinit();
continue;
@ -201,7 +204,11 @@ pub fn getIndex(
cp,
deferred_face.name(&buf) catch "<error>",
});
return self.collection.add(alloc, style, face) catch {
return self.collection.addDeferred(alloc, deferred_face, .{
.style = style,
.fallback = true,
.size_adjustment = font.default_fallback_adjustment,
}) catch {
deferred_face.deinit();
break :discover;
};
@ -263,11 +270,11 @@ fn getIndexCodepointOverride(
// Add the font to our list of fonts so we can get an index for it,
// and ensure the index is stored in the descriptor cache for next time.
const idx = try self.collection.add(
alloc,
.regular,
.{ .deferred = face },
);
const idx = try self.collection.addDeferred(alloc, face, .{
.style = .regular,
.fallback = false,
.size_adjustment = font.default_fallback_adjustment,
});
try self.descriptor_cache.put(alloc, desc, idx);
break :idx idx;
@ -388,32 +395,36 @@ test getIndex {
{
errdefer c.deinit(alloc);
_ = try c.add(alloc, .regular, .{ .loaded = try .init(
_ = try c.add(alloc, try .init(
lib,
testFont,
.{ .size = .{ .points = 12, .xdpi = 96, .ydpi = 96 } },
) });
), .{
.style = .regular,
.fallback = false,
.size_adjustment = .none,
});
if (comptime !font.options.backend.hasCoretext()) {
// Coretext doesn't support Noto's format
_ = try c.add(
alloc,
.regular,
.{ .loaded = try .init(
lib,
testEmoji,
.{ .size = .{ .points = 12 } },
) },
);
}
_ = try c.add(
alloc,
.regular,
.{ .loaded = try .init(
_ = try c.add(alloc, try .init(
lib,
testEmojiText,
testEmoji,
.{ .size = .{ .points = 12 } },
) },
);
), .{
.style = .regular,
.fallback = false,
.size_adjustment = .none,
});
}
_ = try c.add(alloc, try .init(
lib,
testEmojiText,
.{ .size = .{ .points = 12 } },
), .{
.style = .regular,
.fallback = false,
.size_adjustment = .none,
});
}
var r: CodepointResolver = .{ .collection = c };
@ -467,21 +478,33 @@ test "getIndex disabled font style" {
var c = Collection.init();
c.load_options = .{ .library = lib };
_ = try c.add(alloc, .regular, .{ .loaded = try .init(
_ = try c.add(alloc, try .init(
lib,
testFont,
.{ .size = .{ .points = 12, .xdpi = 96, .ydpi = 96 } },
) });
_ = try c.add(alloc, .bold, .{ .loaded = try .init(
), .{
.style = .regular,
.fallback = false,
.size_adjustment = .none,
});
_ = try c.add(alloc, try .init(
lib,
testFont,
.{ .size = .{ .points = 12, .xdpi = 96, .ydpi = 96 } },
) });
_ = try c.add(alloc, .italic, .{ .loaded = try .init(
), .{
.style = .bold,
.fallback = false,
.size_adjustment = .none,
});
_ = try c.add(alloc, try .init(
lib,
testFont,
.{ .size = .{ .points = 12, .xdpi = 96, .ydpi = 96 } },
) });
), .{
.style = .italic,
.fallback = false,
.size_adjustment = .none,
});
var r: CodepointResolver = .{ .collection = c };
defer r.deinit(alloc);
@ -522,6 +545,7 @@ test "getIndex box glyph" {
.collection = c,
.sprite = .{
.metrics = font.Metrics.calc(.{
.px_per_em = 30.0,
.cell_width = 18.0,
.ascent = 30.0,
.descent = -6.0,

File diff suppressed because it is too large Load Diff

View File

@ -55,6 +55,11 @@ const Minimums = struct {
/// Metrics extracted from a font face, based on
/// the metadata tables and glyph measurements.
pub const FaceMetrics = struct {
/// Pixels per em, dividing the other values in this struct by this should
/// yield sizes in ems, to allow comparing metrics from faces of different
/// sizes.
px_per_em: f64,
/// The minimum cell width that can contain any glyph in the ASCII range.
///
/// Determined by measuring all printable glyphs in the ASCII range.
@ -120,6 +125,60 @@ pub const FaceMetrics = struct {
pub inline fn lineHeight(self: FaceMetrics) f64 {
return self.ascent - self.descent + self.line_gap;
}
/// Convenience function for getting the cap height. If this is not
/// defined in the font, we estimate it as 75% of the ascent.
pub inline fn capHeight(self: FaceMetrics) f64 {
if (self.cap_height) |value| if (value > 0) return value;
return 0.75 * self.ascent;
}
/// Convenience function for getting the ex height. If this is not
/// defined in the font, we estimate it as 75% of the cap height.
pub inline fn exHeight(self: FaceMetrics) f64 {
if (self.ex_height) |value| if (value > 0) return value;
return 0.75 * self.capHeight();
}
/// Convenience function for getting the ideograph width. If this is
/// not defined in the font, we estimate it as two cell widths.
pub inline fn icWidth(self: FaceMetrics) f64 {
if (self.ic_width) |value| if (value > 0) return value;
return 2 * self.cell_width;
}
/// Convenience function for getting the underline thickness. If
/// this is not defined in the font, we estimate it as 15% of the ex
/// height.
pub inline fn underlineThickness(self: FaceMetrics) f64 {
if (self.underline_thickness) |value| if (value > 0) return value;
return 0.15 * self.exHeight();
}
/// Convenience function for getting the strikethrough thickness. If
/// this is not defined in the font, we set it equal to the
/// underline thickness.
pub inline fn strikethroughThickness(self: FaceMetrics) f64 {
if (self.strikethrough_thickness) |value| if (value > 0) return value;
return self.underlineThickness();
}
// NOTE: The getters below return positions, not sizes, so both
// positive and negative values are valid, hence no sign validation.
/// Convenience function for getting the underline position. If
/// this is not defined in the font, we place it one underline
/// thickness below the baseline.
pub inline fn underlinePosition(self: FaceMetrics) f64 {
return self.underline_position orelse -self.underlineThickness();
}
/// Convenience function for getting the strikethrough position. If
/// this is not defined in the font, we center it at half the ex
/// height, so that it's perfectly centered on lower case text.
pub inline fn strikethroughPosition(self: FaceMetrics) f64 {
return self.strikethrough_position orelse (self.exHeight() + self.strikethroughThickness()) * 0.5;
}
};
/// Calculate our metrics based on values extracted from a font.
@ -147,35 +206,13 @@ pub fn calc(face: FaceMetrics) Metrics {
// We calculate a top_to_baseline to make following calculations simpler.
const top_to_baseline = cell_height - cell_baseline;
// If we don't have a provided cap height,
// we estimate it as 75% of the ascent.
const cap_height = face.cap_height orelse face.ascent * 0.75;
// If we don't have a provided ex height,
// we estimate it as 75% of the cap height.
const ex_height = face.ex_height orelse cap_height * 0.75;
// If we don't have a provided underline thickness,
// we estimate it as 15% of the ex height.
const underline_thickness = @max(1, @ceil(face.underline_thickness orelse 0.15 * ex_height));
// If we don't have a provided strikethrough thickness
// then we just use the underline thickness for it.
const strikethrough_thickness = @max(1, @ceil(face.strikethrough_thickness orelse underline_thickness));
// If we don't have a provided underline position then
// we place it 1 underline-thickness below the baseline.
const underline_position = @round(top_to_baseline -
(face.underline_position orelse
-underline_thickness));
// If we don't have a provided strikethrough position
// then we center the strikethrough stroke at half the
// ex height, so that it's perfectly centered on lower
// case text.
const strikethrough_position = @round(top_to_baseline -
(face.strikethrough_position orelse
ex_height * 0.5 + strikethrough_thickness * 0.5));
// Get the other font metrics or their estimates. See doc comments
// in FaceMetrics for explanations of the estimation heuristics.
const cap_height = face.capHeight();
const underline_thickness = @max(1, @ceil(face.underlineThickness()));
const strikethrough_thickness = @max(1, @ceil(face.strikethroughThickness()));
const underline_position = @round(top_to_baseline - face.underlinePosition());
const strikethrough_position = @round(top_to_baseline - face.strikethroughPosition());
// The calculation for icon height in the nerd fonts patcher
// is two thirds cap height to one third line height, but we

View File

@ -376,11 +376,15 @@ fn testGrid(mode: TestMode, alloc: Allocator, lib: Library) !SharedGrid {
switch (mode) {
.normal => {
_ = try c.add(alloc, .regular, .{ .loaded = try .init(
_ = try c.add(alloc, try .init(
lib,
testFont,
.{ .size = .{ .points = 12, .xdpi = 96, .ydpi = 96 } },
) });
), .{
.style = .regular,
.fallback = false,
.size_adjustment = .none,
});
},
}

View File

@ -200,11 +200,12 @@ fn collection(
try face.name(&name_buf),
});
_ = try c.add(
self.alloc,
style,
.{ .deferred = face },
);
_ = try c.addDeferred(self.alloc, face, .{
.style = style,
.fallback = false,
// No size adjustment for primary fonts.
.size_adjustment = .none,
});
continue;
}
@ -230,11 +231,12 @@ fn collection(
try face.name(&name_buf),
});
_ = try c.add(
self.alloc,
style,
.{ .deferred = face },
);
_ = try c.addDeferred(self.alloc, face, .{
.style = style,
.fallback = false,
// No size adjustment for primary fonts.
.size_adjustment = .none,
});
continue;
}
@ -257,42 +259,58 @@ fn collection(
// Our built-in font will be used as a backup
_ = try c.add(
self.alloc,
.regular,
.{ .fallback_loaded = try .init(
try .init(
self.font_lib,
font.embedded.variable,
load_options.faceOptions(),
) },
),
.{
.style = .regular,
.fallback = true,
.size_adjustment = font.default_fallback_adjustment,
},
);
try (try c.getFace(try c.add(
self.alloc,
.bold,
.{ .fallback_loaded = try .init(
try .init(
self.font_lib,
font.embedded.variable,
load_options.faceOptions(),
) },
),
.{
.style = .bold,
.fallback = true,
.size_adjustment = font.default_fallback_adjustment,
},
))).setVariations(
&.{.{ .id = .init("wght"), .value = 700 }},
load_options.faceOptions(),
);
_ = try c.add(
self.alloc,
.italic,
.{ .fallback_loaded = try .init(
try .init(
self.font_lib,
font.embedded.variable_italic,
load_options.faceOptions(),
) },
),
.{
.style = .italic,
.fallback = true,
.size_adjustment = font.default_fallback_adjustment,
},
);
try (try c.getFace(try c.add(
self.alloc,
.bold_italic,
.{ .fallback_loaded = try .init(
try .init(
self.font_lib,
font.embedded.variable_italic,
load_options.faceOptions(),
) },
),
.{
.style = .bold_italic,
.fallback = true,
.size_adjustment = font.default_fallback_adjustment,
},
))).setVariations(
&.{.{ .id = .init("wght"), .value = 700 }},
load_options.faceOptions(),
@ -301,12 +319,17 @@ fn collection(
// Nerd-font symbols fallback.
_ = try c.add(
self.alloc,
.regular,
.{ .fallback_loaded = try Face.init(
try .init(
self.font_lib,
font.embedded.symbols_nerd_font,
load_options.faceOptions(),
) },
),
.{
.style = .regular,
.fallback = true,
// No size adjustment for the symbols font.
.size_adjustment = .none,
},
);
// On macOS, always search for and add the Apple Emoji font
@ -321,11 +344,12 @@ fn collection(
});
defer disco_it.deinit();
if (try disco_it.next()) |face| {
_ = try c.add(
self.alloc,
.regular,
.{ .fallback_deferred = face },
);
_ = try c.addDeferred(self.alloc, face, .{
.style = .regular,
.fallback = true,
// No size adjustment for emojis.
.size_adjustment = .none,
});
}
}
@ -334,21 +358,31 @@ fn collection(
if (comptime !builtin.target.os.tag.isDarwin() or Discover == void) {
_ = try c.add(
self.alloc,
.regular,
.{ .fallback_loaded = try .init(
try .init(
self.font_lib,
font.embedded.emoji,
load_options.faceOptions(),
) },
),
.{
.style = .regular,
.fallback = true,
// No size adjustment for emojis.
.size_adjustment = .none,
},
);
_ = try c.add(
self.alloc,
.regular,
.{ .fallback_loaded = try .init(
try .init(
self.font_lib,
font.embedded.emoji_text,
load_options.faceOptions(),
) },
),
.{
.style = .regular,
.fallback = true,
// No size adjustment for emojis.
.size_adjustment = .none,
},
);
}

View File

@ -52,9 +52,9 @@ pub const DesiredSize = struct {
ydpi: u16 = default_dpi,
// Converts points to pixels
pub fn pixels(self: DesiredSize) u16 {
pub fn pixels(self: DesiredSize) f32 {
// 1 point = 1/72 inch
return @intFromFloat(@round((self.points * @as(f32, @floatFromInt(self.ydpi))) / 72));
return (self.points * @as(f32, @floatFromInt(self.ydpi))) / 72;
}
/// Make this a valid gobject if we're in a GTK environment.
@ -233,7 +233,7 @@ pub const RenderOptions = struct {
) GlyphSize {
var g = glyph;
var available_width: f64 = @floatFromInt(
const available_width: f64 = @floatFromInt(
metrics.cell_width * @min(
self.max_constraint_width,
constraint_width,
@ -244,22 +244,6 @@ pub const RenderOptions = struct {
.icon => metrics.icon_height,
});
// We make the opinionated choice here to reduce the width
// of icon-height symbols by the same amount horizontally,
// since otherwise wide aspect ratio icons like folders end
// up far too wide.
//
// But we *only* do this if the constraint width is 2, since
// otherwise it would make them way too small when sized for
// a single cell.
const is_icon_width = self.height == .icon and @min(self.max_constraint_width, constraint_width) > 1;
const orig_avail_width = available_width;
if (is_icon_width) {
const cell_height: f64 = @floatFromInt(metrics.cell_height);
const ratio = available_height / cell_height;
available_width *= ratio;
}
const w = available_width -
self.pad_left * available_width -
self.pad_right * available_width;
@ -383,11 +367,6 @@ pub const RenderOptions = struct {
.center => g.y = (h - g.height) / 2,
}
// Add offset for icon width restriction, to keep it centered.
if (is_icon_width) {
g.x += (orig_avail_width - available_width) / 2;
}
// Re-add our padding before returning.
g.x += self.pad_left * available_width;
g.y += self.pad_bottom * available_height;

View File

@ -78,7 +78,7 @@ pub const Face = struct {
// but we need to scale the points by the DPI and to do that we use our
// function called "pixels".
const ct_font = try base.copyWithAttributes(
@floatFromInt(opts.size.pixels()),
opts.size.pixels(),
null,
null,
);
@ -94,7 +94,8 @@ pub const Face = struct {
var hb_font = if (comptime harfbuzz_shaper) font: {
var hb_font = try harfbuzz.coretext.createFont(ct_font);
hb_font.setScale(opts.size.pixels(), opts.size.pixels());
const pixels: opentype.sfnt.F26Dot6 = .from(opts.size.pixels());
hb_font.setScale(@bitCast(pixels), @bitCast(pixels));
break :font hb_font;
} else {};
errdefer if (comptime harfbuzz_shaper) hb_font.destroy();
@ -240,10 +241,14 @@ pub const Face = struct {
desc = next;
}
// Put our current size in the opts so that we don't change size.
var new_opts = opts;
new_opts.size = self.size;
// Initialize a font based on these attributes.
const ct_font = try self.font.copyWithAttributes(0, null, desc);
errdefer ct_font.release();
const face = try initFont(ct_font, opts);
const face = try initFont(ct_font, new_opts);
self.deinit();
self.* = face;
}
@ -842,14 +847,20 @@ pub const Face = struct {
};
return .{
.px_per_em = px_per_em,
.cell_width = cell_width,
.ascent = ascent,
.descent = descent,
.line_gap = line_gap,
.underline_position = underline_position,
.underline_thickness = underline_thickness,
.strikethrough_position = strikethrough_position,
.strikethrough_thickness = strikethrough_thickness,
.cap_height = cap_height,
.ex_height = ex_height,
.ic_width = ic_width,

View File

@ -217,7 +217,7 @@ pub const Face = struct {
if (face.isScalable()) {
const size_26dot6: i32 = @intFromFloat(@round(size.points * 64));
try face.setCharSize(0, size_26dot6, size.xdpi, size.ydpi);
} else try selectSizeNearest(face, size.pixels());
} else try selectSizeNearest(face, @intFromFloat(@round(size.pixels())));
}
/// Selects the fixed size in the loaded face that is closest to the
@ -933,6 +933,8 @@ pub const Face = struct {
};
return .{
.px_per_em = px_per_em,
.cell_width = cell_width,
.ascent = ascent,

View File

@ -174,6 +174,11 @@ pub const Presentation = enum(u1) {
/// A FontIndex that can be used to use the sprite font directly.
pub const sprite_index = Collection.Index.initSpecial(.sprite);
/// The default font size adjustment we use when loading fallback fonts.
///
/// TODO: Add user configuration for this instead of hard-coding it.
pub const default_fallback_adjustment: Collection.SizeAdjustment = .ic_width;
test {
// For non-wasm we want to test everything we can
if (!comptime builtin.target.cpu.arch.isWasm()) {

View File

@ -41,7 +41,7 @@ pub fn getConstraint(cp: u21) Constraint {
.max_constraint_width = 1,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.4028056112224450,
.group_width = 1.3999999999999999,
.group_height = 1.1222570532915361,
.group_x = 0.1428571428571428,
.group_y = 0.0349162011173184,
@ -395,8 +395,7 @@ pub fn getConstraint(cp: u21) Constraint {
0xeb72...0xeb89,
0xeb8b...0xeb99,
0xeb9b...0xebd4,
0xebd6,
0xebd8...0xec06,
0xebd7...0xec06,
0xec08...0xec0a,
0xec0d...0xec1e,
0xed00...0xf018,
@ -412,8 +411,7 @@ pub fn getConstraint(cp: u21) Constraint {
0xf07c...0xf080,
0xf082...0xf08b,
0xf08d...0xf091,
0xf093...0xf09b,
0xf09d...0xf09e,
0xf093...0xf09e,
0xf0a0,
0xf0a5...0xf0a9,
0xf0ab...0xf0c9,
@ -421,7 +419,7 @@ pub fn getConstraint(cp: u21) Constraint {
0xf0d7...0xf0dd,
0xf0df...0xf0e6,
0xf0e8...0xf295,
0xf297...0xf2c1,
0xf297...0xf2c3,
0xf2c6...0xf2ef,
0xf2f1...0xf305,
0xf307...0xf847,
@ -440,10 +438,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.3315669947009841,
.group_height = 1.0763840224246670,
.group_x = 0.0847072200113701,
.group_y = 0.0709635416666667,
.group_width = 1.3310225303292895,
.group_height = 1.0762439807383628,
.group_x = 0.0846354166666667,
.group_y = 0.0708426547352722,
},
0xea7d,
=> .{
@ -452,10 +450,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.1913145539906103,
.group_height = 1.1428571428571428,
.group_x = 0.0916256157635468,
.group_y = 0.0415039062500000,
.group_width = 1.1912058627581612,
.group_height = 1.1426759670259987,
.group_x = 0.0917225950782998,
.group_y = 0.0416204217536071,
},
0xea99,
=> .{
@ -464,10 +462,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0639412997903563,
.group_height = 2.0940695296523519,
.group_x = 0.0295566502463054,
.group_y = 0.2270507812500000,
.group_width = 1.0642857142857143,
.group_height = 2.0929152148664345,
.group_x = 0.0302013422818792,
.group_y = 0.2269700332963374,
},
0xea9a,
0xeaa1,
@ -477,10 +475,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.3029525032092426,
.group_height = 1.1729667812142039,
.group_x = 0.1527093596059113,
.group_y = 0.0751953125000000,
.group_width = 1.3032069970845481,
.group_height = 1.1731770833333333,
.group_x = 0.1526845637583893,
.group_y = 0.0754716981132075,
},
0xea9b,
=> .{
@ -489,10 +487,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.1639908256880733,
.group_height = 1.3128205128205128,
.group_x = 0.0719211822660099,
.group_y = 0.0869140625000000,
.group_width = 1.1640625000000000,
.group_height = 1.3134110787172011,
.group_x = 0.0721476510067114,
.group_y = 0.0871254162042175,
},
0xea9c,
=> .{
@ -501,10 +499,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.1639908256880733,
.group_height = 1.3195876288659794,
.group_x = 0.0719211822660099,
.group_y = 0.0830078125000000,
.group_width = 1.1640625000000000,
.group_height = 1.3201465201465201,
.group_x = 0.0721476510067114,
.group_y = 0.0832408435072142,
},
0xea9d,
0xeaa0,
@ -514,10 +512,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 2.4457831325301207,
.group_height = 1.9692307692307693,
.group_x = 0.2857142857142857,
.group_y = 0.2763671875000000,
.group_width = 2.4493150684931506,
.group_height = 1.9693989071038251,
.group_x = 0.2863534675615212,
.group_y = 0.2763596004439512,
},
0xea9e...0xea9f,
=> .{
@ -526,10 +524,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.9556840077071291,
.group_height = 2.4674698795180725,
.group_x = 0.2137931034482759,
.group_y = 0.3066406250000000,
.group_width = 1.9540983606557376,
.group_height = 2.4684931506849317,
.group_x = 0.2136465324384788,
.group_y = 0.3068812430632630,
},
0xeaa2,
=> .{
@ -538,10 +536,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.2412121212121212,
.group_height = 1.0591799039527152,
.group_x = 0.0683593750000000,
.group_y = 0.0146484375000000,
.group_width = 1.2405228758169935,
.group_height = 1.0595187680461982,
.group_x = 0.0679662802950474,
.group_y = 0.0147523709167545,
},
0xeab4,
=> .{
@ -550,9 +548,9 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0049115913555993,
.group_height = 1.8998144712430427,
.group_y = 0.2026367187500000,
.group_width = 1.0054815974941269,
.group_height = 1.8994082840236686,
.group_y = 0.2024922118380062,
},
0xeab5,
=> .{
@ -561,10 +559,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.8979591836734695,
.group_height = 1.0054000981836033,
.group_x = 0.2023460410557185,
.group_y = 0.0053710937500000,
.group_width = 1.8994082840236686,
.group_height = 1.0054815974941269,
.group_x = 0.2024922118380062,
.group_y = 0.0054517133956386,
},
0xeab6,
=> .{
@ -573,9 +571,9 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.8979591836734695,
.group_height = 1.0054000981836033,
.group_x = 0.2707722385141740,
.group_width = 1.8994082840236686,
.group_height = 1.0054815974941269,
.group_x = 0.2710280373831775,
},
0xeab7,
=> .{
@ -584,10 +582,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0049115913555993,
.group_height = 1.8980537534754403,
.group_x = 0.0048875855327468,
.group_y = 0.2709960937500000,
.group_width = 1.0054815974941269,
.group_height = 1.8994082840236686,
.group_x = 0.0054517133956386,
.group_y = 0.2710280373831775,
},
0xead4...0xead5,
=> .{
@ -596,8 +594,8 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.4152542372881356,
.group_x = 0.1486118671747414,
.group_width = 1.4144620811287478,
.group_x = 0.1483790523690773,
},
0xead6,
=> .{
@ -606,8 +604,8 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_height = 1.1390433815350389,
.group_y = 0.0688476562500000,
.group_height = 1.1388535031847133,
.group_y = 0.0687919463087248,
},
0xeb43,
=> .{
@ -616,10 +614,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.3635153129161119,
.group_height = 1.0002360944082516,
.group_x = 0.1992187500000000,
.group_y = 0.0002360386808388,
.group_width = 1.3631840796019901,
.group_height = 1.0003813300793167,
.group_x = 0.1991657977059437,
.group_y = 0.0003811847221163,
},
0xeb6e,
0xeb71,
@ -629,8 +627,8 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_height = 2.0197238658777121,
.group_y = 0.2524414062500000,
.group_height = 2.0183246073298431,
.group_y = 0.2522697795071336,
},
0xeb6f,
=> .{
@ -639,8 +637,8 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 2.0098619329388558,
.group_x = 0.2492639842983317,
.group_width = 2.0104712041884816,
.group_x = 0.2493489583333333,
},
0xeb70,
=> .{
@ -649,10 +647,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 2.0098619329388558,
.group_height = 1.0039215686274510,
.group_x = 0.2492639842983317,
.group_y = 0.0039062500000000,
.group_width = 2.0104712041884816,
.group_height = 1.0039062500000000,
.group_x = 0.2493489583333333,
.group_y = 0.0038910505836576,
},
0xeb8a,
=> .{
@ -661,10 +659,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 2.8826979472140764,
.group_height = 2.9804097167804766,
.group_x = 0.2634791454730417,
.group_y = 0.3314678485576923,
.group_width = 2.8828125000000000,
.group_height = 2.9818561935339356,
.group_x = 0.2642276422764228,
.group_y = 0.3313050881410256,
},
0xeb9a,
=> .{
@ -673,10 +671,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.1441340782122904,
.group_height = 1.0591799039527152,
.group_x = 0.0683593750000000,
.group_y = 0.0146484375000000,
.group_width = 1.1440626883664857,
.group_height = 1.0595187680461982,
.group_x = 0.0679662802950474,
.group_y = 0.0147523709167545,
},
0xebd5,
=> .{
@ -685,19 +683,19 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0723270440251573,
.group_height = 1.0728129910948141,
.group_y = 0.0678710937500000,
.group_width = 1.0727069351230425,
.group_height = 1.0730882652023592,
.group_y = 0.0681102082395584,
},
0xebd7,
0xebd6,
=> .{
.size_horizontal = .fit,
.size_vertical = .fit,
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_height = 1.0000418544302916,
.group_y = 0.0000418526785714,
.group_height = 1.0003554839321263,
.group_y = 0.0003553576082064,
},
0xec07,
=> .{
@ -706,10 +704,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 2.8615369874243446,
.group_height = 2.9789458113505249,
.group_x = 0.2609446802539727,
.group_y = 0.3313029661016949,
.group_width = 2.8604846818377689,
.group_height = 2.9804665603035656,
.group_x = 0.2615335565120357,
.group_y = 0.3311487268518519,
},
0xec0b,
=> .{
@ -718,9 +716,9 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0722513089005237,
.group_height = 1.0002360944082516,
.group_y = 0.0002360386808388,
.group_width = 1.0721073225265512,
.group_height = 1.0003813300793167,
.group_y = 0.0003811847221163,
},
0xec0c,
=> .{
@ -729,18 +727,17 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.2487804878048780,
.group_x = 0.1992187500000000,
.group_width = 1.2486979166666667,
.group_x = 0.1991657977059437,
},
0xf019,
0xf08c,
=> .{
.size_horizontal = .fit,
.size_vertical = .fit,
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0004882812500000,
.group_width = 1.1253968253968254,
},
0xf030,
0xf03e,
@ -750,9 +747,9 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0004882812500000,
.group_height = 1.1428571428571428,
.group_y = 0.0625000000000000,
.group_width = 1.1253968253968254,
.group_height = 1.1426844014510278,
.group_y = 0.0624338624338624,
},
0xf03d,
=> .{
@ -761,9 +758,8 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0004882812500000,
.group_height = 1.5014662756598240,
.group_y = 0.1669921875000000,
.group_height = 1.3328631875881523,
.group_y = 0.1248677248677249,
},
0xf03f,
=> .{
@ -772,8 +768,8 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.6018762826150690,
.group_x = 0.1876220107369448,
.group_width = 1.8003104407193382,
.group_x = 0.0005406676069582,
},
0xf040,
=> .{
@ -782,10 +778,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0006976906439684,
.group_height = 1.0001808776182035,
.group_x = 0.0006972042111134,
.group_y = 0.0001808449074074,
.group_width = 1.1263939384681190,
.group_height = 1.0007255897868335,
.group_x = 0.0003164442515641,
.group_y = 0.0001959631589261,
},
0xf044,
=> .{
@ -794,10 +790,9 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.1029147024980515,
.group_height = 1.1024142703367676,
.group_x = 0.0463592039005675,
.group_y = 0.0430325010461710,
.group_width = 1.0087313432835820,
.group_height = 1.0077472527472529,
.group_y = 0.0002010014265405,
},
0xf04a,
=> .{
@ -806,9 +801,9 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0004882812500000,
.group_height = 1.3312975252838291,
.group_y = 0.1245571402616279,
.group_width = 1.1253968253968254,
.group_height = 1.3321224771947897,
.group_y = 0.1247354497354497,
},
0xf051,
=> .{
@ -817,10 +812,9 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.6007812500000000,
.group_height = 1.3312170271945341,
.group_x = 0.1874084919472914,
.group_y = 0.1245117187500000,
.group_width = 1.7994923857868019,
.group_height = 1.3321224771947897,
.group_y = 0.1247354497354497,
},
0xf052,
=> .{
@ -829,10 +823,9 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.1436671384194865,
.group_height = 1.1430165816326530,
.group_x = 0.0624629273607646,
.group_y = 0.0625610266424885,
.group_width = 1.1439802384724422,
.group_height = 1.1430071621244535,
.group_y = 0.0626172338785870,
},
0xf053,
=> .{
@ -841,14 +834,11 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.8765709864847797,
.group_height = 1.0707191397207079,
.group_x = 0.2332599943628554,
.group_y = 0.0332682382480123,
.group_width = 2.0025185185185186,
.group_height = 1.1416267186919362,
.group_y = 0.0620882827561120,
},
0xf05a...0xf05b,
0xf081,
0xf092,
0xf0aa,
=> .{
.size_horizontal = .fit,
@ -856,9 +846,9 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0005935142780173,
.group_height = 1.0001395089285714,
.group_y = 0.0000697447342726,
.group_width = 1.0012592592592593,
.group_height = 1.0002824582824583,
.group_y = 0.0002010014265405,
},
0xf071,
=> .{
@ -867,10 +857,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0014662756598240,
.group_height = 1.1428571428571428,
.group_x = 0.0004880429477794,
.group_y = 0.0625000000000000,
.group_width = 1.1253968253968254,
.group_height = 1.1426844014510278,
.group_x = 0.0004701457451810,
.group_y = 0.0624338624338624,
},
0xf078,
=> .{
@ -879,10 +869,9 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0717654378877508,
.group_height = 1.8757195185766613,
.group_x = 0.0331834301604062,
.group_y = 0.1670386385827870,
.group_width = 1.1434320241691844,
.group_height = 2.0026841590612778,
.group_y = 0.1879786499051550,
},
0xf07b,
=> .{
@ -891,17 +880,32 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_height = 1.1428571428571428,
.group_y = 0.0625000000000000,
.group_width = 1.1253968253968254,
.group_height = 1.2285368802902055,
.group_y = 0.0930118110236220,
},
0xf09c,
0xf081,
0xf092,
=> .{
.size_horizontal = .fit,
.size_vertical = .fit,
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_height = 1.0810546875000000,
.group_width = 1.1441233373639663,
.group_height = 1.1430071621244535,
.group_y = 0.0626172338785870,
},
0xf08c,
=> .{
.size_horizontal = .fit,
.size_vertical = .fit,
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.2859733978234582,
.group_height = 1.1426844014510278,
.group_y = 0.0624338624338624,
},
0xf09f,
=> .{
@ -910,9 +914,8 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.7506617925122907,
.group_height = 1.0810546875000000,
.group_x = 0.2143937211981567,
.group_width = 1.7489690176588770,
.group_x = 0.0006952841596131,
},
0xf0a1,
=> .{
@ -921,8 +924,9 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0009775171065494,
.group_x = 0.0004882812500000,
.group_width = 1.1253968253968254,
.group_height = 1.0749103295228757,
.group_y = 0.0349409448818898,
},
0xf0a2,
=> .{
@ -931,10 +935,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.1433271023627367,
.group_height = 1.0001395089285714,
.group_x = 0.0624235731978609,
.group_y = 0.0000697447342726,
.group_width = 1.1429529187840552,
.group_height = 1.0002824582824583,
.group_x = 0.0001253913778381,
.group_y = 0.0002010014265405,
},
0xf0a3,
=> .{
@ -943,10 +947,9 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0005760656161586,
.group_height = 1.0001220681837999,
.group_x = 0.0004792774839344,
.group_y = 0.0000610266424885,
.group_width = 1.0005921977940631,
.group_height = 1.0001448722153810,
.group_x = 0.0005918473033957,
},
0xf0a4,
=> .{
@ -955,9 +958,9 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0005935142780173,
.group_height = 1.3335193452380951,
.group_y = 0.1250523085507044,
.group_width = 1.0012592592592593,
.group_height = 1.3332396658348704,
.group_y = 0.1250334663306335,
},
0xf0ca,
=> .{
@ -966,9 +969,9 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0005935142780173,
.group_height = 1.1922501247297521,
.group_y = 0.0806249128190822,
.group_width = 1.0335226652102676,
.group_height = 1.2308163060897437,
.group_y = 0.0938253501046103,
},
0xf0d6,
=> .{
@ -977,8 +980,8 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_height = 1.5014662756598240,
.group_y = 0.1669921875000000,
.group_height = 1.4330042313117066,
.group_y = 0.1510826771653543,
},
0xf0de,
=> .{
@ -987,10 +990,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.2253421114919656,
.group_height = 2.5216400911161729,
.group_x = 0.0918898809523810,
.group_y = 0.6034327009936766,
.group_width = 1.3984670905653893,
.group_height = 2.6619718309859155,
.group_x = 0.0004030632809351,
.group_y = 0.5708994708994709,
},
0xf0e7,
=> .{
@ -999,8 +1002,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.3336843856081169,
.group_x = 0.1247597299147187,
.group_width = 1.3348918927786344,
.group_height = 1.0001196386424678,
.group_x = 0.0006021702214782,
.group_y = 0.0001196243307751,
},
0xf296,
=> .{
@ -1009,21 +1014,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0005148743038617,
.group_height = 1.0385966606705219,
.group_x = 0.0005146093447336,
.group_y = 0.0186218440507742,
},
0xf2c2...0xf2c3,
=> .{
.size_horizontal = .fit,
.size_vertical = .fit,
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0000770970394737,
.group_height = 1.2864321608040201,
.group_y = 0.1113281250000000,
.group_width = 1.0005202277820979,
.group_height = 1.0386597451628128,
.group_x = 0.0001795653226322,
.group_y = 0.0187142907131644,
},
0xf2c4,
=> .{
@ -1032,8 +1026,7 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0344231791600214,
.group_x = 0.0166002826673519,
.group_width = 1.3292088488938882,
},
0xf2c5,
=> .{
@ -1042,10 +1035,10 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0004538836055876,
.group_height = 1.4840579710144928,
.group_x = 0.0004536776887225,
.group_y = 0.1630859375000000,
.group_width = 1.0118264574212998,
.group_height = 1.1664315937940761,
.group_x = 0.0004377219006858,
.group_y = 0.0713422007255139,
},
0xf2f0,
=> .{
@ -1054,9 +1047,9 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.0005935142780173,
.group_height = 1.0334438518091393,
.group_y = 0.0161807783512345,
.group_width = 1.0012592592592593,
.group_height = 1.0342088873926949,
.group_y = 0.0165984862232646,
},
0xf306,
=> .{
@ -1065,8 +1058,7 @@ pub fn getConstraint(cp: u21) Constraint {
.height = .icon,
.align_horizontal = .center,
.align_vertical = .center,
.group_width = 1.2427184466019416,
.group_x = 0.0976562500000000,
.group_width = 1.3001222493887530,
},
else => .none,
};

View File

@ -9,7 +9,7 @@ be safe and not malicious or anything.
This script requires Python 3.12 or greater, requires that the `fontTools`
python module is installed, and requires that the path to a copy of the
SymbolsNerdFontMono font is passed as the first argument to the script.
SymbolsNerdFont (not Mono!) font is passed as the first argument to it.
"""
import ast

View File

@ -1779,19 +1779,27 @@ fn testShaperWithFont(alloc: Allocator, font_req: TestFont) !TestShaper {
c.load_options = .{ .library = lib };
// Setup group
_ = try c.add(alloc, .regular, .{ .loaded = try .init(
_ = try c.add(alloc, try .init(
lib,
testFont,
.{ .size = .{ .points = 12 } },
) });
), .{
.style = .regular,
.fallback = false,
.size_adjustment = .none,
});
if (font.options.backend != .coretext) {
// Coretext doesn't support Noto's format
_ = try c.add(alloc, .regular, .{ .loaded = try .init(
_ = try c.add(alloc, try .init(
lib,
testEmoji,
.{ .size = .{ .points = 12 } },
) });
), .{
.style = .regular,
.fallback = false,
.size_adjustment = .none,
});
} else {
// On CoreText we want to load Apple Emoji, we should have it.
var disco = font.Discover.init();
@ -1804,13 +1812,21 @@ fn testShaperWithFont(alloc: Allocator, font_req: TestFont) !TestShaper {
defer disco_it.deinit();
var face = (try disco_it.next()).?;
errdefer face.deinit();
_ = try c.add(alloc, .regular, .{ .deferred = face });
_ = try c.addDeferred(alloc, face, .{
.style = .regular,
.fallback = false,
.size_adjustment = .none,
});
}
_ = try c.add(alloc, .regular, .{ .loaded = try .init(
_ = try c.add(alloc, try .init(
lib,
testEmojiText,
.{ .size = .{ .points = 12 } },
) });
), .{
.style = .regular,
.fallback = false,
.size_adjustment = .none,
});
const grid_ptr = try alloc.create(SharedGrid);
errdefer alloc.destroy(grid_ptr);

View File

@ -158,16 +158,11 @@ pub const Shaper = struct {
.glyph_index = info_v.codepoint,
});
if (font.options.backend.hasFreetype()) {
// Freetype returns 26.6 fixed point values, so we need to
// divide by 64 to get the actual value. I can't find any
// HB API to stop this.
cell_offset.x += pos_v.x_advance >> 6;
cell_offset.y += pos_v.y_advance >> 6;
} else {
cell_offset.x += pos_v.x_advance;
cell_offset.y += pos_v.y_advance;
}
// Under both FreeType and CoreText the harfbuzz scale is
// in 26.6 fixed point units, so we round to the nearest
// whole value here.
cell_offset.x += (pos_v.x_advance + 0b100_000) >> 6;
cell_offset.y += (pos_v.y_advance + 0b100_000) >> 6;
// const i = self.cell_buf.items.len - 1;
// log.warn("i={} info={} pos={} cell={}", .{ i, info_v, pos_v, self.cell_buf.items[i] });
@ -1247,19 +1242,27 @@ fn testShaperWithFont(alloc: Allocator, font_req: TestFont) !TestShaper {
c.load_options = .{ .library = lib };
// Setup group
_ = try c.add(alloc, .regular, .{ .loaded = try .init(
_ = try c.add(alloc, try .init(
lib,
testFont,
.{ .size = .{ .points = 12 } },
) });
), .{
.style = .regular,
.fallback = false,
.size_adjustment = .none,
});
if (comptime !font.options.backend.hasCoretext()) {
// Coretext doesn't support Noto's format
_ = try c.add(alloc, .regular, .{ .loaded = try .init(
_ = try c.add(alloc, try .init(
lib,
testEmoji,
.{ .size = .{ .points = 12 } },
) });
), .{
.style = .regular,
.fallback = false,
.size_adjustment = .none,
});
} else {
// On CoreText we want to load Apple Emoji, we should have it.
var disco = font.Discover.init();
@ -1272,13 +1275,21 @@ fn testShaperWithFont(alloc: Allocator, font_req: TestFont) !TestShaper {
defer disco_it.deinit();
var face = (try disco_it.next()).?;
errdefer face.deinit();
_ = try c.add(alloc, .regular, .{ .deferred = face });
_ = try c.addDeferred(alloc, face, .{
.style = .regular,
.fallback = false,
.size_adjustment = .none,
});
}
_ = try c.add(alloc, .regular, .{ .loaded = try .init(
_ = try c.add(alloc, try .init(
lib,
testEmojiText,
.{ .size = .{ .points = 12 } },
) });
), .{
.style = .regular,
.fallback = false,
.size_adjustment = .none,
});
const grid_ptr = try alloc.create(SharedGrid);
errdefer alloc.destroy(grid_ptr);

View File

@ -389,6 +389,9 @@ fn testDrawRanges(
const alloc = testing.allocator;
const metrics: font.Metrics = .calc(.{
// Fudged number, not used in anything we care about here.
.px_per_em = 16,
.cell_width = @floatFromInt(width),
.ascent = @floatFromInt(ascent),
.descent = -@as(f64, @floatFromInt(descent)),