diff options
Diffstat (limited to 'sub/osd_libass.c')
-rw-r--r-- | sub/osd_libass.c | 137 |
1 files changed, 65 insertions, 72 deletions
diff --git a/sub/osd_libass.c b/sub/osd_libass.c index e9225a891a..6bb125723b 100644 --- a/sub/osd_libass.c +++ b/sub/osd_libass.c @@ -107,38 +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 < 2) { - int sid = ass_alloc_style(track); - track->default_style = sid; - ASS_Style *style = track->styles + sid; - style->Name = strdup("OSD"); - // Set to neutral base direction, as opposed to VSFilter LTR default - style->Encoding = -1; - - sid = ass_alloc_style(track); - assert(sid == track->default_style + 1); - style = track->styles + sid; - style->Name = strdup("Default"); - style->Encoding = -1; - } - - ASS_Style *s_osd = track->styles + track->default_style; - mp_ass_set_style(s_osd, track->PlayResY, osd->opts->osd_style); + obj->osd_track = track; +} - 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); +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; +} - 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) @@ -189,19 +197,20 @@ static void mangle_ass(bstr *dst, const char *in) } } -static void 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); - add_osd_ass_event(track, buf.start); + ASS_Event *e = add_osd_ass_event(track, style, buf.start); talloc_free(buf.start); + return e; } -static void update_osd(struct osd_state *osd, struct osd_object *obj) +static void update_osd_text(struct osd_state *osd, struct osd_object *obj) { struct MPOpts *opts = osd->opts; - clear_obj(obj); if (!obj->text[0]) return; @@ -215,10 +224,8 @@ static void update_osd(struct osd_state *osd, struct osd_object *obj) if (!opts->osd_scale_by_window) playresy *= 720.0 / obj->vo_res.h; - ASS_Style *style = obj->osd_track->styles + obj->osd_track->default_style; - mp_ass_set_style(style, playresy, &font); - - add_osd_ass_event_escaped(obj->osd_track, obj->text); + 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 @@ -303,7 +310,14 @@ static void get_osd_bar_box(struct osd_state *osd, struct osd_object *obj, 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); @@ -327,8 +341,6 @@ static void get_osd_bar_box(struct osd_state *osd, struct osd_object *obj, static void update_progbar(struct osd_state *osd, struct osd_object *obj) { - clear_obj(obj); - if (obj->progbar_state.type < 0) return; @@ -350,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 }; @@ -360,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 @@ -370,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); @@ -399,10 +411,17 @@ 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); } +static void update_osd(struct osd_state *osd, struct osd_object *obj) +{ + clear_obj(obj); + update_osd_text(osd, obj); + update_progbar(osd, obj); +} + static void update_external(struct osd_state *osd, struct osd_object *obj) { clear_obj(obj); @@ -412,56 +431,30 @@ static void update_external(struct osd_state *osd, struct osd_object *obj) return; 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); } } } -static void update_sub(struct osd_state *osd, struct osd_object *obj) -{ - struct MPOpts *opts = osd->opts; - - clear_obj(obj); - - if (!obj->text || !obj->text[0] || obj->sub_state.render_bitmap_subs) - return; - - create_ass_renderer(osd, obj); - if (!obj->osd_track) - obj->osd_track = mp_ass_default_track(obj->osd_ass_library, osd->opts); - - struct osd_style_opts font = *opts->sub_text_style; - font.font_size *= opts->sub_scale; - - ASS_Style *style = obj->osd_track->styles + obj->osd_track->default_style; - mp_ass_set_style(style, obj->osd_track->PlayResY, &font); - if (obj->type == OSDTYPE_SUB2) - style->Alignment = 6; - - ass_set_line_position(obj->osd_render, 100 - opts->sub_pos); - - add_osd_ass_event_escaped(obj->osd_track, obj->text); -} - static void update_object(struct osd_state *osd, struct osd_object *obj) { switch (obj->type) { case OSDTYPE_OSD: update_osd(osd, obj); break; - case OSDTYPE_SUB: - case OSDTYPE_SUB2: - update_sub(osd, obj); - break; - case OSDTYPE_PROGBAR: - update_progbar(osd, obj); - break; case OSDTYPE_EXTERNAL: update_external(osd, obj); break; |