From 964a0c8eb3cc4f3737a334eaf27cfb31627577ca Mon Sep 17 00:00:00 2001 From: Fini Jastrow Date: Tue, 7 Mar 2023 19:49:41 +0100 Subject: [PATCH] font-patcher: Fix alignment with overlap [why] Some few glyphs get a wrong left side bearing in `Nerd Font`: E0C2: -1230 E0C5: -857 E0C7: -667 E0CA: -1230 These are the powerline glyphs which are right aligned and have overlap and a target width of 2 cells wide. [how] To simplify the code add a new function that decides if a symbol shall be one or two cells wide. That function is then used where we had explicit tests already. Use the function also in the overlap correction code, such that the overlap is corrected for the right cell occupancy of the concrete glyph. [note] I guess that the overlap correction for 'c' alignment for 2 cell wide glyphs is also broken. But we do not have such glyphs, so we ignore it for now :-} This fixes the previous commit 'font-patcher: Fix overlap for align c and r'. Signed-off-by: Fini Jastrow --- font-patcher | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/font-patcher b/font-patcher index d89ff1f60..5eeb3b68d 100755 --- a/font-patcher +++ b/font-patcher @@ -1144,19 +1144,21 @@ class font_patcher: # print("FINAL", self.font_dim) + def get_target_width(self, stretch): + """ Get the target width (1 or 2 'cell') for a given stretch parameter """ + # For monospaced fonts all chars need to be maximum 'one' space wide + # other fonts allows double width glyphs for 'pa' or if requested with '2' + if self.args.single or ('pa' not in stretch and '2' not in stretch) or '1' in stretch: + return 1 + return 2 + def get_scale_factors(self, sym_dim, stretch): """ Get scale in x and y as tuple """ # It is possible to have empty glyphs, so we need to skip those. if not sym_dim['width'] or not sym_dim['height']: return (1.0, 1.0) - # For monospaced fonts all chars need to be maximum 'one' space wide - # other fonts allows double width glyphs for 'pa' or if requested with '2' - if self.args.single or ('pa' not in stretch and '2' not in stretch) or '1' in stretch: - relative_width = 1.0 - else: - relative_width = 2.0 - target_width = self.font_dim['width'] * relative_width + target_width = self.font_dim['width'] * self.get_target_width(stretch) scale_ratio_x = target_width / sym_dim['width'] # font_dim['height'] represents total line height, keep our symbols sized based upon font's em @@ -1351,9 +1353,7 @@ class font_patcher: x_align_distance += (self.font_dim['width'] / 2) - (sym_dim['width'] / 2) elif sym_attr['align'] == 'r': # Right align - x_align_distance += self.font_dim['width'] - sym_dim['width'] - if not self.args.single and '2' in sym_attr['stretch']: - x_align_distance += self.font_dim['width'] + x_align_distance += self.font_dim['width'] * self.get_target_width(sym_attr['stretch']) - sym_dim['width'] # If symbol glyph is wider than target font cell, just left-align x_align_distance = max(self.font_dim['xmin'] - sym_dim['xmin'], x_align_distance) @@ -1366,8 +1366,10 @@ class font_patcher: x_align_distance -= overlap_width / 2 elif sym_attr['align'] == 'r': # Check and correct overlap; it can go wrong if we have a xy-ratio limit - correction = ((self.font_dim['xmin'] + self.font_dim['width'] + overlap_width) - - (sym_dim['xmax'] + x_align_distance)) + target_xmax = (self.font_dim['xmin'] + self.font_dim['width']) * self.get_target_width(sym_attr['stretch']) + target_xmax += overlap_width + glyph_xmax = sym_dim['xmax'] + x_align_distance + correction = target_xmax - glyph_xmax x_align_distance += correction align_matrix = psMat.translate(x_align_distance, y_align_distance)