-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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: Make Nerd Fonts Monospaced Again #764
Conversation
Some additional thoughts:
There is some back and forth about this, and at one point you (Ryan) say 'proper fix is with the actual font patcher'. Maybe somehow related: #747 #748 (for some fonts) #746 (comment) (on color changes?! 👀 ) |
Here a visual representation of what the code does. After this PR shown firstself.sourceFont.paste()
self.sourceFont[currentSourceFontGlyph].transform(align_matrix)
self.remove_glyph_neg_bearings(self.sourceFont[currentSourceFontGlyph])
self.set_glyph_width_mono(self.sourceFont[currentSourceFontGlyph]) Creates flavor 2
And when we swap the last two lines, as done in 59c45baself.sourceFont.paste()
self.sourceFont[currentSourceFontGlyph].transform(align_matrix)
self.set_glyph_width_mono(self.sourceFont[currentSourceFontGlyph])
self.remove_glyph_neg_bearings(self.sourceFont[currentSourceFontGlyph]) Creates flavor 3 Wide Icon:
Small Icon:
CommentThis is also to show that the code as it is does not really describe in a good way what is intended. because both Appendix: CodeCode used to create the imagery above diff --git a/font-patcher b/font-patcher
index 1c5c9693..991e33c1 100755
--- a/font-patcher
+++ b/font-patcher
@@ -809,12 +809,44 @@ class font_patcher:
if sym_attr['align'] == 'r':
x_align_distance += overlap_width
+ inserter = 0x5000 if currentSourceFontGlyph == 60036 else 0x5004
+ if currentSourceFontGlyph == 60036 or currentSourceFontGlyph == 58017:
+ print("\nA")
+ print(get_glyph_dimensions(self.sourceFont[currentSourceFontGlyph]))
+ print((self.sourceFont[currentSourceFontGlyph].width, self.sourceFont[currentSourceFontGlyph].left_side_bearing, self.sourceFont[currentSourceFontGlyph].right_side_bearing))
+ self.sourceFont.selection.select(currentSourceFontGlyph)
+ self.sourceFont.copy()
+ self.sourceFont.selection.select(inserter)
+ self.sourceFont.paste()
+ self.sourceFont[inserter].glyphname = "before"
+ inserter += 1
+
align_matrix = psMat.translate(x_align_distance, y_align_distance)
self.sourceFont[currentSourceFontGlyph].transform(align_matrix)
+ if currentSourceFontGlyph == 60036 or currentSourceFontGlyph == 58017:
+ print("A after transform")
+ print(get_glyph_dimensions(self.sourceFont[currentSourceFontGlyph]))
+ print((self.sourceFont[currentSourceFontGlyph].width, self.sourceFont[currentSourceFontGlyph].left_side_bearing, self.sourceFont[currentSourceFontGlyph].right_side_bearing))
+ self.sourceFont.selection.select(currentSourceFontGlyph)
+ self.sourceFont.copy()
+ self.sourceFont.selection.select(inserter)
+ self.sourceFont.paste()
+ self.sourceFont[inserter].glyphname = "transformed"
+ inserter += 1
# Ensure after horizontal adjustments and centering that the glyph
# does not overlap the bearings (edges)
self.remove_glyph_neg_bearings(self.sourceFont[currentSourceFontGlyph])
+ if currentSourceFontGlyph == 60036 or currentSourceFontGlyph == 58017:
+ print("A after remove_glyph_neg_bearings")
+ print(get_glyph_dimensions(self.sourceFont[currentSourceFontGlyph]))
+ print((self.sourceFont[currentSourceFontGlyph].width, self.sourceFont[currentSourceFontGlyph].left_side_bearing, self.sourceFont[currentSourceFontGlyph].right_side_bearing))
+ self.sourceFont.selection.select(currentSourceFontGlyph)
+ self.sourceFont.copy()
+ self.sourceFont.selection.select(inserter)
+ self.sourceFont.paste()
+ self.sourceFont[inserter].glyphname = "de-bearinged"
+ inserter += 1
# Needed for setting 'advance width' on each glyph so they do not overlap,
# also ensures the font is considered monospaced on Windows by setting the
@@ -822,6 +854,16 @@ class font_patcher:
# even the ones that are empty and didn't go through the scaling operations.
# it should come after setting the glyph bearings
self.set_glyph_width_mono(self.sourceFont[currentSourceFontGlyph])
+ if currentSourceFontGlyph == 60036 or currentSourceFontGlyph == 58017:
+ print("A after set_glyph_width_mono")
+ print(get_glyph_dimensions(self.sourceFont[currentSourceFontGlyph]))
+ print((self.sourceFont[currentSourceFontGlyph].width, self.sourceFont[currentSourceFontGlyph].left_side_bearing, self.sourceFont[currentSourceFontGlyph].right_side_bearing))
+ self.sourceFont.selection.select(currentSourceFontGlyph)
+ self.sourceFont.copy()
+ self.sourceFont.selection.select(inserter)
+ self.sourceFont.paste()
+ self.sourceFont[inserter].glyphname = "monospaced"
+ inserter += 1
# end for
|
Hi. Why is this not merged yet? |
After re-reading the description (topmost comment) it is a bit clumbsily formulated. Will fix that. But most probably it is not merged because it has heavy implications that need time to evaluate. AND a decision is needed which of the 3 font types we want to generate (flavor 1, 2, 3 ?) Edit: Add 'AND' paragraph |
[why] For some powerline symbols we add a certain amount of overlap into the previous or next character to cover up a small gap between the symbols that otherwise can show up as ugly thin (usually colored) line. But after we carefully design that glyph with a bit overlap (over-sized and having negative bearings) we remove all bearings. That breaks of course the glyph and no actual overlap on the left side happens. [how] Just do not remove negative bearings on overlap-enabled glyphs. As they are rescaled in both directions anyhow all bearings are wanted and must be kept. Reported-by: Mihail Ivanchev <@MIvanchev> Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
@Finii, can you please rebase this PR on top of the current master? |
9b3caea
to
f7d1302
Compare
Rebased, force push. |
f7d1302
to
5045abe
Compare
Rebase on master, force push. Thanks to @saumyajyoti |
[why] The commit 59c45ba Remove negative bearings on 2048-em glyphs has been introduced to fix some problems with the symbols only font, at least from the commit message. That font is intended to be used in font-fallback situations, and so we do not know the advance width of the current font anyhow. It does not make sense to enforce an advance width with these. [how] Create the NerdFontsSymbolsOnly as if 59c45ba would be still in effect, i.e. with variable advance width. [note] There have been a lot discussions about the reverted commit, some can be found here: * #900 * #764 * #731 Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
5045abe
to
c425a80
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't we need to update https://github.com/ryanoasis/nerd-fonts/blob/master/readme.md ?
Yes! I will add it. |
This reverts commit 59c45ba. [why] The commit breaks the non-mono Nerd Fonts for a lot of people. The issue was not very good documented and investigation can not be seen. For the TITLE it should have affected only the 2048-em Symbols only font, but in fact all patched fonts were changed. Maybe that was intended, maybe not. [how] This will make the advance width again equal for all glyphs. This enables the use of the non-mono variant in more terminals. For wider symbols a space is now (again) needed after the symbol. That is expected by a lot applications. [note] See Pull Request 764 for more details. See next commits for alternative solution for original problem. Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
[why] Theoretically we can produce 3 types on fonts: * A: Strictly monospaced font * B: Allow bigger symbols, but advance width still monospaced * C: Allow bigger symbols, advance width will vary All have their uses. Historically Nerd Fonts produced A and B. Then we had kind of a breaking change with 2.2.0 that it produces now A and C. The commit b9b7a5080 Revert "Remove negative bearings on 2048-em glyphs" restores the old (pre 2.2.0) behavior. But the type C fonts can be useful, so maybe we can have them as option? [how] Add commandline option to be able to create all fonts types: * A: specify -s or --mono or --use-single-width-glyphs * B: specify nothing * C: specify --variable-width-glyphs Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
[why] The commit 59c45ba Remove negative bearings on 2048-em glyphs has been introduced to fix some problems with the symbols only font, at least from the commit message. That font is intended to be used in font-fallback situations, and so we do not know the advance width of the current font anyhow. It does not make sense to enforce an advance width with these. [how] Create the NerdFontsSymbolsOnly as if 59c45ba would be still in effect, i.e. with variable advance width. [note] There have been a lot discussions about the reverted commit, some can be found here: * #900 * #764 * #731 Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
Reported-by: Saumyajyoti Mukherjee <saumyajyoti> Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
c425a80
to
f4d96f2
Compare
[why] The params are half way handled as dict, but if unset it is an empty string. That makes accessing it needlessly complicated. [how] With no functional change the params becomes now a dict, also when it does not contain any particular information. At the moment that seems not nessecary, as it can only contain one key: 'overlap'. We could also rename 'params' to 'overlap' and just store the value. But we keep the generic params dictionary as it might come in handy some time in the far future when more parameters are added. Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
[why] For some powerline symbols we add a certain amount of overlap into the previous or next character to cover up a small gap between the symbols that otherwise can show up as ugly thin (usually colored) line. But after we carefully design that glyph with a bit overlap (over-sized and having negative bearings) we remove all bearings. That breaks of course the glyph and no actual overlap on the left side happens. [how] Just do not remove negative bearings on overlap-enabled glyphs. As they are rescaled in both directions anyhow all bearings are wanted and must be kept. Reported-by: Mihail Ivanchev <@MIvanchev> Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
Thanks to everyone who helped sorting out the actual problem(s) and solving this irritating issue :-) |
[why] Some fonts have invalid (or unset) Panose flags. When we create a "Nerd Font Mono" font the Panose proportion is set to 'monospace'. This make the font selectable in certain applications that need monospaced fonts. After #764 the "Nerd Font" variant shall (again) be detected as monospaced font, but the glyphs have a big right side bearing (hang into the next 'cell'). So we need to set the Panose bits there also. [how] We already have a check if the font is propably monospaced, independent from Panose. This is used to prevent --mono patching on originally proportional fonts. If we find out with that check that the font is (most probably) monospaced we also set the appropriate bits in Panose; unless Panose has valid values that contradict that change. Fixes: #1098 Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
[why] Some fonts have invalid (or unset) Panose flags. When we create a "Nerd Font Mono" font the Panose proportion is set to 'monospace'. This make the font selectable in certain applications that need monospaced fonts. After ryanoasis#764 the "Nerd Font" variant shall (again) be detected as monospaced font, but the glyphs have a big right side bearing (hang into the next 'cell'). So we need to set the Panose bits there also. [how] We already have a check if the font is propably monospaced, independent from Panose. This is used to prevent --mono patching on originally proportional fonts. If we find out with that check that the font is (most probably) monospaced we also set the appropriate bits in Panose; unless Panose has valid values that contradict that change. Fixes: ryanoasis#1098 Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
…-Monospaced-Again font-patcher: Make Nerd Fonts Monospaced Again
Another bugfix release to fix the regression introduced with 2.2.0 that is fixed by ryanoasis#764. Also note ryanoasis#900. Some other smaller PRs also pulled. Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
[why] Some fonts have invalid (or unset) Panose flags. When we create a "Nerd Font Mono" font the Panose proportion is set to 'monospace'. This make the font selectable in certain applications that need monospaced fonts. After ryanoasis#764 the "Nerd Font" variant shall (again) be detected as monospaced font, but the glyphs have a big right side bearing (hang into the next 'cell'). So we need to set the Panose bits there also. [how] We already have a check if the font is propably monospaced, independent from Panose. This is used to prevent --mono patching on originally proportional fonts. If we find out with that check that the font is (most probably) monospaced we also set the appropriate bits in Panose; unless Panose has valid values that contradict that change. Fixes: ryanoasis#1098 Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
This reverts commit 59c45ba.
In the following The Commit means the commit that this PR want to revert (remove).
[why]
The Commit breaks the non-mono Nerd Fonts for a lot of people.
The issue which is the reason for This Commit was not very good documented and investigation can not be
seen.
From The Commit's TITLE it should have affected the 2048-em Symbols font only, but in fact all patched fonts were changed.
Maybe that was intended, maybe not.
[how]
This will make the advance width again equal for all glyphs.
This enables the use of the non-mono variant in more terminals.
For wider symbols a space is now (again) needed after the symbol.
That is expected by a lot applications.
Requirements / Checklist
What does this Pull Request (PR) do?
Make Non-Mono Nerd Fonts monospaced but allow added symbols to extend over the allotted space to the right (negative right side bearings).
How should this be manually tested?
Any background context you can provide?
The behavior has been changed with The Commit 59c45ba that has been written to fix this issue (at Arch) https://bugs.archlinux.org/task/66212.
Most of the fonts in
patched-fonts/
were not updated after that change, so the problems with that change became not obvious until recently.If it is a problem or not depends also on the used terminal application. Some scale individual glyphs (like Windows Terminal), some just write them out.
What has been the problem and why is the solution a problem
A User complained that in their use case (which is not described in detail, but can be in a non-terminal program that shows a status bar somewhere) the added wide symbols overlap with immediately following ordinary letters.
This is the case because obviously the program that shows the symbols and letters follows the advance width, which is the same for every symbol in a monospaced font. The bigger symbols extrude to the right more than the cursor will more, so this is expected.
This is the reason why applications that use the symbols typically add a blank after the symbol itself, to preserve monospace grid and prevent overlap. For example vim-devicons adds an
ArtifactFix
(i.e. blank' '
) when appropriate. Other programs like 'ls
with filetype symbols' also add a blank space directly after a symbol that is to be displayed.After That Commit the fonts are not monospaced anymore and terminal emulators do one of
Nerd Font Mono
)The original problem poster should maybe have changed that application to include the customary blank after symbols.
But then it looks like at least some problem commenter use the font in proportional mode like this
The numbers-and-letter part of the font in this example is proportional, and so the poster (rightfully?) expects proportional symbols. I assume the symbols are not patched in but come from the Symbols-Only font (as described in The Commit message 59c45ba.
Lets define some nomenclature:
Nerd Font Mono
: strictly monospaced font (i.e. all symbols fit into one 'space' (symbols scaled way down)Nerd Font Classic
: monospaced font (all 'letters' monospaced, symbols have monospace advance, but extend to right)Nerd Font Proportional
: monospaced letters, but proportional symbols (no negative bearings)Nerd Fonts contained up to 59c45ba the fonts 1 and 2. Afterward the font-patch result is 1 and 3. This PR reverts / changes it back to 1 and 2. Typical use cases of Nerd Fonts expect the overwide symbols of 2 and handle them appropriately. Also 2 is useful in more terminal applications. People who want non-tiny symbols (i.e. not 1) need 2 or a proportional-font-allowed terminal to use 3.
Possibly the font 3 would also be nice to have (or at least allow users to self patch it with a command line option).
What are the relevant tickets (if any)?
The problem comes up in various guises, and the list is not complete.
Screenshots (if appropriate or helpful)
Font 1 example
Symbols scaled down to fit into one advance width (i.e. 1200 here), strictly monospaced, all glyphs have 1200 advance width.
Font taken from this repo, MASTER,
patched-fonts/CascadiaCode/Regular/complete/Caskaydia\ Cove\ Regular\ Nerd\ Font\ Complete\ Mono.otf
Font 2 example
Symbols not scaled but changed advance width (i.e. 1200), monospaced, all glyphs have 1200 advance width, symbols have negative right bearing (extrude out to the right).
Font created from this repo, MASTER,
fontforge patched-fonts/CascadiaCode/Regular/complete/Caskaydia\ Cove\ Regular\ Nerd\ Font\ Complete.otf patched-fonts/CascadiaCode/Regular/complete/Caskaydia\ Cove\ Regular\ Nerd\ Font\ Complete\ Mono.otf
Font 3 example
Symbols not scaled with original advance width (i.e. 2048 here), not strictly monospaced, all textual glyphs have 1200 advance width, symbols have any advance width.
Font taken from this repo, MASTER,
patched-fonts/CascadiaCode/Regular/complete/Caskaydia\ Cove\ Regular\ Nerd\ Font\ Complete.otf
Edit: Make more clear what The Commit means and highlight the term as special