typemytype / drawbot

http://www.drawbot.com
Other
408 stars 63 forks source link

Kerning pairs missing with FormattedString, works with app but not with module #406

Open joachimvu opened 4 years ago

joachimvu commented 4 years ago

The Issue

The output of passing some text to a FormattedString is missing some kerning pairs when I use the module version of Drawbot, but works properly when using the same script with the app.

The script

I'm working on a cli tool to generate various documents using the drawBot module. A part of it is reading from a text file and outputting a pdf, appending the content of the file to a FormattedString.

The input text file is mixing regular text and slashed glyph names, in a way that it's also usable as a sample strings file inside Glyphs (its generated from another script, parses the kerning groups in a Glyphs file to make the needed strings and uses slashed glyph names for the two glyphs of a pair to support alternates and other unencoded glyphs): non/o/o non ono/o/o ono\nnon/o/a non ono/o/a ono\nnon/a/o non ono/a/o ono\nnon/o/b non ono/o/b ono\nnon/c/o non ono/c/o ono\nnon/e/o non ono/e/o ono\nnon/o/f non ono/o/f ono\nnon/f/o non ono/f/o ono\nnon/o/g non ono/o/g ono\nnon/g/o non ono/g/o ono\nnon/o/i non ono/o/i ono\nnon/i/o non ono/i/o ono\nnon/o/j non ono/o/j ono\nnon/j/o non ono/j/o ono\nnon/k/o non ono/k/o ono\nnon/o/l non ono/o/l ono\nnon/l/o non ono/l/o ono\nnon/q/o non ono/q/o ono\nnon/r/o non ono/r/o ono\nnon/o/s non ono/o/s ono\nnon/s/o non ono/s/o ono\nnon/o/t non ono/o/t ono\nnon/t/o non ono/t/o ono\nnon/o/u non ono/o/u ono\nnon/u/o non ono/u/o ono\nnon/o/v non ono/o/v ono\nnon/v/o non ono/v/o ono\nnon/o/w non ono/o/w ono\nnon/w/o non ono/w/o ono\nnon/o/x non ono/o/x ono\nnon/x/o non ono/x/o ono\nnon/o/y non ono/o/y ono\nnon/y/o non ono/y/o ono\nnon/o/z non ono/o/z ono\nnon/z/o non ono/z/o ono\n

Here's the script that's responsible for outputting the pdf, rewritten so it can be launched on its own, both from and outside the Drawbot app:

from drawBot import *
import os
import re

text = "path/to/text/file.txt"
fontPath = "path/to/font.otf"
fontSize = 16

width = 842
height = 1190
margin = 20

newDrawing()
font = installFont(fontPath)
content = FormattedString()
content.font(font)
content.fontSize(fontSize)
content.openTypeFeatures(calt=True, kern=True)
x, y, w, h = margin, margin, width - margin * 2, height - margin * 2

with open(text, "r") as reader:
    for p in reader.readlines():
        split_p = p.split("\\n")
        for line in split_p:
            if line:
                line = line.strip('\n')
                slashed_glyphnames = re.findall(
                    r"(.*?)((?:\/\w+)(?:\.\w*)*)([\w ]*)", line
                )
                if slashed_glyphnames:
                    for match in slashed_glyphnames:
                        for group in match:
                            if group and group[0] == "/":
                                glyphname = group[1:].strip()
                                content.appendGlyph(glyphname)
                            elif group != " ":
                                content.append(group.strip())
                    content.append("\n")
                else:
                    content.append(line)
                    content.append("\n")

while len(content) > 0:
    newPage(width, height)

    colSize = w / 3
    for c in range(3):
        content = textBox(
            content, (x + (colSize * c), y, colSize, h), align="left"
        )

saveImage("~/Desktop/test.pdf")
uninstallFont(font)
endDrawing()

Results

The output of that script is that the generated pdf when using the module version of Drawbot is missing some kerning. Using the exact same script from inside the app produced a correct result:

module:

Capture d’écran 2020-11-07 à 20 07 40

app:

Capture d’écran 2020-11-07 à 20 10 05

I originally thought it could be a cache issue, but I tested generating a font multiple times with drawing changes and they appeared in the output pdf every time.

Also to note: depending on the length of the text file, its not always the same pairs that go missing with the module version of the script. Using as input just the small chunk of text presented at the beginning of this post, the output will be just fine. It seems that problems occur past a certain length, but I havent been able to figure out exactly what is triggering the errors. For reference, here is the text file used to make the pdf from the two screenshots above.

kern.txt

justvanrossum commented 4 years ago

Your kern.txt file doesn't match the screenshots, though.

A few things:

joachimvu commented 4 years ago

Hi Just, thank you for your answer.

The screenshots are from line 28 of the kern.txt (in the UC/UC section)

• The following tests are made with an installed version of IBMPlexSans-Bold, and AvenirNext-Heavy for the system font. • A simpler script now includes the kern strings as one big string, without slashed glyph names. It's rather long because, according to my previous tests, size seem to have something to do with the issue. I've kept the same content that I know will show the problems.

The exact same issues are reproducible with these new tests:

Heres IBM Plex Sans, module:

Capture d’écran 2020-11-08 à 18 16 22

IBM Plex Sans, app:

Capture d’écran 2020-11-08 à 18 16 46

Avenir Next Heavy, module:

Capture d’écran 2020-11-08 à 18 19 12

Avenir Next Heavy, app:

Capture d’écran 2020-11-08 à 18 19 48

The script used for these tests:

from drawBot import *

