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

Ligature support #57

Closed
opened 2020年08月02日 22:32:19 +02:00 by overfl0w · 23 comments

I use iosevka which offers a few ligatures, I notice foot doesn't support these. Registering some interest in this feature.

I use iosevka which offers a few ligatures, I notice foot doesn't support these. Registering some interest in this feature.
Owner
Copy link

I've been expecting this feature request :)

If someone else wants to have a go at this, please go ahead. I'll be happy to assist. For a PR to get merged, its performance impact would have to be very low though. If that cannot be done, then a runtime or compile time option may be warranted.

I've been expecting this feature request :) If someone else wants to have a go at this, please go ahead. I'll be happy to assist. For a PR to get merged, its performance impact would have to be very low though. If that cannot be done, then a runtime or compile time option may be warranted.
dnkl changed title from (削除) Ligature support (削除ここまで) to Text shaping (ligatures + emoji ZWJ etc) 2021年05月14日 13:06:48 +02:00
dnkl changed title from (削除) Text shaping (ligatures + emoji ZWJ etc) (削除ここまで) to Ligature support 2021年06月15日 11:21:20 +02:00

For if/when this is implemented, I thought I'd mention a setting from Kitty which I rather like: disable_ligatures cursor. As one might expect, this just stops ligatures from being composed around the cursor.

For if/when this is implemented, I thought I'd mention a setting from Kitty which I rather like: `disable_ligatures cursor`. As one might expect, this just stops ligatures from being composed around the cursor.

I'm quite new to software development overall and am a novice in C coding, but am interested in contributing.
How would one start to implement this on the current codebase (any references for font rendering stuff and related would be much appreciated)?

I'm quite new to software development overall and am a novice in C coding, but am interested in contributing. How would one start to implement this on the current codebase (any references for font rendering stuff and related would be much appreciated)?

AFAIK, fontconfig is used to determine applicable fonts, load fonts, etc. But it's not used for actualling rendering, right? What does do the rendering?

AFAIK, `fontconfig` is used to determine applicable fonts, load fonts, etc. But it's not used for actualling rendering, right? What _does_ do the rendering?
Owner
Copy link

Harfbuzz is used to select which glyphs to use, and freetype then renders said glyphs.

Foot uses fcft which handles all fontconfig/harfbuzz/freetype interaction.

Finally, foot uses pixman to blend the by-freetype generated glyphs to the terminal window.

Harfbuzz is used to select _which_ glyphs to use, and freetype then renders said glyphs. Foot uses fcft which handles all fontconfig/harfbuzz/freetype interaction. Finally, foot uses pixman to blend the by-freetype generated glyphs to the terminal window.

is this gonna be added to foot?

is this gonna be added to foot?

It would be useful to have a somewhat-high-level overview what still needs to be done for this in order for this to happen.

fcft seems to have support for full-text-run shaping since 2.4.0, so that seems to check out.

What are the steps required to get this working in foot? I doubt it is as easy as calling different fcft functions to make magic happen. I am too unfamiliar with harfbuzz to know the steps.

If we were to implement this, do we need to care about modifying the actual rendering done by pixman here at all?

It would be useful to have a somewhat-high-level overview what still needs to be done for this in order for this to happen. fcft seems to have support for full-text-run shaping since 2.4.0, so that seems to check out. What are the steps required to get this working in foot? I doubt it is as easy as calling different fcft functions to make magic happen. I am too unfamiliar with harfbuzz to know the steps. If we were to implement this, do we need to care about modifying the actual rendering done by pixman here at all?

I would not mind trying to implement this if someone could give me directions on what to do and how the codebase is layed out.

I would not mind trying to implement this if someone could give me directions on what to do and how the codebase is layed out.

I would not mind trying to implement this if someone could give me directions on what to do and how the codebase is layed out.

Did you make any progress? I'd like to work on adding this feature as well

> I would not mind trying to implement this if someone could give me directions on what to do and how the codebase is layed out. Did you make any progress? I'd like to work on adding this feature as well

I would not mind trying to implement this if someone could give me directions on what to do and how the codebase is layed out.

Did you make any progress? I'd like to work on adding this feature as well

So far I have not done anything because I'm quite busy atm and I didn't get any hints on how to do this. I'll be on vacation in a few weeks so I was planning on doing it then. If you want to start implementing this now go ahead but I would ask @dnkl about it first.

