ToxicFrog / Ligaturizer

Programming Fonts with Ligatures added (& a script to add them to other fonts)
GNU General Public License v3.0
2.19k stars 112 forks source link

Character lookup fails on Dank Mono #40

Closed Notaduck closed 4 years ago

Notaduck commented 6 years ago

I tried to use your tool to add ligatures to these font's

$ Ligaturizer ll input-fonts                                                                                             (master)  ✱
total 7,6M
-rwxr-xr-x 1 daniel daniel 155K Jul  8 12:30 Anonymous_Pro.ttf
-rw-r--r-- 1 daniel daniel  92K Jul  8 12:30 CamingoCode-Regular.ttf
-rw-r--r-- 1 daniel daniel 290K Jul  8 12:30 Cousine-Bold.ttf
-rwxr-xr-x 1 daniel daniel 302K Jul  8 12:30 Cousine-Regular.ttf
-rw-r--r-- 1 daniel daniel 333K Jul  8 12:30 DejaVuSansMono.ttf
-rwxr-xr-x 1 daniel daniel 115K Jul  8 12:30 DroidSansMono.ttf
-rw-r--r-- 1 daniel daniel  27K Jul  8 12:30 edlo.ttf
drwxr-xr-x 2 daniel daniel 4,0K Jul  8 12:30 FantasqueSansMono-NoLoopK
drwxr-xr-x 2 daniel daniel 4,0K Jul  8 12:30 FantasqueSansMono-Normal
-rw-r--r-- 1 daniel daniel 311K Jul  8 12:30 Hack-Bold.ttf
-rw-r--r-- 1 daniel daniel 303K Jul  8 12:30 Hack-Regular.ttf
-rw-r--r-- 1 daniel daniel  50K Jul  8 12:30 IBMPlexMono-Regular.otf
-rw-r--r-- 1 daniel daniel  51K Jul  8 12:30 IBMPlexMono-SemiBold.otf
-rw-r--r-- 1 daniel daniel  53K Jul  8 12:30 Inconsolata-g.otf
-rwxr-xr-x 1 daniel daniel  58K Jul  8 12:30 Inconsolata.otf
-rwxr-xr-x 1 daniel daniel  95K Jul  8 12:30 Inconsolata-Regular.ttf
-rwxr-xr-x 1 daniel daniel 622K Jul  8 12:30 MesloLGLDZ-Regular.ttf
-rwxr-xr-x 1 daniel daniel 622K Jul  8 12:30 MesloLGL-Regular.ttf
-rwxr-xr-x 1 daniel daniel 622K Jul  8 12:30 MesloLGMDZ-Regular.ttf
-rwxr-xr-x 1 daniel daniel 622K Jul  8 12:30 MesloLGM-Regular.ttf
-rwxr-xr-x 1 daniel daniel 622K Jul  8 12:30 MesloLGSDZ-Regular.ttf
-rwxr-xr-x 1 daniel daniel 622K Jul  8 12:30 MesloLGS-Regular.ttf
-rwxr-xr-x 1 daniel daniel  68K Jul  8 12:30 OxygenMono-Regular.ttf
-rwxr-xr-x 1 daniel daniel 112K Jul  8 12:30 RobotoMono-Regular.ttf
-rw-r--r-- 1 daniel daniel  92K Jul  8 12:30 SFMono-Regular.otf
-rw-r--r-- 1 daniel daniel  92K Jul  8 12:30 SFMono-Semibold.otf
-rw-r--r-- 1 daniel daniel 118K Jul  8 12:30 SourceCodePro-Black.ttf
-rw-r--r-- 1 daniel daniel 118K Jul  8 12:30 SourceCodePro-Bold.ttf
-rw-r--r-- 1 daniel daniel 119K Jul  8 12:30 SourceCodePro-ExtraLight.ttf
-rw-r--r-- 1 daniel daniel 119K Jul  8 12:30 SourceCodePro-Light.ttf
-rw-r--r-- 1 daniel daniel 118K Jul  8 12:30 SourceCodePro-Medium.ttf
-rw-r--r-- 1 daniel daniel 118K Jul  8 12:30 SourceCodePro-Regular.ttf
-rw-r--r-- 1 daniel daniel 118K Jul  8 12:30 SourceCodePro-Semibold.ttf
-rw-r--r-- 1 daniel daniel 279K Jul  8 12:30 SourceCodeVariable-Roman.ttf
-rwxr-xr-x 1 daniel daniel 201K Jul  8 12:30 UbuntuMono-Regular.ttf

