diff options
Diffstat (limited to 'libass/ass_rasterizer.c')
-rw-r--r-- | libass/ass_rasterizer.c | 176 |
1 files changed, 34 insertions, 142 deletions
diff --git a/libass/ass_rasterizer.c b/libass/ass_rasterizer.c index 97bebb2..1af4509 100644 --- a/libass/ass_rasterizer.c +++ b/libass/ass_rasterizer.c @@ -263,167 +263,59 @@ static bool add_cubic(RasterizerData *rst, const ASS_Vector *pt) bool rasterizer_set_outline(RasterizerData *rst, const ASS_Outline *path, bool extra) { - enum Status { - S_ON, S_Q, S_C1, S_C2 - }; - if (!extra) { rst->x_min = rst->y_min = INT32_MAX; rst->x_max = rst->y_max = INT32_MIN; rst->n_first = 0; } rst->size[0] = rst->n_first; - for (size_t i = 0, j = 0; i < path->n_contours; i++) { - ASS_Vector start, p[4]; - int process_end = 1; - enum Status st; - - int last = path->contours[i]; - if (j > last) - return false; - if (path->points[j].x < -(1 << 28) || path->points[j].x >= (1 << 28)) + for (size_t i = 0; i < path->n_points; i++) { + if (path->points[i].x < OUTLINE_MIN || path->points[i].x > OUTLINE_MAX) return false; - if (path->points[j].y < -(1 << 28) || path->points[j].y >= (1 << 28)) + if (path->points[i].y < OUTLINE_MIN || path->points[i].y > OUTLINE_MAX) return false; + } - switch (FT_CURVE_TAG(path->tags[j])) { - case FT_CURVE_TAG_ON: - p[0] = path->points[j]; - start = p[0]; - st = S_ON; - break; - - case FT_CURVE_TAG_CONIC: - switch (FT_CURVE_TAG(path->tags[last])) { - case FT_CURVE_TAG_ON: - p[0] = path->points[last]; - p[1] = path->points[j]; - process_end = 0; - st = S_Q; - break; - - case FT_CURVE_TAG_CONIC: - p[1] = path->points[j]; - p[0].x = (p[1].x + path->points[last].x) >> 1; - p[0].y = (p[1].y + path->points[last].y) >> 1; - start = p[0]; - st = S_Q; - break; - - default: - return false; - } - break; + ASS_Vector *start = path->points, *cur = start; + for (size_t i = 0; i < path->n_segments; i++) { + int n = path->segments[i] & OUTLINE_COUNT_MASK; + cur += n; - default: - return false; + ASS_Vector *end = cur, p[4]; + if (path->segments[i] & OUTLINE_CONTOUR_END) { + end = start; + start = cur; } - for (j++; j <= last; j++) { - if (path->points[j].x < -(1 << 28) || path->points[j].x >= (1 << 28)) - return false; - if (path->points[j].y < -(1 << 28) || path->points[j].y >= (1 << 28)) + switch (n) { + case OUTLINE_LINE_SEGMENT: + if (!add_line(rst, cur[-1], *end)) return false; + break; - switch (FT_CURVE_TAG(path->tags[j])) { - case FT_CURVE_TAG_ON: - switch (st) { - case S_ON: - p[1] = path->points[j]; - if (!add_line(rst, p[0], p[1])) - return false; - p[0] = p[1]; - break; - - case S_Q: - p[2] = path->points[j]; - if (!add_quadratic(rst, p)) - return false; - p[0] = p[2]; - st = S_ON; - break; - - case S_C2: - p[3] = path->points[j]; - if (!add_cubic(rst, p)) - return false; - p[0] = p[3]; - st = S_ON; - break; - - default: - return false; - } - break; - - case FT_CURVE_TAG_CONIC: - switch (st) { - case S_ON: - p[1] = path->points[j]; - st = S_Q; - break; - - case S_Q: - p[3] = path->points[j]; - p[2].x = (p[1].x + p[3].x) >> 1; - p[2].y = (p[1].y + p[3].y) >> 1; - if (!add_quadratic(rst, p)) - return false; - p[0] = p[2]; - p[1] = p[3]; - break; - - default: - return false; - } - break; - - case FT_CURVE_TAG_CUBIC: - switch (st) { - case S_ON: - p[1] = path->points[j]; - st = S_C1; - break; - - case S_C1: - p[2] = path->points[j]; - st = S_C2; - break; - - default: - return false; - } - break; - - default: + case OUTLINE_QUADRATIC_SPLINE: + p[0] = cur[-2]; + p[1] = cur[-1]; + p[2] = *end; + if (!add_quadratic(rst, p)) return false; - } - } + break; - if (process_end) - switch (st) { - case S_ON: - if (!add_line(rst, p[0], start)) - return false; - break; - - case S_Q: - p[2] = start; - if (!add_quadratic(rst, p)) - return false; - break; - - case S_C2: - p[3] = start; - if (!add_cubic(rst, p)) - return false; - break; - - default: + case OUTLINE_CUBIC_SPLINE: + p[0] = cur[-3]; + p[1] = cur[-2]; + p[2] = cur[-1]; + p[3] = *end; + if (!add_cubic(rst, p)) return false; - } + break; + + default: + return false; + } } + assert(start == cur && cur == path->points + path->n_points); for (size_t k = rst->n_first; k < rst->size[0]; k++) { rst->x_min = FFMIN(rst->x_min, rst->linebuf[0][k].x_min); |