kovidgoyal / kitty

Cross-platform, fast, feature-rich, GPU based terminal
https://sw.kovidgoyal.net/kitty/
GNU General Public License v3.0
24.4k stars 980 forks source link

OpenType ligatures #50

Closed skosch closed 6 years ago

skosch commented 7 years ago

I wonder if it's possible to enable – or to humbly request :) – the rendering of ligatures, as provided by many coding fonts (e.g. Hasklig)?

kovidgoyal commented 7 years ago

I'm afraid not. kitty works by rendering individual character cells into a sprite map that is uploaded to the GPU. It is fundamentally designed to work on a character grid. Ligatures, and other advanced typographic facilities are not possible given this design, as every character is rendered only once, in isolation. This has many upsides, including performance, grid fidelity and code simplicity. The downside is no ligatures/kerning, substitution.

tiberiuichim commented 7 years ago

But wouldn't it be possible to prerender all ligatures and treat groups of 2 characters as a single one, with a given sprite?

kovidgoyal commented 7 years ago

Not really 1) The set of all ligatures can be very large, depending on the font 2) Treating two characters as one messes up cursor movement, backspace, etc.

What can theoretically be done is detect a ligature, render it, partition it into individual character bitmaps, render each bitmap at the location of the underlying characters.

However doing this is very performance intensive. Every time any character changes, the entire line has to be re-scanned for ligatures. Every cell in the underlying data structure has to now carry extra information, probably four bytes worth to map the cell to the special ligature bitmap, when needed. Then the function that transfers sprite indices from the screen structure to the GPU will now need at least one extra branch to handle cells with the special ligatures.

I suppose that if this were made optional, the only cost people who did not use it would carry be the extra four bytes per cell, which is not too bad. Not something I am motivated to implement, but I'll re-open the bug report, if someone else wants to take it up.