But I do get this output(I tired with python 2.x and 3.x):

make                                                                                                       (master)  ✱
fontforge -lang=py ligaturize.py --prefix=Liga "input-fonts/SourceCodePro-Black.ttf" "output-fonts/LigaSourceCodePro-Black.ttf" 2>&1 \
| fgrep -v 'This contextual rule applies no lookups.'
Copyright (c) 2000-2014 by George Williams. See AUTHORS for Contributors.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE. Based on sources from 23:10 UTC  5-Aug-2017-ML-D.
 Based on source from git with hash: 
The following table(s) in the font have been ignored by FontForge
  Ignoring 'DSIG' digital signature table
Warning: Mac string is a subset of the Windows string in the 'name' table
  for the License string in the English (US) language.
Reading ligatures from fira/FiraCode-Regular.otf
Exception while adding ligature: {'chars': ['ampersand', 'ampersand'], 'firacode_ligature_name': 'ampersand_ampersand.liga'}
Traceback (most recent call last):
  File "ligaturize.py", line 275, in <module>
    creator.add_ligature(lig_spec['chars'], lig_spec['firacode_ligature_name'])
  File "ligaturize.py", line 170, in add_ligature
    self.font[char].addPosSub(lookup_sub_name(i), cr_name(i))
TypeError: expected bytes, str found
fontforge -lang=py ligaturize.py --prefix=Liga "input-fonts/SourceCodePro-Light.ttf" "output-fonts/LigaSourceCodePro-Light.ttf" 2>&1 \
| fgrep -v 'This contextual rule applies no lookups.'
Copyright (c) 2000-2014 by George Williams. See AUTHORS for Contributors.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE. Based on sources from 23:10 UTC  5-Aug-2017-ML-D.
 Based on source from git with hash: 
The following table(s) in the font have been ignored by FontForge
  Ignoring 'DSIG' digital signature table
Warning: Mac string is a subset of the Windows string in the 'name' table
  for the License string in the English (US) language.
Warning: Mac string is a subset of the Windows string in the 'name' table
  for the Family string in the English (US) language.
Warning: Mac and Windows entries in the 'name' table differ for the
  Styles (SubFamily) string in the language English (US)
  Mac String: Light
  Windows String: Regular
Reading ligatures from fira/FiraCode-Light.otf
Exception while adding ligature: {'chars': ['ampersand', 'ampersand'], 'firacode_ligature_name': 'ampersand_ampersand.liga'}
Traceback (most recent call last):
  File "ligaturize.py", line 275, in <module>
    creator.add_ligature(lig_spec['chars'], lig_spec['firacode_ligature_name'])
  File "ligaturize.py", line 170, in add_ligature
    self.font[char].addPosSub(lookup_sub_name(i), cr_name(i))
TypeError: expected bytes, str found
fontforge -lang=py ligaturize.py --prefix=Liga "input-fonts/SourceCodePro-ExtraLight.ttf" "output-fonts/LigaSourceCodePro-ExtraLight.ttf" 2>&1 \
| fgrep -v 'This contextual rule applies no lookups.'
Copyright (c) 2000-2014 by George Williams. See AUTHORS for Contributors.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE. Based on sources from 23:10 UTC  5-Aug-2017-ML-D.
 Based on source from git with hash: 
The following table(s) in the font have been ignored by FontForge
  Ignoring 'DSIG' digital signature table
Warning: Mac string is a subset of the Windows string in the 'name' table
  for the License string in the English (US) language.
Reading ligatures from fira/FiraCode-Regular.otf
Exception while adding ligature: {'chars': ['ampersand', 'ampersand'], 'firacode_ligature_name': 'ampersand_ampersand.liga'}
Traceback (most recent call last):
  File "ligaturize.py", line 275, in <module>
    creator.add_ligature(lig_spec['chars'], lig_spec['firacode_ligature_name'])
  File "ligaturize.py", line 170, in add_ligature
    self.font[char].addPosSub(lookup_sub_name(i), cr_name(i))
