phronmophobic / membrane.term

A terminal emulator in pure clojure
Eclipse Public License 1.0
58 stars 1 forks source link

Consider supporting font selection #2

Closed lread closed 2 years ago

lread commented 3 years ago

Proposal Same vein as #1 but for specifying fonts.

It would be nice to be able to specify font size. It would be super nice to be able to specify the font itself.

This might be super easy, or maybe have nuances I'm not aware of.

Next steps If you are interested in this idea, same offer as #1, happy to take a crack at it! But also don't want to get in your way if this work entices you.

phronmophobic commented 3 years ago

Font control seems like a good idea. Fonts are currently hard coded as top level defs, but should work with any monospaced font. I tried it with a few different mono spaced fonts locally.

(def term-font
  (cond
    (skia/font-exists? (ui/font "Menlo" 12))
    (ui/font "Menlo" 12)

    :else (ui/font "monospace" 12)))

(def font-metrics (skia/skia-font-metrics term-font))
(def cell-width (#'skia/skia-advance-x term-font " "))
(def cell-height (skia/skia-line-height term-font))
(def bg-offset (:Descent font-metrics))

In a similar vein, asciinema/vt already surfaces bold, italic, underline, blink, inverse, and strikethrough. I just implemented bold and italic (inside of emacs running in membrane.term :D), but adding some of the others might be fun at some point.

I would love a PR and would be happy to answer any questions to help make it happen!

lread commented 3 years ago

Ok, now thinking about this one!

Initial ramblings...

How about --font-face and --font-size for options (:font-face and :font-size internally). If I understand correctly, font size unit is points?

What about specifying something like a google font directly from the web? Maybe too complicated for user to specify? Not sure how that would work, just throwing the idea out there. I do see some support in skija for typefaces... but yeah, unless you know something that would make this simple, seems a bit much for a first cut.

But we could certainly document google fonts and nerd fonts as interesting places to find monospace fonts.

I think I'll separate out support rendering of vt underline,blink,inverse and strikethrough to its own issue.

phronmophobic commented 3 years ago

I'm trying to use the same terminology that Skia uses for fonts which I think is: Font: TypeFace + size TypeFace: FamilyName + FontStyle FontStyle: Width + Weight + Slant Width: normal, condensed, expanded (less commonly specified) Weight: normal, bold, extra bold, thin, etc. Slant: Upright (aka. normal), Italic

Based on that, I would suggest either :font-name or :font-family or :font-family-name.

:font-size is 👍

If I understand correctly, font size unit is points?

I think so.

What about specifying something like a google font directly from the web?

You can pass a path to a font file like ttf or ttc as the name for membrane.ui/font. There's some tricky business since formats like ttc can contain multiple typefaces. Text rendering is a whole thing that I'm still trying to learn and improve my understanding on. Since I'm using skia for text rendering, the io/reader trick won't quite work. However, google fonts does let you download font files.

Hopefully, skia uses the text related terminology correctly! If not, it would be good to have another reference to follow. Otherwise, it becomes tricky to talk about all the weird issues with text+fonts.

References. https://api.skia.org/classSkFont.html https://api.skia.org/classSkTypeface.html#a1cd98b2bdf57d80e06917c24c5526b59 https://api.skia.org/classSkFontStyle.html

lread commented 3 years ago

Thanks, the glossary helps!

HTML/CSS uses font-family, so that seems like a good choice. Since the screen size is computed from font character dimensions, we won't have any conversions to think about. (So the font size unit is not that important after all, I think).

Anything we want to do if the user selects a proportional (non-monospace) font?

I think that only supporting OS-installed fonts for a first cut is reasonable. How about you?

phronmophobic commented 3 years ago

Anything we want to do if the user selects a proportional (non-monospace) font?

I just checked to see what my macbook's built in terminal does. It looks like they just use the max character advance for every character? I'm basically ok with anything that doesn't crash as trying to use a non-monospace font doesn't really make sense.

I think that only supporting OS-installed fonts for a first cut is reasonable. How about you?

👍

lread commented 2 years ago

@phronmophobic, have you tried fancy prompts like powerlevel10k under zsh with membrane.term?

I wonder if I have a font-related, or some other (or both) issue.

Here's a zsh powerlevel10k session in iTerm2 using the recommended "MesloLGS NF" font. image

And here's the same using membrane.term (looking pretty nice, BTW!): image

But...

Might be a asciinema/vt thing. Will look deeper but thought I'd ping you to see if you were already aware.

phronmophobic commented 2 years ago

Just looking at https://github.com/romkatv/powerlevel10k/blob/master/font.md#manual-font-installation, it doesn't look like that font actually contains the emoji characters. I know that usually there are different fonts that apply for different character ranges, but I'm actually not totally sure how that works.

phronmophobic commented 2 years ago

Even if we wanted to use multiple fonts depending on the character range, I'm not sure how to ask for the default emoji font on the system. I'll try to look it up.

phronmophobic commented 2 years ago

You can display emoji by using the font family: "Apple Color Emoji". Trying to see if there's a way to pull up the default system emoji font like "monospaced" does for mono space fonts.

lread commented 2 years ago

Thanks! He's added a bunch of glyphs. But I can't say I understand much of this yet. The NF stands for Nerd Font which implies the glyphs.

I might have lead you down the wrong path with that emoji.

Here's maybe a better example from iTerm2 using the "MesloLGS NF" font: image

If I switch to a non-Nerd Font like Menlo I lose the glyphs: image

I switch to another Nerd Font like "Hack Nerd Font" the glyphs are back: image

lread commented 2 years ago

Oho, a bit askew but: image

We were reading bytes from the pty input stream, switching to reading chars got us the Unicode.

Fully supporting Unicode in terminals might be a bit complex though? I'll try to figure out what minimal support means.

We probably don't need to be as thorough as, for example, the Countour terminal folks are being.

phronmophobic commented 2 years ago

We were reading bytes from the pty input stream, switching to reading chars got us the Unicode.

Wow! Not bad. Good catch!

Fully supporting Unicode in terminals might be a bit complex though? I'll try to figure out what minimal support means.

I imagine that full unicode support would probably require changes to membrane. There's a lot of text improvements I'd like to make, but there are a few other priorities at the moment.