summaryrefslogtreecommitdiffstats
path: root/sub
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-11-29 13:50:51 +0100
committerwm4 <wm4@nowhere>2015-11-29 17:55:02 +0100
commit2b990ac8105f500aafc43b617eb35d474f1c5107 (patch)
tree42e38f0c06ef7a3c64efd7d1dc5a7da43c7ca9d4 /sub
parent005f03d99fe457abf37a3171bfac15240851d72a (diff)
downloadmpv-2b990ac8105f500aafc43b617eb35d474f1c5107.tar.bz2
mpv-2b990ac8105f500aafc43b617eb35d474f1c5107.tar.xz
osd: fix and cleanup font style management
Commit 2b07d3eb merged progbar and OSD text renderer into one ASS_Track, but it confused the styles. Specifically, if both progbar and OSD are visible, the create_ass_track() call made by the progbar code will reset the style adjusted by the OSD text code. Change create_ass_track() not to add any styles. Instead let the caller manage the styles. They are now referenced by name, and lazily added if they don't exist yet. This is also much cleaner.
Diffstat (limited to 'sub')
-rw-r--r--sub/ass_mp.c3
-rw-r--r--sub/osd_libass.c107
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);
}
}