text = """lc/lc
nonnnnonononnono\nnonnononononoono\nnononnononoonono\nnonnanonononaono\nnonannononoanono\nnonnbnonononbono\nnoncnnononocnono\nnonennononoenono\nnonnfnonononfono\nnonfnnononofnono\nnonngnononongono\nnongnnononognono\nnonninonononiono\nnoninnononoinono\nnonnjnonononjono\nnonjnnononojnono\nnonknnononoknono\nnonnlnonononlono\nnonlnnononolnono\nnonqnnononoqnono\nnonrnnononornono\nnonnsnonononsono\nnonsnnononosnono\nnonntnononontono\nnontnnononotnono\nnonnunonononuono\nnonunnononounono\nnonnvnonononvono\nnonvnnononovnono\nnonnwnonononwono\nnonwnnononownono\nnonnxnonononxono\nnonxnnononoxnono\nnonnynonononyono\nnonynnononoynono\nnonnznonononzono\nnonznnononoznono\n
nonoonononoooono\nnonoanononooaono\nnonaonononoaoono\nnonobnononoobono\nnonconononocoono\nnoneonononoeoono\nnonofnononoofono\nnonfonononofoono\nnonognononoogono\nnongonononogoono\nnonoinononooiono\nnonionononoioono\nnonojnononoojono\nnonjonononojoono\nnonkonononokoono\nnonolnononoolono\nnonlonononoloono\nnonqonononoqoono\nnonronononoroono\nnonosnononoosono\nnonsonononosoono\nnonotnononootono\nnontonononotoono\nnonounononoouono\nnonuonononouoono\nnonovnononoovono\nnonvonononovoono\nnonownononoowono\nnonwonononowoono\nnonoxnononooxono\nnonxonononoxoono\nnonoynononooyono\nnonyonononoyoono\nnonoznononoozono\nnonzonononozoono\n
nonaanononoaaono\nnonabnononoabono\nnoncanononocaono\nnoneanononoeaono\nnonafnononoafono\nnonfanononofaono\nnonagnononoagono\nnonganononogaono\nnonainononoaiono\nnonianononoiaono\nnonajnononoajono\nnonjanononojaono\nnonkanononokaono\nnonalnononoalono\nnonlanononolaono\nnonqanononoqaono\nnonranononoraono\nnonasnononoasono\nnonsanononosaono\nnonatnononoatono\nnontanononotaono\nnonaunononoauono\nnonuanononouaono\nnonavnononoavono\nnonvanononovaono\nnonawnononoawono\nnonwanononowaono\nnonaxnononoaxono\nnonxanononoxaono\nnonaynononoayono\nnonyanononoyaono\nnonaznononoazono\nnonzanononozaono\n
noncbnononocbono\nnonebnononoebono\nnonfbnononofbono\nnongbnononogbono\nnonibnononoibono\nnonjbnononojbono\nnonkbnononokbono\nnonlbnononolbono\nnonqbnononoqbono\nnonrbnononorbono\nnonsbnononosbono\nnontbnononotbono\nnonubnononoubono\nnonvbnononovbono\nnonwbnononowbono\nnonxbnononoxbono\nnonybnononoybono\nnonzbnononozbono\n
noncfnononocfono\nnoncgnononocgono\nnoncinononociono\nnoncjnononocjono\nnonclnononoclono\nnoncsnononocsono\nnonctnononoctono\nnoncunononocuono\nnoncvnononocvono\nnoncwnononocwono\nnoncxnononocxono\nnoncynononocyono\nnoncznononoczono\n
nonefnononoefono\nnonegnononoegono\nnoneinononoeiono\nnonejnononoejono\nnonelnononoelono\nnonesnononoesono\nnonetnononoetono\nnoneunononoeuono\nnonevnononoevono\nnonewnononoewono\nnonexnononoexono\nnoneynononoeyono\nnoneznononoezono\n
nonffnononoffono\nnonfgnononofgono\nnongfnononogfono\nnonfinononofiono\nnonifnononoifono\nnonfjnononofjono\nnonjfnononojfono\nnonkfnononokfono\nnonflnononoflono\nnonlfnononolfono\nnonqfnononoqfono\nnonrfnononorfono\nnonfsnononofsono\nnonsfnononosfono\nnonftnononoftono\nnontfnononotfono\nnonfunononofuono\nnonufnononoufono\nnonfvnononofvono\nnonvfnononovfono\nnonfwnononofwono\nnonwfnononowfono\nnonfxnononofxono\nnonxfnononoxfono\nnonfynononofyono\nnonyfnononoyfono\nnonfznononofzono\nnonzfnononozfono\n
nonggnononoggono\nnonginononogiono\nnonignononoigono\nnongjnononogjono\nnonjgnononojgono\nnonkgnononokgono\nnonglnononoglono\nnonlgnononolgono\nnonqgnononoqgono\nnonrgnononorgono\nnongsnononogsono\nnonsgnononosgono\nnongtnononogtono\nnontgnononotgono\nnongunononoguono\nnonugnononougono\nnongvnononogvono\nnonvgnononovgono\nnongwnononogwono\nnonwgnononowgono\nnongxnononogxono\nnonxgnononoxgono\nnongynononogyono\nnonygnononoygono\nnongznononogzono\nnonzgnononozgono\n
noniinononoiiono\nnonijnononoijono\nnonjinononojiono\nnonkinononokiono\nnonilnononoilono\nnonlinononoliono\nnonqinononoqiono\nnonrinononoriono\nnonisnononoisono\nnonsinononosiono\nnonitnononoitono\nnontinononotiono\nnoniunononoiuono\nnonuinononouiono\nnonivnononoivono\nnonvinononoviono\nnoniwnononoiwono\nnonwinononowiono\nnonixnononoixono\nnonxinononoxiono\nnoniynononoiyono\nnonyinononoyiono\nnoniznononoizono\nnonzinononoziono\n
nonjjnononojjono\nnonkjnononokjono\nnonjlnononojlono\nnonljnononoljono\nnonqjnononoqjono\nnonrjnononorjono\nnonjsnononojsono\nnonsjnononosjono\nnonjtnononojtono\nnontjnononotjono\nnonjunononojuono\nnonujnononoujono\nnonjvnononojvono\nnonvjnononovjono\nnonjwnononojwono\nnonwjnononowjono\nnonjxnononojxono\nnonxjnononoxjono\nnonjynononojyono\nnonyjnononoyjono\nnonjznononojzono\nnonzjnononozjono\n
nonklnononoklono\nnonksnononoksono\nnonktnononoktono\nnonkunononokuono\nnonkvnononokvono\nnonkwnononokwono\nnonkxnononokxono\nnonkynononokyono\nnonkznononokzono\n
nonllnononollono\nnonqlnononoqlono\nnonrlnononorlono\nnonlsnononolsono\nnonslnononoslono\nnonltnononoltono\nnontlnononotlono\nnonlunononoluono\nnonulnononoulono\nnonlvnononolvono\nnonvlnononovlono\nnonlwnononolwono\nnonwlnononowlono\nnonlxnononolxono\nnonxlnononoxlono\nnonlynononolyono\nnonylnononoylono\nnonlznononolzono\nnonzlnononozlono\n
nonqsnononoqsono\nnonqtnononoqtono\nnonqunononoquono\nnonqvnononoqvono\nnonqwnononoqwono\nnonqxnononoqxono\nnonqynononoqyono\nnonqznononoqzono\n
nonrsnononorsono\nnonrtnononortono\nnonrunononoruono\nnonrvnononorvono\nnonrwnononorwono\nnonrxnononorxono\nnonrynononoryono\nnonrznononorzono\n
nonssnononossono\nnonstnononostono\nnontsnononotsono\nnonsunononosuono\nnonusnononousono\nnonsvnononosvono\nnonvsnononovsono\nnonswnononoswono\nnonwsnononowsono\nnonsxnononosxono\nnonxsnononoxsono\nnonsynononosyono\nnonysnononoysono\nnonsznononoszono\nnonzsnononozsono\n
nonttnononottono\nnontunononotuono\nnonutnononoutono\nnontvnononotvono\nnonvtnononovtono\nnontwnononotwono\nnonwtnononowtono\nnontxnononotxono\nnonxtnononoxtono\nnontynononotyono\nnonytnononoytono\nnontznononotzono\nnonztnononoztono\n
nonuunononouuono\nnonuvnononouvono\nnonvunononovuono\nnonuwnononouwono\nnonwunononowuono\nnonuxnononouxono\nnonxunononoxuono\nnonuynononouyono\nnonyunononoyuono\nnonuznononouzono\nnonzunononozuono\n
nonvvnononovvono\nnonvwnononovwono\nnonwvnononowvono\nnonvxnononovxono\nnonxvnononoxvono\nnonvynononovyono\nnonyvnononoyvono\nnonvznononovzono\nnonzvnononozvono\n
nonwwnononowwono\nnonwxnononowxono\nnonxwnononoxwono\nnonwynononowyono\nnonywnononoywono\nnonwznononowzono\nnonzwnononozwono\n
nonxxnononoxxono\nnonxynononoxyono\nnonyxnononoyxono\nnonxznononoxzono\nnonzxnononozxono\n
nonyynononoyyono\nnonyznononoyzono\nnonzynononozyono\n
nonzznononozzono\n

UC/UC
HOHHHHOHOHOHHOHO\nHOHHOHOHOHOHOOHO\nHOHOHHOHOHOOHOHO\nHOHHAHOHOHOHAOHO\nHOHAHHOHOHOAHOHO\nHOHBHHOHOHOBHOHO\nHOHCHHOHOHOCHOHO\nHOHEHHOHOHOEHOHO\nHOHFHHOHOHOFHOHO\nHOHGHHOHOHOGHOHO\nHOHHJHOHOHOHJOHO\nHOHJHHOHOHOJHOHO\nHOHKHHOHOHOKHOHO\nHOHLHHOHOHOLHOHO\nHOHHMHOHOHOHMOHO\nHOHMHHOHOHOMHOHO\nHOHHNHOHOHOHNOHO\nHOHNHHOHOHONHOHO\nHOHPHHOHOHOPHOHO\nHOHRHHOHOHORHOHO\nHOHHSHOHOHOHSOHO\nHOHSHHOHOHOSHOHO\nHOHHTHOHOHOHTOHO\nHOHTHHOHOHOTHOHO\nHOHHUHOHOHOHUOHO\nHOHUHHOHOHOUHOHO\nHOHHVHOHOHOHVOHO\nHOHVHHOHOHOVHOHO\nHOHHWHOHOHOHWOHO\nHOHWHHOHOHOWHOHO\nHOHHXHOHOHOHXOHO\nHOHXHHOHOHOXHOHO\nHOHHYHOHOHOHYOHO\nHOHYHHOHOHOYHOHO\nHOHHZHOHOHOHZOHO\nHOHZHHOHOHOZHOHO\n
HOHOOHOHOHOOOOHO\nHOHOAHOHOHOOAOHO\nHOHAOHOHOHOAOOHO\nHOHBOHOHOHOBOOHO\nHOHCOHOHOHOCOOHO\nHOHEOHOHOHOEOOHO\nHOHFOHOHOHOFOOHO\nHOHGOHOHOHOGOOHO\nHOHOJHOHOHOOJOHO\nHOHJOHOHOHOJOOHO\nHOHKOHOHOHOKOOHO\nHOHLOHOHOHOLOOHO\nHOHOMHOHOHOOMOHO\nHOHMOHOHOHOMOOHO\nHOHONHOHOHOONOHO\nHOHNOHOHOHONOOHO\nHOHPOHOHOHOPOOHO\nHOHROHOHOHOROOHO\nHOHOSHOHOHOOSOHO\nHOHSOHOHOHOSOOHO\nHOHOTHOHOHOOTOHO\nHOHTOHOHOHOTOOHO\nHOHOUHOHOHOOUOHO\nHOHUOHOHOHOUOOHO\nHOHOVHOHOHOOVOHO\nHOHVOHOHOHOVOOHO\nHOHOWHOHOHOOWOHO\nHOHWOHOHOHOWOOHO\nHOHOXHOHOHOOXOHO\nHOHXOHOHOHOXOOHO\nHOHOYHOHOHOOYOHO\nHOHYOHOHOHOYOOHO\nHOHOZHOHOHOOZOHO\nHOHZOHOHOHOZOOHO\n
HOHAAHOHOHOAAOHO\nHOHBAHOHOHOBAOHO\nHOHCAHOHOHOCAOHO\nHOHEAHOHOHOEAOHO\nHOHFAHOHOHOFAOHO\nHOHGAHOHOHOGAOHO\nHOHAJHOHOHOAJOHO\nHOHJAHOHOHOJAOHO\nHOHKAHOHOHOKAOHO\nHOHLAHOHOHOLAOHO\nHOHAMHOHOHOAMOHO\nHOHMAHOHOHOMAOHO\nHOHANHOHOHOANOHO\nHOHNAHOHOHONAOHO\nHOHPAHOHOHOPAOHO\nHOHRAHOHOHORAOHO\nHOHASHOHOHOASOHO\nHOHSAHOHOHOSAOHO\nHOHATHOHOHOATOHO\nHOHTAHOHOHOTAOHO\nHOHAUHOHOHOAUOHO\nHOHUAHOHOHOUAOHO\nHOHAVHOHOHOAVOHO\nHOHVAHOHOHOVAOHO\nHOHAWHOHOHOAWOHO\nHOHWAHOHOHOWAOHO\nHOHAXHOHOHOAXOHO\nHOHXAHOHOHOXAOHO\nHOHAYHOHOHOAYOHO\nHOHYAHOHOHOYAOHO\nHOHAZHOHOHOAZOHO\nHOHZAHOHOHOZAOHO\n
HOHBJHOHOHOBJOHO\nHOHBMHOHOHOBMOHO\nHOHBNHOHOHOBNOHO\nHOHBSHOHOHOBSOHO\nHOHBTHOHOHOBTOHO\nHOHBUHOHOHOBUOHO\nHOHBVHOHOHOBVOHO\nHOHBWHOHOHOBWOHO\nHOHBXHOHOHOBXOHO\nHOHBYHOHOHOBYOHO\nHOHBZHOHOHOBZOHO\n
HOHCJHOHOHOCJOHO\nHOHCMHOHOHOCMOHO\nHOHCNHOHOHOCNOHO\nHOHCSHOHOHOCSOHO\nHOHCTHOHOHOCTOHO\nHOHCUHOHOHOCUOHO\nHOHCVHOHOHOCVOHO\nHOHCWHOHOHOCWOHO\nHOHCXHOHOHOCXOHO\nHOHCYHOHOHOCYOHO\nHOHCZHOHOHOCZOHO\n
HOHEJHOHOHOEJOHO\nHOHEMHOHOHOEMOHO\nHOHENHOHOHOENOHO\nHOHESHOHOHOESOHO\nHOHETHOHOHOETOHO\nHOHEUHOHOHOEUOHO\nHOHEVHOHOHOEVOHO\nHOHEWHOHOHOEWOHO\nHOHEXHOHOHOEXOHO\nHOHEYHOHOHOEYOHO\nHOHEZHOHOHOEZOHO\n
HOHFJHOHOHOFJOHO\nHOHFMHOHOHOFMOHO\nHOHFNHOHOHOFNOHO\nHOHFSHOHOHOFSOHO\nHOHFTHOHOHOFTOHO\nHOHFUHOHOHOFUOHO\nHOHFVHOHOHOFVOHO\nHOHFWHOHOHOFWOHO\nHOHFXHOHOHOFXOHO\nHOHFYHOHOHOFYOHO\nHOHFZHOHOHOFZOHO\n
HOHGJHOHOHOGJOHO\nHOHGMHOHOHOGMOHO\nHOHGNHOHOHOGNOHO\nHOHGSHOHOHOGSOHO\nHOHGTHOHOHOGTOHO\nHOHGUHOHOHOGUOHO\nHOHGVHOHOHOGVOHO\nHOHGWHOHOHOGWOHO\nHOHGXHOHOHOGXOHO\nHOHGYHOHOHOGYOHO\nHOHGZHOHOHOGZOHO\n
HOHJJHOHOHOJJOHO\nHOHKJHOHOHOKJOHO\nHOHLJHOHOHOLJOHO\nHOHJMHOHOHOJMOHO\nHOHMJHOHOHOMJOHO\nHOHJNHOHOHOJNOHO\nHOHNJHOHOHONJOHO\nHOHPJHOHOHOPJOHO\nHOHRJHOHOHORJOHO\nHOHJSHOHOHOJSOHO\nHOHSJHOHOHOSJOHO\nHOHJTHOHOHOJTOHO\nHOHTJHOHOHOTJOHO\nHOHJUHOHOHOJUOHO\nHOHUJHOHOHOUJOHO\nHOHJVHOHOHOJVOHO\nHOHVJHOHOHOVJOHO\nHOHJWHOHOHOJWOHO\nHOHWJHOHOHOWJOHO\nHOHJXHOHOHOJXOHO\nHOHXJHOHOHOXJOHO\nHOHJYHOHOHOJYOHO\nHOHYJHOHOHOYJOHO\nHOHJZHOHOHOJZOHO\nHOHZJHOHOHOZJOHO\n
HOHKMHOHOHOKMOHO\nHOHKNHOHOHOKNOHO\nHOHKSHOHOHOKSOHO\nHOHKTHOHOHOKTOHO\nHOHKUHOHOHOKUOHO\nHOHKVHOHOHOKVOHO\nHOHKWHOHOHOKWOHO\nHOHKXHOHOHOKXOHO\nHOHKYHOHOHOKYOHO\nHOHKZHOHOHOKZOHO\n
HOHLMHOHOHOLMOHO\nHOHLNHOHOHOLNOHO\nHOHLSHOHOHOLSOHO\nHOHLTHOHOHOLTOHO\nHOHLUHOHOHOLUOHO\nHOHLVHOHOHOLVOHO\nHOHLWHOHOHOLWOHO\nHOHLXHOHOHOLXOHO\nHOHLYHOHOHOLYOHO\nHOHLZHOHOHOLZOHO\n
HOHMMHOHOHOMMOHO\nHOHMNHOHOHOMNOHO\nHOHNMHOHOHONMOHO\nHOHPMHOHOHOPMOHO\nHOHRMHOHOHORMOHO\nHOHMSHOHOHOMSOHO\nHOHSMHOHOHOSMOHO\nHOHMTHOHOHOMTOHO\nHOHTMHOHOHOTMOHO\nHOHMUHOHOHOMUOHO\nHOHUMHOHOHOUMOHO\nHOHMVHOHOHOMVOHO\nHOHVMHOHOHOVMOHO\nHOHMWHOHOHOMWOHO\nHOHWMHOHOHOWMOHO\nHOHMXHOHOHOMXOHO\nHOHXMHOHOHOXMOHO\nHOHMYHOHOHOMYOHO\nHOHYMHOHOHOYMOHO\nHOHMZHOHOHOMZOHO\nHOHZMHOHOHOZMOHO\n
HOHNNHOHOHONNOHO\nHOHPNHOHOHOPNOHO\nHOHRNHOHOHORNOHO\nHOHNSHOHOHONSOHO\nHOHSNHOHOHOSNOHO\nHOHNTHOHOHONTOHO\nHOHTNHOHOHOTNOHO\nHOHNUHOHOHONUOHO\nHOHUNHOHOHOUNOHO\nHOHNVHOHOHONVOHO\nHOHVNHOHOHOVNOHO\nHOHNWHOHOHONWOHO\nHOHWNHOHOHOWNOHO\nHOHNXHOHOHONXOHO\nHOHXNHOHOHOXNOHO\nHOHNYHOHOHONYOHO\nHOHYNHOHOHOYNOHO\nHOHNZHOHOHONZOHO\nHOHZNHOHOHOZNOHO\n
HOHPSHOHOHOPSOHO\nHOHPTHOHOHOPTOHO\nHOHPUHOHOHOPUOHO\nHOHPVHOHOHOPVOHO\nHOHPWHOHOHOPWOHO\nHOHPXHOHOHOPXOHO\nHOHPYHOHOHOPYOHO\nHOHPZHOHOHOPZOHO\n
HOHRSHOHOHORSOHO\nHOHRTHOHOHORTOHO\nHOHRUHOHOHORUOHO\nHOHRVHOHOHORVOHO\nHOHRWHOHOHORWOHO\nHOHRXHOHOHORXOHO\nHOHRYHOHOHORYOHO\nHOHRZHOHOHORZOHO\n
HOHSSHOHOHOSSOHO\nHOHSTHOHOHOSTOHO\nHOHTSHOHOHOTSOHO\nHOHSUHOHOHOSUOHO\nHOHUSHOHOHOUSOHO\nHOHSVHOHOHOSVOHO\nHOHVSHOHOHOVSOHO\nHOHSWHOHOHOSWOHO\nHOHWSHOHOHOWSOHO\nHOHSXHOHOHOSXOHO\nHOHXSHOHOHOXSOHO\nHOHSYHOHOHOSYOHO\nHOHYSHOHOHOYSOHO\nHOHSZHOHOHOSZOHO\nHOHZSHOHOHOZSOHO\n
HOHTTHOHOHOTTOHO\nHOHTUHOHOHOTUOHO\nHOHUTHOHOHOUTOHO\nHOHTVHOHOHOTVOHO\nHOHVTHOHOHOVTOHO\nHOHTWHOHOHOTWOHO\nHOHWTHOHOHOWTOHO\nHOHTXHOHOHOTXOHO\nHOHXTHOHOHOXTOHO\nHOHTYHOHOHOTYOHO\nHOHYTHOHOHOYTOHO\nHOHTZHOHOHOTZOHO\nHOHZTHOHOHOZTOHO\n
HOHUUHOHOHOUUOHO\nHOHUVHOHOHOUVOHO\nHOHVUHOHOHOVUOHO\nHOHUWHOHOHOUWOHO\nHOHWUHOHOHOWUOHO\nHOHUXHOHOHOUXOHO\nHOHXUHOHOHOXUOHO\nHOHUYHOHOHOUYOHO\nHOHYUHOHOHOYUOHO\nHOHUZHOHOHOUZOHO\nHOHZUHOHOHOZUOHO\n
HOHVVHOHOHOVVOHO\nHOHVWHOHOHOVWOHO\nHOHWVHOHOHOWVOHO\nHOHVXHOHOHOVXOHO\nHOHXVHOHOHOXVOHO\nHOHVYHOHOHOVYOHO\nHOHYVHOHOHOYVOHO\nHOHVZHOHOHOVZOHO\nHOHZVHOHOHOZVOHO\n
HOHWWHOHOHOWWOHO\nHOHWXHOHOHOWXOHO\nHOHXWHOHOHOXWOHO\nHOHWYHOHOHOWYOHO\nHOHYWHOHOHOYWOHO\nHOHWZHOHOHOWZOHO\nHOHZWHOHOHOZWOHO\n
HOHXXHOHOHOXXOHO\nHOHXYHOHOHOXYOHO\nHOHYXHOHOHOYXOHO\nHOHXZHOHOHOXZOHO\nHOHZXHOHOHOZXOHO\n
HOHYYHOHOHOYYOHO\nHOHYZHOHOHOYZOHO\nHOHZYHOHOHOZYOHO\n
HOHZZHOHOHOZZOHO\n

UC/lc
nonHnnononoHnono\nnonnHnonononHono\nnonHonononoHoono\nnonoHnononooHono\nnonHanononoHaono\nnonaHnononoaHono\nnonHbnononoHbono\nnoncHnononocHono\nnoneHnononoeHono\nnonHfnononoHfono\nnonfHnononofHono\nnonHgnononoHgono\nnongHnononogHono\nnonHinononoHiono\nnoniHnononoiHono\nnonHjnononoHjono\nnonjHnononojHono\nnonkHnononokHono\nnonHlnononoHlono\nnonlHnononolHono\nnonqHnononoqHono\nnonrHnononorHono\nnonHsnononoHsono\nnonsHnononosHono\nnonHtnononoHtono\nnontHnononotHono\nnonHunononoHuono\nnonuHnononouHono\nnonHvnononoHvono\nnonvHnononovHono\nnonHwnononoHwono\nnonwHnononowHono\nnonHxnononoHxono\nnonxHnononoxHono\nnonHynononoHyono\nnonyHnononoyHono\nnonHznononoHzono\nnonzHnononozHono\n
nonOnnononoOnono\nnonnOnonononOono\nnonOonononoOoono\nnonoOnononooOono\nnonOanononoOaono\nnonaOnononoaOono\nnonObnononoObono\nnoncOnononocOono\nnoneOnononoeOono\nnonOfnononoOfono\nnonfOnononofOono\nnonOgnononoOgono\nnongOnononogOono\nnonOinononoOiono\nnoniOnononoiOono\nnonOjnononoOjono\nnonjOnononojOono\nnonkOnononokOono\nnonOlnononoOlono\nnonlOnononolOono\nnonqOnononoqOono\nnonrOnononorOono\nnonOsnononoOsono\nnonsOnononosOono\nnonOtnononoOtono\nnontOnononotOono\nnonOunononoOuono\nnonuOnononouOono\nnonOvnononoOvono\nnonvOnononovOono\nnonOwnononoOwono\nnonwOnononowOono\nnonOxnononoOxono\nnonxOnononoxOono\nnonOynononoOyono\nnonyOnononoyOono\nnonOznononoOzono\nnonzOnononozOono\n
nonAnnononoAnono\nnonnAnonononAono\nnonAonononoAoono\nnonoAnononooAono\nnonAanononoAaono\nnonaAnononoaAono\nnonAbnononoAbono\nnoncAnononocAono\nnoneAnononoeAono\nnonAfnononoAfono\nnonfAnononofAono\nnonAgnononoAgono\nnongAnononogAono\nnonAinononoAiono\nnoniAnononoiAono\nnonAjnononoAjono\nnonjAnononojAono\nnonkAnononokAono\nnonAlnononoAlono\nnonlAnononolAono\nnonqAnononoqAono\nnonrAnononorAono\nnonAsnononoAsono\nnonsAnononosAono\nnonAtnononoAtono\nnontAnononotAono\nnonAunononoAuono\nnonuAnononouAono\nnonAvnononoAvono\nnonvAnononovAono\nnonAwnononoAwono\nnonwAnononowAono\nnonAxnononoAxono\nnonxAnononoxAono\nnonAynononoAyono\nnonyAnononoyAono\nnonAznononoAzono\nnonzAnononozAono\n
nonBnnononoBnono\nnonBonononoBoono\nnonBanononoBaono\nnonBbnononoBbono\nnonBfnononoBfono\nnonBgnononoBgono\nnonBinononoBiono\nnonBjnononoBjono\nnonBlnononoBlono\nnonBsnononoBsono\nnonBtnononoBtono\nnonBunononoBuono\nnonBvnononoBvono\nnonBwnononoBwono\nnonBxnononoBxono\nnonBynononoByono\nnonBznononoBzono\n
nonCnnononoCnono\nnonConononoCoono\nnonCanononoCaono\nnonCbnononoCbono\nnonCfnononoCfono\nnonCgnononoCgono\nnonCinononoCiono\nnonCjnononoCjono\nnonClnononoClono\nnonCsnononoCsono\nnonCtnononoCtono\nnonCunononoCuono\nnonCvnononoCvono\nnonCwnononoCwono\nnonCxnononoCxono\nnonCynononoCyono\nnonCznononoCzono\n
nonEnnononoEnono\nnonEonononoEoono\nnonEanononoEaono\nnonEbnononoEbono\nnonEfnononoEfono\nnonEgnononoEgono\nnonEinononoEiono\nnonEjnononoEjono\nnonElnononoElono\nnonEsnononoEsono\nnonEtnononoEtono\nnonEunononoEuono\nnonEvnononoEvono\nnonEwnononoEwono\nnonExnononoExono\nnonEynononoEyono\nnonEznononoEzono\n
nonFnnononoFnono\nnonFonononoFoono\nnonFanononoFaono\nnonFbnononoFbono\nnonFfnononoFfono\nnonFgnononoFgono\nnonFinononoFiono\nnonFjnononoFjono\nnonFlnononoFlono\nnonFsnononoFsono\nnonFtnononoFtono\nnonFunononoFuono\nnonFvnononoFvono\nnonFwnononoFwono\nnonFxnononoFxono\nnonFynononoFyono\nnonFznononoFzono\n
nonGnnononoGnono\nnonGonononoGoono\nnonGanononoGaono\nnonGbnononoGbono\nnonGfnononoGfono\nnonGgnononoGgono\nnonGinononoGiono\nnonGjnononoGjono\nnonGlnononoGlono\nnonGsnononoGsono\nnonGtnononoGtono\nnonGunononoGuono\nnonGvnononoGvono\nnonGwnononoGwono\nnonGxnononoGxono\nnonGynononoGyono\nnonGznononoGzono\n
nonJnnononoJnono\nnonnJnonononJono\nnonJonononoJoono\nnonoJnononooJono\nnonJanononoJaono\nnonaJnononoaJono\nnonJbnononoJbono\nnoncJnononocJono\nnoneJnononoeJono\nnonJfnononoJfono\nnonfJnononofJono\nnonJgnononoJgono\nnongJnononogJono\nnonJinononoJiono\nnoniJnononoiJono\nnonJjnononoJjono\nnonjJnononojJono\nnonkJnononokJono\nnonJlnononoJlono\nnonlJnononolJono\nnonqJnononoqJono\nnonrJnononorJono\nnonJsnononoJsono\nnonsJnononosJono\nnonJtnononoJtono\nnontJnononotJono\nnonJunononoJuono\nnonuJnononouJono\nnonJvnononoJvono\nnonvJnononovJono\nnonJwnononoJwono\nnonwJnononowJono\nnonJxnononoJxono\nnonxJnononoxJono\nnonJynononoJyono\nnonyJnononoyJono\nnonJznononoJzono\nnonzJnononozJono\n
nonKnnononoKnono\nnonKonononoKoono\nnonKanononoKaono\nnonKbnononoKbono\nnonKfnononoKfono\nnonKgnononoKgono\nnonKinononoKiono\nnonKjnononoKjono\nnonKlnononoKlono\nnonKsnononoKsono\nnonKtnononoKtono\nnonKunononoKuono\nnonKvnononoKvono\nnonKwnononoKwono\nnonKxnononoKxono\nnonKynononoKyono\nnonKznononoKzono\n
nonLnnononoLnono\nnonLonononoLoono\nnonLanononoLaono\nnonLbnononoLbono\nnonLfnononoLfono\nnonLgnononoLgono\nnonLinononoLiono\nnonLjnononoLjono\nnonLlnononoLlono\nnonLsnononoLsono\nnonLtnononoLtono\nnonLunononoLuono\nnonLvnononoLvono\nnonLwnononoLwono\nnonLxnononoLxono\nnonLynononoLyono\nnonLznononoLzono\n
nonMnnononoMnono\nnonnMnonononMono\nnonMonononoMoono\nnonoMnononooMono\nnonManononoMaono\nnonaMnononoaMono\nnonMbnononoMbono\nnoncMnononocMono\nnoneMnononoeMono\nnonMfnononoMfono\nnonfMnononofMono\nnonMgnononoMgono\nnongMnononogMono\nnonMinononoMiono\nnoniMnononoiMono\nnonMjnononoMjono\nnonjMnononojMono\nnonkMnononokMono\nnonMlnononoMlono\nnonlMnononolMono\nnonqMnononoqMono\nnonrMnononorMono\nnonMsnononoMsono\nnonsMnononosMono\nnonMtnononoMtono\nnontMnononotMono\nnonMunononoMuono\nnonuMnononouMono\nnonMvnononoMvono\nnonvMnononovMono\nnonMwnononoMwono\nnonwMnononowMono\nnonMxnononoMxono\nnonxMnononoxMono\nnonMynononoMyono\nnonyMnononoyMono\nnonMznononoMzono\nnonzMnononozMono\n
nonNnnononoNnono\nnonnNnonononNono\nnonNonononoNoono\nnonoNnononooNono\nnonNanononoNaono\nnonaNnononoaNono\nnonNbnononoNbono\nnoncNnononocNono\nnoneNnononoeNono\nnonNfnononoNfono\nnonfNnononofNono\nnonNgnononoNgono\nnongNnononogNono\nnonNinononoNiono\nnoniNnononoiNono\nnonNjnononoNjono\nnonjNnononojNono\nnonkNnononokNono\nnonNlnononoNlono\nnonlNnononolNono\nnonqNnononoqNono\nnonrNnononorNono\nnonNsnononoNsono\nnonsNnononosNono\nnonNtnononoNtono\nnontNnononotNono\nnonNunononoNuono\nnonuNnononouNono\nnonNvnononoNvono\nnonvNnononovNono\nnonNwnononoNwono\nnonwNnononowNono\nnonNxnononoNxono\nnonxNnononoxNono\nnonNynononoNyono\nnonyNnononoyNono\nnonNznononoNzono\nnonzNnononozNono\n
nonPnnononoPnono\nnonPonononoPoono\nnonPanononoPaono\nnonPbnononoPbono\nnonPfnononoPfono\nnonPgnononoPgono\nnonPinononoPiono\nnonPjnononoPjono\nnonPlnononoPlono\nnonPsnononoPsono\nnonPtnononoPtono\nnonPunononoPuono\nnonPvnononoPvono\nnonPwnononoPwono\nnonPxnononoPxono\nnonPynononoPyono\nnonPznononoPzono\n
nonRnnononoRnono\nnonRonononoRoono\nnonRanononoRaono\nnonRbnononoRbono\nnonRfnononoRfono\nnonRgnononoRgono\nnonRinononoRiono\nnonRjnononoRjono\nnonRlnononoRlono\nnonRsnononoRsono\nnonRtnononoRtono\nnonRunononoRuono\nnonRvnononoRvono\nnonRwnononoRwono\nnonRxnononoRxono\nnonRynononoRyono\nnonRznononoRzono\n
nonSnnononoSnono\nnonnSnonononSono\nnonSonononoSoono\nnonoSnononooSono\nnonSanononoSaono\nnonaSnononoaSono\nnonSbnononoSbono\nnoncSnononocSono\nnoneSnononoeSono\nnonSfnononoSfono\nnonfSnononofSono\nnonSgnononoSgono\nnongSnononogSono\nnonSinononoSiono\nnoniSnononoiSono\nnonSjnononoSjono\nnonjSnononojSono\nnonkSnononokSono\nnonSlnononoSlono\nnonlSnononolSono\nnonqSnononoqSono\nnonrSnononorSono\nnonSsnononoSsono\nnonsSnononosSono\nnonStnononoStono\nnontSnononotSono\nnonSunononoSuono\nnonuSnononouSono\nnonSvnononoSvono\nnonvSnononovSono\nnonSwnononoSwono\nnonwSnononowSono\nnonSxnononoSxono\nnonxSnononoxSono\nnonSynononoSyono\nnonySnononoySono\nnonSznononoSzono\nnonzSnononozSono\n
nonTnnononoTnono\nnonnTnonononTono\nnonTonononoToono\nnonoTnononooTono\nnonTanononoTaono\nnonaTnononoaTono\nnonTbnononoTbono\nnoncTnononocTono\nnoneTnononoeTono\nnonTfnononoTfono\nnonfTnononofTono\nnonTgnononoTgono\nnongTnononogTono\nnonTinononoTiono\nnoniTnononoiTono\nnonTjnononoTjono\nnonjTnononojTono\nnonkTnononokTono\nnonTlnononoTlono\nnonlTnononolTono\nnonqTnononoqTono\nnonrTnononorTono\nnonTsnononoTsono\nnonsTnononosTono\nnonTtnononoTtono\nnontTnononotTono\nnonTunononoTuono\nnonuTnononouTono\nnonTvnononoTvono\nnonvTnononovTono\nnonTwnononoTwono\nnonwTnononowTono\nnonTxnononoTxono\nnonxTnononoxTono\nnonTynononoTyono\nnonyTnononoyTono\nnonTznononoTzono\nnonzTnononozTono\n
nonUnnononoUnono\nnonnUnonononUono\nnonUonononoUoono\nnonoUnononooUono\nnonUanononoUaono\nnonaUnononoaUono\nnonUbnononoUbono\nnoncUnononocUono\nnoneUnononoeUono\nnonUfnononoUfono\nnonfUnononofUono\nnonUgnononoUgono\nnongUnononogUono\nnonUinononoUiono\nnoniUnononoiUono\nnonUjnononoUjono\nnonjUnononojUono\nnonkUnononokUono\nnonUlnononoUlono\nnonlUnononolUono\nnonqUnononoqUono\nnonrUnononorUono\nnonUsnononoUsono\nnonsUnononosUono\nnonUtnononoUtono\nnontUnononotUono\nnonUunononoUuono\nnonuUnononouUono\nnonUvnononoUvono\nnonvUnononovUono\nnonUwnononoUwono\nnonwUnononowUono\nnonUxnononoUxono\nnonxUnononoxUono\nnonUynononoUyono\nnonyUnononoyUono\nnonUznononoUzono\nnonzUnononozUono\n
nonVnnononoVnono\nnonnVnonononVono\nnonVonononoVoono\nnonoVnononooVono\nnonVanononoVaono\nnonaVnononoaVono\nnonVbnononoVbono\nnoncVnononocVono\nnoneVnononoeVono\nnonVfnononoVfono\nnonfVnononofVono\nnonVgnononoVgono\nnongVnononogVono\nnonVinononoViono\nnoniVnononoiVono\nnonVjnononoVjono\nnonjVnononojVono\nnonkVnononokVono\nnonVlnononoVlono\nnonlVnononolVono\nnonqVnononoqVono\nnonrVnononorVono\nnonVsnononoVsono\nnonsVnononosVono\nnonVtnononoVtono\nnontVnononotVono\nnonVunononoVuono\nnonuVnononouVono\nnonVvnononoVvono\nnonvVnononovVono\nnonVwnononoVwono\nnonwVnononowVono\nnonVxnononoVxono\nnonxVnononoxVono\nnonVynononoVyono\nnonyVnononoyVono\nnonVznononoVzono\nnonzVnononozVono\n
nonWnnononoWnono\nnonnWnonononWono\nnonWonononoWoono\nnonoWnononooWono\nnonWanononoWaono\nnonaWnononoaWono\nnonWbnononoWbono\nnoncWnononocWono\nnoneWnononoeWono\nnonWfnononoWfono\nnonfWnononofWono\nnonWgnononoWgono\nnongWnononogWono\nnonWinononoWiono\nnoniWnononoiWono\nnonWjnononoWjono\nnonjWnononojWono\nnonkWnononokWono\nnonWlnononoWlono\nnonlWnononolWono\nnonqWnononoqWono\nnonrWnononorWono\nnonWsnononoWsono\nnonsWnononosWono\nnonWtnononoWtono\nnontWnononotWono\nnonWunononoWuono\nnonuWnononouWono\nnonWvnononoWvono\nnonvWnononovWono\nnonWwnononoWwono\nnonwWnononowWono\nnonWxnononoWxono\nnonxWnononoxWono\nnonWynononoWyono\nnonyWnononoyWono\nnonWznononoWzono\nnonzWnononozWono\n
nonXnnononoXnono\nnonnXnonononXono\nnonXonononoXoono\nnonoXnononooXono\nnonXanononoXaono\nnonaXnononoaXono\nnonXbnononoXbono\nnoncXnononocXono\nnoneXnononoeXono\nnonXfnononoXfono\nnonfXnononofXono\nnonXgnononoXgono\nnongXnononogXono\nnonXinononoXiono\nnoniXnononoiXono\nnonXjnononoXjono\nnonjXnononojXono\nnonkXnononokXono\nnonXlnononoXlono\nnonlXnononolXono\nnonqXnononoqXono\nnonrXnononorXono\nnonXsnononoXsono\nnonsXnononosXono\nnonXtnononoXtono\nnontXnononotXono\nnonXunononoXuono\nnonuXnononouXono\nnonXvnononoXvono\nnonvXnononovXono\nnonXwnononoXwono\nnonwXnononowXono\nnonXxnononoXxono\nnonxXnononoxXono\nnonXynononoXyono\nnonyXnononoyXono\nnonXznononoXzono\nnonzXnononozXono\n
nonYnnononoYnono\nnonnYnonononYono\nnonYonononoYoono\nnonoYnononooYono\nnonYanononoYaono\nnonaYnononoaYono\nnonYbnononoYbono\nnoncYnononocYono\nnoneYnononoeYono\nnonYfnononoYfono\nnonfYnononofYono\nnonYgnononoYgono\nnongYnononogYono\nnonYinononoYiono\nnoniYnononoiYono\nnonYjnononoYjono\nnonjYnononojYono\nnonkYnononokYono\nnonYlnononoYlono\nnonlYnononolYono\nnonqYnononoqYono\nnonrYnononorYono\nnonYsnononoYsono\nnonsYnononosYono\nnonYtnononoYtono\nnontYnononotYono\nnonYunononoYuono\nnonuYnononouYono\nnonYvnononoYvono\nnonvYnononovYono\nnonYwnononoYwono\nnonwYnononowYono\nnonYxnononoYxono\nnonxYnononoxYono\nnonYynononoYyono\nnonyYnononoyYono\nnonYznononoYzono\nnonzYnononozYono\n
nonZnnononoZnono\nnonnZnonononZono\nnonZonononoZoono\nnonoZnononooZono\nnonZanononoZaono\nnonaZnononoaZono\nnonZbnononoZbono\nnoncZnononocZono\nnoneZnononoeZono\nnonZfnononoZfono\nnonfZnononofZono\nnonZgnononoZgono\nnongZnononogZono\nnonZinononoZiono\nnoniZnononoiZono\nnonZjnononoZjono\nnonjZnononojZono\nnonkZnononokZono\nnonZlnononoZlono\nnonlZnononolZono\nnonqZnononoqZono\nnonrZnononorZono\nnonZsnononoZsono\nnonsZnononosZono\nnonZtnononoZtono\nnontZnononotZono\nnonZunononoZuono\nnonuZnononouZono\nnonZvnononoZvono\nnonvZnononovZono\nnonZwnononoZwono\nnonwZnononowZono\nnonZxnononoZxono\nnonxZnononoxZono\nnonZynononoZyono\nnonyZnononoyZono\nnonZznononoZzono\nnonzZnononozZono\n
"""

