]> granicus.if.org Git - libass/commitdiff
Switch to native coordinate system for outlines
authorDr.Smile <vabnick@gmail.com>
Wed, 2 Aug 2017 01:34:28 +0000 (04:34 +0300)
committerDr.Smile <vabnick@gmail.com>
Sun, 17 Sep 2017 01:07:20 +0000 (04:07 +0300)
libass/ass_drawing.c
libass/ass_outline.c
libass/ass_rasterizer.c
libass/ass_render.c

index d235517f4f392e983462800b35600fa53f9a96d0..4deb19a0e7e1ca630cc6b156bfa0c18504a1dc9b 100644 (file)
@@ -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);
 }
index a1dfa1e6af72466ef8fe175f49be2adb19c1a4aa..c4aa5106cf85f563f7b3b6f41e72308319c738a8 100644 (file)
@@ -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;
 
index 8234f077bbef397f56d7c879eb2947d52b77d833..97bebb2544e1e2cbe75672b299c4aaae86e21706 100644 (file)
@@ -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;
 
index 7ff1db8adef04f3a16893bc3f32dfee39b6e1867..c340e1a510bbca27389c91789659057c817634f3 100644 (file)
@@ -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;