vertical text - cleanup and bugfixes

This commit is contained in:
nulano 2020-04-14 03:16:32 +02:00
parent e8dcbff64e
commit cee61d7622

View File

@ -609,7 +609,8 @@ text_layout(PyObject* string, FontObject* self, const char* dir, PyObject *featu
static PyObject* static PyObject*
font_getsize(FontObject* self, PyObject* args) font_getsize(FontObject* self, PyObject* args)
{ {
int x_position, x_max, x_min, y_max, y_min; int position, advanced;
int x_max, x_min, y_max, y_min;
FT_Face face; FT_Face face;
int xoffset, yoffset; int xoffset, yoffset;
int horizontal_dir; int horizontal_dir;
@ -634,12 +635,10 @@ font_getsize(FontObject* self, PyObject* args)
} }
face = NULL; face = NULL;
xoffset = yoffset = 0; position = x_max = x_min = y_max = y_min = 0;
x_position = x_max = x_min = y_max = y_min = 0;
horizontal_dir = dir && strcmp(dir, "ttb") == 0 ? 0 : 1; horizontal_dir = dir && strcmp(dir, "ttb") == 0 ? 0 : 1;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
int index, error, offset, x_advanced; int index, error, offset;
FT_BBox bbox; FT_BBox bbox;
FT_Glyph glyph; FT_Glyph glyph;
face = self->face; face = self->face;
@ -657,15 +656,16 @@ font_getsize(FontObject* self, PyObject* args)
} }
if (i == 0) { if (i == 0) {
// adjust start position if glyph bearing extends before origin
if (horizontal_dir) { if (horizontal_dir) {
if (face->glyph->metrics.horiBearingX + glyph_info[i].x_offset < 0) { if (face->glyph->metrics.horiBearingX + glyph_info[i].x_offset < 0) {
x_min = x_position = face->glyph->metrics.horiBearingX + x_min = position = face->glyph->metrics.horiBearingX +
glyph_info[i].x_offset; glyph_info[i].x_offset;
} }
} else { } else {
if (face->glyph->metrics.vertBearingY < 0) { if (face->glyph->metrics.vertBearingY + glyph_info[i].y_offset > 0) {
yoffset = face->glyph->metrics.vertBearingY; y_max = position = face->glyph->metrics.vertBearingY +
y_max -= yoffset; glyph_info[i].y_offset;
} }
} }
} }
@ -673,18 +673,19 @@ font_getsize(FontObject* self, PyObject* args)
FT_Get_Glyph(face->glyph, &glyph); FT_Get_Glyph(face->glyph, &glyph);
FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_SUBPIXELS, &bbox); FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_SUBPIXELS, &bbox);
if (horizontal_dir) { if (horizontal_dir) {
x_position += glyph_info[i].x_advance; position += glyph_info[i].x_advance;
x_advanced = x_position; advanced = position;
// adjust glyph end position if bearing extends past advanced point
offset = glyph_info[i].x_advance - offset = glyph_info[i].x_advance -
glyph_info[i].x_offset - glyph_info[i].x_offset -
face->glyph->metrics.width - face->glyph->metrics.horiBearingX -
face->glyph->metrics.horiBearingX; face->glyph->metrics.width;
if (offset < 0) { if (offset < 0) {
x_advanced -= offset; advanced -= offset;
} }
if (x_advanced > x_max) { if (advanced > x_max) {
x_max = x_advanced; x_max = advanced;
} }
bbox.yMax += glyph_info[i].y_offset; bbox.yMax += glyph_info[i].y_offset;
@ -696,23 +697,27 @@ font_getsize(FontObject* self, PyObject* args)
y_min = bbox.yMin; y_min = bbox.yMin;
} }
} else { } else {
y_max -= glyph_info[i].y_advance; position += glyph_info[i].y_advance;
if (i == count - 1) { advanced = position;
// trim end gap from final glyph // adjust glyph end position if bearing extends past advanced point
int offset; offset = glyph_info[i].y_advance -
offset = -glyph_info[i].y_advance - glyph_info[i].y_offset -
face->glyph->metrics.height - face->glyph->metrics.vertBearingY +
face->glyph->metrics.vertBearingY; face->glyph->metrics.height;
if (offset < 0) { if (offset > 0) {
y_max -= offset; advanced -= offset;
} }
if (advanced < y_min) {
y_min = advanced;
} }
bbox.xMax += glyph_info[i].x_offset;
bbox.xMin += glyph_info[i].x_offset;
if (bbox.xMax > x_max) { if (bbox.xMax > x_max) {
x_max = bbox.xMax; x_max = bbox.xMax;
} }
if (i == 0 || bbox.xMin < x_min) { if (bbox.xMin < x_min) {
x_min = bbox.xMin; x_min = bbox.xMin;
} }
} }
@ -730,12 +735,8 @@ font_getsize(FontObject* self, PyObject* args)
xoffset = x_min; xoffset = x_min;
yoffset = self->face->size->metrics.ascender - y_max; yoffset = self->face->size->metrics.ascender - y_max;
} else { } else {
// top bearing xoffset = 0;
if (yoffset < 0) { yoffset = -y_max;
y_max -= yoffset;
} else {
yoffset = 0;
}
} }
} }
@ -749,8 +750,7 @@ font_getsize(FontObject* self, PyObject* args)
static PyObject* static PyObject*
font_render(FontObject* self, PyObject* args) font_render(FontObject* self, PyObject* args)
{ {
int x; int x, y;
unsigned int y;
Imaging im; Imaging im;
int index, error, baseline, horizontal_dir; int index, error, baseline, horizontal_dir;
int load_flags; int load_flags;
@ -761,15 +761,13 @@ font_render(FontObject* self, PyObject* args)
FT_BitmapGlyph bitmap_glyph; FT_BitmapGlyph bitmap_glyph;
int stroke_width = 0; int stroke_width = 0;
FT_Stroker stroker = NULL; FT_Stroker stroker = NULL;
FT_Int left;
/* render string into given buffer (the buffer *must* have /* render string into given buffer (the buffer *must* have
the right size, or this will crash) */ the right size, or this will crash) */
PyObject* string; PyObject* string;
Py_ssize_t id; Py_ssize_t id;
int mask = 0; int mask = 0;
int temp; int temp;
int xx, x0, x1; int xx, x0, x1, yy;
int yy;
unsigned int bitmap_y; unsigned int bitmap_y;
const char *dir = NULL; const char *dir = NULL;
const char *lang = NULL; const char *lang = NULL;
@ -832,12 +830,17 @@ font_render(FontObject* self, PyObject* args)
} }
} }
} else { } else {
// TODO temp = -(glyph_slot->metrics.vertBearingX + glyph_info[i].x_offset);
// baseline was called ascender and measured the descender if (temp > baseline) {
temp = bitmap.rows - glyph_slot->bitmap_top;
temp -= PIXEL(glyph_info[i].y_offset);
if (temp > baseline)
baseline = temp; baseline = temp;
}
if (i == 0) {
temp = glyph_slot->metrics.vertBearingY + glyph_info[i].y_offset;
if (temp > 0) {
y = -temp;
}
}
} }
} }
@ -869,19 +872,14 @@ font_render(FontObject* self, PyObject* args)
bitmap_glyph = (FT_BitmapGlyph)glyph; bitmap_glyph = (FT_BitmapGlyph)glyph;
bitmap = bitmap_glyph->bitmap; bitmap = bitmap_glyph->bitmap;
left = bitmap_glyph->left;
} else { } else {
bitmap = glyph_slot->bitmap; bitmap = glyph_slot->bitmap;
left = glyph_slot->bitmap_left;
} }
if (horizontal_dir) { if (horizontal_dir) {
xx = PIXEL(x + glyph_info[i].x_offset) + left + stroke_width; xx = PIXEL(x + glyph_slot->metrics.horiBearingX + glyph_info[i].x_offset) + stroke_width;
} else { } else {
if (glyph_slot->metrics.vertBearingX < 0) { xx = PIXEL(baseline + glyph_slot->metrics.vertBearingX + glyph_info[i].x_offset) + stroke_width;
x = -glyph_slot->metrics.vertBearingX;
}
xx = im->xsize / 2 - bitmap.width / 2;
} }
x0 = 0; x0 = 0;
@ -899,8 +897,8 @@ font_render(FontObject* self, PyObject* args)
yy = PIXEL(baseline - glyph_slot->metrics.horiBearingY - glyph_info[i].y_offset) + yy = PIXEL(baseline - glyph_slot->metrics.horiBearingY - glyph_info[i].y_offset) +
stroke_width + bitmap_y; stroke_width + bitmap_y;
} else { } else {
yy = bitmap_y + PIXEL(y + glyph_slot->metrics.vertBearingY) + baseline; yy = PIXEL(-(y + glyph_slot->metrics.vertBearingY + glyph_info[i].y_offset)) +
yy += PIXEL(glyph_info[i].y_offset); stroke_width + bitmap_y;
} }
if (yy >= 0 && yy < im->ysize) { if (yy >= 0 && yy < im->ysize) {
// blend this glyph into the buffer // blend this glyph into the buffer
@ -930,7 +928,7 @@ font_render(FontObject* self, PyObject* args)
source += bitmap.pitch; source += bitmap.pitch;
} }
x += glyph_info[i].x_advance; x += glyph_info[i].x_advance;
y -= glyph_info[i].y_advance; y += glyph_info[i].y_advance;
if (stroker != NULL) { if (stroker != NULL) {
FT_Done_Glyph(glyph); FT_Done_Glyph(glyph);
} }