TypeError: expected bytes, str found
fontforge -lang=py ligaturize.py --prefix=Liga "input-fonts/SourceCodePro-Bold.ttf" "output-fonts/LigaSourceCodePro-Bold.ttf" 2>&1 \
| fgrep -v 'This contextual rule applies no lookups.'
Copyright (c) 2000-2014 by George Williams. See AUTHORS for Contributors.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE.
 Based on sources from 23:10 UTC  5-Aug-2017-ML-D.
 Based on source from git with hash: 
The following table(s) in the font have been ignored by FontForge
  Ignoring 'DSIG' digital signature table
Warning: Mac string is a subset of the Windows string in the 'name' table
  for the License string in the English (US) language.
Reading ligatures from fira/FiraCode-Bold.otf
Exception while adding ligature: {'chars': ['ampersand', 'ampersand'], 'firacode_ligature_name': 'ampersand_ampersand.liga'}
Traceback (most recent call last):
  File "ligaturize.py", line 275, in <module>
    creator.add_ligature(lig_spec['chars'], lig_spec['firacode_ligature_name'])
  File "ligaturize.py", line 170, in add_ligature
    self.font[char].addPosSub(lookup_sub_name(i), cr_name(i))
TypeError: expected bytes, str found
fontforge -lang=py ligaturize.py --prefix=Liga "input-fonts/SourceCodePro-Regular.ttf" "output-fonts/LigaSourceCodePro-Regular.ttf" 2>&1 \
| fgrep -v 'This contextual rule applies no lookups.'
Copyright (c) 2000-2014 by George Williams. See AUTHORS for Contributors.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE.
 Based on sources from 23:10 UTC  5-Aug-2017-ML-D.
 Based on source from git with hash: 
The following table(s) in the font have been ignored by FontForge
  Ignoring 'DSIG' digital signature table
Warning: Mac string is a subset of the Windows string in the 'name' table
  for the License string in the English (US) language.
Reading ligatures from fira/FiraCode-Regular.otf
Exception while adding ligature: {'chars': ['ampersand', 'ampersand'], 'firacode_ligature_name': 'ampersand_ampersand.liga'}
Traceback (most recent call last):
  File "ligaturize.py", line 275, in <module>
    creator.add_ligature(lig_spec['chars'], lig_spec['firacode_ligature_name'])
  File "ligaturize.py", line 170, in add_ligature
    self.font[char].addPosSub(lookup_sub_name(i), cr_name(i))
TypeError: expected bytes, str found
fontforge -lang=py ligaturize.py --prefix=Liga "input-fonts/SourceCodePro-Medium.ttf" "output-fonts/LigaSourceCodePro-Medium.ttf" 2>&1 \
| fgrep -v 'This contextual rule applies no lookups.'
Copyright (c) 2000-2014 by George Williams. See AUTHORS for Contributors.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE.
 Based on sources from 23:10 UTC  5-Aug-2017-ML-D.
 Based on source from git with hash: 
The following table(s) in the font have been ignored by FontForge
  Ignoring 'DSIG' digital signature table
Warning: Mac string is a subset of the Windows string in the 'name' table
  for the License string in the English (US) language.
Warning: Mac string is a subset of the Windows string in the 'name' table
  for the Family string in the English (US) language.
Warning: Mac and Windows entries in the 'name' table differ for the
  Styles (SubFamily) string in the language English (US)
  Mac String: Medium
  Windows String: Regular
Reading ligatures from fira/FiraCode-Medium.otf
Exception while adding ligature: {'chars': ['ampersand', 'ampersand'], 'firacode_ligature_name': 'ampersand_ampersand.liga'}
Traceback (most recent call last):
  File "ligaturize.py", line 275, in <module>
    creator.add_ligature(lig_spec['chars'], lig_spec['firacode_ligature_name'])
  File "ligaturize.py", line 170, in add_ligature
    self.font[char].addPosSub(lookup_sub_name(i), cr_name(i))
