diff options
Diffstat (limited to 'sub')
-rw-r--r-- | sub/ass_mp.c | 3 | ||||
-rw-r--r-- | sub/osd_libass.c | 107 |
2 files changed, 62 insertions, 48 deletions
diff --git a/sub/ass_mp.c b/sub/ass_mp.c index a3a7c73cd3..df32d17ce6 100644 --- a/sub/ass_mp.c +++ b/sub/ass_mp.c @@ -40,6 +40,9 @@ void mp_ass_set_style(ASS_Style *style, double res_y, const struct osd_style_opts *opts) { + if (!style) + return; + if (opts->font) { if (!style->FontName || strcmp(style->FontName, opts->font) != 0) { free(style->FontName); 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); } } |