> > I would not mind trying to implement this if someone could give me directions on what to do and how the codebase is layed out. > > Did you make any progress? I'd like to work on adding this feature as well So far I have not done anything because I'm quite busy atm and I didn't get any hints on how to do this. I'll be on vacation in a few weeks so I was planning on doing it then. If you want to start implementing this now go ahead but I would ask @dnkl about it first.
Owner
Copy link

I've given this some thought, a number of times. There's no doubt that ligatures can be done. The issue is getting it done while maintaining a) performance, and b) code size.

I don't see a clear path forward, hence the lack of hints - I simply don't know how to best attack this feature.

At this point, given everything I know about foot itself, and fcft/harfbuzz and ligatures in general, I consider this a hard problem.

Unless you ('you' meaning anyone reading this, and not anyone in particular) are proficient in C, have an understanding of what makes an algorithm fast, understand how ligatures and font rasterization in general works, then I strongly recommend working on something else in foot.

Anyone giving this a go is also expected to know how to setup relevant benchmarks and compare before/after results.

I hope I don't come off as being too negative. That's not the intention. But I do want everyone to understand how hard (to the best of my knowledge) this problem is.

I've given this some thought, a number of times. There's no doubt that ligatures _can_ be done. The issue is getting it done while maintaining **a)** performance, and **b)** code size. I don't see a clear path forward, hence the lack of hints - I simply don't know how to best attack this feature. At this point, given everything I know about foot itself, and fcft/harfbuzz and ligatures in general, I consider this a **hard** problem. Unless you ('you' meaning anyone reading this, and not anyone in particular) are proficient in C, have an understanding of what makes an algorithm fast, understand how ligatures and font rasterization in general works, then I strongly recommend working on something else in foot. Anyone giving this a go is also expected to know how to setup relevant benchmarks and compare before/after results. I hope I don't come off as being too negative. That's not the intention. But I do want everyone to understand how hard (to the best of my knowledge) this problem is.

Would it be viable to have ligature support just a feature that can be enabled with explicit remarks that it might inhibit performance (if we even get to that point)? I know Alacritty has this issue where some person created a fork, but maybe if it made it into here as a setting it could be beneficial.

Would it be viable to have ligature support just a feature that can be enabled with explicit remarks that it might inhibit performance (if we even get to that point)? I know Alacritty has this issue where some person created a fork, but maybe if it made it into here as a setting it could be beneficial.
Owner
Copy link

@TheMyth I'm not against a toggle, in the general sense. The problems I see with this approach is: a) code size, b) code maintainability.

Why? Well, the assumption is we're going to need two implementations of the renderer: one fast, without ligatures, and one slower, with ligatures.

That means increased code size, but more importantly, more code that I have to understand how it works, to be able to maintain it. It also increases the number of variables needed to be understood when debugging rendering issues, making it harder, and taking longer time, to fix issues.

@TheMyth I'm not against a toggle, in the general sense. The problems I see with this approach is: a) code size, b) code maintainability. Why? Well, the assumption is we're going to need two implementations of the renderer: one fast, without ligatures, and one slower, with ligatures. That means increased code size, but more importantly, more code that I have to understand how it works, to be able to maintain it. It also increases the number of variables needed to be understood when debugging rendering issues, making it harder, and taking longer time, to fix issues.

I agree, this is an indispensable feature for many of us trying to daily drive the foot terminal.
As for having a toggle, it's not a problem.

@dnkl if there are any updates to developing an alpha release of ligature support, I'm sure the community would be happy to try it out and give relevant feedback.

I agree, this is an indispensable feature for many of us trying to daily drive the `foot` terminal. As for having a toggle, it's not a problem. @dnkl if there are any updates to developing an alpha release of ligature support, I'm sure the community would be happy to try it out and give relevant feedback.

since fcft can have ligatures, wouldn't adding it to foot be relatively easy? i've never read over the source of either so sorry if this is ignorant

since fcft can have ligatures, wouldn't adding it to foot be relatively easy? i've never read over the source of either so sorry if this is ignorant
Collaborator
Copy link

i've never read over the source

@bunbun seems like you haven't read this issue either...

> i've never read over the source @bunbun seems like you haven't read this issue either...

what do you mean? what did i miss?

what do you mean? what did i miss?
Collaborator
Copy link

what did i miss?

The part where @dnkl already answered your question above.

> what did i miss? The part where @dnkl already answered your question above.

where? sorry i don't see what you mean

where? sorry i don't see what you mean
@bunbun https://codeberg.org/dnkl/foot/issues/57#issuecomment-857048
Owner
Copy link

I decided to take a closer look at this.

