dnkl/foot
41
2.0k
Fork
You've already forked foot
243

Consider removing support for font bleeding #2015

Open
opened 2025年03月31日 08:27:15 +02:00 by dnkl · 11 comments
Owner
Copy link

Describe your feature request

Foot currently allows font glyphs to "bleed" (extend outside their bounding box) from left to right. This was done for two main cases:

  1. Support rendering (mainly) glyphs from private use areas (PUAs)
  2. Handle italics "leaning" into the next character

Depending on your definition of a valid font, point 2 can be argued to be caused by broken fonts (the glyphs are extending outside their bounding box).

1 is better solved with the text-sizing protocol (by setting an explicit width). Or we can add a config option defining which codepoints should be allowed to render double width.

Q: if we already support this, and a lot of fonts are affected, why should we remove support?

A: first, I don't know if it really is "a lot of fonts". This is something we'll have to investigate. I'd argue that if all major fonts don't bleed, then "a lot of fonts" isn't really an argument. Yes, we'll break a couple of fonts, people will be mad etc. But if we can say that "look, all major fonts are well behaving..." then it'll be easier for people to accept.

Second, we only do left-to-right. We don't do right-to-left, or any vertical bleeding. I don't ever intend to support that. And if so, why should we support left-to-right?

So what do we gain by removing support for font bleeding? Reduced rendering complexity, and rendering performance.

It should be noted that one can already turn this off in foot by setting tweak.overflowing-glyphs=no (it defaults to yes). You do gain most of the performance improvements by doing that, but code complexity obviously remains.

Without having looked to deep into it, my belief is terminal emulators fall into one of two categories: either they support font bleeding in all directions, or they don't support it at all. Foot is the odd one, only supporting left-to-right.

Examples

Generated by running

foot -c /dev/null -o tweak.overflowing-glyphs=no -f <font>:size=20

followed by

printf "\n\e[48:2::0:0:0m pgjbdPMW \e[3m pgjbdPMW \e[1m pgjbdPMW \e[0;48:2::0:0:0;1m pgjbdPMW\e[m\n\n"
Font Output
Cascadia Cascadia
Dejavu Dejavu
Fira Fira
Inconsolata Inconsolata
Intel One Mono Intel
Iosevka Term Iosevka
Jetbrains Jetbrains
IBM Plex Plex

TODO

  • Check all major fonts
  • (optionally) check a bunch of other terminal emulators
### Describe your feature request Foot currently allows font glyphs to "bleed" (extend outside their bounding box) from left to right. This was done for two main cases: 1. Support rendering (mainly) glyphs from private use areas (PUAs) 2. Handle italics "leaning" into the next character Depending on your definition of a valid font, point 2 can be argued to be caused by broken fonts (the glyphs _are_ extending outside their bounding box). 1 is better solved with the text-sizing protocol (by setting an explicit width). Or we can add a config option defining which codepoints should be allowed to render double width. Q: if we already support this, and a lot of fonts are affected, why should we remove support? A: first, I don't know if it really is "a lot of fonts". This is something we'll have to investigate. I'd argue that if all major fonts don't bleed, then "a lot of fonts" isn't really an argument. Yes, we'll break a couple of fonts, people will be mad etc. But if we can say that "look, all major fonts are well behaving..." then it'll be easier for people to accept. Second, we only do left-to-right. We don't do right-to-left, or any vertical bleeding. I don't ever intend to support _that_. And if so, why should we support left-to-right? So what do we gain by removing support for font bleeding? Reduced rendering complexity, and rendering performance. It should be noted that one can already turn this off in foot by setting `tweak.overflowing-glyphs=no` (it defaults to `yes`). You do gain most of the performance improvements by doing that, but code complexity obviously remains. Without having looked to deep into it, my belief is terminal emulators fall into one of two categories: either they support font bleeding in all directions, or they don't support it at all. Foot is the odd one, only supporting left-to-right. ### Examples Generated by running ```sh foot -c /dev/null -o tweak.overflowing-glyphs=no -f <font>:size=20 ``` followed by ```sh printf "\n\e[48:2::0:0:0m pgjbdPMW \e[3m pgjbdPMW \e[1m pgjbdPMW \e[0;48:2::0:0:0;1m pgjbdPMW\e[m\n\n" ``` | Font | Output | |----|----| | Cascadia | ![Cascadia](https://codeberg.org/attachments/f479aecc-9ef1-4d81-97c8-73d2c44c2114) | | Dejavu | ![Dejavu](https://codeberg.org/attachments/cb573b97-881c-4457-b37f-32ed47f555c6) | | Fira | ![Fira](https://codeberg.org/attachments/ede9b05f-6db9-40fc-921c-071bf3b85ee3) | | Inconsolata | ![Inconsolata](https://codeberg.org/attachments/11283a31-f18f-478d-ac3b-babb0cc0a6f4) | | Intel One Mono | ![Intel](https://codeberg.org/attachments/78e35018-b8b0-48c1-8d5b-1eb2ae34eb0e) | | Iosevka Term | ![Iosevka](https://codeberg.org/attachments/95cce67e-b43e-4168-8784-f76149e7aca4) | | Jetbrains | ![Jetbrains](https://codeberg.org/attachments/f970d167-4620-4218-9d7a-c20522744a21) | | IBM Plex | ![Plex](https://codeberg.org/attachments/3396d792-a68a-4849-a3a4-8dfaa7d4b1b2) | **TODO** * [x] Check all major fonts * [ ] (optionally) check a bunch of other terminal emulators
Author
Owner
Copy link

