From: YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
To: <hafner@tutanota.com>
Cc: 24582@debbugs.gnu.org
Subject: bug#24582: 25.1; liga incorrect work (dublicate)
Date: Fri, 07 Oct 2016 08:25:53 +0900 [thread overview]
Message-ID: <wlmvihvz3y.wl%mituharu@math.s.chiba-u.ac.jp> (raw)
In-Reply-To: <1475666134.612387.746497785.7FCC6A56@webmail.messagingengine.com>
>>>>> On Wed, 05 Oct 2016 14:15:34 +0300, eli@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@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;
next prev parent reply other threads:[~2016-10-06 23:25 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-01 10:52 bug#24582: 25.1; liga incorrect work (prettify-symbols-mode) hafner
2016-10-02 18:13 ` bug#24582: 25.1; liga incorrect work hafner
2016-10-02 19:50 ` Eli Zaretskii
[not found] ` <KTBc6t3--3-0@tutanota.com>
2016-10-04 6:30 ` Eli Zaretskii
2016-10-05 11:05 ` bug#24582: Fwd: " hafner
2016-10-05 11:15 ` bug#24582: 25.1; liga incorrect work (dublicate) eli
2016-10-06 23:25 ` YAMAMOTO Mitsuharu [this message]
2020-08-11 13:55 ` Lars Ingebrigtsen
2020-08-11 20:01 ` Alan Third
2020-08-12 11:16 ` Lars Ingebrigtsen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=wlmvihvz3y.wl%mituharu@math.s.chiba-u.ac.jp \
--to=mituharu@math.s.chiba-u.ac.jp \
--cc=24582@debbugs.gnu.org \
--cc=hafner@tutanota.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.