reportlab/lib/_rl_accel.c
author rgbecker
Wed, 25 Oct 2000 08:57:46 +0000
changeset 494 54257447cfe9
parent 461 228b00fb140a
child 515 7b9d69c7ea4f
permissions -rw-r--r--
Changed to indirect copyright
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
494
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 461
diff changeset
     1
/****************************************************************************
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 461
diff changeset
     2
#copyright ReportLab Inc. 2000
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 461
diff changeset
     3
#see license.txt for license details
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 461
diff changeset
     4
#history http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/reportlab/lib/_rl_accel.c?cvsroot=reportlab
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 461
diff changeset
     5
#$Header: /tmp/reportlab/reportlab/lib/_rl_accel.c,v 1.4 2000/10/25 08:57:45 rgbecker Exp $
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 461
diff changeset
     6
 ****************************************************************************/
54257447cfe9 Changed to indirect copyright
rgbecker
parents: 461
diff changeset
     7
static __version__=" $Id: _rl_accel.c,v 1.4 2000/10/25 08:57:45 rgbecker Exp $ "
413
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
     8
#include <Python.h>
425
27d01a9348fa Linux/GnuC fixes
rgbecker
parents: 413
diff changeset
     9
#include <stdlib.h>
27d01a9348fa Linux/GnuC fixes
rgbecker
parents: 413
diff changeset
    10
#include <math.h>
461
228b00fb140a Fix for sun compiler
rgbecker
parents: 425
diff changeset
    11
#if defined(__GNUC__) || defined(sun)
425
27d01a9348fa Linux/GnuC fixes
rgbecker
parents: 413
diff changeset
    12
#	define STRICMP strcasecmp
27d01a9348fa Linux/GnuC fixes
rgbecker
parents: 413
diff changeset
    13
#elif defined(_MSC_VER)
27d01a9348fa Linux/GnuC fixes
rgbecker
parents: 413
diff changeset
    14
#	define STRICMP stricmp
27d01a9348fa Linux/GnuC fixes
rgbecker
parents: 413
diff changeset
    15
#else
27d01a9348fa Linux/GnuC fixes
rgbecker
parents: 413
diff changeset
    16
#	error "Don't know how to define STRICMP"
27d01a9348fa Linux/GnuC fixes
rgbecker
parents: 413
diff changeset
    17
#endif
27d01a9348fa Linux/GnuC fixes
rgbecker
parents: 413
diff changeset
    18
#ifndef max
27d01a9348fa Linux/GnuC fixes
rgbecker
parents: 413
diff changeset
    19
#	define max(a,b) ((a)>(b)?(a):(b))
27d01a9348fa Linux/GnuC fixes
rgbecker
parents: 413
diff changeset
    20
#endif
27d01a9348fa Linux/GnuC fixes
rgbecker
parents: 413
diff changeset
    21
#ifndef min
27d01a9348fa Linux/GnuC fixes
rgbecker
parents: 413
diff changeset
    22
#	define min(a,b) ((a)<(b)?(a):(b))
27d01a9348fa Linux/GnuC fixes
rgbecker
parents: 413
diff changeset
    23
#endif
413
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    24
typedef struct _fI_t {
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    25
		char*			name;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    26
		int				ascent, descent;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    27
		int				widths[256];
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    28
		struct _fI_t*	next;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    29
		} fI_t;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    30
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    31
typedef struct _eI_t {
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    32
		char*			name;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    33
		fI_t*			fonts;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    34
		struct _eI_t*	next;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    35
		} eI_t;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    36
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    37
eI_t		*Encodings=NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    38
eI_t		*defaultEncoding = NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    39
PyObject	*_SWRecover=NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    40
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    41
static PyObject *ErrorObject;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    42
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    43
static	eI_t*	find_encoding(char* name)
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    44
{
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    45
	eI_t*	e = Encodings;
425
27d01a9348fa Linux/GnuC fixes
rgbecker
parents: 413
diff changeset
    46
	for(;e;e=e->next) if(!STRICMP(name,e->name)) return e;
413
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    47
	return (eI_t*)0;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    48
}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    49
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    50
static	fI_t* find_font(char* name, fI_t* f)
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    51
{
425
27d01a9348fa Linux/GnuC fixes
rgbecker
parents: 413
diff changeset
    52
	for(;f;f=f->next) if(!STRICMP(name,f->name)) return f;
413
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    53
	return (fI_t*)0;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    54
}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    55
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    56
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    57
static	int _parseSequenceInt(PyObject* e, int i, int *x)
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    58
{
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    59
	PyObject	*p;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    60
	if((p = PySequence_GetItem(e,i)) && (p = PyNumber_Int(p))){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    61
		*x=PyInt_AS_LONG(p);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    62
		return 1;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    63
		}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    64
	return 0;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    65
}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    66
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    67
static PyObject *_pdfmetrics__SWRecover(PyObject* dummy, PyObject* args)
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    68
{
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    69
	PyObject *result = NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    70
	PyObject *temp=NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    71
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    72
	if (PyArg_ParseTuple(args, "|O:_SWRecover", &temp)) {
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    73
		if(temp){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    74
			if (!PyCallable_Check(temp)) {
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    75
				PyErr_SetString(PyExc_TypeError, "parameter must be callable");
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    76
				return NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    77
				}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    78
			Py_INCREF(temp);         			/* Add a reference to new callback */
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    79
			Py_XDECREF(_SWRecover);	/* Dispose of previous callback */
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    80
			_SWRecover = temp;				/* Remember new callback */
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    81
			}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    82
		else if(_SWRecover){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    83
			Py_INCREF(_SWRecover);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    84
			return _SWRecover;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    85
			}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    86
		/* Boilerplate to return "None" */
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    87
		Py_INCREF(Py_None);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    88
		result = Py_None;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    89
		}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    90
	return result;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    91
}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    92
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    93
static PyObject *_pdfmetrics_defaultEncoding(PyObject *self, PyObject* args)
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    94
{
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    95
	char*	encoding=NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    96
	eI_t*	e;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    97
	if (!PyArg_ParseTuple(args, "|s", &encoding)) return NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    98
	if(encoding){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
    99
		if(!(e= find_encoding(encoding))){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   100
			PyErr_SetString(ErrorObject,"Unknown encoding");
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   101
			return NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   102
			}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   103
		else defaultEncoding = e;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   104
		}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   105
	else if(defaultEncoding) return Py_BuildValue("s",defaultEncoding->name);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   106
	Py_INCREF(Py_None);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   107
	return Py_None;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   108
}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   109
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   110
static PyObject *_pdfmetrics_setFontInfo(PyObject *self, PyObject* args)
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   111
{
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   112
	char		*fontName, *encoding;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   113
	int			ascent, descent;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   114
	PyObject	*pW;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   115
	int			i;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   116
	eI_t*		e;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   117
	fI_t*		f;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   118
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   119
	if (!PyArg_ParseTuple(args, "ssiiO", &fontName, &encoding, &ascent, &descent,&pW)) return NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   120
	i = PySequence_Length(pW);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   121
	if(i!=256){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   122
badSeq:	PyErr_SetString(ErrorObject,"widths should be a length 256 sequence of integers");
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   123
		return NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   124
		}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   125
	e = find_encoding(encoding);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   126
	if(!e){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   127
		e = (eI_t*)malloc(sizeof(eI_t));
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   128
		e->name = strdup(encoding);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   129
		e->next = Encodings;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   130
		e->fonts = NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   131
		Encodings = e;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   132
		f = NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   133
		}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   134
	else 
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   135
		f = find_font(fontName,e->fonts);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   136
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   137
	if(!f){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   138
		f = (fI_t*)malloc(sizeof(fI_t));
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   139
		f->name = strdup(fontName);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   140
		f->next = e->fonts;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   141
		e->fonts = f;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   142
		}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   143
	f->ascent = ascent;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   144
	f->descent = descent;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   145
	for(i=0;i<256;i++)
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   146
		if(!_parseSequenceInt(pW,i,&f->widths[i])) goto badSeq;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   147
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   148
	Py_INCREF(Py_None);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   149
	return Py_None;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   150
}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   151
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   152
static PyObject *_pdfmetrics_stringWidth(PyObject *self, PyObject* args)
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   153
{
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   154
	char		*text, *fontName, *encoding=NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   155
	PyObject	*pS;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   156
	double		fontSize;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   157
	fI_t		*fI;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   158
	eI_t		*e;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   159
	int			w, *width, i, textLen;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   160
	static int	recover=1;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   161
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   162
	if (!PyArg_ParseTuple(args, "s#sO|s", &text, &textLen, &fontName, &pS, &encoding)) return NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   163
	if((pS=PyNumber_Float(pS))) fontSize = PyFloat_AS_DOUBLE(pS);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   164
	else{
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   165
		PyErr_SetString(ErrorObject,"bad fontSize");
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   166
		return NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   167
		}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   168
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   169
	if(!(e=encoding?find_encoding(encoding):defaultEncoding)){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   170
		PyErr_SetString(ErrorObject,"unknown encoding");
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   171
		return NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   172
		}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   173
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   174
	if(!(fI=find_font(fontName,e->fonts))){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   175
		if(_SWRecover && recover){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   176
			PyObject *arglist = Py_BuildValue("(s#sds)",text,textLen,fontName,fontSize,e->name);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   177
			PyObject *result;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   178
			if(!arglist){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   179
				PyErr_SetString(ErrorObject,"recovery failed!");
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   180
				return NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   181
				}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   182
			recover = 0;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   183
			result = PyEval_CallObject(_SWRecover, arglist);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   184
			recover = 1;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   185
			Py_DECREF(arglist);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   186
			if(!result) return NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   187
			if(result==Py_None){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   188
				Py_DECREF(result);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   189
				if(!(fI=find_font(fontName,e->fonts))) goto L_ufe;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   190
				}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   191
			else return result;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   192
			}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   193
L_ufe:	PyErr_SetString(ErrorObject,"unknown font");
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   194
		return NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   195
		}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   196
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   197
	width = fI->widths;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   198
	for(i=w=0;i<textLen;i++)
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   199
		w += width[(unsigned)text[i]];
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   200
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   201
	return Py_BuildValue("f",0.001*fontSize*w);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   202
}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   203
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   204
static const unsigned long _a85_nums[5] = {1L, 85L, 7225L, 614125L, 52200625L};
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   205
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   206
PyObject *_a85_encode(PyObject *self, PyObject *args)
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   207
{
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   208
	unsigned char	*inData;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   209
	int				length, blocks, extra, i, j, k, lim;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   210
	unsigned long	block, res;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   211
	char			*buf;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   212
	PyObject		*retVal;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   213
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   214
	if (!PyArg_ParseTuple(args, "z#", &inData, &length)) return NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   215
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   216
	blocks = length / 4;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   217
	extra = length % 4;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   218
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   219
	buf = (char*)malloc((blocks+1)*5+3);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   220
	lim = 4*blocks;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   221
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   222
	for(k=i=0; i<lim; i += 4){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   223
		/*
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   224
		 * If you evere have trouble with this consider using masking to ensure
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   225
		 * that the shifted quantity is only 8 bits long
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   226
		 */
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   227
		block = ((unsigned long)inData[i]<<24)|((unsigned long)inData[i+1]<<16)
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   228
				|((unsigned long)inData[i+2]<<8)|((unsigned long)inData[i+3]);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   229
		if (block == 0) buf[k++] = 'z';
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   230
		else
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   231
			for (j=4; j>=0; j--) {
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   232
				res = block / _a85_nums[j];
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   233
				buf[k++] = (char)(res+33);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   234
				block -= res * _a85_nums[j];
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   235
				}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   236
		}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   237
	
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   238
	block = 0L;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   239
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   240
	for (i=0; i<extra; i++)
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   241
		block += (unsigned long)inData[length-extra+i] << (24-8*i);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   242
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   243
	for (j=4; j>=4-extra; j--){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   244
		res = block / _a85_nums[j];
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   245
		buf[k++] = (char)(res+33);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   246
		block -= res * _a85_nums[j];
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   247
		}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   248
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   249
	buf[k++] = '~';
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   250
	buf[k++] = '>';
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   251
	retVal = PyString_FromStringAndSize(buf, k);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   252
	free(buf);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   253
	return retVal;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   254
}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   255
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   256
static	char* _fp_fmts[]={"%.0f", "%.1f", "%.2f", "%.3f", "%.4f", "%.5f", "%.6f", "%.8f", "%.9f"};
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   257
static	char *_fp_one(PyObject *pD)
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   258
{
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   259
	double d;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   260
	static	char s[30];
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   261
	int l;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   262
	if((pD=PyNumber_Float(pD))) d = PyFloat_AS_DOUBLE(pD);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   263
	else {
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   264
		PyErr_SetString(ErrorObject, "bad numeric value");
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   265
		return NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   266
		}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   267
	l = min(max(0,6-(int)log10(fabs(d))),6);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   268
	sprintf(s,_fp_fmts[l], d);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   269
	l = strlen(s)-1;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   270
	while(l && s[l]=='0') l--;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   271
	if(s[l]=='.') s[l]=0;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   272
	else {
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   273
		s[l+1]=0;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   274
		if(s[0]=='0' && s[1]=='.') return s+1;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   275
		}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   276
	return s;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   277
}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   278
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   279
PyObject *_fp_str(PyObject *self, PyObject *args)
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   280
{
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   281
	int				aL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   282
	PyObject		*retVal;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   283
	char			*pD;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   284
	char			*buf, *pB;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   285
	int				i;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   286
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   287
	if((aL=PySequence_Length(args))>=0){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   288
		if(aL==1){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   289
			retVal = PySequence_GetItem(args,0);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   290
			if((i=PySequence_Length(retVal))>=0){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   291
				aL = i;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   292
				args = retVal;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   293
				}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   294
			else PyErr_Clear();
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   295
			}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   296
		buf=malloc(31*aL);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   297
		pB = buf;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   298
		for(i=0;i<aL;i++){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   299
			if(!(pD = _fp_one(PySequence_GetItem(args,i)))){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   300
				free(buf);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   301
				return NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   302
				}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   303
			if(pB!=buf){
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   304
				*pB++ = ' ';
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   305
				}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   306
			strcpy(pB,pD);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   307
			pB = pB + strlen(pB);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   308
			}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   309
		*pB = 0;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   310
		retVal = PyString_FromString(buf);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   311
		free(buf);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   312
		return retVal;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   313
		}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   314
	else {
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   315
		PyErr_Clear();
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   316
		PyArg_ParseTuple(args, "O:_fp_str", &retVal);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   317
		return NULL;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   318
		}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   319
}
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   320
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   321
static char *__doc__=
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   322
"_rl_accel contains various accelerated utilities\n\
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   323
    a fast string width function\n\
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   324
    defaultEncoding gets/sets the default encoding for stringWidth\n\
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   325
    setFontInfo adds a font to the internal table\n\
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   326
    _SWRecover gets/sets a callback for stringWidth recovery\n\
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   327
	\n\
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   328
	_AsciiBase85Encode does what is says\n\
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   329
	\n\
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   330
	fp_str converts numeric arguments to a single blank separated string\n\
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   331
";
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   332
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   333
static struct PyMethodDef _methods[] = {
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   334
	{"defaultEncoding", _pdfmetrics_defaultEncoding, 1, "defaultEncoding([encoding])\ngets/sets the default encoding."},
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   335
	{"setFontInfo", _pdfmetrics_setFontInfo, 1, "setFontInfo(fontName,encoding,ascent, descent, widths)\nadds the font to the table for encoding"},
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   336
	{"stringWidth", _pdfmetrics_stringWidth, 1, "stringwidth(text,fontName,fontSize,[encoding]) returns width of text in points"},
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   337
	{"_SWRecover", _pdfmetrics__SWRecover, 1,
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   338
					"_SWRecover([callable])\n"
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   339
					"get/set the string width recovery\n"
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   340
					"callback callable(text,font,size,encoding)\n"
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   341
					"return None to retry or the correct result."},
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   342
	{"_AsciiBase85Encode", _a85_encode, METH_VARARGS, "_AsciiBase85Encode(\".....\") return encoded string"},
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   343
	{"fp_str", _fp_str, METH_VARARGS, "fp_str(a0, a1,...) convert numerics to blank separated string"},
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   344
	{NULL,		NULL}		/* sentinel */
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   345
	};
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   346
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   347
/*Initialization function for the module (*must* be called init_pdfmetrics)*/
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   348
void init_rl_accel()
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   349
{
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   350
	PyObject *m, *d;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   351
	int i=0;
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   352
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   353
	/*Create the module and add the functions */
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   354
	m = Py_InitModule("_rl_accel", _methods);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   355
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   356
	/*Add some symbolic constants to the module */
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   357
	d = PyModule_GetDict(m);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   358
	ErrorObject = PyString_FromString("_rl_accel.error");
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   359
	PyDict_SetItemString(d, "error", ErrorObject);
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   360
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   361
	/*add in the docstring */
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   362
	PyDict_SetItemString(d, "__doc__", Py_BuildValue("s", __doc__));
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   363
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   364
	/* Check for errors */
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   365
	if (PyErr_Occurred()) Py_FatalError("can't initialize module _rl_accel");
6312e8296c9b Initial version
rgbecker
parents:
diff changeset
   366
}