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

font-patcher: Use correct source font metrics #593

Merged

Conversation

Finii
Copy link
Collaborator

@Finii Finii commented Mar 17, 2021

Description

[why]
With a source font where Win Ascent/Descent differs from Typo
Ascend/Descent newly added symbols that are intended to be centered
within the visual space can end up too far up or down.

The happens for example when patching CascadiaCode. Added glyphs like
the Ubuntu logo (unicode 0xF31B) is not centered between the square
brackets or on a line with the less then and other centered glyphs.

[how]
The calculation takes the Win Ascent/Descent to calculate the visual
hight. That information is a mix of hight and line spacing and can be
misleading.

Therefore, if use_typo_metrics is set in a font, we obey that flag
and use the typo metrics values instead.

[note]
Some websites with further information follow.

https://github.com/googlefonts/gf-docs/tree/main/VerticalMetrics

Hhea metrics are used in Mac OS X, whilst Microsoft uses
Typo when Use_Typo_Metrics is enabled

https://docs.microsoft.com/en-us/typography/opentype/otspec160/os2#fsselection
https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6hhea.html

Requirements / Checklist

  • Read the Contributing Guidelines
  • Read or at least glanced at the FAQ
  • Read or at least glanced at the Wiki
  • Scripts execute without error (if necessary):
    • If any of the scripts were modified they have been tested and execute without error, e.g.:
      • ./font-patcher Inconsolata.otf --fontawesome --octicons --pomicons
      • ./gotta-patch-em-all-font-patcher\!.sh Hermit
  • Extended the README and documentation if necessary, e.g. You added a new font please update the table

How should this be manually tested?

This need visual inspection of the generated fonts. Only some fonts are affected, I will give a list of these in a comment below (with a script that creates that list).

Any background context you can provide?

This came up as Issue adam7/delugia-code#53 at Delugia Code, where we use font-patcher also to patch Cascadia Code, but with some (few) specialties. That repo stems from the time when Cascadia Code was not part of Nerd Fonts and is (almost) obsolete now (except for the added specialties).

What are the relevant tickets (if any)?

#592

Screenshots (if appropriate or helpful)

Screenshots will follow as comments after the 'affected fonts' list.

[why]
With a source font where Win Ascent/Descent differs from Typo
Ascend/Descent newly added symbols that are intended to be centered
_within the visual space_ can end up too far up or down.

The happens for example when patching CascadiaCode. Added glyphs like
the Ubuntu logo (unicode 0xF31B) is not centered between the square
brackets or on a line with the less then and other centered glyphs.

[how]
The calculation takes the Win Ascent/Descent to calculate the visual
hight. That information is a mix of hight and line spacing and can be
misleading.

Therefore, if use_typo_metrics is set in a font, we obey that flag
and use the typo metrics values instead.

[note]
Some websites with further information follow.

https://github.com/googlefonts/gf-docs/tree/main/VerticalMetrics
  > Hhea metrics are used in Mac OS X, whilst Microsoft uses
  > Typo when Use_Typo_Metrics is enabled

https://docs.microsoft.com/en-us/typography/opentype/otspec160/os2#fsselection
https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6hhea.html

Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
@Finii
Copy link
Collaborator Author

Finii commented Mar 17, 2021

Because this PR can potentially break all patched fonts, we want to know which fonts are really patched differently.

Here follows a complete list of all fonts where the PR changes the behavior, all other will run the same as before.
The script gives the centerline shift that is introduced in percent of capital height, for any font where that number is not identical to zero. For the following discussion I will ignore shifts of less than 5% as they are almost invisible.

nerd-fonts/src/unpatched-fonts$ find . -name '*tf' -exec fontforge -quiet -script get_size2 {} \; 2>/dev/null

