diff options
Diffstat (limited to 'src/font/nerd_font_codegen.py')
| -rw-r--r-- | src/font/nerd_font_codegen.py | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/src/font/nerd_font_codegen.py b/src/font/nerd_font_codegen.py index a973c6c6e..c7d592798 100644 --- a/src/font/nerd_font_codegen.py +++ b/src/font/nerd_font_codegen.py @@ -302,14 +302,23 @@ def generate_zig_switch_arms( print(f"Info: Extracting rules from patch set '{entry['Name']}'") attributes = entry["Attributes"] - for cp in range(entry["SymStart"], entry["SymEnd"] + 1): - if cp not in cmap: - print(f"Info: Skipping missing codepoint {hex(cp)}") + # A glyph's scale rules are specified using its codepoint in + # the original font, which is sometimes different from its + # Nerd Font codepoint. In font_patcher, the font to be patched + # (including the Symbols Only font embedded in Ghostty) is + # termed the sourceFont, while the original font is the + # symbolFont. Thus, the offset that maps the scale rule + # codepoint to the Nerd Font codepoint is SrcStart - SymStart. + cp_offset = entry["SrcStart"] - entry["SymStart"] if entry["SrcStart"] else 0 + for cp_rule in range(entry["SymStart"], entry["SymEnd"] + 1): + cp_font = cp_rule + cp_offset + if cp_font not in cmap: + print(f"Info: Skipping missing codepoint {hex(cp_font)}") continue - if cp in attributes: - entries[cp] = attributes[cp].copy() + if cp_rule in attributes: + entries[cp_font] = attributes[cp_rule].copy() else: - entries[cp] = attributes["default"].copy() + entries[cp_font] = attributes["default"].copy() if entry["ScaleRules"] is not None: if "ScaleGroups" not in entry["ScaleRules"]: @@ -323,14 +332,15 @@ def generate_zig_switch_arms( yMax = -math.inf individual_bounds: dict[int, tuple[int, int, int, int]] = {} individual_advances: set[float] = set() - for cp in group: - if cp not in cmap: + for cp_rule in group: + cp_font = cp_rule + cp_offset + if cp_font not in cmap: continue - glyph = glyphs[cmap[cp]] + glyph = glyphs[cmap[cp_font]] individual_advances.add(glyph.width) bounds = BoundsPen(glyphSet=glyphs) glyph.draw(bounds) - individual_bounds[cp] = bounds.bounds + individual_bounds[cp_font] = bounds.bounds xMin = min(bounds.bounds[0], xMin) yMin = min(bounds.bounds[1], yMin) xMax = max(bounds.bounds[2], xMax) @@ -340,27 +350,30 @@ def generate_zig_switch_arms( group_is_monospace = (len(individual_bounds) > 1) and ( len(individual_advances) == 1 ) - for cp in group: + for cp_rule in group: + cp_font = cp_rule + cp_offset if ( - cp not in cmap - or cp not in entries + cp_font not in cmap + or cp_font not in entries # Codepoints may contribute to the bounding box of multiple groups, # but should be scaled according to the first group they are found # in. Hence, to avoid overwriting, we need to skip codepoints that # have already been assigned a scale group. - or "relative_height" in entries[cp] + or "relative_height" in entries[cp_font] ): continue - this_bounds = individual_bounds[cp] + this_bounds = individual_bounds[cp_font] this_height = this_bounds[3] - this_bounds[1] - entries[cp]["relative_height"] = this_height / group_height - entries[cp]["relative_y"] = (this_bounds[1] - yMin) / group_height + entries[cp_font]["relative_height"] = this_height / group_height + entries[cp_font]["relative_y"] = ( + this_bounds[1] - yMin + ) / group_height # Horizontal alignment should only be grouped if the group is monospace, # that is, if all glyphs in the group have the same advance width. if group_is_monospace: this_width = this_bounds[2] - this_bounds[0] - entries[cp]["relative_width"] = this_width / group_width - entries[cp]["relative_x"] = ( + entries[cp_font]["relative_width"] = this_width / group_width + entries[cp_font]["relative_x"] = ( this_bounds[0] - xMin ) / group_width |
