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

Automatic bold font synthesis for Lucida Console #2074

Closed
TomiBelan opened this issue Jun 5, 2022 · 4 comments
Closed

Automatic bold font synthesis for Lucida Console #2074

TomiBelan opened this issue Jun 5, 2022 · 4 comments
Labels
bug Something isn't working fixed-in-nightly This is (or is assumed to be) fixed in the nightly builds.

Comments

@TomiBelan
Copy link

What Operating System(s) are you seeing this problem on?

Windows

WezTerm version

wezterm 20220408-101518-b908e2dd

Did you try the latest nightly build to see if the issue is better (or worse!) than your current version?

No, and I'll explain why below

Describe the bug

Hi Wez! Nice terminal!

With this config

local wezterm = require 'wezterm';
return {font = wezterm.font("Lucida Console")}

wezterm renders everything in regular Lucida Console, never any bold font.

$ echo $'\e[1m hello \e[m hello'
 hello  hello

image

To Reproduce

See above.

Configuration

See above.

Expected Behavior

$ echo $'\e[1m hello \e[m hello'
 hello  hello

image

Logs

Nothing relevant.

Anything else?

Lucida Console is a preinstalled font in Windows. It does not have a built in bold version. Compare with Courier New:

C:\Users\Tomi>wezterm ls-fonts --list-system | findstr Lucida
wezterm.font("Lucida Console", {weight="Regular", stretch="SemiCondensed", style="Normal"}) -- C:\WINDOWS\FONTS\LUCON.TTF, DirectWrite pixel_sizes=[5, 6, 7, 8]
wezterm.font("Lucida Sans Unicode", {weight="Regular", stretch="Normal", style="Normal"}) -- C:\WINDOWS\FONTS\L_10646.TTF, DirectWrite

C:\Users\Tomi>wezterm ls-fonts --list-system | findstr "Courier"
wezterm.font("Courier New", {weight="Regular", stretch="Normal", style="Normal"}) -- C:\WINDOWS\FONTS\COUR.TTF, DirectWrite pixel_sizes=[4, 6, 7, 8, 8, 12, 12, 14, 15, 16, 17, 17, 18, 20, 20, 20, 22, 23]
wezterm.font("Courier New", {weight="Regular", stretch="Normal", style="Italic"}) -- C:\WINDOWS\FONTS\COURI.TTF, DirectWrite
wezterm.font("Courier New", {weight="Bold", stretch="Normal", style="Normal"}) -- C:\WINDOWS\FONTS\COURBD.TTF, DirectWrite
wezterm.font("Courier New", {weight="Bold", stretch="Normal", style="Italic"}) -- C:\WINDOWS\FONTS\COURBI.TTF, DirectWrite

With return {font = wezterm.font("Lucida Console")}, ls-fonts is:

wezterm ls-fonts
C:\Users\Tomi>wezterm ls-fonts
Primary font:
wezterm.font_with_fallback({
  -- <imported to RAM>, Gdi
  -- Pixel sizes: [5, 6, 7, 8]
  {family="Lucida Console", stretch="SemiCondensed"},

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  -- Assumed to have Emoji Presentation
  -- Pixel sizes: [128]
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Symbols Nerd Font Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})


When Intensity=Half Italic=true:
wezterm.font_with_fallback({
  -- <imported to RAM>, Gdi
  -- Will synthesize italics
  -- Will synthesize dim
  -- Pixel sizes: [5, 6, 7, 8]
  {family="Lucida Console", stretch="SemiCondensed"},

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  -- Assumed to have Emoji Presentation
  -- Pixel sizes: [128]
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Symbols Nerd Font Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})


When Intensity=Half Italic=false:
wezterm.font_with_fallback({
  -- <imported to RAM>, Gdi
  -- Will synthesize dim
  -- Pixel sizes: [5, 6, 7, 8]
  {family="Lucida Console", stretch="SemiCondensed"},

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  -- Assumed to have Emoji Presentation
  -- Pixel sizes: [128]
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Symbols Nerd Font Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})