TypeError: expected bytes, str found
fontforge -lang=py ligaturize.py --prefix=Liga "input-fonts/SourceCodePro-Semibold.ttf" "output-fonts/LigaSourceCodePro-Semibold.ttf" 2>&1 \
| fgrep -v 'This contextual rule applies no lookups.'
Copyright (c) 2000-2014 by George Williams. See AUTHORS for Contributors.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE.
 Based on sources from 23:10 UTC  5-Aug-2017-ML-D.
 Based on source from git with hash: 
The following table(s) in the font have been ignored by FontForge
  Ignoring 'DSIG' digital signature table
Warning: Mac string is a subset of the Windows string in the 'name' table
  for the License string in the English (US) language.
Reading ligatures from fira/FiraCode-Regular.otf
Exception while adding ligature: {'chars': ['ampersand', 'ampersand'], 'firacode_ligature_name': 'ampersand_ampersand.liga'}
Traceback (most recent call last):
  File "ligaturize.py", line 275, in <module>
    creator.add_ligature(lig_spec['chars'], lig_spec['firacode_ligature_name'])
  File "ligaturize.py", line 170, in add_ligature
    self.font[char].addPosSub(lookup_sub_name(i), cr_name(i))
TypeError: expected bytes, str found
0xShamil commented 5 years ago

Same issue here. I tried to add ligatures to Dank Mono .

fontforge -lang=py ligaturize.py --prefix=Liga "input-fonts/DankMono-Regular.ttf" "output-fonts/LigaDankMono-Regular.ttf" 2>&1 \
| fgrep -v 'This contextual rule applies no lookups.'
Copyright (c) 2000-2014 by George Williams. See AUTHORS for Contributors.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE.
 Based on sources from 00:15 UTC 31-Jul-2017-ML-D.
 Based on source from git with hash: b9149c13e8f9464fc21473f1f676b36a2130775d
The following table(s) in the font have been ignored by FontForge
  Ignoring 'DSIG' digital signature table
Reading ligatures from fira/FiraCode-Regular.otf
Exception while adding ligature: {'chars': ['ampersand', 'ampersand'], 'firacode_ligature_name': 'ampersand_ampersand.liga'}
Traceback (most recent call last):
  File "ligaturize.py", line 275, in <module>
    creator.add_ligature(lig_spec['chars'], lig_spec['firacode_ligature_name'])
  File "ligaturize.py", line 162, in add_ligature
    self.font[ord(char)].glyphname = char
TypeError: ord() expected a character, but string of length 9 found
ryands17 commented 5 years ago

facing the same issue

ToxicFrog commented 5 years ago

There's two issues here.

@notaduck "TypeError: expected bytes, str found" is characteristic of trying to run it via a Fontforge install that uses Python 3. How did you "try it with both python 2 and python 3"? In my experience with fontforge it's either one or the other. I should probably add a check to FF so that it fails fast if run inside py3.

@shamilchoudhury I'll look into this.

@ryands17 Which issue?

ToxicFrog commented 5 years ago

@notaduck I've pushed a version that should now fail unambiguously if it's running under Fontforge with Python 3; try that to make sure you're actually running it under Py2 when you think you are. If you're still getting that error in Py2 it's a different and new issue.

ToxicFrog commented 5 years ago

@shamilchoudhury Reading the code, the wheels are coming off when it tries to find the glyphs in the target font that it needs to add ligaturization rules for. It tries to look it up by name first, and if the name lookup fails it assumes that it's a plain letter and looks it up by codepoint.

In this case it tries to look up "ampersand", can't find it because Dank Mono doesn't have glyph names at all (I assume; I don't have a copy myself, and since it costs $40 I'm not likely to), tries to look it up by codepoint, and dies because ord("ampersand") is not valid the way ord("&") is.

It might be possible to mitigate this by storing the full name -> actual character mapping so that it can just look up everything by codepoint; if implementing this doesn't break its support for existing fonts I'll do it, although I have no way of testing if it works on Dank Mono.

0xShamil commented 5 years ago

@ToxicFrog Thanks for looking into this. If you could implement the full name --> actual character mapping in a separate branch, I'd test it with Dank Mono .

rouzbeh84 commented 5 years ago

@shamilchoudhury but dank mono explicitly has built in ligatures, it's one of the main reasons to buy it...

ToxicFrog commented 4 years ago

Should be fixed with #73