[Image-SIG] TrueType support in PIL 1.1.4 a1
Fredrik Lundh
fredrik@pythonware.com
Fri, 17 Jan 2003 10:00:59 +0100
frank wrote:
> I have been a long time user of PIL and I appreciate it very much. I us=
e it
> for auto labelling of pictures and make town maps
> (http://art-nouveau.kubos.org/en/index.htm). The new
> truetype support is great but it seems to be broken with special charac=
ters
> like =E9,=E8,=FC, © .... they appear as squares in PIL although in=
my
> favourite word processor they are OK with the same tt font.
the version in 1.1.4a1 messes up on non-ascii characters. the
following patch fixes this, and adds support for unicode strings
as well.
regards /F
=3D=3D=3D=3D //modules/pil/_imagingft.c#4 (ktext) - //modules/pil/_imagin=
gft.c#7 (ktext) =3D=3D=3D=3D content
***************
*** 7,18 ****
* history:
* 2001-02-17 fl Created (based on old experimental freetype 1.0 code)
* 2001-04-18 fl Fixed some egcs compiler nits
*
* Copyright (c) 1998-2001 by Secret Labs AB
*/
- /* FIXME: add unicode support (1.6 and later) */
-
#include "Python.h"
#include "Imaging.h"
--- 7,17 ----
* history:
* 2001-02-17 fl Created (based on old experimental freetype 1.0 code)
* 2001-04-18 fl Fixed some egcs compiler nits
+ * 2002-11-08 fl Added unicode support; more font metrics, etc
*
* Copyright (c) 1998-2001 by Secret Labs AB
*/
#include "Python.h"
#include "Imaging.h"
***************
*** 82,105 ****
return (PyObject*) self;
}
static PyObject*
font_getsize(FontObject* self, PyObject* args)
{
int i, x;
/* calculate size for a given string */
! char* text;
! int chars;
! if (!PyArg_ParseTuple(args, "s#", &text, &chars))
return NULL;
#if PY_VERSION_HEX >=3D 0x01060000
! /* FIXME: Unicode support */
#endif
! for (x =3D i =3D 0; i < chars; i++) {
int index, error;
! index =3D FT_Get_Char_Index(self->face, (FT_ULong) text[i]);
error =3D FT_Load_Glyph(self->face, index, FT_LOAD_DEFAULT);
if (error)
goto failure;
--- 81,134 ----
return (PyObject*) self;
}
+ static int
+ font_getchar(PyObject* string, int index, FT_ULong* char_out)
+ {
+ #if PY_VERSION_HEX >=3D 0x01060000
+ if (PyUnicode_Check(string)) {
+ Py_UNICODE* p =3D PyUnicode_AS_UNICODE(string);
+ int size =3D PyUnicode_GET_SIZE(string);
+ if (index >=3D size)
+ return 0;
+ *char_out =3D p[index];
+ return 1;
+ } else
+ #endif
+ if (PyString_Check(string)) {
+ unsigned char* p =3D PyString_AS_STRING(string);
+ int size =3D PyString_GET_SIZE(string);
+ if (index >=3D size)
+ return 0;
+ *char_out =3D (unsigned char) p[index];
+ return 1;
+ }
+ return 0;
+ }
+
static PyObject*
font_getsize(FontObject* self, PyObject* args)
{
int i, x;
+ FT_ULong ch;
/* calculate size for a given string */
!
! PyObject* string;
! if (!PyArg_ParseTuple(args, "O:getsize", &string))
return NULL;
#if PY_VERSION_HEX >=3D 0x01060000
! if (!PyUnicode_Check(string) && !PyString_Check(string)) {
! #else
! if (!PyString_Check(string)) {
#endif
+ PyErr_SetString(PyExc_TypeError, "expected string");
+ return NULL;
+ }
! for (x =3D i =3D 0; font_getchar(string, i, &ch); i++) {
int index, error;
! index =3D FT_Get_Char_Index(self->face, ch);
error =3D FT_Load_Glyph(self->face, index, FT_LOAD_DEFAULT);
if (error)
goto failure;
***************
*** 123,146 ****
Imaging im;
int index, error, ascender;
unsigned char *source;
FT_GlyphSlot glyph;
/* render string into given buffer (the buffer *must* have
the right size, or this will crash) */
! char* text;
! int chars;
long id;
! if (!PyArg_ParseTuple(args, "s#l", &text, &chars, &id))
return NULL;
#if PY_VERSION_HEX >=3D 0x01060000
! /* FIXME: Unicode support */
#endif
im =3D (Imaging) id;
! for (x =3D i =3D 0; i < chars; i++) {
! index =3D FT_Get_Char_Index(self->face, (FT_ULong) text[i]);
error =3D FT_Load_Glyph(self->face, index, FT_LOAD_RENDER);
if (error)
goto failure;
--- 152,180 ----
Imaging im;
int index, error, ascender;
unsigned char *source;
+ FT_ULong ch;
FT_GlyphSlot glyph;
/* render string into given buffer (the buffer *must* have
the right size, or this will crash) */
! PyObject* string;
long id;
! if (!PyArg_ParseTuple(args, "Ol:render", &string, &id))
return NULL;
#if PY_VERSION_HEX >=3D 0x01060000
! if (!PyUnicode_Check(string) && !PyString_Check(string)) {
! #else
! if (!PyString_Check(string)) {
#endif
+ PyErr_SetString(PyExc_TypeError, "expected string");
+ return NULL;
+ }
im =3D (Imaging) id;
! for (x =3D i =3D 0; font_getchar(string, i, &ch); i++) {
! index =3D FT_Get_Char_Index(self->face, ch);
error =3D FT_Load_Glyph(self->face, index, FT_LOAD_RENDER);
if (error)
goto failure;
***************
*** 198,210 ****
/* attributes */
if (!strcmp(name, "family"))
! return Py_BuildValue("s", self->face->family_name);
if (!strcmp(name, "style"))
! return Py_BuildValue("s", self->face->style_name);
if (!strcmp(name, "glyphs"))
/* number of glyphs provided by this font */
! return Py_BuildValue("i", self->face->num_glyphs);
PyErr_SetString(PyExc_AttributeError, name);
return NULL;
--- 232,249 ----
/* attributes */
if (!strcmp(name, "family"))
! return PyString_FromString(self->face->family_name);
if (!strcmp(name, "style"))
! return PyString_FromString(self->face->style_name);
!
! if (!strcmp(name, "ascent"))
! return PyInt_FromLong(PIXEL(self->face->size->metrics.ascender)=
);
! if (!strcmp(name, "descent"))
! return PyInt_FromLong(-PIXEL(self->face->size->metrics.descende=
r));
if (!strcmp(name, "glyphs"))
/* number of glyphs provided by this font */
! return PyInt_FromLong(self->face->num_glyphs);
PyErr_SetString(PyExc_AttributeError, name);
return NULL;