When Intensity=Bold Italic=false:
wezterm.font_with_fallback({
  -- <imported to RAM>, Gdi
  -- Pixel sizes: [5, 6, 7, 8]
  {family="Lucida Console", stretch="SemiCondensed"},

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  -- Assumed to have Emoji Presentation
  -- Pixel sizes: [128]
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Symbols Nerd Font Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})


When Intensity=Bold Italic=true:
wezterm.font_with_fallback({
  -- <imported to RAM>, Gdi
  -- Will synthesize italics
  -- Pixel sizes: [5, 6, 7, 8]
  {family="Lucida Console", stretch="SemiCondensed"},

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  -- Assumed to have Emoji Presentation
  -- Pixel sizes: [128]
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Symbols Nerd Font Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})


When Intensity=Normal Italic=true:
wezterm.font_with_fallback({
  -- <imported to RAM>, Gdi
  -- Will synthesize italics
  -- Pixel sizes: [5, 6, 7, 8]
  {family="Lucida Console", stretch="SemiCondensed"},

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  -- Assumed to have Emoji Presentation
  -- Pixel sizes: [128]
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Symbols Nerd Font Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})

Title font:
wezterm.font_with_fallback({
  -- <built-in>, BuiltIn
  {family="Roboto", weight="Bold"},

  -- <imported to RAM>, Gdi
  -- Pixel sizes: [5, 6, 7, 8]
  {family="Lucida Console", stretch="SemiCondensed"},

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  -- Assumed to have Emoji Presentation
  -- Pixel sizes: [128]
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Symbols Nerd Font Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})

Notice how it says "Will synthesize italics" and "Will synthesize dim", but never "bold".

I managed to work around the bug in my config with font_rules. With this config, I get the expected result:

return {
  font = wezterm.font("Lucida Console"),
  font_rules = {
    {
      intensity = "Bold",
      italic = true,
      font = wezterm.font("Lucida Console", {bold=true, italic=true}),
    },
    {
      intensity = "Bold",
      italic = false,
      font = wezterm.font("Lucida Console", {bold=true}),
    },
  },
}
wezterm ls-fonts with font_rules
C:\Users\Tomi>wezterm ls-fonts
Primary font:
wezterm.font_with_fallback({
  -- <imported to RAM>, Gdi
  -- Pixel sizes: [5, 6, 7, 8]
  {family="Lucida Console", stretch="SemiCondensed"},

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  -- Assumed to have Emoji Presentation
  -- Pixel sizes: [128]
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Symbols Nerd Font Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})


When Intensity=Bold Italic=true:
wezterm.font_with_fallback({
  -- <imported to RAM>, Gdi
  -- Will synthesize italics
  -- Will synthesize bold
  -- Pixel sizes: [5, 6, 7, 8]
  {family="Lucida Console", stretch="SemiCondensed"},

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  -- Assumed to have Emoji Presentation
  -- Pixel sizes: [128]
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Symbols Nerd Font Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})


When Intensity=Bold Italic=false:
wezterm.font_with_fallback({
  -- <imported to RAM>, Gdi
  -- Will synthesize bold
  -- Pixel sizes: [5, 6, 7, 8]
  {family="Lucida Console", stretch="SemiCondensed"},

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  -- Assumed to have Emoji Presentation
  -- Pixel sizes: [128]
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Symbols Nerd Font Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})


When Intensity=Half Italic=true:
wezterm.font_with_fallback({
  -- <imported to RAM>, Gdi
  -- Will synthesize italics
  -- Will synthesize dim
  -- Pixel sizes: [5, 6, 7, 8]
  {family="Lucida Console", stretch="SemiCondensed"},

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  -- Assumed to have Emoji Presentation
  -- Pixel sizes: [128]
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Symbols Nerd Font Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})


