Skip to content
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

Kitty shrinks glyphs with their ink box wider than the advance width. #297

Closed
be5invis opened this issue Jan 27, 2018 · 33 comments
Closed

Comments

@be5invis
Copy link

cc. @jpotier

@jpotier built an Iosevka build with ligations, however Kitty zooms out the glyphs that having larger ink box. In Iosevka, there are glyphs that extends out the x=0 and x=500 boundary, to connect to other glyphs to form a ligature.

@jpotier
Copy link

jpotier commented Jan 27, 2018

Oh, I just opened the same bug >< I'll remove it

@be5invis
Copy link
Author

be5invis commented Jan 27, 2018

Per @jpotier's font file, (download), the calt GSUB is defined like:

image

The hyphen glyph is replaced by a bar that overflows the left boundary to connect with the < glyph.

The other ligations are defined in the similar manner:

image
image

@kovidgoyal
Copy link
Owner

That's not going to work in kitty. There are two types of ligatures that will work, either substitute a single glyph for '<-' that is two chars wide or a dummy glyph + single glyph that is two chars wide with a negative left bearing. For example, from Fira Code for '<-'

hb-shape --cluster-level=1 --show-extents  ~/work/env/conf/fonts/FiraCode-Regular.otf '<-'     
[LIG=0+600<0,0,0,0>|less_hyphen.liga=1+600<-477,618,952,-610>]

Notice the first glyph is a dummy glyph and the second has a negative left bearing and is two cells wide. This pattern needs to be followed for most ligatures anyway, since they cannot typically be created by leaving some glyphs unchanged and changing only other glyphs. So stick to that pattern for all ligatures and it will work fine.

@be5invis
Copy link
Author

@kovidgoyal
Well, in Iosevka, actually, the ligations could be arbitrary length, like this:

image

So, I cannot stick to that pattern.

@jpotier
Copy link

jpotier commented Jan 27, 2018

@kovidgoyal can the single glyph be of more that 2 times a base glyph width? In iosevka there's the WwW glyph, how does this one work?

@kovidgoyal
Copy link
Owner

Well, kitty is never going to support arbitrary length ligatures, as it works by storing cell level rendered bitmaps (technically alpha masks) on the GPU for performance, and that scheme has to have a finite max ligature length, otherwise glyph lookup times become too large.

@jpotier substitute N for 2 in my previous post and it remains the same. The only limitation is that in kitty the max value for N is 9. Basically N character string must be replaced by a ligature that is N glyphs wide.

@be5invis
Copy link
Author

@kovidgoyal Hmmm, you will experience a lot of problems when dealing with complex scripts (like Indian scripts, Arabic, ...)

@jpotier
Copy link

jpotier commented Jan 27, 2018

Ok. So, only way to get it to work for me, would be to change how ligatures are done in the font. I have no experience in this field, though.

@be5invis well kitty is a terminal emulator. Maybe that's not going to be a problem :D

@kovidgoyal
Copy link
Owner

Yes, I know. I dont intend to ever support complex scripts in kitty. It is fundamentally a character grid, scripts that dont work in character grids are not going to be renderable.

@jpotier
Copy link

jpotier commented Jan 27, 2018

@be5invis How hard would it be for me to implement ligatures by glyph substitution for Iosevka? Any tools you know on Linux for that task?

@kovidgoyal
Copy link
Owner

kovidgoyal commented Jan 27, 2018

@be5invis I'm not sure I understand why you want to support arbitrary length ligature in any case? If one wants to draw solid lines, the way to do it is to use the unicode box drawing characters, not replacing ------- with a ligature. Maybe there's some use case I am overlooking.

@be5invis
Copy link
Author

@kovidgoyal You know, in functional languages like Haskell there are very long operators (look at them in Lens!), so, hmmm, I made the arbitrary-length operators.

@kovidgoyal
Copy link
Owner

I'm not familiar with Haskell -- but surely they are not arbitrarily sized operators! I imagine sticking to a max of five characters would be ample -- kitty itself supports ligatures of up to 9 characters, this is because of Source Code Pro with has ligatures for [WARNING]