Sigh, it was a lot worse than I though. All fonts bleed, more or less. Intel One Mono, Jetbrains Mono, Cascadia all bleeds moderately (bold italic is the worse). Fira Mono bleeds heavily. Iosevka is almost well-behaving (assuming you use the Term variant); only minor right-to-left bleeding on e.g. p.

The worst letters are typically upper case M, W, lower case d etc.

You can test for yourself with foot -o tweak.overflowing-glyphs=no, and then

printf " pgjbdPMW \e[3m pgjbdPMWx \e[1m pgjbdPMW \e[0;1m pgjbdPMW\e[0m\n"
Sigh, it was a lot worse than I though. **All** fonts bleed, more or less. _Intel One Mono_, _Jetbrains Mono_, _Cascadia_ all bleeds moderately (bold italic is the worse). _Fira Mono_ bleeds **heavily**. Iosevka is _almost_ well-behaving (assuming you use the _Term_ variant); only minor right-to-left bleeding on e.g. `p`. The worst letters are typically upper case `M`, `W`, lower case `d` etc. You can test for yourself with `foot -o tweak.overflowing-glyphs=no`, and then ```sh printf " pgjbdPMW \e[3m pgjbdPMWx \e[1m pgjbdPMW \e[0;1m pgjbdPMW\e[0m\n" ```
Author
Owner
Copy link