centerline height       change               Path: Name
before ->  after     (% of capitalheight)

 306   ->    300     (  -6:  -1%)        on ./3270/Medium/3270Medium.otf: 3270-Medium
 306   ->    300     (  -6:  -1%)        on ./3270/Medium/3270Medium.ttf: 3270-Medium
 306   ->    300     (  -6:  -1%)        on ./3270/Narrow/3270Narrow.otf: 3270 Narrow
 306   ->    300     (  -6:  -1%)        on ./3270/Narrow/3270Narrow.ttf: 3270 Narrow
 306   ->    300     (  -6:  -1%)        on ./3270/Semi-Narrow/3270SemiNarrow.otf: 3270 Semi-Narrow
 306   ->    300     (  -6:  -1%)        on ./3270/Semi-Narrow/3270SemiNarrow.ttf: 3270 Semi-Narrow
 640   ->    512     (-128:  -7%)        on ./Agave/agave-r.ttf: agave regular
 873   ->    710     (-163:  -7%)        on ./CascadiaCode/Bold/CascadiaCode-Bold.otf: Cascadia Code Bold
 873   ->    710     (-163:  -7%)        on ./CascadiaCode/ExtraLight/CascadiaCode-ExtraLight.otf: Cascadia Code ExtraLight
 873   ->    710     (-163:  -7%)        on ./CascadiaCode/Light/CascadiaCode-Light.otf: Cascadia Code Light                 
 873   ->    710     (-163:  -7%)        on ./CascadiaCode/Regular/CascadiaCode-Regular.otf: Cascadia Code Regular
 873   ->    710     (-163:  -7%)        on ./CascadiaCode/SemiBold/CascadiaCode-SemiBold.otf: Cascadia Code SemiBold
 873   ->    710     (-163:  -7%)        on ./CascadiaCode/SemiLight/CascadiaCode-SemiLight.otf: Cascadia Code SemiLight
 676   ->    626     ( -50:  -3%)        on ./FantasqueSansMono/Bold/FantasqueSansMono-Bold.ttf: Fantasque Sans Mono Bold
 676   ->    626     ( -50:  -3%)        on ./FantasqueSansMono/Bold-Italic/FantasqueSansMono-BoldItalic.ttf: Fantasque Sans Mono Bold Italic
 676   ->    626     ( -50:  -3%)        on ./FantasqueSansMono/Italic/FantasqueSansMono-Italic.ttf: Fantasque Sans Mono Italic
 676   ->    626     ( -50:  -3%)        on ./FantasqueSansMono/Regular/FantasqueSansMono-Regular.ttf: Fantasque Sans Mono Regular
 654   ->    614     ( -40:  -2%)        on ./Gohu/11/gohufont-11.ttf: GohuFont
 586   ->    614     (  28:   2%)        on ./Gohu/14/gohufont-14.ttf: GohuFont
 654   ->    614     ( -40:  -2%)        on ./Gohu/uni-11/gohufont-uni-11.ttf: GohuFont
 586   ->    614     (  28:   2%)        on ./Gohu/uni-14/gohufont-uni-14.ttf: GohuFont
 281   ->    250     ( -31:  -3%)        on ./Hermit/Bold/Hermit-bold.otf: Hermit Bold 
 296   ->    250     ( -46:  -5%)        on ./Hermit/Light/Hermit-light.otf: Hermit Light
 293   ->    250     ( -43:  -4%)        on ./Hermit/Medium/Hermit-medium.otf: Hermit Medium
 275   ->    335     (  60:   6%)        on ./Inconsolata/Inconsolata-Bold.otf: Inconsolata Bold
 275   ->    335     (  60:   6%)        on ./Inconsolata/Inconsolata-Bold.ttf: Inconsolata Bold
 275   ->    334     (  60:   6%)        on ./Inconsolata/Inconsolata-Regular.otf: Inconsolata Regular
 275   ->    334     (  60:   6%)        on ./Inconsolata/Inconsolata-Regular.ttf: Inconsolata Regular
 750   ->    525     (-225: -12%)        on ./Monofur/Italic/Monofur Italic for Powerline.ttf: monofur   italic for Powerline
 342   ->    250     ( -92:  -9%)        on ./Overpass/Mono/Bold/overpass-mono-bold.otf: Overpass Mono Bold
 342   ->    250     ( -92:  -9%)        on ./Overpass/Mono/Light/overpass-mono-light.otf: Overpass Mono Light
 342   ->    250     ( -92:  -9%)        on ./Overpass/Mono/Regular/overpass-mono-regular.otf: Overpass Mono Regular
 342   ->    250     ( -92:  -9%)        on ./Overpass/Mono/Semi-Bold/overpass-mono-semibold.otf: Overpass Mono SemiBold
 342   ->    250     ( -92:  -9%)        on ./Overpass/Non-Mono/Bold-Italic/overpass-bold-italic.otf: Overpass Bold Italic
 342   ->    250     ( -92:  -9%)        on ./Overpass/Non-Mono/Bold/overpass-bold.otf: Overpass Bold
 342   ->    250     ( -92:  -9%)        on ./Overpass/Non-Mono/Extra-Bold-Italic/overpass-extrabold-italic.otf: Overpass ExtraBold Italic
 342   ->    250     ( -92:  -9%)        on ./Overpass/Non-Mono/Extra-Bold/overpass-extrabold.otf: Overpass ExtraBold
 342   ->    250     ( -92:  -9%)        on ./Overpass/Non-Mono/Extra-Light-Italic/overpass-extralight-italic.otf: Overpass ExtraLight Italic
 342   ->    250     ( -92:  -9%)        on ./Overpass/Non-Mono/Extra-Light/overpass-extralight.otf: Overpass ExtraLight
 342   ->    250     ( -92:  -9%)        on ./Overpass/Non-Mono/Heavy-Italic/overpass-heavy-italic.otf: Overpass Heavy Italic
 342   ->    250     ( -92:  -9%)        on ./Overpass/Non-Mono/Heavy/overpass-heavy.otf: Overpass Heavy
 342   ->    250     ( -92:  -9%)        on ./Overpass/Non-Mono/Italic/overpass-italic.otf: Overpass Italic
 342   ->    250     ( -92:  -9%)        on ./Overpass/Non-Mono/Light-Italic/overpass-light-italic.otf: Overpass Light Italic
 342   ->    250     ( -92:  -9%)        on ./Overpass/Non-Mono/Light/overpass-light.otf: Overpass Light
 342   ->    250     ( -92:  -9%)        on ./Overpass/Non-Mono/Regular/overpass-regular.otf: Overpass Regular
 342   ->    250     ( -92:  -9%)        on ./Overpass/Non-Mono/Semi-Bold-Italic/overpass-semibold-italic.otf: Overpass SemiBold Italic
 342   ->    250     ( -92:  -9%)        on ./Overpass/Non-Mono/Semi-Bold/overpass-semibold.otf: Overpass SemiBold
 342   ->    250     ( -92:  -9%)        on ./Overpass/Non-Mono/Thin-Italic/overpass-thin-italic.otf: Overpass Thin Italic
 342   ->    250     ( -92:  -9%)        on ./Overpass/Non-Mono/Thin/overpass-thin.otf: Overpass Thin
 326   ->    333     (   6:   1%)        on ./Terminus/terminus-ttf-4.40.1/BoldItalic/TerminusTTF-Bold Italic-4.40.1.ttf: Terminus (TTF) Bold Italic