@jpotier
Copy link

jpotier commented Jan 27, 2018

Prelude> (============================================================================================================) = (+)
Prelude> 1 ============================================================================================================ 1
2

@kovidgoyal nearly :D

@kovidgoyal
Copy link
Owner

kovidgoyal commented Jan 27, 2018

Sure you can define large operators, you can do that in many languages, but are they actually used in practice? If you are going to have a ten character operator, it makes far more sense to use a function.

@jpotier
Copy link

jpotier commented Jan 27, 2018

I'm quite convinced that it's not the case. But I have no proof of that either.

@be5invis
Copy link
Author

@be5invis
Copy link
Author

For long operators it is hard to enumerate them all, so writing chaining GSUBs is a pretty simple solution for them.

@maximbaz
Copy link
Contributor

Hey @be5invis, I just want to confirm with you, is it possible to compile Iosevka in a way so that the ligatures of size less than N (9) are supported in this terminal, but arbitrary-length ligations are not? Or that requires designing the font in a completely different manner, and thus we can declare that no Iosevka ligatures will ever work properly in kitty terminal?

I'm asking because while I support the engineering effort behind making ligatures as generic as possible that allows them to be of arbitrary length, in practice I personally would be satisfied if I was able to use ligatures that are smaller than 9 characters.

Cross-link to the issue in Iosevka repo for future reference: be5invis/Iosevka#248

ahmedelgabri added a commit to ahmedelgabri/dotfiles that referenced this issue May 11, 2018
https://nerdfonts.com/

For a long time I was skeptical but I decided to try it anyway & I like
it to be honest.

I have a switch in case I want to toggle this `$NERD_FONTS`

- I'm using Iosevka Term Nerd Font because Kitty doesn't render the
normal Iosevka ligatures properly kovidgoyal/kitty#297, but in iTerm & Alacrrity it should be fine I suppose.
  - But here is the catch, I can have both fonts installed 🤦 because ryanoasis/nerd-fonts#257 (comment) so for now using the Term one for now (no ligatures)