Another argument for why bleeding fonts are buggy is this: right-to-left bleeding will cause cut off glyphs in the left most column, and left-to-right bleeding will cause cut off glyphs in the right most column. In theory, we could allow the glyphs to bleed into the margin (we currently don't), but if the margin is set to 0 px... 🤷

Another argument for why bleeding fonts are buggy is this: right-to-left bleeding will cause cut off glyphs in the left most column, and left-to-right bleeding will cause cut off glyphs in the right most column. In theory, we could allow the glyphs to bleed into the margin (we currently don't), but if the margin is set to 0 px... 🤷
Author
Owner
Copy link

Inconsolata, DejaVu Mono and IBM Plex Mono also bleed.

Inconsolata, DejaVu Mono and IBM Plex Mono also bleed.

Maybe I misunderstood the essence, but does this change mean that the nerd fonts will be cut off? If so, that would be terrible

Maybe I misunderstood the essence, but does this change mean that the nerd fonts will be cut off? If so, that would be terrible
Author
Owner
Copy link

@cbacc yes (assuming they use PUA codepoints). But that particular problem can be solved in a different way, for example, a config option specifying which codepoints should be treated as double-width when rendering.

@cbacc yes (assuming they use PUA codepoints). But that particular problem can be solved in a different way, for example, a config option specifying which codepoints should be treated as double-width when rendering.

Noto Sans Mono bleeds too:

image

Noto Sans Mono bleeds too: ![image](/attachments/db0d4e6f-de42-462c-89dc-db1016b27178)

Twemoji doesn't seem to bleed:

image

Twemoji doesn't seem to bleed: ![image](/attachments/7fbf9195-133c-42fa-a943-4c071d992110)

Adding on some subjective perspective as a bitmap font enjoyer:

The XLFD specs categorize bitmap font spacing into proportional, monospace, and charcell. Proportional for when glyph advances aren't the same, monospace when glyph advances are the same. Charcell is a subset of monospace where none of the glyphs bleed; these are maximally compatible with all terminals (including foot with no bleed support).

In practice, however, charcell fonts tend to have relatively low Unicode support (one exception being UW ttyp0 with an impressive 3001 glyphs). Here are 2 examples of fonts that rely on bleeds as a design compromise for small size + comprehensive Unicode support.

Cozette

Dual-width (6px and 12px advances). The Nerd Fonts glyphs are not double-width. Single-width bleeds left-to-right -- and more situationally, right-to-left.

cozette triple integral

Triple integral glyph, with 2px LTR bleed and 1px RTL bleed.

kirsch

My personal font project. Base version is strictly 6px monospace and bleeds all over the place 😅

kirsch wayland

Nerd Font linux-wayland glyph, with 3px LTR bleed and 2px RTL bleed.

I recently developed a "Propo" variant which adjusts glyph widths to work with foot. The main issue with this variant is that the

wezterm

Wezterm with base variant. Font rendering works as expected, bleeding included.

foot

foot with Propo variant. Notice how, unlike with Wezterm, the Nerd Fonts glyphs in the bottom left corner aren't centered as a side effect of the Propo adjustments.

Conclusion

As much as I'd prefer if foot had full bleed support, realistically speaking the lack of bleed support won't really affect the average bitmap font user's experience. There are plenty of charcell bitmap fonts (e.g. the aforementioned UW ttyp0) that are more than usable, especially with foot's fallback font support for Nerd Fonts, CJK, etc. But it would be nice if e.g. there was a way to center cells as a visual preference.

Adding on some subjective perspective as a bitmap font enjoyer: The XLFD specs categorize bitmap font spacing into *proportional*, *monospace*, and *charcell*. Proportional for when glyph advances aren't the same, monospace when glyph advances are the same. Charcell is a subset of monospace where none of the glyphs bleed; these are maximally compatible with all terminals (including foot with no bleed support). In practice, however, charcell fonts tend to have relatively low Unicode support (one exception being [UW ttyp0](https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/) with an impressive 3001 glyphs). Here are 2 examples of fonts that rely on bleeds as a design compromise for small size + comprehensive Unicode support. ## [Cozette](https://github.com/slavfox/Cozette) Dual-width (6px and 12px advances). The Nerd Fonts glyphs are not double-width. Single-width bleeds left-to-right -- and more situationally, right-to-left. ![cozette triple integral](/attachments/381f7f36-ddf3-47a5-9931-09bdcf2c64b5) *Triple integral glyph, with 2px LTR bleed and 1px RTL bleed.* ## [kirsch](https://github.com/molarmanful/kirsch) My personal font project. Base version is strictly 6px monospace and bleeds all over the place 😅 ![kirsch wayland](/attachments/96b337a9-8ce8-4753-9901-bfc54a7f3c77) *Nerd Font `linux-wayland` glyph, with 3px LTR bleed and 2px RTL bleed.* I recently developed a "Propo" variant which adjusts glyph widths to work with foot. The main issue with this variant is that the ![wezterm](/attachments/0c6991ac-5ab5-489d-87c8-b4c440d9e68f) *Wezterm with base variant. Font rendering works as expected, bleeding included.* ![foot](/attachments/4f31f255-c5c8-4878-b451-05e24485aad2) *foot with Propo variant. Notice how, unlike with Wezterm, the Nerd Fonts glyphs in the bottom left corner aren't centered as a side effect of the Propo adjustments.* ## Conclusion As much as I'd prefer if foot had full bleed support, realistically speaking the lack of bleed support won't *really* affect the average bitmap font user's experience. There are plenty of charcell bitmap fonts (e.g. the aforementioned UW ttyp0) that are more than usable, especially with foot's fallback font support for Nerd Fonts, CJK, etc. But it would be nice if e.g. there was a way to center cells as a visual preference.

For ASCII characters, "not using italic" is no big deal as some fonts (especially old ones) have no "italic" variants anyway. Foot did not support ligatures once, which was the only point stopping me from using it as my main code editor. That is totally fine. Coding is merely one of the many use cases of a terminal emulator. Removing bleeding support will not change my mind, yet will make Foot itself way more consistent and harmonious.

Fancy visuals in fonts (including "ligature" and "italic") are for IDEs or web-browsers, not a general purpose terminal emulator which claims to be "fast, lightweight and minimalistic".

Foot must protect its original font rendering model (possibly characters fully contained by non-overlapping atomic rectangles I guess) to maintain efficiency and simplicity.

By the way, full bleeding support for random shapes within the same rendering pipeline probably requires migration from memcpy overwrites to per-pixel alpha compositions, while the latter one is cheap for GPU but expensive for CPU. Neither performance drop nor GPU acceleration is acceptable.

For ASCII characters, "not using italic" is no big deal as some fonts (especially old ones) have no "italic" variants anyway. Foot did not support ligatures once, which was the only point stopping me from using it as my main code editor. That is totally fine. Coding is merely one of the many use cases of a terminal emulator. Removing bleeding support will not change my mind, yet will make Foot itself way more consistent and harmonious. Fancy visuals in fonts (including "ligature" and "italic") are for IDEs or web-browsers, not a general purpose terminal emulator which claims to be "fast, lightweight and minimalistic". Foot must protect its original font rendering model (possibly characters fully contained by non-overlapping atomic rectangles I guess) to maintain efficiency and simplicity. By the way, full bleeding support for random shapes within the same rendering pipeline probably requires migration from `memcpy` overwrites to per-pixel alpha compositions, while the latter one is cheap for GPU but expensive for CPU. Neither performance drop nor GPU acceleration is acceptable.

Testing font bleeding enabled and disabled by config I could not measure any meaningful difference in drawing performance:

$ # Generate some large text file with pretty long lines
$ find / >/tmp/f 2>/dev/null
$ # from Alacritty:
$ foot -c /dev/null -o tweak.overflowing-glyphs=no &
$ foot -c /dev/null -o tweak.overflowing-glyphs=yes &

with no:

$ time cat /tmp/f
[...]
real	0m7,667s
user	0m0,002s
sys	0m3,098s

with yes:

$ time cat /tmp/f
[...]
real	0m7,690s
user	0m0,001s
sys	0m3,165s

I'd consider losing bleeding capability weighting heavier then saving less than 0.05 s.

Testing font bleeding enabled and disabled by config I could not measure any meaningful difference in drawing performance: ```shell $ # Generate some large text file with pretty long lines $ find / >/tmp/f 2>/dev/null $ # from Alacritty: $ foot -c /dev/null -o tweak.overflowing-glyphs=no & $ foot -c /dev/null -o tweak.overflowing-glyphs=yes & ``` with `no`: ```shell $ time cat /tmp/f [...] real 0m7,667s user 0m0,002s sys 0m3,098s ``` with `yes`: ```shell $ time cat /tmp/f [...] real 0m7,690s user 0m0,001s sys 0m3,165s ``` I'd consider losing bleeding capability weighting heavier then saving less than 0.05 s.

After trying out a bunch of nerd fonts patches and eventually making my own, I was wondering why the PUA characters were not being treated as wide (like CJK) even though they're exactly 2 units. It'd be great if foot could detect this automatically, but a config would be helpful as a last resort too. Right now, they bleed out of a a single cell which is awkward to work around.

After trying out a bunch of nerd fonts patches and eventually making my own, I was wondering why the PUA characters were not being treated as wide (like CJK) even though they're exactly 2 units. It'd be great if foot could detect this automatically, but a config would be helpful as a last resort too. Right now, they bleed out of a a single cell which is awkward to work around.
Sign in to join this conversation.
No Branch/Tag specified
master
osc-5522
sixel-heap-buffer-overflow
releases/1.27
releases/1.26
releases/1.25
releases/1.24
multi-cursor
releases/1.23
pixman-16f-2
releases/1.22
releases/1.21
releases/1.20
releases/1.19
releases/1.18
releases/1.17
releases/1.16
releases/1.15
releases/1.14
releases/1.13
releases/1.12
releases/1.11
releases/1.10
releases/1.9
releases/1.8
releases/1.7
releases/1.6
releases/1.5
releases/1.4
releases/1.3
releases/1.2
releases/1.1
releases/1.0
1.27.0
1.26.1
1.26.0
1.25.0
1.24.0
1.23.1
1.23.0
1.22.3
1.22.2
1.22.1
1.22.0
1.21.0
1.20.2
1.20.1
1.20.0
1.19.0
1.18.1
1.18.0
1.17.2
1.17.1
1.17.0
1.16.2
1.16.1
1.16.0
1.15.3
1.15.2
1.15.1
1.15.0
1.14.0
1.13.1
1.13.0
1.12.1
1.12.0
1.11.0
1.10.3
1.10.2
1.10.1
1.10.0
1.9.2
1.9.1
1.9.0
1.8.2
1.8.1
1.8.0
1.7.2
1.7.1
1.7.0
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.0
1.2.3
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
0.9.0
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
7 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
dnkl/foot#2015
Reference in a new issue
dnkl/foot
No description provided.
Delete branch "%!s()"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?