From bced14d1a6b83faca46ac3259f5cb77adc101e30 Mon Sep 17 00:00:00 2001 From: "Dr.Smile" Date: Wed, 2 Aug 2017 04:34:28 +0300 Subject: Switch to native coordinate system for outlines --- libass/ass_drawing.c | 4 ++-- libass/ass_outline.c | 51 +++++++++++++++++-------------------------------- libass/ass_rasterizer.c | 43 ++++++++++++++++------------------------- libass/ass_render.c | 32 +++++++++++++++---------------- 4 files changed, 52 insertions(+), 78 deletions(-) diff --git a/libass/ass_drawing.c b/libass/ass_drawing.c index d235517..4deb19a 100644 --- a/libass/ass_drawing.c +++ b/libass/ass_drawing.c @@ -67,7 +67,7 @@ static void drawing_finish(ASS_Drawing *drawing, bool raw_mode) // Place it onto the baseline for (size_t i = 0; i < ol->n_points; i++) - ol->points[i].y += drawing->asc; + ol->points[i].y -= drawing->asc; } /* @@ -193,7 +193,7 @@ static inline void update_cbox(ASS_Drawing *drawing, ASS_Vector *point) static inline void translate_point(ASS_Drawing *drawing, ASS_Vector *point) { point->x = drawing->point_scale_x * point->x; - point->y = drawing->point_scale_y * -point->y; + point->y = drawing->point_scale_y * point->y; update_cbox(drawing, point); } diff --git a/libass/ass_outline.c b/libass/ass_outline.c index a1dfa1e..c4aa510 100644 --- a/libass/ass_outline.c +++ b/libass/ass_outline.c @@ -66,8 +66,8 @@ bool outline_convert(ASS_Outline *outline, const FT_Outline *source) // skip degenerate 2-point contours from broken fonts if (n >= 3) { for (size_t k = 0; k < n; k++) { - outline->points[outline->n_points + k].x = source->points[start + k].x; - outline->points[outline->n_points + k].y = source->points[start + k].y; + outline->points[outline->n_points + k].x = source->points[start + k].x; + outline->points[outline->n_points + k].y = -source->points[start + k].y; } memcpy(outline->tags + outline->n_points, source->tags + start, n); @@ -310,13 +310,11 @@ static bool emit_point(StrokerState *str, ASS_Vector pt, if (dir & 1) { ASS_Vector res = { pt.x + dx, pt.y + dy }; - res.y = -res.y; if (!outline_add_point(str->result[0], res, tag)) return false; } if (dir & 2) { ASS_Vector res = { pt.x - dx, pt.y - dy }; - res.y = -res.y; if (!outline_add_point(str->result[1], res, tag)) return false; } @@ -338,7 +336,6 @@ static void fix_first_point(StrokerState *str, ASS_Vector pt, if (dir & 1) { ASS_Vector res = { pt.x + dx, pt.y + dy }; - res.y = -res.y; ASS_Outline *ol = str->result[0]; size_t first = ol->n_contours ? ol->contours[ol->n_contours - 1] + 1 : 0; @@ -346,7 +343,6 @@ static void fix_first_point(StrokerState *str, ASS_Vector pt, } if (dir & 2) { ASS_Vector res = { pt.x - dx, pt.y - dy }; - res.y = -res.y; ASS_Outline *ol = str->result[1]; size_t first = ol->n_contours ? ol->contours[ol->n_contours - 1] + 1 : 0; @@ -1220,15 +1216,14 @@ bool outline_stroke(ASS_Outline *result, ASS_Outline *result1, if (j > last) return false; - if (path->points[j].x < -(1 << 28) || path->points[j].x >= (1 << 28)) + 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)) + if (path->points[j].y < -(1 << 28) || path->points[j].y >= (1 << 28)) return false; switch (FT_CURVE_TAG(path->tags[j])) { case FT_CURVE_TAG_ON: - p[0].x = path->points[j].x; - p[0].y = -path->points[j].y; + p[0] = path->points[j]; start = p[0]; st = S_ON; break; @@ -1236,20 +1231,17 @@ bool outline_stroke(ASS_Outline *result, ASS_Outline *result1, case FT_CURVE_TAG_CONIC: switch (FT_CURVE_TAG(path->tags[last])) { case FT_CURVE_TAG_ON: - p[0].x = path->points[last].x; - p[0].y = -path->points[last].y; - p[1].x = path->points[j].x; - p[1].y = -path->points[j].y; + p[0] = path->points[last]; + p[1] = path->points[j]; process_end = 0; start = p[0]; st = S_Q; break; case FT_CURVE_TAG_CONIC: - p[1].x = path->points[j].x; - p[1].y = -path->points[j].y; + 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; + p[0].y = (p[1].y + path->points[last].y) >> 1; start = p[0]; st = S_Q; break; @@ -1265,25 +1257,23 @@ bool outline_stroke(ASS_Outline *result, ASS_Outline *result1, str.last_point = start; for (j++; j <= last; j++) { - if (path->points[j].x < -(1 << 28) || path->points[j].x >= (1 << 28)) + 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)) + if (path->points[j].y < -(1 << 28) || path->points[j].y >= (1 << 28)) return false; switch (FT_CURVE_TAG(path->tags[j])) { case FT_CURVE_TAG_ON: switch (st) { case S_ON: - p[1].x = path->points[j].x; - p[1].y = -path->points[j].y; + p[1] = path->points[j]; if (!add_line(&str, p[1], dir)) return false; p[0] = p[1]; break; case S_Q: - p[2].x = path->points[j].x; - p[2].y = -path->points[j].y; + p[2] = path->points[j]; if (!add_quadratic(&str, p, dir)) return false; p[0] = p[2]; @@ -1291,8 +1281,7 @@ bool outline_stroke(ASS_Outline *result, ASS_Outline *result1, break; case S_C2: - p[3].x = path->points[j].x; - p[3].y = -path->points[j].y; + p[3] = path->points[j]; if (!add_cubic(&str, p, dir)) return false; p[0] = p[3]; @@ -1307,14 +1296,12 @@ bool outline_stroke(ASS_Outline *result, ASS_Outline *result1, case FT_CURVE_TAG_CONIC: switch (st) { case S_ON: - p[1].x = path->points[j].x; - p[1].y = -path->points[j].y; + p[1] = path->points[j]; st = S_Q; break; case S_Q: - p[3].x = path->points[j].x; - p[3].y = -path->points[j].y; + 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(&str, p, dir)) @@ -1331,14 +1318,12 @@ bool outline_stroke(ASS_Outline *result, ASS_Outline *result1, case FT_CURVE_TAG_CUBIC: switch (st) { case S_ON: - p[1].x = path->points[j].x; - p[1].y = -path->points[j].y; + p[1] = path->points[j]; st = S_C1; break; case S_C1: - p[2].x = path->points[j].x; - p[2].y = -path->points[j].y; + p[2] = path->points[j]; st = S_C2; break; diff --git a/libass/ass_rasterizer.c b/libass/ass_rasterizer.c index 8234f07..97bebb2 100644 --- a/libass/ass_rasterizer.c +++ b/libass/ass_rasterizer.c @@ -282,15 +282,14 @@ bool rasterizer_set_outline(RasterizerData *rst, if (j > last) return false; - if (path->points[j].x < -(1 << 28) || path->points[j].x >= (1 << 28)) + 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)) + if (path->points[j].y < -(1 << 28) || path->points[j].y >= (1 << 28)) return false; switch (FT_CURVE_TAG(path->tags[j])) { case FT_CURVE_TAG_ON: - p[0].x = path->points[j].x; - p[0].y = -path->points[j].y; + p[0] = path->points[j]; start = p[0]; st = S_ON; break; @@ -298,19 +297,16 @@ bool rasterizer_set_outline(RasterizerData *rst, case FT_CURVE_TAG_CONIC: switch (FT_CURVE_TAG(path->tags[last])) { case FT_CURVE_TAG_ON: - p[0].x = path->points[last].x; - p[0].y = -path->points[last].y; - p[1].x = path->points[j].x; - p[1].y = -path->points[j].y; + p[0] = path->points[last]; + p[1] = path->points[j]; process_end = 0; st = S_Q; break; case FT_CURVE_TAG_CONIC: - p[1].x = path->points[j].x; - p[1].y = -path->points[j].y; + 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; + p[0].y = (p[1].y + path->points[last].y) >> 1; start = p[0]; st = S_Q; break; @@ -325,25 +321,23 @@ bool rasterizer_set_outline(RasterizerData *rst, } for (j++; j <= last; j++) { - if (path->points[j].x < -(1 << 28) || path->points[j].x >= (1 << 28)) + 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)) + if (path->points[j].y < -(1 << 28) || path->points[j].y >= (1 << 28)) return false; switch (FT_CURVE_TAG(path->tags[j])) { case FT_CURVE_TAG_ON: switch (st) { case S_ON: - p[1].x = path->points[j].x; - p[1].y = -path->points[j].y; + 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].x = path->points[j].x; - p[2].y = -path->points[j].y; + p[2] = path->points[j]; if (!add_quadratic(rst, p)) return false; p[0] = p[2]; @@ -351,8 +345,7 @@ bool rasterizer_set_outline(RasterizerData *rst, break; case S_C2: - p[3].x = path->points[j].x; - p[3].y = -path->points[j].y; + p[3] = path->points[j]; if (!add_cubic(rst, p)) return false; p[0] = p[3]; @@ -367,14 +360,12 @@ bool rasterizer_set_outline(RasterizerData *rst, case FT_CURVE_TAG_CONIC: switch (st) { case S_ON: - p[1].x = path->points[j].x; - p[1].y = -path->points[j].y; + p[1] = path->points[j]; st = S_Q; break; case S_Q: - p[3].x = path->points[j].x; - p[3].y = -path->points[j].y; + 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)) @@ -391,14 +382,12 @@ bool rasterizer_set_outline(RasterizerData *rst, case FT_CURVE_TAG_CUBIC: switch (st) { case S_ON: - p[1].x = path->points[j].x; - p[1].y = -path->points[j].y; + p[1] = path->points[j]; st = S_C1; break; case S_C1: - p[2].x = path->points[j].x; - p[2].y = -path->points[j].y; + p[2] = path->points[j]; st = S_C2; break; diff --git a/libass/ass_render.c b/libass/ass_render.c index 7ff1db8..c340e1a 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -473,7 +473,7 @@ static void blend_vector_clip(ASS_Renderer *render_priv, val->bm = val->bm_o = NULL; // Not found in cache, parse and rasterize it - ASS_Outline *outline = ass_drawing_parse(drawing, 1); + ASS_Outline *outline = ass_drawing_parse(drawing, true); if (!outline) { ass_msg(render_priv->library, MSGL_WARN, "Clip vector parsing failed. Skipping."); @@ -487,7 +487,7 @@ static void blend_vector_clip(ASS_Renderer *render_priv, render_priv->settings.top_margin != 0) { ASS_Vector trans = { .x = int_to_d6(render_priv->settings.left_margin), - .y = -int_to_d6(render_priv->settings.top_margin), + .y = int_to_d6(render_priv->settings.top_margin), }; outline_translate(outline, trans.x, trans.y); } @@ -937,10 +937,10 @@ static void draw_opaque_box(ASS_Renderer *render_priv, GlyphInfo *info, desc += asc * (scale_y - 1.0); ASS_Vector points[4] = { - { .x = -sx, .y = asc + sy }, - { .x = adv + sx, .y = asc + sy }, - { .x = adv + sx, .y = -desc - sy }, - { .x = -sx, .y = -desc - sy }, + { .x = -sx, .y = -asc - sy }, + { .x = adv + sx, .y = -asc - sy }, + { .x = adv + sx, .y = desc + sy }, + { .x = -sx, .y = desc + sy }, }; ol->n_points = ol->n_contours = 0; @@ -1030,7 +1030,7 @@ get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info) if (info->drawing) { ASS_Drawing *drawing = info->drawing; ass_drawing_hash(drawing); - if(!ass_drawing_parse(drawing, 0) || + if(!ass_drawing_parse(drawing, false) || !outline_copy(&val->outline, &drawing->outline)) { ass_cache_commit(val, 1); ass_cache_dec_ref(val); @@ -1141,12 +1141,12 @@ transform_3d_points(ASS_Vector shift, ASS_Outline *outline, double frx, double f dist = 20000 * scale; for (size_t i = 0; i < outline->n_points; ++i) { - x = (double) p[i].x + shift.x + (fax * (yshift - p[i].y)); - y = (double) p[i].y + shift.y + (-fay * p[i].x); + x = (double) p[i].x + shift.x + fax * (yshift + p[i].y); + y = (double) p[i].y + shift.y + fay * p[i].x; z = 0.; - xx = x * cz + y * sz; - yy = -(x * sz - y * cz); + xx = x * cz - y * sz; + yy = -(x * sz + y * cz); zz = z; x = xx; @@ -1154,15 +1154,15 @@ transform_3d_points(ASS_Vector shift, ASS_Outline *outline, double frx, double f z = yy * sx - zz * cx; xx = x * cy + z * sy; - yy = y; + yy = -y; zz = x * sy - z * cy; zz = FFMAX(zz, 1000 - dist); x = (xx * dist) / (zz + dist); y = (yy * dist) / (zz + dist); - p[i].x = x - shift.x + 0.5; - p[i].y = y - shift.y + 0.5; + p[i].x = lround(x - shift.x); + p[i].y = lround(y - shift.y); } } @@ -1250,7 +1250,7 @@ get_bitmap_glyph(ASS_Renderer *render_priv, GlyphInfo *info) for (int i = 0; i < n_outlines; i++) outline_transform(&outline[i], &m); for (int i = 0; i < n_outlines; i++) - outline_translate(&outline[i], key->advance.x, -key->advance.y); + outline_translate(&outline[i], key->advance.x, key->advance.y); // render glyph val->valid = outline_to_bitmap2(render_priv, @@ -2021,7 +2021,7 @@ static void calculate_rotation_params(ASS_Renderer *render_priv, DBBox *bbox, if (key->frx || key->fry || key->frz || key->fax || key->fay) { key->shift_x = info->pos.x + double_to_d6(device_x - center.x); - key->shift_y = -(info->pos.y + double_to_d6(device_y - center.y)); + key->shift_y = info->pos.y + double_to_d6(device_y - center.y); } else { key->shift_x = 0; key->shift_y = 0; -- cgit v1.2.3