- Most of the changes are actually in vim mainly the statusline, I also tweaked the statusline too to make is a bit more minimal.
- In tmux, the main major chnages are:
  - in the github status script (won't show anything by default, only if Github is having issue)
  - Battery check this ahmedelgabri/Battery@a4145f5
- zsh prompt check ahmedelgabri/pure@de04c1d
ahmedelgabri added a commit to ahmedelgabri/dotfiles that referenced this issue May 11, 2018
https://nerdfonts.com/

For a long time I was skeptical but I decided to try it anyway & I like
it to be honest.

I have a switch in case I want to toggle this `$NERD_FONTS`

- I'm using Iosevka Term Nerd Font because Kitty doesn't render the
normal Iosevka ligatures properly kovidgoyal/kitty#297, but in iTerm & Alacrrity it should be fine I suppose.
  - But here is the catch, I can have both fonts installed 🤦 because ryanoasis/nerd-fonts#257 (comment) so for now using the Term one for now (no ligatures)
- Most of the changes are actually in vim mainly the statusline, I also tweaked the statusline too to make is a bit more minimal.
- In tmux, the main major chnages are:
  - in the github status script (won't show anything by default, only if Github is having issue)
  - Battery check this ahmedelgabri/Battery@a4145f5
- zsh prompt check ahmedelgabri/pure@de04c1d
ahmedelgabri added a commit to ahmedelgabri/dotfiles that referenced this issue May 11, 2018
https://nerdfonts.com/

For a long time I was skeptical but I decided to try it anyway & I like
it to be honest.

I have a switch in case I want to toggle this `$NERD_FONTS`

- I'm using Iosevka Term Nerd Font because Kitty doesn't render the normal Iosevka ligatures properly kovidgoyal/kitty#297, but in iTerm & Alacrrity it should be fine.
  - But here is the catch, I can't have both fonts installed 🤦 because ryanoasis/nerd-fonts#257 (comment) so for now using the Term one (no ligatures)
- Most of the changes are actually in vim mainly the statusline, I also tweaked the statusline too to make is a bit more minimal.
- In tmux, the main major chnages are:
  - in the github status script (won't show anything by default, only if Github is having issue)
  - Battery check this ahmedelgabri/Battery@a4145f5
- zsh prompt check ahmedelgabri/pure@de04c1d
@be5invis
Copy link
Author

@maximbaz There was a feature called "compLig", which can generate pre-composed glyphs and assign them to a PUA character so editors like Emacs can use it.
It is possible to write a contextual sub...

@EvanCarroll
Copy link

As a side note question on glyph size, i'm not sure of the burdon but it would be nice to have an 80 character tripple = glyph for the stupid terminal apps that use it for progress bars (like wget and such)

@kovidgoyal
Copy link
Owner

Such apps should be updated to use unicode box drawing characters
instead. No need to have unnatural contortions like 80 character wide
glyphs just to draw a progress bar.

@AndydeCleyre
Copy link

Kitty looks very cool, and I'd love to use it, but can't without Iosevka support. I don't see an open issue, so am subscribing here on the off-chance things change.

@blueyed
Copy link
Contributor

blueyed commented Jan 7, 2019

@AndydeCleyre
be5invis/Iosevka#248 (comment) works good for me. (Would be great to have this packaged for Arch Linux (AUR).)

@AndydeCleyre
Copy link

@blueyed Looks like that workaround creates a hybrid font between Iosevka and Fira Code, which I'm not very interested in.

@kovidgoyal
Copy link
Owner

It's never going to change in kitty. Given the way that rendering works supporting infinite length ligatures is simply too high a performance cost. So unless you can convince the maintainers of iosevka to use a different approach for their ligatures, Iosevka is not going to work in kitty.

@kovidgoyal
Copy link
Owner

And just FYI I added code to kitty to handle infinite length ligatures (upto the max length of 9) for FiraCode and Cascadia Code. These fonts use a well defined naming scheme for infinite length ligature glyhs which makes it possible to detect these. If you change Iosevka to properly name the glyphs as well, kitty should work with it. The glyphs are named as *_[start|middle|end].seq For example:

hb-shape --cluster-level=1 --shapers=ot kitty_tests/FiraCode-Medium.otf  '=====>'
[equal_start.seq=0+1200|equal_middle.seq=1+1200|equal_middle.seq=2+1200|equal_middle.seq=3+1200|equal_middle.seq=4+1200|greater_equal_end.seq=5+1200]

@AndydeCleyre
Copy link

@be5invis I'm not sure I understand why you want to support arbitrary length ligature in any case? If one wants to draw solid lines, the way to do it is to use the unicode box drawing characters, not replacing ------- with a ligature. Maybe there's some use case I am overlooking.

In some markup languages such as reStructuredText, long lines of repeated punctuation serve as underlines and overlines for section titles.

@kovidgoyal
Copy link
Owner

kovidgoyal commented Feb 19, 2021 via email

@The-Compiler
Copy link
Contributor

I just tried the kitty master branch with the Iosevka dev branch, and indeed this seems to work beautifully! 🎉 Thanks @kovidgoyal and @be5invis for your collaboration over at be5invis/Iosevka#1007 to make this work ❤️

@Nequo
Copy link

Nequo commented Jun 8, 2021

Hey @The-Compiler, I have just tried building Iosevka from the latest release 7.0.4 and kitty from master, but I still have the same issue. How did you build Iosevka? Could you share the ttf files?

Thanks!

@The-Compiler
Copy link
Contributor

@Nequo I used the Archlinux package and updated the PKGBUILD (version number and checksums being the only changes).

Here's the result: https://t.cmpl.cc/iosevka.tar.gz (993 MB)

And the relevant part of my kitty.conf: https://github.com/The-Compiler/dotfiles/blob/master/kitty.conf#L1-L13

@real-or-random
Copy link

If anyone wonders why this won't work with a recent kitty and Iosevka custom build:
you need to enable export-glyph-names, see https://github.com/be5invis/Iosevka/blob/master/doc/custom-build.md .

(leaving this here, may help others save time)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants