[reportlab-users] TTF loading acceleration

Ury Marshak reportlab-users@reportlab.com
Sat, 19 Oct 2002 17:50:34 +0200


While profiling a small report using TT fonts I found that
most of the time is spent inside ttfonts.calcChecksum
function.

After I rewrote it in C the time (for one-page report) has
dropped from 12-15 secs to 1-2.

Diffs folllow.

Ury

--- C:\TEMP\reportlab\pdfbase\ttfonts.py 2002-07-30 08:06:46.000000000 +0200
+++ C:\Python22\Lib\site-packages\reportlab\pdfbase\ttfonts.py 2002-10-19
17:44:52.000000000 +0200
@@ -152,7 +152,7 @@
     hi = (x >> 16) + (y >> 16) + (lo >> 16)
     return (hi << 16) | (lo & 0xFFFF)

-def calcChecksum(data):
+def _calcChecksum(data):
     """Calculates PDF-style checksums"""
     if len(data)&3: data = data + (4-(len(data)&3))*"\0"
     sum = 0
@@ -162,6 +162,14 @@
         sum = (hi << 16) | (lo & 0xFFFF)
     return sum

+
+try:
+    from reportlab.lib import _rl_accel
+    calcChecksum = _rl_accel.calcChecksum
+except:
+    calcChecksum = _calcChecksum
+
+
 #
 # TrueType font handling
 #



--- C:\TEMP\reportlab\lib\_rl_accel.c 2002-03-18 09:23:32.000000000 +0200
+++ C:\Python22\Lib\site-packages\reportlab\lib\_rl_accel.c 2002-10-19
17:32:33.000000000 +0200
@@ -659,6 +659,43 @@
 L0: return PyInt_FromLong((long)r);
 }

+static PyObject *ttfonts_calcChecksum(PyObject *self, PyObject* args)
+{
+ unsigned char *data;
+ int    dataLen;
+    unsigned long   Sum = 0L;
+    unsigned char   *EndPtr;
+
+    unsigned long n;
+    int leftover;
+
+
+ if (!PyArg_ParseTuple(args, "s#:calcChecksum", &data, &dataLen)) return
NULL;
+
+    EndPtr = data + (dataLen & ~3);
+
+    /* full ULONGs */
+    while (data < EndPtr) {
+        n = ((*data++) << 24) ;
+        n += ((*data++) << 16) ;
+        n += ((*data++) << 8) ;
+        n += ((*data++));
+        Sum += n;
+    }
+
+    /* pad with zeros */
+    leftover = dataLen & 3;
+    if (leftover) {
+        n = ((*data++) << 24) ;
+        if (leftover>1) n += ((*data++) << 16) ;
+        if (leftover>2) n += ((*data++) << 8) ;
+        Sum += n;
+    }
+
+    return PyInt_FromLong(Sum);
+}
+
+
 static char *__doc__=
 "_rl_accel contains various accelerated utilities\n\
     stringWidth a fast string width function\n\
@@ -698,9 +735,11 @@
 #ifdef ATTRDICT
  {"_AttrDict", _AttrDict, METH_VARARGS, "_AttrDict() create a dict which
can use attribute notation"},
 #endif
+ {"calcChecksum", ttfonts_calcChecksum, METH_VARARGS, "calculate checksums
for TTFs"},
  {NULL,  NULL}  /* sentinel */
  };

+
 /*Initialization function for the module (*must* be called
init_pdfmetrics)*/
 void init_rl_accel(void)
 {