(Positiv is after PR the midline is shifted up.)

$ cat get_size2:

#!/usr/bin/env python

# find . -name '*tf' -exec fontforge -quiet -script get_size {} \; 2>/dev/null

import sys
import fontforge

sourceFont = fontforge.open(sys.argv[1])
if sourceFont.os2_use_typo_metrics:
    tya = sourceFont.os2_typoascent
    tyd = sourceFont.os2_typodescent
    osa = sourceFont.os2_winascent
    osd = -sourceFont.os2_windescent
    tysize = tya - tyd
    ossize = osa - osd
    tymiddle = tya - tysize / 2
    osmiddle = osa - ossize / 2

    if sourceFont.os2_use_typo_metrics and tymiddle != osmiddle:
        sys.stdout.write("{:4.0f}   ->   {:4.0f}     ({:4.0f}: {:3.0f}%)       ".format(
            osmiddle, tymiddle, tymiddle - osmiddle, (tymiddle - osmiddle) * 100 / osa))
        sys.stdout.write(" on {}: {}\n".format(sys.argv[1], sourceFont.fullname))

This limits the number of font faces to check from 700+ to 50.

@Finii
Copy link
Collaborator Author

Finii commented Mar 17, 2021

Next will come before/after images, which I will limit to regular mono faces of the fonts with a higher shift (>= 5%)

  • Agave
  • Cascadia Code
  • Hermit
  • Inconsolata
  • Monofur
  • Overpass

@Finii
Copy link
Collaborator Author

Finii commented Mar 17, 2021

Here for all fonts one face shown. First 'original' directly from the patched_fonts/, afterwards how it looks with this MR applied.

All fonts shown with size 40 pt.
Creation of comparsion with e.g. nerd-fonts/bin/scripts$ ./gotta-patch-em-all-font-patcher\!.sh 'Monofur Italic' to get all the meta patch information into the font patch.

Agave

agave regular Nerd Font Complete Mono.ttf
Aagave
Bagave

Cascadia Code

Caskaydia Cove Regular Nerd Font Complete Mono.otf
Acaska
Bcask

Hermit

Hurmit Medium Nerd Font Complete Mono.otf
Ahurmit
Bhurmit

Inconsolata

Inconsolata Regular Nerd Font Complete Mono.otf
Aincon
Bincon

Monofur

monofur italic Nerd Font Complete Mono.ttf
Amonofur
Bmonfur

Overpass

Overpass Regular Nerd Font Complete Mono.otf
Aoverpass
Bover

@Finii
Copy link
Collaborator Author

Finii commented Mar 17, 2021

Even more notable than having the round symbols etc really centered is the now-correct (i.e. working) Powerline Triangular Stuff.

It was not apparent at Delugia, because there we base on Cascadia Code PL and insert with --careful (so we keep the well aligned Powerline stuff done in Cascadia).

@ryanoasis
Copy link
Owner

Really thank you for this. I need a bit to unpack and understand to be honest 😆 ... though it looks like generally a great improvement with some thorough explanation and screenshots which i appreciate.

Tempted to merge this in soon, will try to look in a day or 2 🤞🏻

@ryanoasis
Copy link
Owner

Sorry that I've been unavailable. If anyone else can test this out that'd be great. Going to be digging into PRs again.

@ryanoasis
Copy link
Owner

I'm back merging again, I need to take some more time with this PR though 😄

@ryanoasis
Copy link
Owner

I did some checking locally, most of these do end up looking better, e.g.:

Selection_054

Selection_053

I think Overpass (at least for my setup) looks better as the separators are no longer bleeding over but not quite vertically centered as they were for you:

before

Selection_061

Selection_065

after

Selection_062

Selection_064

I also checked out 3270, agave, fantasque sans, gohu, hurmit, monofur. All of which the separators looked pretty good/centered.

Anyway I think this is an improvement for sure and also based on the info you provided these are the right metrics to use in these cases anyways.

@ryanoasis ryanoasis merged commit f943e8e into ryanoasis:master Dec 11, 2021
@Finii
Copy link
Collaborator Author

Finii commented Dec 13, 2021

I guess all the fonts that leak out originally already, (where the two-dots of Ü end up in the line above) should be rather patched with -l. Although that is a source defect... Hmm.

Overpass looks really bad in your screenshots (e intersecting N in NerdFonts)??
Did a fresh patching with HEAD:

image

@Finii
Copy link
Collaborator Author

Finii commented Dec 13, 2021

Ah, here the test it all script, after patching with -c:
image

Why is the spiky branch thing (uE0A0) too high? :-( Investigating.

Ah it's not in the SYM_ATTR_POWERLINE:

            {'Enabled': self.args.powerline,
                    'Name': "Powerline Symbols",
                    'Filename': "powerline-symbols/PowerlineSymbols.otf",
                    'Exact': True,
                    'SymStart': 0xE0A0, 'SymEnd': 0xE0A2, 'SrcStart': None,   'SrcEnd': None,
                    'ScaleGlyph': None,
                    'Attributes': SYM_ATTR_POWERLINE},
            {'Enabled': self.args.powerline,
                    'Name': "Powerline Symbols",
                    'Filename': "powerline-symbols/PowerlineSymbols.otf",
                    'Exact': True,
                    'SymStart': 0xE0B0, 'SymEnd': 0xE0B3, 'SrcStart': None,   'SrcEnd': None,
                    'ScaleGlyph': None,
                    'Attributes': SYM_ATTR_POWERLINE},

    def setup_patch_set(self):
        """ Creates list of dicts to with instructions on copying glyphs from each symbol font into self.sourceFont """
        # Supported params: overlap | careful
        # Powerline dividers
        SYM_ATTR_POWERLINE = {
            'default': {'align': 'c', 'valign': 'c', 'stretch': 'pa', 'params': ''},

            # Arrow tips
            0xe0b0: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.02}},
            0xe0b1: {'align': 'l', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.02}},
            0xe0b2: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.02}},
            0xe0b3: {'align': 'r', 'valign': 'c', 'stretch': 'xy', 'params': {'overlap': 0.02}},
            # ... and more entries with higer codepoints ... 

Maybe it should have a stretch y 🤔

LNKLEO pushed a commit to LNKLEO/Nerd that referenced this pull request Nov 24, 2023
…-font-metrics

font-patcher: Use correct source font metrics
@Finii Finii deleted the bugfix/use-correct-source-font-metrics branch March 27, 2024 08:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants