summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@blackbox>2011-07-17 17:43:55 +0200
committerGrigori Goronzy <greg@blackbox>2011-07-17 17:43:55 +0200
commit0b709a5df697b36a24e4456b24585ec8f0c54b63 (patch)
treedc27d6c194aac434732a31064bcc13fa12e10694
parent2f01497b9974ab083b99bed3823bbf9702ad8b9a (diff)
downloadlibass-0b709a5df697b36a24e4456b24585ec8f0c54b63.tar.bz2
libass-0b709a5df697b36a24e4456b24585ec8f0c54b63.tar.xz
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.
-rw-r--r--libass/ass_font.c33
1 files 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);