summaryrefslogtreecommitdiffstats
path: root/libass
diff options
context:
space:
mode:
authorDr.Smile <vabnick@gmail.com>2017-08-02 04:34:28 +0300
committerDr.Smile <vabnick@gmail.com>2017-09-17 04:07:20 +0300
commitbced14d1a6b83faca46ac3259f5cb77adc101e30 (patch)
tree3f73fef2ed2136bc035b0b34779365aa022c596f /libass
parentf159a8cf55c8b3f2193ab20159a255310c7c5ca9 (diff)
downloadlibass-bced14d1a6b83faca46ac3259f5cb77adc101e30.tar.bz2
libass-bced14d1a6b83faca46ac3259f5cb77adc101e30.tar.xz
Switch to native coordinate system for outlines
Diffstat (limited to 'libass')
-rw-r--r--libass/ass_drawing.c4
-rw-r--r--libass/ass_outline.c51
-rw-r--r--libass/ass_rasterizer.c43
-rw-r--r--libass/ass_render.c32
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;