When Intensity=Half Italic=false:
wezterm.font_with_fallback({
  -- <imported to RAM>, Gdi
  -- Will synthesize dim
  -- Pixel sizes: [5, 6, 7, 8]
  {family="Lucida Console", stretch="SemiCondensed"},

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  -- Assumed to have Emoji Presentation
  -- Pixel sizes: [128]
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Symbols Nerd Font Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})


When Intensity=Bold Italic=false:
wezterm.font_with_fallback({
  -- <imported to RAM>, Gdi
  -- Pixel sizes: [5, 6, 7, 8]
  {family="Lucida Console", stretch="SemiCondensed"},

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  -- Assumed to have Emoji Presentation
  -- Pixel sizes: [128]
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Symbols Nerd Font Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})


When Intensity=Bold Italic=true:
wezterm.font_with_fallback({
  -- <imported to RAM>, Gdi
  -- Will synthesize italics
  -- Pixel sizes: [5, 6, 7, 8]
  {family="Lucida Console", stretch="SemiCondensed"},

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  -- Assumed to have Emoji Presentation
  -- Pixel sizes: [128]
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Symbols Nerd Font Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})


When Intensity=Normal Italic=true:
wezterm.font_with_fallback({
  -- <imported to RAM>, Gdi
  -- Will synthesize italics
  -- Pixel sizes: [5, 6, 7, 8]
  {family="Lucida Console", stretch="SemiCondensed"},

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  -- Assumed to have Emoji Presentation
  -- Pixel sizes: [128]
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Symbols Nerd Font Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})

Title font:
wezterm.font_with_fallback({
  -- <built-in>, BuiltIn
  {family="Roboto", weight="Bold"},

  -- <imported to RAM>, Gdi
  -- Pixel sizes: [5, 6, 7, 8]
  {family="Lucida Console", stretch="SemiCondensed"},

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  -- Assumed to have Emoji Presentation
  -- Pixel sizes: [128]
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Symbols Nerd Font Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})

The point is that it should do the right thing by default.

Why didn't I try nightly:

Because I was lazy.

@TomiBelan TomiBelan added the bug Something isn't working label Jun 5, 2022
@wez wez added the Windows Issue applies to Microsoft Windows label Jun 5, 2022
wez added a commit that referenced this issue Jun 5, 2022
For fonts like Lucida Console on Windows which do not have a bold
variant, we were not synthesizing bold.

The reason was that the config-level "make bold" logic works by adding
200 to the weight which takes normal -> demibold, but the bold synthesis
logic is enabled only for bold and higher.

This commit changes the threshold for synthesis to demibold or higher.

refs: #2074
@wez wez added the fixed-in-nightly This is (or is assumed to be) fixed in the nightly builds. label Jun 5, 2022
@wez
Copy link
Owner

wez commented Jun 5, 2022

This should be fixed now in main.

It typically takes about an hour before fixes are available as nightly builds for all platforms. Linux builds are the fastest to build and are often available within about 20 minutes. Windows and macOS builds take a bit longer.

Please take a few moments to try out the fix and let me know how that works out.

If you prefer to use packages provided by your distribution or package manager of choice and don't want to replace that with a nightly download, keep in mind that you can download portable packages (eg: a .dmg file on macOS, a .zip file on Windows and an .AppImage file on Linux) that can be run without permanently installing or replacing an existing package, and can then simply be deleted once you no longer need them.

If you are eager and can build from source then you may be able to try this out more quickly.

@wez wez removed the Windows Issue applies to Microsoft Windows label Jun 5, 2022
@TomiBelan
Copy link
Author

I confirm it works in nightly wezterm 20220605-063531-e7258e0e with return {font = wezterm.font("Lucida Console")}. Thanks!

@wez wez closed this as completed Jun 5, 2022
@clementnuss
Copy link

thanks, I was having this issue as well and this fixed it, with another font on Windows.
👏🏻

@github-actions
Copy link
Contributor

github-actions bot commented Feb 4, 2023

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 4, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working fixed-in-nightly This is (or is assumed to be) fixed in the nightly builds.
Projects
None yet
Development

No branches or pull requests

3 participants