fontSize = 16

width = 842
height = 1190
margin = 20

newDrawing()
content = FormattedString()
content.font("AvenirNext-Heavy")
content.fontSize(fontSize)
x, y, w, h = margin, margin, width - margin * 2, height - margin * 2

for line in text.splitlines():
    content.append(f"{line}\n")

while len(content) > 0:
    newPage(width, height)

    colSize = w / 3
    for c in range(3):
        content = textBox(content, (x + (colSize * c), y, colSize, h), align="left")

saveImage("~/Desktop/test.pdf")
endDrawing()
justvanrossum commented 4 years ago

With Avenir (the latest script) I can't reproduce it (the kerning on page 4 looks ok to me).

Which version of Python macOS are you using?

joachimvu commented 4 years ago

I'm on Catalina 10.15.6 (19G73) and using Python 3.6.12 (I manage my python versions with Pyenv) from a virtual environment, but tried with 3.8.4 with the same results.

joachimvu commented 4 years ago

I tested with a python3 version installed from python.org and I don't have the issue either (tested with and without a virtual env). So it has something to do with python versions installed with Pyenv?

justvanrossum commented 4 years ago

So it has something to do with python versions installed with Pyenv?

Check whether perhaps you used a 32-bit version of Python before?

Did you use the latest PyObjC in all cases?

