Package: fonttools Version: 1.99+2.0b1+cvs20031014-1 Severity: normal Tags: patch
ttx accidentally uses a O(n^2) algorithm for converting hexdump to binary: hexdata = "" for chunk in content: if type(chunk) == type(""): hexdata = hexdata + chunk This *copies* hexdata on every line. The mistake is understandable, as the code looks similar to perl's (and few other languages') idiom for $chunk(@content) { $hexdata .= $chunk if something($chunk) } that works in place. For Western fonts, that are usually in ~100kB size range, the O(n^2) behaviour is not very problematic, but the CJK fonts are often 5-10MB or larger, so it takes about forever for the hexdump to binary conversion on ttx->ttf to finish (I don't know how long exactly, I ^C-ed the program and started debugging after about 25 minutes on 6MB Sazanami Gothic font) The patch replaces 2 instances of: data = "" for: data = data + something return data with semantically equivalent, but O(n): data = [] for: data.append(something) return "".join(data) Actually I converted readHex to more pythonesque list-comprehension format instead of appending in loop (it's equivalent to the loop, after compilation), but this isn't very important. In a different thread, fonttools seems to have many other bugs that appear when I try to process CJK fonts with it, and the last release on sf.net was in 2002. Is it abandoned ?
diff -ru fonttools-1.99+2.0b1+cvs20031014.orig/Lib/fontTools/misc/textTools.py fonttools-1.99+2.0b1+cvs20031014/Lib/fontTools/misc/textTools.py --- fonttools-1.99+2.0b1+cvs20031014.orig/Lib/fontTools/misc/textTools.py 2000-02-01 16:28:18.000000000 +0100 +++ fonttools-1.99+2.0b1+cvs20031014/Lib/fontTools/misc/textTools.py 2005-06-06 16:45:46.000000000 +0200 @@ -11,11 +11,7 @@ def readHex(content): """Convert a list of hex strings to binary data.""" - hexdata = "" - for chunk in content: - if type(chunk) == type(""): - hexdata = hexdata + chunk - return deHexStr(hexdata) + return deHexStr(''.join([ chunk for chunk in content if isinstance(chunk,str) ])) def deHexStr(hexdata): """Convert a hex string to binary data.""" @@ -23,10 +19,11 @@ hexdata = string.join(parts, "") if len(hexdata) % 2: hexdata = hexdata + "0" - data = "" + data = [] for i in range(0, len(hexdata), 2): - data = data + chr(string.atoi(hexdata[i:i+2], 16)) - return data + data.append(chr(string.atoi(hexdata[i:i+2], 16))) + return "".join(data) + def hexStr(data): """Convert binary data to a hex string."""