-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inconsolata v3.000 letter-spacing is too wide in programs that use Xft #42
Comments
I see this problem on Fedora 30. It happens with both emacs 26.2 and 26.3. |
This is very likely a bug in Emacs and not the font, though I'm happy to apply a workaround. I recommend filing a bug against Emacs and see if they can analyze it. There are a couple of culprits which seem plausible. One is the ligatures (though if that were the case it would probably have triggered with an earlier version). Perhaps a more likely explanation is that when it assembles a family it gets confused and thinks that the expanded widths are the reference for width. |
Done, here it is: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=39082 |
27.0.50 is an old development version of an unknown date. Current Emacs master is at 28.0.50, and the Please make sure you are using the latest Emacs codebase, and make sure your build is with HarfBuzz, which is our default font-backend starting from Emacs 27. FWIW, I see no problems with this font in Emacs 27, but I'm on MS-Windows, not on Fedora. Maybe it's a problem with font software on Fedora. |
Could you please elaborate on this? What do you mean by "assemble a family", and what are the "expanded widths" and where do they come from? And how is this different from the older versions of Inconsolata? I'm not an expert on fonts, but with enough information I could try looking at the relevant Emacs code to see whether it gets confused by this font. TIA |
Also: are the problems with OTF or TTF version of the font? |
And one more question: what does the below produce in an Emacs session with the problematic display?
Please show the full output (take it from the |
I use the fonts from Fedora's
I get |
And if you invoke Emacs as |
Also, can you try the OTF font? |
The OTF font I've downloaded from dl.fedoraproject.org is also afflicted by this bug. |
Using the related Emacs APIs, we've established that Emacs treats the glyphs of this font as if they had width of 29 pixels, instead of the expected 10 or thereabouts. The way Emacs accesses the glyph metrics is as follows: static void block_input (); metrics->lbearing = - extents.x; (where CODE is the index of the glyph for the character in this font). Can the font experts here tell whether this is incorrect, at least with this font, and if so, how to fix it? |
According to https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-01/msg00509.html, this seems to be a bug in Xft, and the workaround is to use the Cairo build of Emacs, which doesn't have this problem. |
@Eli-Zaretskii Thanks for the update, that's useful. Do you know if there's a workaround that can be done in the font in the meantime? |
Sorry, I have no idea. Someone will have to debug Xft and find out where they fail, and then perhaps there could be a workaround in the font. At this point, I don't even know which change in the font triggers this problem in Xft, I just know that both Cairo's |
Fixing this in Xft is unlikely. Is it possible to identify which version of Inconsolata does not have this issue? If so, it might be possible to compare with the problematic version and fix it in the font. |
Answering my own question: git bisect blames the following commit:
|
Thanks for identifying the culprit. However, it is strange that providing ligatures for these somehow affected ASCII letters. Does the actual change explain why that happened? |
I don't know, it's a huge change and I don't know the format at all |
I can confirm that a Cairo build of emacs doesn't the font spacing issue. |
xterm is suffering from the same issue, making Inconsolata 2.012 and following basically unusable in xterm. When comparing the width reported by That matches the output from xterm debug output (compiled with --enable-trace)
version 2.012
|
Seems Inconsolata 3 broke st as well. |
Arch Linux:
And thanks for the Xft pointer. That explains why there is no issue in urxvt or Emacs outside X11... |
See #35 (comment) for an idea to allow building Inconsolata easily without ligatures which could actually completely avoid this problem (and if @raphlinus by default also provided an already built version of Inconsolata without ligatures, then it'd be super easy to just select this variant of Inconsolata in your app settings and all such Xft apps would be good to go). |
COLORFUL also using Noto Mono since Inconsolata recently broke in emacs googlefonts/Inconsolata#42
Inconsolata is broken nowadays, see: googlefonts/Inconsolata#42 https://bugs.archlinux.org/task/65932
It looks allright now on Emacs 27. Is it ok if I close the issue? |
@agreselin could you maybe leave it open and rename the issue to a more generic name to account for |
For monospace fonts, Xft uses the max_advance_width global metric to move the pen after each glyph. For Inconsolata, that's coming out at 20, but the advance.x for the individual glyphs seem to be 7. |
I've checked in st, and xOff value returned in XGlyphInfo is 3 times as high as it should be. As mentioned before it seems to be related to added ligatures (biggest ligature glyph, eg <=> is thrice as big as normal letter). In st apply this patch: diff --git a/x.c b/x.c
index 36dd8bc..68781cf 100644
--- a/x.c
+++ b/x.c
@@ -953,7 +953,7 @@ xloadfont(Font *f, FcPattern *pattern)
f->rbearing = f->match->max_advance_width;
f->height = f->ascent + f->descent;
- f->width = DIVCEIL(extents.xOff, strlen(ascii_printable));
+ f->width = DIVCEIL(extents.xOff > 18 ? extents.xOff / 3 : extents.xOff, strlen(ascii_printable));
return 0;
} Increase the font with Ctrl+Shift+PageUp. The font looks normal. |
I get the same font spacing issue with dmenu. I can confirm that the above patch fixed the font spacing issue in st for me, so tried to apply a similar patch to dmenu but with no luck. Shrinking the xOff value in dmenu's |
As an alternative to @mokulus's patch, using I tested this with success in urxvt: URxvt.font: xft:Inconsolata Regular:family=mono:size=28 and in st: static char *font = "Inconsolata Regular:family=mono:size=26:antialias=true:autohint=true"; Maybe you can try that with dmenu? As a side note, if that doesn't work, I use rofi instead of dmenu (a replacement with added functionality) with inconsolata and I don't have any problem. |
No dice, still weird spacing. Thanks, though. And I used to use rofi, but I prefer dmenu. |
This is also affecting tk apps such as It also affects the tk example apps, so it's not On Arch Linux. |
Inconsolata is my favorite monospaced font, and i can't live without it, but I use suckless dwm/dmenu/st and i can't live without those either, and this problem exists in all 3 of them, anyone found a viable solution for this yet cuz i'm stuck to using the pre 2.012 |
I'm sure this is not the correct fix for Xft, but this has been working for me for about two months now.
|
I'm on 2.24.32 using Inconsolata 3.001. I compiled from source using I believe using Cairo over Xft is still experimental but I have been using my current build for three months and have had no issues. |
wait what do you mean built from source using ./configure --with-cairo ? build the font from source with cairo? |
Fonts such as "Iosevka Fixed" exhibit the problem. These links refer to the same problem with Inconsolata v3.000. https://bugzilla.redhat.com/show_bug.cgi?id=1786054 googlefonts/Inconsolata#42 https://debbugs.gnu.org/cgi/bugreport.cgi?bug=39082 https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-01/msg00509.html https://ask.csdn.net/questions/6153188
googlefonts/Inconsolata#42 https://discourse.nixos.org/t/how-to-fix-broken-inconsolata-font-in-urxvt-on-21-05/13437/4 Signed-off-by: Jakub Sokołowski <jakub@status.im>
Underlying bug: googlefonts/Inconsolata#42 As yet unmerged fix: NixOS/nixpkgs#136647 This PR can be reverted once this fixed is merged upstream.
reverts commit d95f070 there is a bug in later Inconsolata (v3+?) where it has extra wide spacing. this is apparently due to a bug in Xft, which will never be fixed (?) follow googlefonts/Inconsolata#42 for when this will work. the mentioned patch for 'st' does work btw, but urxvt for example still fails to load, we don't know what else will be affected by this, so we will just revert until this is either fixed in Xft, or fixed by a release of Inconsolata without ligatures, as described in googlefonts/Inconsolata#35
@mokulus curious where the value 18 came from in your st patch? Your fix seems to work in st, but not with older versions of Inconsolata prior to these ligatures. The
I do not understand where these large values are coming from though, they seem wildly wrong. According to https://bugzilla.mozilla.org/show_bug.cgi?id=128153#c25 :
So if they are pixels and it's a relative offset, not sure how value can be in the thousands? (these are as seen in gdb and also error prints with I tried with several fonts with and without ligatures, --- a/x.c
+++ b/x.c
@@ -1057,7 +1057,10 @@ xloadfont(Font *f, FcPattern *pattern)
f->rbearing = f->match->max_advance_width;
f->height = f->ascent + f->descent;
- f->width = DIVCEIL(extents.xOff, strlen(ascii_printable));
+ unsigned short xoff = extents.xOff;
+ signed xdelta = xoff - extents.width;
+ _Bool isnewfont = abs(xdelta) > 18;
+ f->width = DIVCEIL(isnewfont ? xoff / 3 : xoff, strlen(ascii_printable));
return 0;
} then Also note, |
Wow, I thought xft upstream is long dead. If not completely, then it would make sense to submit a patch for this behavior there. |
|
@smemsh awesome, thanks a lot! I have now subscribed to that issue in their GitLab. |
I've been meaning to write a more in-depth analysis of this issue with examples, but I just haven't found the time. Essentially there is no "bug" here on the part either side of libxft or Inconsolata, but a clashing of ideology. Ultimately whose responsibility is it to maintain the monospacing of a font? libxft makes the assumption that if a font says that it's monospace then advance width should be the same for every glyph. This would smooth out fonts that have glyphs that have similar but not the same advances, but would have problems in fonts that have glyphs that represent multiple characters. I think the best solution is for the fonts themselves to maintain their advances for each glyph and for libxft to not handle monospace fonts specially. I've thought about the kinds of heuristics libxft would need to make "bad" monospace fonts look good, while not breaking "good" monospace fonts and it's a bit untenable. The very very simple heuristic in use now, using the max advance obviously doesn't work for fonts with multi-character glyphs. So a further step would be to take the mode advance and always advance in increments of that. That would work for a "good" font, say single character glyphs advance 7 units so the mode would be 7, and the triple glyph would advance 21 units. Let's think of a "bad" font, imagine half the glyphs have an advance of 7 and half -1 have an advance of 8, The mode would be 7 and half -1 of the glyphs would have an advance of 14 because they're 1 unit bigger than the mode. Now you need to take a standard deviation from the mode to account for glyphs that are similar but not the same, but advance issues become more apparent the more you multiply them out. A triple glyph designed on the smaller 7 unit size would have an advance of 24 and would present a noticeable gap at then end of it. And on and on and on with the heuristics of trying to get "bad" fonts to look good. I've been using the patch I posted above since I posted it and haven't noticed any unintended side-effects, but I'm only one user and that doesn't make a good sample size. Also the patch doesn't remove the monospace special case, it only changes the advance in the special case. The proper patch would be to remove the monospace handling completely and just treat a monospace font like other fonts. |
@JasonBrownDeveloper thanks for your input and important observations. I am 100% convinced we must be only pragmatic in this case. If your patch solves the problem (and IMHO it does), then let us spread the patch as much as we can to make it work for the next 10-20 years before Wayland(-like) systems will fully take over the reign of X11. Finally a little nice thing would be to let other unrelated but relevant projects know about this and advice them how to avoid such issues. |
Xft project has now merged @JasonBrownDeveloper 's |
https://build.opensuse.org/request/show/1036197 by user sndirsch + dimstar_suse - Update to version 2.3.7 * libxft issue #15 https://gitlab.freedesktop.org/xorg/lib/libxft/-/issues/15 XftFontLoadGlyphs for mono font returns wrong info in extents from XftTextExtentsUtf8 for variable chars Patch by Scott Mcdermott, based on googlefonts/Inconsolata#42 * fix compiler warning * libxft issue #16 https://gitlab.freedesktop.org/xorg/lib/libxft/-/issues/16 Stack gets smashed in fonts with colors when calling XftGlyphRender BGRA changes made incorrect comparison for local vs allocated buffer in XftGlyphSpecRender * stdint.h header is needed for SIZE_MAX
Hello, after upgrading to Inconsolata v3.000 on Fedora 31, letter-spacing has become too wide in Emacs, as shown in the attached screenshot; it shows the Emacs window I get on running
emacs -Q
. I'm running Emacs 26.3.Note that the font works correctly in other applications such as Gedit and LibreOffice.
The text was updated successfully, but these errors were encountered: