Fix rendered characters have been chipped for some TrueType fonts

This patch is from http://pastebin.com/jP2iLkDN
This commit is contained in:
Takeshi KOMIYA 2013-04-11 19:16:26 +09:00
parent e44f35eec2
commit efd70fb295

View File

@ -35,6 +35,8 @@
#include <freetype/freetype.h>
#endif
#include FT_GLYPH_H
#define KEEP_PY_UNICODE
#include "py3.h"
@ -141,7 +143,7 @@ getfont(PyObject* self_, PyObject* args, PyObject* kw)
return (PyObject*) self;
}
static int
font_getchar(PyObject* string, int index, FT_ULong* char_out)
{
@ -171,7 +173,7 @@ font_getchar(PyObject* string, int index, FT_ULong* char_out)
static PyObject*
font_getsize(FontObject* self, PyObject* args)
{
int i, x;
int i, x, y_max, y_min;
FT_ULong ch;
FT_Face face;
int xoffset;
@ -195,6 +197,7 @@ font_getsize(FontObject* self, PyObject* args)
face = NULL;
xoffset = 0;
y_max = y_min = 0;
for (x = i = 0; font_getchar(string, i, &ch); i++) {
int index, error;
@ -212,6 +215,16 @@ font_getsize(FontObject* self, PyObject* args)
if (i == 0)
xoffset = face->glyph->metrics.horiBearingX;
x += face->glyph->metrics.horiAdvance;
FT_BBox bbox;
FT_Glyph glyph;
FT_Get_Glyph(face->glyph, &glyph);
FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_SUBPIXELS, &bbox);
if (bbox.yMax > y_max)
y_max = bbox.yMax;
if (bbox.yMin < y_min)
y_min = bbox.yMin;
last_index = index;
}
@ -232,7 +245,7 @@ font_getsize(FontObject* self, PyObject* args)
return Py_BuildValue(
"(ii)(ii)",
PIXEL(x), PIXEL(self->face->size->metrics.height),
PIXEL(x), PIXEL(y_max - y_min),
PIXEL(xoffset), 0
);
}
@ -313,6 +326,19 @@ font_render(FontObject* self, PyObject* args)
if (mask)
load_flags |= FT_LOAD_TARGET_MONO;
int temp;
ascender = 0;
for (i = 0; font_getchar(string, i, &ch); i++) {
index = FT_Get_Char_Index(self->face, ch);
error = FT_Load_Glyph(self->face, index, load_flags);
if (error)
return geterror(error);
glyph = self->face->glyph;
temp = (glyph->bitmap.rows - glyph->bitmap_top);
if (temp > ascender)
ascender = temp;
}
for (x = i = 0; font_getchar(string, i, &ch); i++) {
if (i == 0 && self->face->glyph->metrics.horiBearingX < 0)
x = -PIXEL(self->face->glyph->metrics.horiBearingX);
@ -331,7 +357,6 @@ font_render(FontObject* self, PyObject* args)
/* use monochrome mask (on palette images, etc) */
int xx, x0, x1;
source = (unsigned char*) glyph->bitmap.buffer;
ascender = PIXEL(self->face->size->metrics.ascender);
xx = x + glyph->bitmap_left;
x0 = 0;
x1 = glyph->bitmap.width;
@ -340,7 +365,7 @@ font_render(FontObject* self, PyObject* args)
if (xx + x1 > im->xsize)
x1 = im->xsize - xx;
for (y = 0; y < glyph->bitmap.rows; y++) {
int yy = y + ascender - glyph->bitmap_top;
int yy = y + im->ysize - (PIXEL(glyph->metrics.horiBearingY) + ascender);
if (yy >= 0 && yy < im->ysize) {
/* blend this glyph into the buffer */
unsigned char *target = im->image8[yy] + xx;
@ -360,7 +385,6 @@ font_render(FontObject* self, PyObject* args)
/* use antialiased rendering */
int xx, x0, x1;
source = (unsigned char*) glyph->bitmap.buffer;
ascender = PIXEL(self->face->size->metrics.ascender);
xx = x + glyph->bitmap_left;
x0 = 0;
x1 = glyph->bitmap.width;
@ -369,7 +393,7 @@ font_render(FontObject* self, PyObject* args)
if (xx + x1 > im->xsize)
x1 = im->xsize - xx;
for (y = 0; y < glyph->bitmap.rows; y++) {
int yy = y + ascender - glyph->bitmap_top;
int yy = y + im->ysize - (PIXEL(glyph->metrics.horiBearingY) + ascender);
if (yy >= 0 && yy < im->ysize) {
/* blend this glyph into the buffer */
int i;