TL;DR

Ligatures is not possible in foot without a large rewrite of the rendering logic. Therefore, I'm going to close this.

The long story

Traditional ligatures replace (typically) two character glyphs with a single glyph (e.g fi). I had hoped this would be the case for programming ligatures as well, but in all tested fonts1 this was unfortunately not the case. Instead, the ligature appears to consist of two glyphs overlaid (with the latter one using a large negative x-offset). More importantly, the fonts treat the two characters as two separate grapheme clusters. This means we have no good way to group the ligature glyphs together, or map them to the correct cell.

What we would have to do to support this in foot is several things:

  1. Extend the glyph bleed support to handle right-to-left bleeds (in addition to the already existing left-to-right support)
  2. Rewrite the renderer to first draw the background of all dirty cells, and then draw the glyphs. Currently, each cell is rendered in one go, both background and glyph.

That covers the required changes to the existing renderer. In addition to that, we would also have process and shape the text before rendering it, and this would likely incur a fairly large performance hit.

All in all, this has made me decide to not support ligatures in foot. Even if I were willing to put in the (large amount of) work required to rewrite the renderer, I wouldn't want to; there would simply be too much added complexity, as well as a likely performance hit, "just" to support ligatures.


  1. Fira Code, Cascadia, Iosevka, Intel One Mono ↩︎

I decided to take a closer look at this. ### TL;DR Ligatures is not possible in foot without a large rewrite of the rendering logic. Therefore, I'm going to close this. ### The long story Traditional ligatures replace (typically) two character glyphs with a single glyph (e.g `fi`). I had hoped this would be the case for programming ligatures as well, but in all tested fonts[^1] this was unfortunately **not** the case. Instead, the ligature appears to consist of two glyphs overlaid (with the latter one using a large negative x-offset). More importantly, the fonts treat the two characters as two separate grapheme clusters. This means we have no good way to group the ligature glyphs together, or map them to the correct cell. What we would have to do to support this in foot is several things: 1. Extend the glyph bleed support to handle right-to-left bleeds (in addition to the already existing left-to-right support) 2. Rewrite the renderer to first draw the background of all dirty cells, and then draw the glyphs. Currently, each cell is rendered in one go, both background and glyph. That covers the required _changes_ to the existing renderer. In addition to that, we would also have process and shape the text before rendering it, and this would likely incur a fairly large performance hit. All in all, this has made me decide to not support ligatures in foot. Even if I were willing to put in the (large amount of) work required to rewrite the renderer, I wouldn't want to; there would simply be too much added complexity, as well as a likely performance hit, "just" to support ligatures. [^1]: Fira Code, Cascadia, Iosevka, Intel One Mono
dnkl 2025年07月28日 11:02:54 +02:00

Thank you @dnkl for the detailed explanation!

I suppose support for Texture Healing, from GitHub monaspace [1] would present a similar challenge.

Do you have an idea whether the Smart Kerning from Commit Mono [2] also falls into the same category of troublesome features to implement?

As far as I can tell, Commit Mono's kerning is really just that, kerning; which sounds like it may not imply nearly as much of a maintenance and performance burden: the shapes don't change.
On the other hand, it's a much more esoteric feature (in my limited experience) than ligatures are, and may not be worth the trouble for that reason... But that's another question ;-)

[1]: https://github.com/githubnext/monaspace: refer to the "Texture Healing" section
[2]: https://commitmono.com/: press 4 to get to the "Intelligent" section

Thank you @dnkl for the detailed explanation! I suppose support for **_Texture Healing_, from GitHub monaspace** [1] would present a similar challenge. Do you have an idea whether the **_Smart Kerning_ from Commit Mono** [2] also falls into the same category of troublesome features to implement? As far as I can tell, **Commit Mono's kerning is really just that, kerning**; which sounds like it may not imply nearly as much of a maintenance and performance burden: _the shapes don't change_. On the other hand, it's a much more esoteric feature (in my limited experience) than ligatures are, and may not be worth the trouble for that reason... But that's another question ;-) [1]: https://github.com/githubnext/monaspace: refer to the "Texture Healing" section [2]: https://commitmono.com/: press `4` to get to the "Intelligent" section

Texture healing relies on "contextual alternates" specifically.

Both contextual alternates and ligatures involve using different glyphs depending on context, so they sound closely related.

Texture healing relies on "contextual alternates" specifically. Both contextual alternates and ligatures involve using different glyphs depending on context, so they sound closely related.
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
15 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#57
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?