joachimvu commented 4 years ago

I'm using 64-bit versions of Python and started from fresh environments every time, so I get whatever version of PyObjC pip installs when running pip install git+https://github.com/typemytype/drawbot. That would be 6.2.2!

typemytype commented 4 years ago

I cannot reproduce this kerning issue. Not with your example nor with single line of text

from drawBot import *

fontName = "Avenir-Black"

sampleText = "ATAV"

newDrawing()
newPage(1000, 1000)
font(fontName, 200)
print(fontFilePath())
text(sampleText, (100, 100))

t = FormattedString()
t.font(fontName, 200)
t.append(sampleText)

print(t.fontFilePath())

text(t, (100, 400))

import AppKit
# check if we are inside or outside 
appName = AppKit.NSBundle.mainBundle().objectForInfoDictionaryKey_("CFBundleDisplayName")
print(appName)
if appName == "DrawBot":
    fileName = "kerningIndrawbot.png"
else:
    fileName = "kerningAsAModule.png"

saveImage(fileName)
endDrawing()
joachimvu commented 4 years ago

@typemytype, yes the issue is unlikely to arise with such a short string. Even with the small chunk from my first post I don't have the issue, which is why it took a while to spot that there was something going on because I didn't use very long input texts while developing.

I tried uninstalling and reinstalling Pyenv and python versions I used with it, still get the same results. It shows in execution time too:

justvanrossum commented 4 years ago

I don't know what pyenv really does, but it seems the running time has more to do with how you set up your environment then with the kerning test script.

Please show the follow sys fields in both versions, perhaps we can find a difference:

import sys
print(sys.version)
print(sys.maxunicode)
print(sys.executable)
joachimvu commented 4 years ago

Hi @justvanrossum, Here's my output for both python versions I'm using in this test.

>>> import sys
>>> print(sys.version)
3.7.9 (v3.7.9:13c94747c7, Aug 15 2020, 01:31:08)
[Clang 6.0 (clang-600.0.57)]
>>> print(sys.maxunicode)
1114111
>>> print(sys.executable)
/Library/Frameworks/Python.framework/Versions/3.7/bin/python3

>>> import sys
>>> print(sys.version)
3.7.9 (default, Nov 14 2020, 13:13:35)
[Clang 12.0.0 (clang-1200.0.32.2)]
>>> print(sys.maxunicode)
1114111
>>> print(sys.executable)
/Users/joachimvu/.pyenv/versions/3.7.9/bin/python
justvanrossum commented 4 years ago

Ok, so that didn't help finding anything :(

Do you know where pyenv gets its Python from? Could it be homebrew or Anaconda?

Can you show the output of ls -l /Users/joachimvu/.pyenv/versions/3.7.9/bin/ ? That may give a clue.

On the one hand, I'd like to help you, on the other, we may have to say "Please use Python from python.org, as we can't guarantee the results of other builds."

It may be a bug in macOS, that only gets triggered in certain environments.

Probably unrelated, but since I don't have any other ideas at the moment: we have the issue that the Python versions that GitHub Actions provide are not suitable to build an application bundle, because it's not a framework build, which makes it incompatible with py2app, that builds the app. So can we run our tests CI with the Python provided by GH Actions, but we need to download the python.org Python to build the app. So I wonder if what you're seeing could also be related to this kind of build difference.

Can you say a bit more why you're using pyenv? I use venv virtual environments together with Python from python.org. Switching may be a bit less convenient, but I feel I have full control over which Python I'm using. I don't understand how pyenv dictates the Python build.

joachimvu commented 4 years ago

Here's the content of my bin folder:

lrwxr-xr-x  1 joachimvu  staff        8 14 nov 13:14 2to3 -> 2to3-3.7
-rwxr-xr-x  1 joachimvu  staff      129 14 nov 13:14 2to3-3.7
lrwxr-xr-x  1 joachimvu  staff       16 14 nov 13:14 easy_install -> easy_install-3.7
-rwxr-xr-x  1 joachimvu  staff      266 14 nov 13:14 easy_install-3.7
lrwxr-xr-x  1 joachimvu  staff        7 14 nov 13:14 idle -> idle3.7
lrwxr-xr-x  1 joachimvu  staff        7 14 nov 13:14 idle3 -> idle3.7
-rwxr-xr-x  1 joachimvu  staff      127 14 nov 13:14 idle3.7
lrwxr-xr-x  1 joachimvu  staff        6 14 nov 13:14 pip -> pip3.7
-rwxr-xr-x  1 joachimvu  staff      257 14 nov 13:14 pip3
-rwxr-xr-x  1 joachimvu  staff      257 14 nov 13:14 pip3.7
lrwxr-xr-x  1 joachimvu  staff        8 14 nov 13:14 pydoc -> pydoc3.7
lrwxr-xr-x  1 joachimvu  staff        8 14 nov 13:14 pydoc3 -> pydoc3.7
-rwxr-xr-x  1 joachimvu  staff      112 14 nov 13:14 pydoc3.7
lrwxr-xr-x  1 joachimvu  staff        9 14 nov 13:14 python -> python3.7
lrwxr-xr-x  1 joachimvu  staff       16 14 nov 13:14 python-config -> python3.7-config
lrwxr-xr-x  1 joachimvu  staff        9 14 nov 13:14 python3 -> python3.7
lrwxr-xr-x  1 joachimvu  staff       16 14 nov 13:14 python3-config -> python3.7-config
-rwxr-xr-x  2 joachimvu  staff  3292600 14 nov 13:14 python3.7
lrwxr-xr-x  1 joachimvu  staff       17 14 nov 13:14 python3.7-config -> python3.7m-config
-rwxr-xr-x  1 joachimvu  staff    65409 14 nov 13:14 python3.7-gdb.py
-rwxr-xr-x  2 joachimvu  staff  3292600 14 nov 13:14 python3.7m
-rwxr-xr-x  1 joachimvu  staff     1963 14 nov 13:14 python3.7m-config
lrwxr-xr-x  1 joachimvu  staff       10 14 nov 13:14 pyvenv -> pyvenv-3.7
-rwxr-xr-x  1 joachimvu  staff      469 14 nov 13:14 pyvenv-3.7

I believe Pyenv get its Python versions from Homebrew.

I mostly use Pyenv out of convenience. It makes it easy to manage and install various Python versions from a single command pyenv install X.X.X and to choose an interpreter at will either globally or locally. I can then tie a version, or a virtual env to a project (with the pyenv-virtualenv plugin) to activate it when I cd into it.

Although I'd prefer to manage my python versions from a unique tool, its admittedly not the end of the world if I have to use a separate python install for my DrawBot stuff. Now I'm mostly curious to find out what would cause such a weird bug :)

robertjanes commented 9 months ago

Hi all, I just encountered this issue today, also while working on a script to generate kerning proofs. Kerning just seemed to be getting disabled when my string got above a certain length, but only when running the script from the command line and not the app. After playing around a bit I circled in on a limit of 10240, which suspiciously seems to be some sort of hard limit enforced by something. I haven't been able to figure out what is causing this, but maybe you have some ideas?

Below: PDF generated from the command line (left side not enforcing a string length limit, right side enforcing a string length limit of 10240

image

Below: PDF generated from the DrawBot app (left side not enforcing a string length limit, right side enforcing a string length limit of 10240

image

Here's the code I used to generate the tests.

from drawBot import *

newDrawing()
size(1000, 1000)
txt = "HLTHATAHAYAH".ljust(100000, "H")
fontSize(48)
font("Helvetica")
overflow = textBox(txt, (20, 20, 460, 960))
overflow = textBox(txt[0:10240], (520, 20, 460, 960))
endDrawing()
saveImage("bug-test.pdf")