Skip to content

font fallback success depends on selected font #8282

@amonks

Description

@amonks

Describe the bug

Here's two font faces from stock MacOS:

postscript_name has U+2714 file
AndaleMono no /System/Library/Fonts/Supplemental/Andale Mono.ttf
Menlo-BoldItalic no /System/Library/Fonts/Menlo.ttc (face 3 within truetype collection)

Here's two tests, in which I try to print U+2714 in bold-italic (printf "\u001b[3m\u001b[1m\u2714"; read):

config bold italic U+2714 renders log output
bold_italic_font postscript_name=AndaleMono no [0.445] The font chosen by the OS for the text: U+2714 is Face(family=Menlo, full_name=Menlo Bold Italic, postscript_name=Menlo-BoldItalic, path=/System/Library/Fonts/Menlo.ttc, units_per_em=2048, ascent=29.7, descent=7.5, leading=0.0, scaled_point_sz=32.0, underline_position=-2.0 underline_thickness=1.4) but it does not actually contain glyphs for that text
bold_italic_font postscript_name=Menlo-BoldItalic yes [0.443] U+2714 bold italic Face(family=Zapf Dingbats, full_name=Zapf Dingbats, postscript_name=ZapfDingbatsITC, path=/System/Library/Fonts/ZapfDingbats.ttf, units_per_em=2048, ascent=26.0, descent=5.7, leading=0.0, scaled_point_sz=32.0, underline_position=-3.2 underline_thickness=1.9)

If I try to render bold italic U+2714 in AndaleMono, it falls back to Menlo-BoldItalic, which doesn't have the glyph, and fails.

...But if I try to render bold italic U+2714 in Menlo-BoldItalic, it falls back to ZapfDingbatsITC and succeeds. What's going on here?

Why does the OS's choice of fallback face depend on the face we're falling back from? More importantly, why is it wrong from AndaleMono and right from Menlo-BoldItalic?

My real config uses neither AndaleMono nor Menlo-BoldItalic, but I wanted to find a stock-MacOS face to repro with. The first font I thought to try here was Menlo-BoldItalic, since it's the system default. But it worked! I thought it worked because Menlo-BoldItalic comes from a truetype collection that does include a face with U+2714, so I reached for AndaleMono. Then I noticed that Menlo-BoldItalic isn't falling back within the truetype collection to, say, Menlo-Regular, but to ZapfDingbatsITC. Weird!

To Reproduce
Steps to reproduce the behavior:

echo "bold_italic_font postscript_name=AndaleMono" > repro.conf
/Applications/kitty.app/Contents/MacOS/kitty --config=repro.conf --debug-font-fallback zsh -c 'printf "\u001b[3m\u001b[1m\u2714"; read'

Environment details

kitty 0.39.0 (1f920ecc77) created by Kovid Goyal
Darwin brigid 24.1.0 Darwin Kernel Version 24.1.0: Thu Oct 10 21:03:15 PDT 2024; root:xnu-11215.41.3~2/RELEASE_ARM64_T6000 arm64
ProductName:		macOS ProductVersion:		15.1.1 BuildVersion:		24B91
OpenGL: '4.1 Metal - 89.3' Detected version: 4.1
Frozen: True
Fonts:
  medium: Menlo-Regular: /System/Library/Fonts/Menlo.ttc
          Features: ()
    bold: Menlo-Bold: /System/Library/Fonts/Menlo.ttc
          Features: ()
  italic: Menlo-Italic: /System/Library/Fonts/Menlo.ttc
          Features: ()
      bi: AndaleMono: /System/Library/Fonts/Supplemental/Andale Mono.ttf
          Features: ()
Paths:
  kitty: /Applications/kitty.app/Contents/MacOS/kitty
  base dir: /Applications/kitty.app/Contents/Resources/kitty
  extensions dir: /Applications/kitty.app/Contents/Resources/Python/lib/kitty-extensions
  system shell: /opt/local/bin/fish
System color scheme: dark. Applied color theme type: none
Loaded config files:
  repro.conf

Config options different from defaults:
bold_italic_font postscript_name=AndaleMono
Changed shortcuts:
	cmd+k →  clear_terminal_and_scrollback
	ctrl+cmd+, →  reload_config
	ctrl+cmd+l →  clear_screen
	opt+cmd+k →  clear_scrollback
	opt+cmd+r →  reset_terminal
	shift+cmd+/ →  open_kitty_website

Important environment variables seen by the kitty process:
	PATH                                [not relevant]
	LANG                                en_US.UTF-8
	SHELL                               /opt/local/bin/fish
	USER                                ajm
	LC_ALL                              en_US.UTF-8

Additional context
n/a: report specfies conf


I'm aware I can work around this by setting the following, so I'm a completely satisfied user (thanks for Kitty! It's great! You're the best!), I just thought the behavior here was curious.

symbol_map U+2714 postscript_name=ZapfDingbatsITC

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions