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."""

Reply via email to