summaryrefslogtreecommitdiffstats
path: root/sub/osd_libass.c
diff options
context:
space:
mode:
Diffstat (limited to 'sub/osd_libass.c')
-rw-r--r--sub/osd_libass.c107
1 files changed, 59 insertions, 48 deletions
diff --git a/sub/osd_libass.c b/sub/osd_libass.c
index 3fc4e0ec82..6bb125723b 100644
--- a/sub/osd_libass.c
+++ b/sub/osd_libass.c
@@ -81,7 +81,7 @@ void osd_destroy_backend(struct osd_state *osd)
}
static void create_ass_track(struct osd_state *osd, struct osd_object *obj,
- int res_x, int res_y, int n_default_styles)
+ int res_x, int res_y)
{
create_ass_renderer(osd, obj);
@@ -107,43 +107,46 @@ static void create_ass_track(struct osd_state *osd, struct osd_object *obj,
if (old_res_x != track->PlayResX || old_res_y != track->PlayResY)
ass_set_frame_size(obj->osd_render, 1, 1);
- if (track->n_styles < 1 + n_default_styles) {
- int sid1 = ass_alloc_style(track);
- ASS_Style *style = track->styles + sid1;
- style->Name = strdup("Default");
- style->Encoding = -1;
-
- for (int n = 0; n < n_default_styles; n++) {
- int sid2 = ass_alloc_style(track);
- if (n == 0)
- track->default_style = sid2;
- assert(sid1 + 1 == track->default_style);
- style = track->styles + sid2;
- style->Name = strdup("OSD");
- // Set to neutral base direction, as opposed to VSFilter LTR default
- style->Encoding = -1;
- }
- }
+ obj->osd_track = track;
+}
- for (int n = 0; n < n_default_styles; n++) {
- ASS_Style *s_osd = track->styles + track->default_style + n;
- mp_ass_set_style(s_osd, track->PlayResY, osd->opts->osd_style);
+static int find_style(ASS_Track *track, const char *name, int def)
+{
+ for (int n = 0; n < track->n_styles; n++) {
+ if (track->styles[n].Name && strcmp(track->styles[n].Name, name) == 0)
+ return n;
}
+ return def;
+}
- ASS_Style *s_def = track->styles + track->default_style - 1;
- const struct osd_style_opts *def = osd_style_conf.defaults;
- mp_ass_set_style(s_def, track->PlayResY, def);
-
- obj->osd_track = track;
+// Find a given style, or add it if it's missing.
+static ASS_Style *get_style(struct osd_state *osd, struct osd_object *obj,
+ char *name)
+{
+ ASS_Track *track = obj->osd_track;
+ if (!track)
+ return NULL;
+
+ int sid = find_style(track, name, -1);
+ if (sid >= 0)
+ return &track->styles[sid];
+
+ sid = ass_alloc_style(track);
+ ASS_Style *style = &track->styles[sid];
+ style->Name = strdup(name);
+ // Set to neutral base direction, as opposed to VSFilter LTR default
+ style->Encoding = -1;
+ return style;
}
-static ASS_Event *add_osd_ass_event(ASS_Track *track, const char *text)
+static ASS_Event *add_osd_ass_event(ASS_Track *track, const char *style,
+ const char *text)
{
int n = ass_alloc_event(track);
ASS_Event *event = track->events + n;
event->Start = 0;
event->Duration = 100;
- event->Style = track->default_style;
+ event->Style = find_style(track, style, 0);
event->ReadOrder = n;
assert(event->Text == NULL);
if (text)
@@ -194,11 +197,12 @@ static void mangle_ass(bstr *dst, const char *in)
}
}
-static ASS_Event *add_osd_ass_event_escaped(ASS_Track *track, const char *text)
+static ASS_Event *add_osd_ass_event_escaped(ASS_Track *track, const char *style,
+ const char *text)
{
bstr buf = {0};
mangle_ass(&buf, text);
- ASS_Event *e = add_osd_ass_event(track, buf.start);
+ ASS_Event *e = add_osd_ass_event(track, style, buf.start);
talloc_free(buf.start);
return e;
}
@@ -210,7 +214,7 @@ static void update_osd_text(struct osd_state *osd, struct osd_object *obj)
if (!obj->text[0])
return;
- create_ass_track(osd, obj, 0, 0, 2);
+ create_ass_track(osd, obj, 0, 0);
struct osd_style_opts font = *opts->osd_style;
font.font_size *= opts->osd_scale;
@@ -220,15 +224,8 @@ static void update_osd_text(struct osd_state *osd, struct osd_object *obj)
if (!opts->osd_scale_by_window)
playresy *= 720.0 / obj->vo_res.h;
- // the 1st style is used for the progbar
- int style_id = obj->osd_track->default_style + 1;
-
- ASS_Style *style = obj->osd_track->styles + style_id;
- mp_ass_set_style(style, playresy, &font);
-
- ASS_Event *e = add_osd_ass_event_escaped(obj->osd_track, obj->text);
- if (e)
- e->Style = style_id;
+ mp_ass_set_style(get_style(osd, obj, "OSD"), playresy, &font);
+ add_osd_ass_event_escaped(obj->osd_track, "OSD", obj->text);
}
// align: -1 .. +1
@@ -311,9 +308,16 @@ static void get_osd_bar_box(struct osd_state *osd, struct osd_object *obj,
{
struct MPOpts *opts = osd->opts;
- create_ass_track(osd, obj, 0, 0, 2);
+ create_ass_track(osd, obj, 0, 0);
ASS_Track *track = obj->osd_track;
- ASS_Style *style = track->styles + track->default_style;
+
+ ASS_Style *style = get_style(osd, obj, "progbar");
+ if (!style) {
+ *o_x = *o_y = *o_w = *o_h = *o_border = 0;
+ return;
+ }
+
+ mp_ass_set_style(style, track->PlayResY, opts->osd_style);
*o_w = track->PlayResX * (opts->osd_bar_w / 100.0);
*o_h = track->PlayResY * (opts->osd_bar_h / 100.0);
@@ -358,7 +362,7 @@ static void update_progbar(struct osd_state *osd, struct osd_object *obj)
bstr_xappend(NULL, &buf, bstr0("{\\r}"));
}
- add_osd_ass_event(obj->osd_track, buf.start);
+ add_osd_ass_event(obj->osd_track, "progbar", buf.start);
talloc_free(buf.start);
struct ass_draw *d = &(struct ass_draw) { .scale = 4 };
@@ -368,7 +372,7 @@ static void update_progbar(struct osd_state *osd, struct osd_object *obj)
float pos = obj->progbar_state.value * width - border / 2;
ass_draw_rect_cw(d, 0, 0, pos, height);
ass_draw_stop(d);
- add_osd_ass_event(obj->osd_track, d->text);
+ add_osd_ass_event(obj->osd_track, "progbar", d->text);
ass_draw_reset(d);
// position marker
@@ -378,7 +382,7 @@ static void update_progbar(struct osd_state *osd, struct osd_object *obj)
ass_draw_move_to(d, pos + border / 2, 0);
ass_draw_line_to(d, pos + border / 2, height);
ass_draw_stop(d);
- add_osd_ass_event(obj->osd_track, d->text);
+ add_osd_ass_event(obj->osd_track, "progbar", d->text);
ass_draw_reset(d);
d->text = talloc_asprintf_append(d->text, "{\\pos(%f,%f)}", px, py);
@@ -407,7 +411,7 @@ static void update_progbar(struct osd_state *osd, struct osd_object *obj)
}
ass_draw_stop(d);
- add_osd_ass_event(obj->osd_track, d->text);
+ add_osd_ass_event(obj->osd_track, "progbar", d->text);
ass_draw_reset(d);
}
@@ -425,14 +429,21 @@ static void update_external(struct osd_state *osd, struct osd_object *obj)
bstr t = bstr0(obj->text);
if (!t.len)
return;
- create_ass_track(osd, obj, obj->external_res_x, obj->external_res_y, 1);
+ create_ass_track(osd, obj, obj->external_res_x, obj->external_res_y);
+
+ int resy = obj->osd_track->PlayResY;
+ mp_ass_set_style(get_style(osd, obj, "OSD"), resy, osd->opts->osd_style);
+
+ // Some scripts will reference this style name with \r tags.
+ const struct osd_style_opts *def = osd_style_conf.defaults;
+ mp_ass_set_style(get_style(osd, obj, "Default"), resy, def);
while (t.len) {
bstr line;
bstr_split_tok(t, "\n", &line, &t);
if (line.len) {
char *tmp = bstrdup0(NULL, line);
- add_osd_ass_event(obj->osd_track, tmp);
+ add_osd_ass_event(obj->osd_track, "OSD", tmp);
talloc_free(tmp);
}
}