The latest versions of pango dropped support for X11 bitmap fonts (pcf / psf stuff). Thus, existing bitmap fonts are being converted to OTB, which is still supported. However, setting up alacritty for an OTB font produces the following error message:
Alacritty encountered an unrecoverable error:
Invalid size handle
OS: NixOS (Linux)
Version: 0.4.0
X11 i3
Could you provide a full backtrace, running RUST_BACKTRACE=1 alacritty? If you're using the NixOS Alacritty package the debug information is probably stripped, in which case it would be best to do it with a freshly compiled copy for useful backtraces.
Also could you confirm that the version is actually 0.4.0? Since the version 4.0 which you've specified does not exist.
Woops, the version is indeed 0.4.0. Adding RUST_BACKTRACE=1 doesn't add any more infos, I'm recompiling to get a debug build but that looks super weird.
The output you've posted is exactly what you get in stderr when running Alacritty with an OTB font in the config?
Yes it is
I gdb'ed the thing and it looks like the error comes from https://github.com/jwilm/alacritty/blob/v0.4.0/alacritty/src/main.rs#L138. Untortunatly my setup too hacky to go deeper for now
That sounds like something outside of Rust is throwing a fit. Likely freetype directly I'd assume.
Does this happen with all OTB fonts, or only some of them?
I just tried with another font, and I _think_ all OTB fonts fail
something super strange also happens when there's a font available in both pcf and otb format. alacritty then opens, but display no characters (only the cursor)
I can't repro the crash, the font you've provided works as expected on my system.
Some additional system information might be worthwhile. Like freetype/fontconfig version.
I mean we still need a proper backtrace from alacritty, could you post bt full from gdb?
I spent quite a bit of time playing around with rr to get the location of the error, and I think it's from there:
#0 0x00007fec5cc9ad55 in FT_Load_Glyph () from /nix/store/ncj9yarq7lq8sxpx02qzqggpzwr1gk0s-freetype-2.10.1/lib/libfreetype.so.6
#1 0x000055afe1693b0e in <font::ft::FreeTypeRasterizer as font::Rasterize>::get_glyph () at /build/alacritty-0.4.0-vendor/freetype-rs/src/face.rs:138
#2 0x000055afe147d6fd in alacritty::display::Display::new () at alacritty_terminal/src/renderer/mod.rs:358
#3 0x000055afe14c5493 in alacritty::main () at alacritty/src/main.rs:138
The return code of this function is 0x24, which corresponds to the displayed error message
Alacritty is linked against freetype 2.10.1, which seems to be the latest version
@kchibisov what version of freetype do you have ?
@multun it's 2.9.1. As you can see the error is from freetype, so I don't think alacritty can do something about it?
P.s. I can try recent freetype tbh, let me see whether I can repro with it.
Yup sorry for the irrelevant bug report. @kchibisov would you mind trying this out with the font I gave earlier with your version of freetype?
./freetype_test terminusn.otb 'some text' >/dev/null
On my system, the output is as follows:
freetype_test: error 0x24
@multun
~ ➜ ./test terminusn.otb 'some text' >/dev/null
test: error 0x24
test: error 0x24
test: error 0x24
test: error 0x24
test: error 0x24
test: error 0x24
test: error 0x24
test: error 0x24
test: error 0x24
FWIW I also can't repro the issue with freetype 2.10.1.
I've tested on Archlinux with 2.10.1 too and I can't replicate this crash either.
@kchibisov wait what. so with your setup, the error message is there with 2.9.1 and the test passes with 2.10.1 ?
I think this is related to the font size selected. In the test program provided by @multun (where we all get error 0x24), I get error 0x17 from the FT_Set_Char_Size() call.
I can make it work by selecting a different size, known to exist in the font, by replacing the call to FT_Set_Char_Size() with a call to FT_Set_Pixel_Sizes(), which takes an explicit pixel size instead of a point size.
In short, I believe when selecting size in a freetype face object that is backed by a bitmap-only font file, one must select a (pixel)size that exists in the font.
I'm fairly sure FT_Set_Char_Size() is supposed to work too, assuming you give it a point size + DPI value that translates to a pixel size that actually exists in the font file.
Looks like Alacritty doesn't check for errors when setting the size? https://github.com/jwilm/alacritty/blob/77acb26d7328f678b26c8aff2ee5706d78949c44/font/src/ft/mod.rs#L339
It checks, but it doesnt try to work around this error.
Anyway, I can't make it crash just by changing the font size. So if you can crash it, please share instructions on how to do it.
Nope, can't crash it.
But might be worth putting together a POC that ensures Alacritty doesn't try to load glyphs from a font where set_char_size failed, that @multun can test?
@dnkl let me try, but I'm not sure that we're loading anything when things could fail here. I mean in the past we were not loading fallback fonts which were failing(like Noto Color Emoji), but I could be wrong a bit about the primary font...
At least we can provide more logging on where it fails and see why.
@multun could you try running Alacritty with FC_DEBUG=4 alacritty and post the output? It should tell us exactly which font files and sizes Fontconfig has selected for Alacritty.
@dnkl Here it is, thanks for your help!
Ok, so it looks like it found the correct font, and at pixel-size 20.
@kchibisov if I read Alacritty correctly, it should use the pixelsize value as is in this case (as the font isn't scalable) in the call to to_freetype_26_6(). Is this correct?
If I change the test program to call FT_Set_Char_Size(face, 20 * 64, 0, 0, 0 ); then everything works... no errors at all, neither from FT_Set_Char_Size() nor from FT_Load_Glyph(). I suppose more logging in Alacritty is necessary...
yup, I can confirm switching to a font size of 20 in the example program works!
if I read Alacritty correctly, it should use the pixelsize value as is in this case (as the font isn't scalable) in the call to to_freetype_26_6(). Is this correct?
As long as face.non_scalable is Some(_), yeah.
Looks like Alacritty doesn't check for errors when setting the size?
If we would fail here, we'd immediately leave the font crate though. And we're getting an error from a system font library, not unwrapping a Rust Result<_, _>.
@multun Could you apply the following patch?
diff --git a/font/src/ft/mod.rs b/font/src/ft/mod.rs
index 431a500..287294b 100644
--- a/font/src/ft/mod.rs
+++ b/font/src/ft/mod.rs
@@ -344,6 +344,7 @@ impl FreeTypeRasterizer {
freetype::ffi::FT_Library_SetLcdFilter(ft_lib, face.lcd_filter);
}
+ println!("Index: {}, FLAGS: {:?}",index as u32, face.load_flags);
face.ft_face.load_glyph(index as u32, face.load_flags)?;
let glyph = face.ft_face.glyph();
If we would fail here, we'd immediately leave the font crate though. And we're getting an error from a system font library, not unwrapping a Rust Result<_, _>.
I don't see Invalid Size Handle happening in any other way than not having successfully configured the font size.
Is it possible it has failed the set_char_size() call, exited the font crate and _then_ still end up trying to do a load glyph call?
If we would fail here, we'd immediately leave the font crate though. And we're getting an error from a system font library, not unwrapping a Rust Result<_, _>.
Yeah, the key thing here. The crash is in freetype and not in alacritty. And it doesn't throw an error, it just crashes...
@dnkl freetype shouldn't crash if we fail here. It should just throw an error to us...
@kchibisov freetype shouldn't crash if we fail here. It should just throw an error to us...
Of course. But so far, things point to Alacritty having failed to configure the font size. Even if freetype didn't crash, that bug would still be there.
Nah, let's try to see if we fail somewhere silently. @multun just try this patch, forget about previous one.
Annnd here is the result, thanks for the patch!
Index: 109, FLAGS: NO_BITMAP | MONOCHROME | TARGET_MONO
thread 'main' panicked at 'LOAD GLYPH FAILED: InvalidSizeHandle', src/libcore/result.rs:1165:5
stack backtrace:
0: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
1: core::fmt::write
2: std::io::Write::write_fmt
3: std::panicking::default_hook::{{closure}}
4: std::panicking::default_hook
5: std::panicking::rust_panic_with_hook
6: std::panicking::continue_panic_fmt
7: rust_begin_unwind
8: core::panicking::panic_fmt
9: core::result::unwrap_failed
10: core::result::Result<T,E>::expect
at /build/rustc-1.39.0-src/src/libcore/result.rs:960
11: font::ft::FreeTypeRasterizer::get_rendered_glyph
at font/src/ft/mod.rs:348
12: <font::ft::FreeTypeRasterizer as font::Rasterize>::get_glyph
at font/src/ft/mod.rs:146
13: alacritty::renderer::GlyphCache::static_metrics
at alacritty/src/renderer/mod.rs:360
14: alacritty::display::Display::new
at alacritty/src/display.rs:137
15: alacritty::run
at alacritty/src/main.rs:143
16: alacritty::main
at alacritty/src/main.rs:112
17: std::rt::lang_start::{{closure}}
at /build/rustc-1.39.0-src/src/libstd/rt.rs:64
18: std::panicking::try::do_call
19: __rust_maybe_catch_panic
20: std::rt::lang_start_internal
21: std::rt::lang_start
at /build/rustc-1.39.0-src/src/libstd/rt.rs:64
22: main
23: __libc_start_main
24: _start
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Oh. You have disabled loading of bitmap fonts on your system, so I guess this is the case why it fails. I mean I don't see NO_BITMAP flag on my system with my patch.
I've got it disabled too though, so that's a bit surprising that it would explode?
FWIW, I also see embeddedbitmap: False in my FC_DEBUG=4 alacritty output when using OTB fonts.
It still works, with what appears to be the correct font.
Furthermore, it's only false when loaded from Alacritty. fc-match returns embeddedbitmap: True.
It's strange tbh, I can disable and it wont break the world for me either. Could you share your fc-conflist?
@dnkl Could you try
diff --git a/font/src/ft/mod.rs b/font/src/ft/mod.rs
index 431a500..95163b9 100644
--- a/font/src/ft/mod.rs
+++ b/font/src/ft/mod.rs
@@ -414,6 +414,7 @@ impl FreeTypeRasterizer {
};
if !embedded_bitmaps {
+ println!("Disabling loading of bitmap fonts!");
flags |= LoadFlag::NO_BITMAP;
}
I personally don't see any issue with our probing of bitmap fonts.
Ooooooooh yeah you're right. It works now. I wish I knew this setting even existed. I'll submit a pull request to change that default, thanks a lot for your help!!
@kchibisov no output. I find that both surprising, and not surprising.
Surprising, because I thought you look at the fontconfig attribute embeddedbitmap to determine whether to set the NO_BITMAP flag or not?
Not surprising, since the font obviously loads.
Something might be off with the way alacritty handles it, as all other software I could find seem to work just fine with that variable on.
@multun if you provide us with the way you make it not loading bitmap fonts (like on your system) it'll help, since I can't repro it and understand on how to setup things to fail.
@dnkl We're just getting a bool from a pattern. Take a look at https://github.com/jwilm/alacritty/blob/f632919134414e31ffd3ae9b5732d673deb0adf5/font/src/ft/mod.rs#L377
@kchibisov yeah, that's where I've been looking. So since I have embeddedbitmap: False, I'd expect embedded_bitmap to be false, and thus I expected to see the println(). But I didn't. That's what's surprising.
Hmm, I think I understand a bit more now. I guess none of us have embeddedbitmap: false toggle in a config. So adding it to fontconfig should trigger an issue, @multun you don't need to provide any info, since now I can repro myself. The /etc/fonts/conf.avail/70-no-bitmaps.conf: Reject bitmap fonts is a bit different thing, it disable non scalable fonts, which are bitmap ones, so you can't trigger an issue with it.
@kchibisov I did have this in my config:
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!-- Use embedded bitmaps in fonts like Calibri? -->
<match target="font">
<edit name="embeddedbitmap" mode="assign">
<bool>false</bool>
</edit>
</match>
@multun yeah, I've figured that out.
@kchibisov perhaps it would make sense to only set NO_BITMAP if both embeddedbitmap=False and scalable=True?
If the font isn't scalable, you kind of _have_ to enable bitmaps... or skip the font completely and fallback to the next font.
@dnkl Hmm, it'll probably make sense, I'll try to take a look on it, once I finish my other things in our font crate...
The solution similar to the one suggested here was implemented to not blow up on bitmap fonts. So the result criteria should be if embeddedbitmap=False and scalable=True and color=False, since colored glyphs are also marked as scalable, however they don't.
Most helpful comment
@dnkl Hmm, it'll probably make sense, I'll try to take a look on it, once I finish my other things in our font crate...