Package: emacs;
Reported by: <hafner <at> tutanota.com>
Date: Sat, 1 Oct 2016 15:53:01 UTC
Severity: minor
Tags: fixed, patch
Found in version 25.1
Fixed in version 28.1
Done: Lars Ingebrigtsen <larsi <at> gnus.org>
Bug is archived. No further changes may be made.
Message #23 received at 24582 <at> debbugs.gnu.org (full text, mbox):
From: YAMAMOTO Mitsuharu <mituharu <at> math.s.chiba-u.ac.jp> To: <hafner <at> tutanota.com> Cc: eliz <at> gnu.org, 24582 <at> debbugs.gnu.org Subject: Re: bug#24582: 25.1; liga incorrect work (dublicate) Date: Fri, 07 Oct 2016 08:25:53 +0900
>>>>> On Wed, 05 Oct 2016 14:15:34 +0300, eli <at> fastmail.com said: > Please see the attached screenshot. >> So the problem is text alignment due to display of characters such >> as ⇒, is that right? > Yes I could reproduce it with Hasklig 11pt. Does the following patch work for you? YAMAMOTO Mitsuharu mituharu <at> math.s.chiba-u.ac.jp diff --git a/src/macfont.m b/src/macfont.m index 16e489d..eb7dcd9 100644 --- a/src/macfont.m +++ b/src/macfont.m @@ -1123,7 +1123,10 @@ struct macfont_metrics glyph width. The `width_int' member is an integer that is closest to the width. The `width_frac' member is the fractional adjustment representing a value in [-.5, .5], multiplied by - WIDTH_FRAC_SCALE. For synthetic monospace fonts, they represent + WIDTH_FRAC_SCALE. For monospace fonts, non-zero `width_frac' + means `width_int' is further adjusted to a multiple of the + (rounded) font width, and `width_frac' represents adjustment per + unit character. For synthetic monospace fonts, they represent the advance delta for centering instead of the glyph width. */ signed width_frac : WIDTH_FRAC_BITS, width_int : 16 - WIDTH_FRAC_BITS; }; @@ -1150,6 +1153,27 @@ enum metrics_status #define LCD_FONT_SMOOTHING_LEFT_MARGIN (0.396f) #define LCD_FONT_SMOOTHING_RIGHT_MARGIN (0.396f) +/* If FONT is monospace and WIDTH can be regarded as a multiple of its + width where the multiplier is greater than 1, then return the + multiplier. Otherwise return 0. */ +static int +macfont_monospace_width_multiplier (struct font *font, CGFloat width) +{ + struct macfont_info *macfont_info = (struct macfont_info *) font; + int multiplier = 0; + + if (macfont_info->spacing == MACFONT_SPACING_MONO + && font->space_width != 0) + { + multiplier = lround (width / font->space_width); + if (multiplier == 1 + || lround (width / multiplier) != font->space_width) + multiplier = 0; + } + + return multiplier; +} + static int macfont_glyph_extents (struct font *font, CGGlyph glyph, struct font_metrics *metrics, CGFloat *advance_delta, @@ -1194,13 +1218,38 @@ macfont_glyph_extents (struct font *font, CGGlyph glyph, else fwidth = mac_font_get_advance_width_for_glyph (macfont, glyph); - /* For synthetic mono fonts, cache->width_{int,frac} holds the - advance delta value. */ - if (macfont_info->spacing == MACFONT_SPACING_SYNTHETIC_MONO) - fwidth = (font->pixel_size - fwidth) / 2; - cache->width_int = lround (fwidth); - cache->width_frac = lround ((fwidth - cache->width_int) - * WIDTH_FRAC_SCALE); + if (macfont_info->spacing == MACFONT_SPACING_MONO) + { + /* Some monospace fonts for programming languages contain + wider ligature glyphs consisting of multiple characters. + For such glyphs, simply rounding the combined fractional + width to an integer can result in a value that is not a + multiple of the (rounded) font width. */ + int multiplier = macfont_monospace_width_multiplier (font, fwidth); + + if (multiplier) + { + cache->width_int = font->space_width * multiplier; + cache->width_frac = lround ((fwidth / multiplier + - font->space_width) + * WIDTH_FRAC_SCALE); + } + else + { + cache->width_int = lround (fwidth); + cache->width_frac = 0; + } + } + else + { + /* For synthetic mono fonts, cache->width_{int,frac} holds + the advance delta value. */ + if (macfont_info->spacing == MACFONT_SPACING_SYNTHETIC_MONO) + fwidth = (font->pixel_size - fwidth) / 2; + cache->width_int = lround (fwidth); + cache->width_frac = lround ((fwidth - cache->width_int) + * WIDTH_FRAC_SCALE); + } METRICS_SET_STATUS (cache, METRICS_WIDTH_VALID); } if (macfont_info->spacing == MACFONT_SPACING_SYNTHETIC_MONO) @@ -1237,6 +1286,10 @@ macfont_glyph_extents (struct font *font, CGGlyph glyph, / (CGFloat) (WIDTH_FRAC_SCALE * 2)); break; case MACFONT_SPACING_MONO: + if (cache->width_frac) + bounds.origin.x += - ((cache->width_frac + / (CGFloat) (WIDTH_FRAC_SCALE * 2)) + * (cache->width_int / font->space_width)); break; case MACFONT_SPACING_SYNTHETIC_MONO: bounds.origin.x += (cache->width_int @@ -1273,7 +1326,16 @@ macfont_glyph_extents (struct font *font, CGGlyph glyph, / (CGFloat) (WIDTH_FRAC_SCALE * 2))); break; case MACFONT_SPACING_MONO: - *advance_delta = 0; + if (cache->width_frac) + *advance_delta = 0; + else + { + CGFloat delta = - ((cache->width_frac + / (CGFloat) (WIDTH_FRAC_SCALE * 2)) + * (cache->width_int / font->space_width)); + + *advance_delta = (force_integral_p ? round (delta) : delta); + } break; case MACFONT_SPACING_SYNTHETIC_MONO: *advance_delta = (force_integral_p ? cache->width_int @@ -3139,7 +3201,7 @@ macfont_shape (Lisp_Object lgstring) struct mac_glyph_layout *gl = glyph_layouts + i; EMACS_INT from, to; struct font_metrics metrics; - int xoff, yoff, wadjust; + int xoff, yoff, wadjust, multiplier; if (NILP (lglyph)) { @@ -3192,7 +3254,11 @@ macfont_shape (Lisp_Object lgstring) xoff = lround (gl->advance_delta); yoff = lround (- gl->baseline_delta); - wadjust = lround (gl->advance); + multiplier = macfont_monospace_width_multiplier (font, gl->advance); + if (multiplier) + wadjust = font->space_width * multiplier; + else + wadjust = lround (gl->advance); if (xoff != 0 || yoff != 0 || wadjust != metrics.width) { Lisp_Object vec;
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.