From 0b709a5df697b36a24e4456b24585ec8f0c54b63 Mon Sep 17 00:00:00 2001 From: Grigori Goronzy Date: Sun, 17 Jul 2011 17:43:55 +0200 Subject: Fix crash with FreeType's updated stroker The new revision of the stroker in FreeType doesn't like the way contours are zero-filled to disable them. It's not particularly clean anyway, so rewrite the whole outline instead. --- libass/ass_font.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/libass/ass_font.c b/libass/ass_font.c index 21ad297..370623d 100644 --- a/libass/ass_font.c +++ b/libass/ass_font.c @@ -647,8 +647,20 @@ static int get_contour_direction(FT_Vector *points, int start, int end) } /** - * \brief Fix-up stroker result for huge borders by removing inside contours - * that would reverse in size + * \brief Apply fixups to please the FreeType stroker and improve the + * rendering result, especially in case the outline has some anomalies. + * At the moment, the following fixes are done: + * + * 1. Reverse contours that have "inside" winding direction but are not + * contained in any other contours' cbox. + * 2. Remove "inside" contours depending on border size, so that large + * borders do not reverse the winding direction, which leads to "holes" + * inside the border. The inside will be filled by the border of the + * outside contour anyway in this case. + * + * \param outline FreeType outline, modified in-place + * \param border_x border size, x direction, d6 format + * \param border_x border size, y direction, d6 format */ void fix_freetype_stroker(FT_Outline *outline, int border_x, int border_y) { @@ -716,19 +728,26 @@ void fix_freetype_stroker(FT_Outline *outline, int border_x, int border_y) } } - // zero-out contours that can be removed; much simpler than copying + // if we need to modify the outline, rewrite it and skip + // the contours that we determined should be removed. if (modified) { + int p = 0, c = 0; for (i = 0; i < nc; i++) { - if (valid_cont[i]) + if (!valid_cont[i]) continue; begin = (i == 0) ? 0 : outline->contours[i - 1] + 1; stop = outline->contours[i]; for (j = begin; j <= stop; j++) { - outline->points[j].x = 0; - outline->points[j].y = 0; - outline->tags[j] = 0; + outline->points[p].x = outline->points[j].x; + outline->points[p].y = outline->points[j].y; + outline->tags[p] = outline->tags[j]; + p++; } + outline->contours[c] = p - 1; + c++; } + outline->n_points = p; + outline->n_contours = c; } free(boxes); -- cgit v1.2.3