From a2f6deaec25059551c469239a7ec70f4d267b411 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=B6rg=20Lehmann?= Date: Sat, 24 Sep 2005 11:39:30 +0000 Subject: [PATCH] Added new extension module t1code which contains C versions of the de-/encoders used in Type 1 font file. On my machine this yields a speedup of around 50% for test_text.py compared to the pure Python version. git-svn-id: https://pyx.svn.sourceforge.net/svnroot/pyx/trunk/pyx@2474 069f4177-920e-0410-937b-c2a4a81bcd90 --- CHANGES | 2 + pyx/font/_t1code.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++ setup.py | 4 +- 3 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 pyx/font/_t1code.c diff --git a/CHANGES b/CHANGES index 13cc1b87..123816f4 100644 --- a/CHANGES +++ b/CHANGES @@ -553,6 +553,8 @@ TODO: - t1strip module: - new fallback solution in pure python - bugfix: pyxadapt.h needs to open files binary under Windows (reported by Gary Pajer) + - t1code extension module (new): + - C version for decoders and encoders uses in Type 1 font files - box module: - _xxx -> xxx_pt renaming - trafo module: diff --git a/pyx/font/_t1code.c b/pyx/font/_t1code.c new file mode 100644 index 00000000..2b9a724d --- /dev/null +++ b/pyx/font/_t1code.c @@ -0,0 +1,109 @@ +/* t1code.c: Copyright 2005 Jörg Lehmann + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include + +#define C1 52845 +#define C2 22719 + +/* +def decoder(code, r, n): + c1 = 52845 + c2 = 22719 + data = array.array("B") + for x in array.array("B", code): + data.append(x ^ (r >> 8)) + r = ((x + r) * c1 + c2) & 0xffff + return data.tostring()[n:] + +*/ + +static PyObject *py_decoder(PyObject *self, PyObject *args) +{ + unsigned char *code; + int lcode, r, n; + + if (PyArg_ParseTuple(args, "s#ii", (char **) &code, &lcode, &r, &n)) { + unsigned char *data; + int i; + unsigned char x; + + if (! (data = (unsigned char *) malloc(lcode)) ) + return NULL; + + for (i=0; i> 8); + r = ((x + r) * C1 + C2) & 0xFFFF; + } + + /* convert result to string stripping first n chars */ + return PyString_FromStringAndSize((const char *)data + n, lcode - n); + } + else return NULL; + +} + +/* +def encoder(data, r, random): + c1 = 52845 + c2 = 22719 + code = array.array("B") + for x in array.array("B", random+data): + code.append(x ^ (r >> 8)) + r = ((code[-1] + r) * c1 + c2) & 0xffff; + return code.tostring() +*/ + +static PyObject *py_encoder(PyObject *self, PyObject *args) +{ + unsigned char *data; + unsigned char *random; + int ldata, lrandom, r; + + if (PyArg_ParseTuple(args, "s#is#", (char **) &data, &ldata, &r, (char **) &random, &lrandom)) { + unsigned char *code; + int i; + + if (! (code = (unsigned char *) malloc(ldata + lrandom)) ) + return NULL; + + for (i=0; i> 8); + r = ((code[i] + r) * C1 + C2) & 0xFFFF; + } + + for (i=0; i> 8); + r = ((code[i+lrandom] + r) * C1 + C2) & 0xFFFF; + } + + return PyString_FromStringAndSize((const char *)code, ldata + lrandom); + } + else return NULL; + +} + + + +/* exported methods */ + +static PyMethodDef t1code_methods[] = { + {"decoder", py_decoder, METH_VARARGS}, + {"encoder", py_encoder, METH_VARARGS}, + {NULL, NULL} +}; + +void init_t1code(void) { + (void) Py_InitModule("_t1code", t1code_methods); +} diff --git a/setup.py b/setup.py index c76e2e52..ba70f80d 100755 --- a/setup.py +++ b/setup.py @@ -30,8 +30,8 @@ ext_modules = [] pykpathsea_ext_module = Extension("pyx.pykpathsea._pykpathsea", sources=["pyx/pykpathsea/pykpathsea.c"], libraries=["kpathsea"]) -# t1code_ext_module = Extension("pyx.font._t1code", -# sources=["pyx/font/_t1code.c"]) +t1code_ext_module = Extension("pyx.font._t1code", + sources=["pyx/font/_t1code.c"]) # obtain information on which modules have to be built from setup.cfg file cfg = ConfigParser.ConfigParser() -- 2.11.4.GIT