mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
font: add scale groups to nerd font constraints
We do this by characterizing the shared bounding boxes in a static copy of the symbols only nerd font when we're doing the codegen. This allows us to get results of our scaling that are just as good as in a patched font, since related glyphs can now be sized and positioned relative to each other.
This commit is contained in:
@ -144,6 +144,23 @@ pub const RenderOptions = struct {
|
|||||||
/// Bottom padding when resizing.
|
/// Bottom padding when resizing.
|
||||||
pad_bottom: f64 = 0.0,
|
pad_bottom: f64 = 0.0,
|
||||||
|
|
||||||
|
// This acts as a multiple of the provided width when applying
|
||||||
|
// constraints, so if this is 1.6 for example, then a width of
|
||||||
|
// 10 would be treated as though it were 16.
|
||||||
|
group_width: f64 = 1.0,
|
||||||
|
// This acts as a multiple of the provided height when applying
|
||||||
|
// constraints, so if this is 1.6 for example, then a height of
|
||||||
|
// 10 would be treated as though it were 16.
|
||||||
|
group_height: f64 = 1.0,
|
||||||
|
// This is an x offset for the actual width within the group width.
|
||||||
|
// If this is 0.5 then the glyph will be offset so that its left
|
||||||
|
// edge sits at the halfway point of the group width.
|
||||||
|
group_x: f64 = 0.0,
|
||||||
|
// This is a y offset for the actual height within the group height.
|
||||||
|
// If this is 0.5 then the glyph will be offset so that its bottom
|
||||||
|
// edge sits at the halfway point of the group height.
|
||||||
|
group_y: f64 = 0.0,
|
||||||
|
|
||||||
/// Maximum ratio of width to height when resizing.
|
/// Maximum ratio of width to height when resizing.
|
||||||
max_xy_ratio: ?f64 = null,
|
max_xy_ratio: ?f64 = null,
|
||||||
|
|
||||||
@ -245,6 +262,10 @@ pub const RenderOptions = struct {
|
|||||||
g.x -= self.pad_left * available_width;
|
g.x -= self.pad_left * available_width;
|
||||||
g.y -= self.pad_bottom * available_height;
|
g.y -= self.pad_bottom * available_height;
|
||||||
|
|
||||||
|
// Multiply by group width and height for better sizing.
|
||||||
|
g.width *= self.group_width;
|
||||||
|
g.height *= self.group_height;
|
||||||
|
|
||||||
switch (self.size_horizontal) {
|
switch (self.size_horizontal) {
|
||||||
.none => {},
|
.none => {},
|
||||||
.fit => if (g.width > w) {
|
.fit => if (g.width > w) {
|
||||||
@ -323,6 +344,14 @@ pub const RenderOptions = struct {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add group-relative position
|
||||||
|
g.x += self.group_x * g.width;
|
||||||
|
g.y += self.group_y * g.height;
|
||||||
|
|
||||||
|
// Divide group width and height back out before we align.
|
||||||
|
g.width /= self.group_width;
|
||||||
|
g.height /= self.group_height;
|
||||||
|
|
||||||
if (self.max_xy_ratio) |ratio| if (g.width > g.height * ratio) {
|
if (self.max_xy_ratio) |ratio| if (g.width > g.height * ratio) {
|
||||||
const orig_width = g.width;
|
const orig_width = g.width;
|
||||||
g.width = g.height * ratio;
|
g.width = g.height * ratio;
|
||||||
|
@ -34,7 +34,35 @@ pub fn getConstraint(cp: u21) Constraint {
|
|||||||
.pad_top = 0.1,
|
.pad_top = 0.1,
|
||||||
.pad_bottom = 0.1,
|
.pad_bottom = 0.1,
|
||||||
},
|
},
|
||||||
0x276c...0x2771,
|
0x276c...0x276d,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .cover,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.max_constraint_width = 1,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.4028056112224450,
|
||||||
|
.group_height = 1.1222570532915361,
|
||||||
|
.group_x = 0.1428571428571428,
|
||||||
|
.group_y = 0.0349162011173184,
|
||||||
|
.pad_top = 0.15,
|
||||||
|
.pad_bottom = 0.15,
|
||||||
|
},
|
||||||
|
0x276e...0x276f,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .cover,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.max_constraint_width = 1,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0115606936416186,
|
||||||
|
.group_height = 1.1222570532915361,
|
||||||
|
.group_x = 0.0057142857142857,
|
||||||
|
.group_y = 0.0125698324022346,
|
||||||
|
.pad_top = 0.15,
|
||||||
|
.pad_bottom = 0.15,
|
||||||
|
},
|
||||||
|
0x2770...0x2771,
|
||||||
=> .{
|
=> .{
|
||||||
.size_horizontal = .cover,
|
.size_horizontal = .cover,
|
||||||
.size_vertical = .fit,
|
.size_vertical = .fit,
|
||||||
@ -357,8 +385,46 @@ pub fn getConstraint(cp: u21) Constraint {
|
|||||||
0x2b58,
|
0x2b58,
|
||||||
0xe000...0xe0a9,
|
0xe000...0xe0a9,
|
||||||
0xe4fa...0xe7ef,
|
0xe4fa...0xe7ef,
|
||||||
0xea60...0xec1e,
|
0xea60,
|
||||||
0xed00...0xf847,
|
0xea62...0xea7c,
|
||||||
|
0xea7e...0xea98,
|
||||||
|
0xeaa3...0xeab3,
|
||||||
|
0xeab8...0xead3,
|
||||||
|
0xead7...0xeb42,
|
||||||
|
0xeb44...0xeb6d,
|
||||||
|
0xeb72...0xeb89,
|
||||||
|
0xeb8b...0xeb99,
|
||||||
|
0xeb9b...0xebd4,
|
||||||
|
0xebd6,
|
||||||
|
0xebd8...0xec06,
|
||||||
|
0xec08...0xec0a,
|
||||||
|
0xec0d...0xec1e,
|
||||||
|
0xed00...0xf018,
|
||||||
|
0xf01a...0xf02f,
|
||||||
|
0xf031...0xf03c,
|
||||||
|
0xf041...0xf043,
|
||||||
|
0xf045...0xf049,
|
||||||
|
0xf04b...0xf050,
|
||||||
|
0xf054...0xf059,
|
||||||
|
0xf05c...0xf070,
|
||||||
|
0xf072...0xf077,
|
||||||
|
0xf079...0xf07a,
|
||||||
|
0xf07c...0xf080,
|
||||||
|
0xf082...0xf08b,
|
||||||
|
0xf08d...0xf091,
|
||||||
|
0xf093...0xf09b,
|
||||||
|
0xf09d...0xf09e,
|
||||||
|
0xf0a0,
|
||||||
|
0xf0a5...0xf0a9,
|
||||||
|
0xf0ab...0xf0c9,
|
||||||
|
0xf0cb...0xf0d5,
|
||||||
|
0xf0d7...0xf0dd,
|
||||||
|
0xf0df...0xf0e6,
|
||||||
|
0xf0e8...0xf295,
|
||||||
|
0xf297...0xf2c1,
|
||||||
|
0xf2c6...0xf2ef,
|
||||||
|
0xf2f1...0xf305,
|
||||||
|
0xf307...0xf847,
|
||||||
0xf0001...0xf1af0,
|
0xf0001...0xf1af0,
|
||||||
=> .{
|
=> .{
|
||||||
.size_horizontal = .fit,
|
.size_horizontal = .fit,
|
||||||
@ -367,6 +433,641 @@ pub fn getConstraint(cp: u21) Constraint {
|
|||||||
.align_horizontal = .center,
|
.align_horizontal = .center,
|
||||||
.align_vertical = .center,
|
.align_vertical = .center,
|
||||||
},
|
},
|
||||||
|
0xea61,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.3315669947009841,
|
||||||
|
.group_height = 1.0763840224246670,
|
||||||
|
.group_x = 0.0847072200113701,
|
||||||
|
.group_y = 0.0709635416666667,
|
||||||
|
},
|
||||||
|
0xea7d,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.1913145539906103,
|
||||||
|
.group_height = 1.1428571428571428,
|
||||||
|
.group_x = 0.0916256157635468,
|
||||||
|
.group_y = 0.0415039062500000,
|
||||||
|
},
|
||||||
|
0xea99,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0639412997903563,
|
||||||
|
.group_height = 2.0940695296523519,
|
||||||
|
.group_x = 0.0295566502463054,
|
||||||
|
.group_y = 0.2270507812500000,
|
||||||
|
},
|
||||||
|
0xea9a,
|
||||||
|
0xeaa1,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.3029525032092426,
|
||||||
|
.group_height = 1.1729667812142039,
|
||||||
|
.group_x = 0.1527093596059113,
|
||||||
|
.group_y = 0.0751953125000000,
|
||||||
|
},
|
||||||
|
0xea9b,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.1639908256880733,
|
||||||
|
.group_height = 1.3128205128205128,
|
||||||
|
.group_x = 0.0719211822660099,
|
||||||
|
.group_y = 0.0869140625000000,
|
||||||
|
},
|
||||||
|
0xea9c,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.1639908256880733,
|
||||||
|
.group_height = 1.3195876288659794,
|
||||||
|
.group_x = 0.0719211822660099,
|
||||||
|
.group_y = 0.0830078125000000,
|
||||||
|
},
|
||||||
|
0xea9d,
|
||||||
|
0xeaa0,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 2.4457831325301207,
|
||||||
|
.group_height = 1.9692307692307693,
|
||||||
|
.group_x = 0.2857142857142857,
|
||||||
|
.group_y = 0.2763671875000000,
|
||||||
|
},
|
||||||
|
0xea9e...0xea9f,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.9556840077071291,
|
||||||
|
.group_height = 2.4674698795180725,
|
||||||
|
.group_x = 0.2137931034482759,
|
||||||
|
.group_y = 0.3066406250000000,
|
||||||
|
},
|
||||||
|
0xeaa2,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.2412121212121212,
|
||||||
|
.group_height = 1.0591799039527152,
|
||||||
|
.group_x = 0.0683593750000000,
|
||||||
|
.group_y = 0.0146484375000000,
|
||||||
|
},
|
||||||
|
0xeab4,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0049115913555993,
|
||||||
|
.group_height = 1.8998144712430427,
|
||||||
|
.group_y = 0.2026367187500000,
|
||||||
|
},
|
||||||
|
0xeab5,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.8979591836734695,
|
||||||
|
.group_height = 1.0054000981836033,
|
||||||
|
.group_x = 0.2023460410557185,
|
||||||
|
.group_y = 0.0053710937500000,
|
||||||
|
},
|
||||||
|
0xeab6,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.8979591836734695,
|
||||||
|
.group_height = 1.0054000981836033,
|
||||||
|
.group_x = 0.2707722385141740,
|
||||||
|
},
|
||||||
|
0xeab7,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0049115913555993,
|
||||||
|
.group_height = 1.8980537534754403,
|
||||||
|
.group_x = 0.0048875855327468,
|
||||||
|
.group_y = 0.2709960937500000,
|
||||||
|
},
|
||||||
|
0xead4...0xead5,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.4152542372881356,
|
||||||
|
.group_x = 0.1486118671747414,
|
||||||
|
},
|
||||||
|
0xead6,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_height = 1.1390433815350389,
|
||||||
|
.group_y = 0.0688476562500000,
|
||||||
|
},
|
||||||
|
0xeb43,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.3635153129161119,
|
||||||
|
.group_height = 1.0002360944082516,
|
||||||
|
.group_x = 0.1992187500000000,
|
||||||
|
.group_y = 0.0002360386808388,
|
||||||
|
},
|
||||||
|
0xeb6e,
|
||||||
|
0xeb71,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_height = 2.0197238658777121,
|
||||||
|
.group_y = 0.2524414062500000,
|
||||||
|
},
|
||||||
|
0xeb6f,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 2.0098619329388558,
|
||||||
|
.group_x = 0.2492639842983317,
|
||||||
|
},
|
||||||
|
0xeb70,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 2.0098619329388558,
|
||||||
|
.group_height = 1.0039215686274510,
|
||||||
|
.group_x = 0.2492639842983317,
|
||||||
|
.group_y = 0.0039062500000000,
|
||||||
|
},
|
||||||
|
0xeb8a,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 2.8826979472140764,
|
||||||
|
.group_height = 2.9804097167804766,
|
||||||
|
.group_x = 0.2634791454730417,
|
||||||
|
.group_y = 0.3314678485576923,
|
||||||
|
},
|
||||||
|
0xeb9a,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.1441340782122904,
|
||||||
|
.group_height = 1.0591799039527152,
|
||||||
|
.group_x = 0.0683593750000000,
|
||||||
|
.group_y = 0.0146484375000000,
|
||||||
|
},
|
||||||
|
0xebd5,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0723270440251573,
|
||||||
|
.group_height = 1.0728129910948141,
|
||||||
|
.group_y = 0.0678710937500000,
|
||||||
|
},
|
||||||
|
0xebd7,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_height = 1.0000418544302916,
|
||||||
|
.group_y = 0.0000418526785714,
|
||||||
|
},
|
||||||
|
0xec07,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 2.8615369874243446,
|
||||||
|
.group_height = 2.9789458113505249,
|
||||||
|
.group_x = 0.2609446802539727,
|
||||||
|
.group_y = 0.3313029661016949,
|
||||||
|
},
|
||||||
|
0xec0b,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0722513089005237,
|
||||||
|
.group_height = 1.0002360944082516,
|
||||||
|
.group_y = 0.0002360386808388,
|
||||||
|
},
|
||||||
|
0xec0c,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.2487804878048780,
|
||||||
|
.group_x = 0.1992187500000000,
|
||||||
|
},
|
||||||
|
0xf019,
|
||||||
|
0xf08c,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0004882812500000,
|
||||||
|
},
|
||||||
|
0xf030,
|
||||||
|
0xf03e,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0004882812500000,
|
||||||
|
.group_height = 1.1428571428571428,
|
||||||
|
.group_y = 0.0625000000000000,
|
||||||
|
},
|
||||||
|
0xf03d,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0004882812500000,
|
||||||
|
.group_height = 1.5014662756598240,
|
||||||
|
.group_y = 0.1669921875000000,
|
||||||
|
},
|
||||||
|
0xf03f,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.6018762826150690,
|
||||||
|
.group_x = 0.1876220107369448,
|
||||||
|
},
|
||||||
|
0xf040,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0006976906439684,
|
||||||
|
.group_height = 1.0001808776182035,
|
||||||
|
.group_x = 0.0006972042111134,
|
||||||
|
.group_y = 0.0001808449074074,
|
||||||
|
},
|
||||||
|
0xf044,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.1029147024980515,
|
||||||
|
.group_height = 1.1024142703367676,
|
||||||
|
.group_x = 0.0463592039005675,
|
||||||
|
.group_y = 0.0430325010461710,
|
||||||
|
},
|
||||||
|
0xf04a,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0004882812500000,
|
||||||
|
.group_height = 1.3312975252838291,
|
||||||
|
.group_y = 0.1245571402616279,
|
||||||
|
},
|
||||||
|
0xf051,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.6007812500000000,
|
||||||
|
.group_height = 1.3312170271945341,
|
||||||
|
.group_x = 0.1874084919472914,
|
||||||
|
.group_y = 0.1245117187500000,
|
||||||
|
},
|
||||||
|
0xf052,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.1436671384194865,
|
||||||
|
.group_height = 1.1430165816326530,
|
||||||
|
.group_x = 0.0624629273607646,
|
||||||
|
.group_y = 0.0625610266424885,
|
||||||
|
},
|
||||||
|
0xf053,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.8765709864847797,
|
||||||
|
.group_height = 1.0707191397207079,
|
||||||
|
.group_x = 0.2332599943628554,
|
||||||
|
.group_y = 0.0332682382480123,
|
||||||
|
},
|
||||||
|
0xf05a...0xf05b,
|
||||||
|
0xf081,
|
||||||
|
0xf092,
|
||||||
|
0xf0aa,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0005935142780173,
|
||||||
|
.group_height = 1.0001395089285714,
|
||||||
|
.group_y = 0.0000697447342726,
|
||||||
|
},
|
||||||
|
0xf071,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0014662756598240,
|
||||||
|
.group_height = 1.1428571428571428,
|
||||||
|
.group_x = 0.0004880429477794,
|
||||||
|
.group_y = 0.0625000000000000,
|
||||||
|
},
|
||||||
|
0xf078,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0717654378877508,
|
||||||
|
.group_height = 1.8757195185766613,
|
||||||
|
.group_x = 0.0331834301604062,
|
||||||
|
.group_y = 0.1670386385827870,
|
||||||
|
},
|
||||||
|
0xf07b,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_height = 1.1428571428571428,
|
||||||
|
.group_y = 0.0625000000000000,
|
||||||
|
},
|
||||||
|
0xf09c,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_height = 1.0810546875000000,
|
||||||
|
},
|
||||||
|
0xf09f,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.7506617925122907,
|
||||||
|
.group_height = 1.0810546875000000,
|
||||||
|
.group_x = 0.2143937211981567,
|
||||||
|
},
|
||||||
|
0xf0a1,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0009775171065494,
|
||||||
|
.group_x = 0.0004882812500000,
|
||||||
|
},
|
||||||
|
0xf0a2,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.1433271023627367,
|
||||||
|
.group_height = 1.0001395089285714,
|
||||||
|
.group_x = 0.0624235731978609,
|
||||||
|
.group_y = 0.0000697447342726,
|
||||||
|
},
|
||||||
|
0xf0a3,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0005760656161586,
|
||||||
|
.group_height = 1.0001220681837999,
|
||||||
|
.group_x = 0.0004792774839344,
|
||||||
|
.group_y = 0.0000610266424885,
|
||||||
|
},
|
||||||
|
0xf0a4,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0005935142780173,
|
||||||
|
.group_height = 1.3335193452380951,
|
||||||
|
.group_y = 0.1250523085507044,
|
||||||
|
},
|
||||||
|
0xf0ca,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0005935142780173,
|
||||||
|
.group_height = 1.1922501247297521,
|
||||||
|
.group_y = 0.0806249128190822,
|
||||||
|
},
|
||||||
|
0xf0d6,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_height = 1.5014662756598240,
|
||||||
|
.group_y = 0.1669921875000000,
|
||||||
|
},
|
||||||
|
0xf0de,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.2253421114919656,
|
||||||
|
.group_height = 2.5216400911161729,
|
||||||
|
.group_x = 0.0918898809523810,
|
||||||
|
.group_y = 0.6034327009936766,
|
||||||
|
},
|
||||||
|
0xf0e7,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.3336843856081169,
|
||||||
|
.group_x = 0.1247597299147187,
|
||||||
|
},
|
||||||
|
0xf296,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.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,
|
||||||
|
},
|
||||||
|
0xf2c4,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0344231791600214,
|
||||||
|
.group_x = 0.0166002826673519,
|
||||||
|
},
|
||||||
|
0xf2c5,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0004538836055876,
|
||||||
|
.group_height = 1.4840579710144928,
|
||||||
|
.group_x = 0.0004536776887225,
|
||||||
|
.group_y = 0.1630859375000000,
|
||||||
|
},
|
||||||
|
0xf2f0,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.0005935142780173,
|
||||||
|
.group_height = 1.0334438518091393,
|
||||||
|
.group_y = 0.0161807783512345,
|
||||||
|
},
|
||||||
|
0xf306,
|
||||||
|
=> .{
|
||||||
|
.size_horizontal = .fit,
|
||||||
|
.size_vertical = .fit,
|
||||||
|
.height = .icon,
|
||||||
|
.align_horizontal = .center,
|
||||||
|
.align_vertical = .center,
|
||||||
|
.group_width = 1.2427184466019416,
|
||||||
|
.group_x = 0.0976562500000000,
|
||||||
|
},
|
||||||
else => .none,
|
else => .none,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,16 @@ attributes and scaling rules.
|
|||||||
This does include an `eval` call! This is spooky, but we trust the nerd fonts code to
|
This does include an `eval` call! This is spooky, but we trust the nerd fonts code to
|
||||||
be safe and not malicious or anything.
|
be safe and not malicious or anything.
|
||||||
|
|
||||||
This script requires Python 3.12 or greater.
|
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.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import ast
|
import ast
|
||||||
|
import sys
|
||||||
import math
|
import math
|
||||||
|
from fontTools.ttLib import TTFont
|
||||||
|
from fontTools.pens.boundsPen import BoundsPen
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@ -19,7 +24,18 @@ from types import SimpleNamespace
|
|||||||
from typing import Literal, TypedDict, cast
|
from typing import Literal, TypedDict, cast
|
||||||
|
|
||||||
type PatchSetAttributes = dict[Literal["default"] | int, PatchSetAttributeEntry]
|
type PatchSetAttributes = dict[Literal["default"] | int, PatchSetAttributeEntry]
|
||||||
type AttributeHash = tuple[str | None, str | None, str, float, float, float]
|
type AttributeHash = tuple[
|
||||||
|
str | None,
|
||||||
|
str | None,
|
||||||
|
str,
|
||||||
|
float,
|
||||||
|
float,
|
||||||
|
float,
|
||||||
|
float,
|
||||||
|
float,
|
||||||
|
float,
|
||||||
|
float,
|
||||||
|
]
|
||||||
type ResolvedSymbol = PatchSetAttributes | PatchSetScaleRules | int | None
|
type ResolvedSymbol = PatchSetAttributes | PatchSetScaleRules | int | None
|
||||||
|
|
||||||
|
|
||||||
@ -34,6 +50,11 @@ class PatchSetAttributeEntry(TypedDict):
|
|||||||
stretch: str
|
stretch: str
|
||||||
params: dict[str, float | bool]
|
params: dict[str, float | bool]
|
||||||
|
|
||||||
|
group_x: float
|
||||||
|
group_y: float
|
||||||
|
group_width: float
|
||||||
|
group_height: float
|
||||||
|
|
||||||
|
|
||||||
class PatchSet(TypedDict):
|
class PatchSet(TypedDict):
|
||||||
SymStart: int
|
SymStart: int
|
||||||
@ -137,6 +158,10 @@ def attr_key(attr: PatchSetAttributeEntry) -> AttributeHash:
|
|||||||
float(params.get("overlap", 0.0)),
|
float(params.get("overlap", 0.0)),
|
||||||
float(params.get("xy-ratio", -1.0)),
|
float(params.get("xy-ratio", -1.0)),
|
||||||
float(params.get("ypadding", 0.0)),
|
float(params.get("ypadding", 0.0)),
|
||||||
|
float(attr.get("group_x", 0.0)),
|
||||||
|
float(attr.get("group_y", 0.0)),
|
||||||
|
float(attr.get("group_width", 1.0)),
|
||||||
|
float(attr.get("group_height", 1.0)),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -162,6 +187,11 @@ def emit_zig_entry_multikey(codepoints: list[int], attr: PatchSetAttributeEntry)
|
|||||||
stretch = attr.get("stretch", "")
|
stretch = attr.get("stretch", "")
|
||||||
params = attr.get("params", {})
|
params = attr.get("params", {})
|
||||||
|
|
||||||
|
group_x = attr.get("group_x", 0.0)
|
||||||
|
group_y = attr.get("group_y", 0.0)
|
||||||
|
group_width = attr.get("group_width", 1.0)
|
||||||
|
group_height = attr.get("group_height", 1.0)
|
||||||
|
|
||||||
overlap = params.get("overlap", 0.0)
|
overlap = params.get("overlap", 0.0)
|
||||||
xy_ratio = params.get("xy-ratio", -1.0)
|
xy_ratio = params.get("xy-ratio", -1.0)
|
||||||
y_padding = params.get("ypadding", 0.0)
|
y_padding = params.get("ypadding", 0.0)
|
||||||
@ -192,7 +222,6 @@ def emit_zig_entry_multikey(codepoints: list[int], attr: PatchSetAttributeEntry)
|
|||||||
if "^" not in stretch:
|
if "^" not in stretch:
|
||||||
s += " .height = .icon,\n"
|
s += " .height = .icon,\n"
|
||||||
|
|
||||||
|
|
||||||
# There are two cases where we want to limit the constraint width to 1:
|
# There are two cases where we want to limit the constraint width to 1:
|
||||||
# - If there's a `1` in the stretch mode string.
|
# - If there's a `1` in the stretch mode string.
|
||||||
# - If the stretch mode is `xy` and there's not an explicit `2`.
|
# - If the stretch mode is `xy` and there's not an explicit `2`.
|
||||||
@ -204,6 +233,15 @@ def emit_zig_entry_multikey(codepoints: list[int], attr: PatchSetAttributeEntry)
|
|||||||
if valign is not None:
|
if valign is not None:
|
||||||
s += f" .align_vertical = {valign},\n"
|
s += f" .align_vertical = {valign},\n"
|
||||||
|
|
||||||
|
if group_width != 1.0:
|
||||||
|
s += f" .group_width = {group_width:.16f},\n"
|
||||||
|
if group_height != 1.0:
|
||||||
|
s += f" .group_height = {group_height:.16f},\n"
|
||||||
|
if group_x != 0.0:
|
||||||
|
s += f" .group_x = {group_x:.16f},\n"
|
||||||
|
if group_y != 0.0:
|
||||||
|
s += f" .group_y = {group_y:.16f},\n"
|
||||||
|
|
||||||
# `overlap` and `ypadding` are mutually exclusive,
|
# `overlap` and `ypadding` are mutually exclusive,
|
||||||
# this is asserted in the nerd fonts patcher itself.
|
# this is asserted in the nerd fonts patcher itself.
|
||||||
if overlap:
|
if overlap:
|
||||||
@ -226,16 +264,53 @@ def emit_zig_entry_multikey(codepoints: list[int], attr: PatchSetAttributeEntry)
|
|||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
def generate_zig_switch_arms(patch_sets: list[PatchSet]) -> str:
|
def generate_zig_switch_arms(
|
||||||
|
patch_sets: list[PatchSet],
|
||||||
|
nerd_font: TTFont,
|
||||||
|
) -> str:
|
||||||
|
cmap = nerd_font.getBestCmap()
|
||||||
|
glyphs = nerd_font.getGlyphSet()
|
||||||
|
|
||||||
entries: dict[int, PatchSetAttributeEntry] = {}
|
entries: dict[int, PatchSetAttributeEntry] = {}
|
||||||
for entry in patch_sets:
|
for entry in patch_sets:
|
||||||
attributes = entry["Attributes"]
|
attributes = entry["Attributes"]
|
||||||
|
|
||||||
for cp in range(entry["SymStart"], entry["SymEnd"] + 1):
|
for cp in range(entry["SymStart"], entry["SymEnd"] + 1):
|
||||||
entries[cp] = attributes["default"]
|
entries[cp] = attributes["default"].copy()
|
||||||
|
|
||||||
entries |= {k: v for k, v in attributes.items() if isinstance(k, int)}
|
entries |= {k: v for k, v in attributes.items() if isinstance(k, int)}
|
||||||
|
|
||||||
|
if entry["ScaleRules"] is not None and "ScaleGroups" in entry["ScaleRules"]:
|
||||||
|
for group in entry["ScaleRules"]["ScaleGroups"]:
|
||||||
|
xMin = math.inf
|
||||||
|
yMin = math.inf
|
||||||
|
xMax = -math.inf
|
||||||
|
yMax = -math.inf
|
||||||
|
individual_bounds: dict[int, tuple[int, int, int ,int]] = {}
|
||||||
|
for cp in group:
|
||||||
|
if cp not in cmap:
|
||||||
|
continue
|
||||||
|
glyph = glyphs[cmap[cp]]
|
||||||
|
bounds = BoundsPen(glyphSet=glyphs)
|
||||||
|
glyph.draw(bounds)
|
||||||
|
individual_bounds[cp] = bounds.bounds
|
||||||
|
xMin = min(bounds.bounds[0], xMin)
|
||||||
|
yMin = min(bounds.bounds[1], yMin)
|
||||||
|
xMax = max(bounds.bounds[2], xMax)
|
||||||
|
yMax = max(bounds.bounds[3], yMax)
|
||||||
|
group_width = xMax - xMin
|
||||||
|
group_height = yMax - yMin
|
||||||
|
for cp in group:
|
||||||
|
if cp not in cmap or cp not in entries:
|
||||||
|
continue
|
||||||
|
this_bounds = individual_bounds[cp]
|
||||||
|
this_width = this_bounds[2] - this_bounds[0]
|
||||||
|
this_height = this_bounds[3] - this_bounds[1]
|
||||||
|
entries[cp]["group_width"] = group_width / this_width
|
||||||
|
entries[cp]["group_height"] = group_height / this_height
|
||||||
|
entries[cp]["group_x"] = (this_bounds[0] - xMin) / group_width
|
||||||
|
entries[cp]["group_y"] = (this_bounds[1] - yMin) / group_height
|
||||||
|
|
||||||
del entries[0]
|
del entries[0]
|
||||||
|
|
||||||
# Group codepoints by attribute key
|
# Group codepoints by attribute key
|
||||||
@ -256,6 +331,10 @@ def generate_zig_switch_arms(patch_sets: list[PatchSet]) -> str:
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
project_root = Path(__file__).resolve().parents[2]
|
project_root = Path(__file__).resolve().parents[2]
|
||||||
|
|
||||||
|
nf_path = sys.argv[1]
|
||||||
|
|
||||||
|
nerd_font = TTFont(nf_path)
|
||||||
|
|
||||||
patcher_path = project_root / "vendor" / "nerd-fonts" / "font-patcher.py"
|
patcher_path = project_root / "vendor" / "nerd-fonts" / "font-patcher.py"
|
||||||
source = patcher_path.read_text(encoding="utf-8")
|
source = patcher_path.read_text(encoding="utf-8")
|
||||||
patch_set = extract_patch_set_values(source)
|
patch_set = extract_patch_set_values(source)
|
||||||
@ -275,5 +354,5 @@ const Constraint = @import("face.zig").RenderOptions.Constraint;
|
|||||||
pub fn getConstraint(cp: u21) Constraint {
|
pub fn getConstraint(cp: u21) Constraint {
|
||||||
return switch (cp) {
|
return switch (cp) {
|
||||||
""")
|
""")
|
||||||
f.write(generate_zig_switch_arms(patch_set))
|
f.write(generate_zig_switch_arms(patch_set, nerd_font))
|
||||||
f.write("\n else => .none,\n };\n}\n")
|
f.write("\n else => .none,\n };\n}\n")
|
||||||
|
Reference in New Issue
Block a user