summaryrefslogtreecommitdiffstats
path: root/sub
diff options
context:
space:
mode:
Diffstat (limited to 'sub')
-rw-r--r--sub/ass_mp.c76
-rw-r--r--sub/ass_mp.h14
-rw-r--r--sub/osd_libass.c46
-rw-r--r--sub/sub.c45
-rw-r--r--sub/sub.h23
5 files changed, 135 insertions, 69 deletions
diff --git a/sub/ass_mp.c b/sub/ass_mp.c
index 503bd23188..079afbe17e 100644
--- a/sub/ass_mp.c
+++ b/sub/ass_mp.c
@@ -38,13 +38,46 @@
#include "stream/stream.h"
#include "core/options.h"
+void mp_ass_set_style(ASS_Style *style, struct osd_style_opts *opts)
+{
+ if (opts->font) {
+ free(style->FontName);
+ style->FontName = strdup(opts->font);
+ style->treat_fontname_as_pattern = 1;
+ }
+
+ // libass_font_size = FontSize * (window_height / MP_ASS_FONT_PLAYRESY)
+ // scale translates parameters from PlayResY=720 to MP_ASS_FONT_PLAYRESY
+ double scale = MP_ASS_FONT_PLAYRESY / 720.0;
+
+ style->FontSize = opts->font_size * scale;
+ style->PrimaryColour = MP_ASS_COLOR(opts->color);
+ style->SecondaryColour = style->PrimaryColour;
+ if (opts->back_color.a) {
+ style->OutlineColour = MP_ASS_COLOR(opts->back_color);
+ style->BorderStyle = 3; // opaque box
+ } else {
+ style->OutlineColour = MP_ASS_COLOR(opts->border_color);
+ style->BorderStyle = 1; // outline
+ }
+ style->BackColour = MP_ASS_COLOR(opts->shadow_color);
+ style->Outline = opts->border_size * scale;
+ style->Shadow = opts->shadow_offset * scale;
+ style->Spacing = opts->spacing * scale;
+ style->MarginL = opts->margin_x * scale;
+ style->MarginR = style->MarginL;
+ style->MarginV = opts->margin_y * scale;
+ style->ScaleX = 1.;
+ style->ScaleY = 1.;
+}
+
ASS_Track *mp_ass_default_track(ASS_Library *library, struct MPOpts *opts)
{
ASS_Track *track = ass_new_track(library);
track->track_type = TRACK_TYPE_ASS;
track->Timer = 100.;
- track->PlayResY = 288;
+ track->PlayResY = MP_ASS_FONT_PLAYRESY;
track->WrapStyle = 0;
if (opts->ass_styles_file && opts->ass_style_override)
@@ -56,32 +89,8 @@ ASS_Track *mp_ass_default_track(ASS_Library *library, struct MPOpts *opts)
track->default_style = sid;
ASS_Style *style = track->styles + sid;
style->Name = strdup("Default");
- style->FontName = sub_font_name ? strdup(sub_font_name)
- : font_name ? strdup(font_name) : strdup("Sans");
- style->treat_fontname_as_pattern = 1;
-
- double fs = track->PlayResY * text_font_scale_factor / 100.;
-
- uint32_t c1 = 0xFFFFFF00;
- uint32_t c2 = 0x00000000;
- if (opts->ass_color)
- c1 = strtoll(opts->ass_color, NULL, 16);
- if (opts->ass_border_color)
- c2 = strtoll(opts->ass_border_color, NULL, 16);
-
- style->FontSize = fs;
- style->PrimaryColour = c1;
- style->SecondaryColour = c1;
- style->OutlineColour = c2;
- style->BackColour = 0x00000000;
- style->BorderStyle = 1;
style->Alignment = 2;
- style->Outline = fs / 16;
- style->MarginL = 10;
- style->MarginR = 10;
- style->MarginV = 5;
- style->ScaleX = 1.;
- style->ScaleY = 1.;
+ mp_ass_set_style(style, opts->osd_style);
}
if (opts->ass_style_override)
@@ -231,7 +240,7 @@ void mp_ass_configure(ASS_Renderer *priv, struct MPOpts *opts,
set_use_margins = opts->ass_use_margins;
set_sub_pos = 100 - sub_pos;
set_line_spacing = opts->ass_line_spacing;
- set_font_scale = opts->ass_font_scale;
+ set_font_scale = opts->sub_scale;
set_hinting = opts->ass_hinting & 3; // +4 was for no hinting if scaled
}
@@ -244,27 +253,20 @@ void mp_ass_configure(ASS_Renderer *priv, struct MPOpts *opts,
ass_set_line_spacing(priv, set_line_spacing);
}
-void mp_ass_configure_fonts(ASS_Renderer *priv)
+void mp_ass_configure_fonts(ASS_Renderer *priv, struct osd_style_opts *opts)
{
- char *dir, *path, *family;
+ char *dir, *path;
dir = get_path("fonts");
path = get_path("subfont.ttf");
if (!mp_path_exists(path)) {
free(path);
path = NULL;
}
- if (sub_font_name)
- family = strdup(sub_font_name);
- else if (font_name)
- family = strdup(font_name);
- else
- family = 0;
- ass_set_fonts(priv, path, family, 1, NULL, 1);
+ ass_set_fonts(priv, path, opts->font, 1, NULL, 1);
free(dir);
free(path);
- free(family);
}
void mp_ass_render_frame(ASS_Renderer *renderer, ASS_Track *track, double time,
diff --git a/sub/ass_mp.h b/sub/ass_mp.h
index c3dbc5e28f..e0a5917fa4 100644
--- a/sub/ass_mp.h
+++ b/sub/ass_mp.h
@@ -27,12 +27,24 @@
#include "config.h"
#include "subreader.h"
+// font sizes and explicit tags in subassconvert.c assume this size (?)
+#define MP_ASS_FONT_PLAYRESY 288
+
+#define MP_ASS_RGBA(r, g, b, a) \
+ (((r) << 24U) | ((g) << 16) | ((b) << 8) | (0xFF - (a)))
+
+// m_color argument
+#define MP_ASS_COLOR(c) MP_ASS_RGBA((c).r, (c).g, (c).b, (c).a)
+
#ifdef CONFIG_ASS
#include <ass/ass.h>
#include <ass/ass_types.h>
struct MPOpts;
struct mp_osd_res;
+struct osd_style_opts;
+
+void mp_ass_set_style(ASS_Style *style, struct osd_style_opts *opts);
ASS_Track *mp_ass_default_track(ASS_Library *library, struct MPOpts *opts);
ASS_Track *mp_ass_read_subdata(ASS_Library *library, struct MPOpts *opts,
@@ -43,7 +55,7 @@ ASS_Track *mp_ass_read_stream(ASS_Library *library, const char *fname,
struct MPOpts;
void mp_ass_configure(ASS_Renderer *priv, struct MPOpts *opts,
struct mp_osd_res *dim);
-void mp_ass_configure_fonts(ASS_Renderer *priv);
+void mp_ass_configure_fonts(ASS_Renderer *priv, struct osd_style_opts *opts);
ASS_Library *mp_ass_init(struct MPOpts *opts);
struct sub_bitmap;
diff --git a/sub/osd_libass.c b/sub/osd_libass.c
index 8e7d766024..749b46d6ae 100644
--- a/sub/osd_libass.c
+++ b/sub/osd_libass.c
@@ -46,7 +46,7 @@ void osd_init_backend(struct osd_state *osd)
sizeof(osd_font_pfb) - 1);
osd->osd_render = ass_renderer_init(osd->osd_ass_library);
- mp_ass_configure_fonts(osd->osd_render);
+ mp_ass_configure_fonts(osd->osd_render, osd->opts->osd_style);
ass_set_aspect_ratio(osd->osd_render, 1.0, 1.0);
}
@@ -59,30 +59,27 @@ void osd_destroy_backend(struct osd_state *osd)
osd->osd_ass_library = NULL;
}
-static void update_font_style(ASS_Track *track, ASS_Style *style, double factor)
-{
- // Set to neutral base direction, as opposed to VSFilter LTR default
- style->Encoding = -1;
-
- // duplicated from ass_mp.c
- style->FontSize = track->PlayResY * factor / 100.;
- style->Outline = style->FontSize / 16;
-}
-
-
static ASS_Track *create_osd_ass_track(struct osd_state *osd)
{
- ASS_Track *track = mp_ass_default_track(osd->osd_ass_library, osd->opts);
- ASS_Style *style = track->styles + track->default_style;
+ ASS_Track *track = ass_new_track(osd->osd_ass_library);
+ track->track_type = TRACK_TYPE_ASS;
+ track->Timer = 100.;
+ track->PlayResY = MP_ASS_FONT_PLAYRESY;
track->PlayResX = track->PlayResY * 1.33333;
-
- update_font_style(track, style, text_font_scale_factor);
-
- style->Alignment = 5;
-
- free(style->FontName);
- style->FontName = strdup(font_name ? font_name : "Sans");
+ track->WrapStyle = 1; // end-of-line wrapping instead of smart wrapping
+
+ if (track->n_styles == 0) {
+ track->Kerning = true;
+ int sid = ass_alloc_style(track);
+ track->default_style = sid;
+ ASS_Style *style = track->styles + sid;
+ style->Alignment = 5; // top-title, left
+ style->Name = strdup("OSD");
+ mp_ass_set_style(style, osd->opts->osd_style);
+ // Set to neutral base direction, as opposed to VSFilter LTR default
+ style->Encoding = -1;
+ }
return track;
}
@@ -172,7 +169,7 @@ static void update_progbar(struct osd_state *osd, struct osd_object *obj)
ASS_Style *style = obj->osd_track->styles + obj->osd_track->default_style;
- style->Alignment = 10;
+ style->Alignment = 10; // all centered
style->MarginL = style->MarginR = style->MarginV = 0;
// We need a fixed font size with respect to the OSD width.
@@ -226,9 +223,12 @@ static void update_sub(struct osd_state *osd, struct osd_object *obj)
if (!obj->osd_track)
obj->osd_track = mp_ass_default_track(osd->osd_ass_library, osd->opts);
+ struct osd_style_opts font = *opts->osd_style;
+ font.font_size *= opts->sub_scale;
+
ASS_Style *style = obj->osd_track->styles + obj->osd_track->default_style;
+ mp_ass_set_style(style, &font);
- update_font_style(obj->osd_track, style, text_font_scale_factor);
#if LIBASS_VERSION >= 0x01010000
ass_set_line_position(osd->osd_render, 100 - sub_pos);
#endif
diff --git a/sub/sub.c b/sub/sub.c
index eafa2cc831..8fde350d4d 100644
--- a/sub/sub.c
+++ b/sub/sub.c
@@ -63,18 +63,47 @@ int sub_pos=100;
int sub_visibility=1;
subtitle* vo_sub=NULL;
-float text_font_scale_factor = 6;
-char *font_name = NULL;
-char *sub_font_name = NULL;
float sub_delay = 0;
float sub_fps = 0;
void *vo_spudec=NULL;
void *vo_vobsub=NULL;
-static struct osd_state *global_osd;
+static const const struct osd_style_opts osd_style_opts_def = {
+ .font = "Sans",
+ .font_size = 45,
+ .color = {255, 255, 255, 255},
+ .border_color = {0, 0, 0, 255},
+ .shadow_color = {240, 240, 240, 128},
+ .border_size = 2.5,
+ .shadow_offset = 0,
+ .margin_x = 25,
+ .margin_y = 10,
+};
+#undef OPT_BASE_STRUCT
+#define OPT_BASE_STRUCT struct osd_style_opts
+const struct m_sub_options osd_style_conf = {
+ .opts = (m_option_t[]) {
+ OPT_STRING("font", font, 0),
+ OPT_FLOATRANGE("font-size", font_size, 0, 1, 9000),
+ OPT_COLOR("color", color, 0),
+ OPT_COLOR("border-color", border_color, 0),
+ OPT_COLOR("shadow-color", shadow_color, 0),
+ OPT_COLOR("back-color", back_color, 0),
+ OPT_FLOATRANGE("border-size", border_size, 0, 0, 10),
+ OPT_FLOATRANGE("shadow-offset", shadow_offset, 0, 0, 10),
+ OPT_FLOATRANGE("spacing", spacing, 0, -10, 10),
+ OPT_INTRANGE("margin-x", margin_x, 0, 0, 300),
+ OPT_INTRANGE("margin-y", margin_y, 0, 0, 600),
+ {0}
+ },
+ .size = sizeof(struct osd_style_opts),
+ .defaults = &osd_style_opts_def,
+};
+
+static struct osd_state *global_osd;
static bool osd_res_equals(struct mp_osd_res a, struct mp_osd_res b)
{
@@ -265,6 +294,14 @@ void vo_osd_changed(int new_value)
osd->want_redraw = true;
}
+void osd_subs_changed(struct osd_state *osd)
+{
+ for (int n = 0; n < MAX_OSD_PARTS; n++) {
+ if (osd->objs[n]->is_sub)
+ vo_osd_changed(n);
+ }
+}
+
bool sub_bitmaps_bb(struct sub_bitmaps *imgs, struct mp_rect *out_bb)
{
struct mp_rect bb = {INT_MAX, INT_MAX, INT_MIN, INT_MIN};
diff --git a/sub/sub.h b/sub/sub.h
index cdc094d290..f894682596 100644
--- a/sub/sub.h
+++ b/sub/sub.h
@@ -23,6 +23,8 @@
#include <stdbool.h>
#include <stdint.h>
+#include "core/m_option.h"
+
// NOTE: VOs must support at least SUBBITMAP_LIBASS and SUBBITMAP_RGBA.
enum sub_bitmap_format {
SUBBITMAP_EMPTY = 0,// no bitmaps; always has num_parts==0
@@ -172,6 +174,22 @@ enum mp_osd_font_codepoints {
OSD_PB_1 = 0x13,
};
+struct osd_style_opts {
+ char *font;
+ float font_size;
+ struct m_color color;
+ struct m_color border_color;
+ struct m_color shadow_color;
+ struct m_color back_color;
+ float border_size;
+ float shadow_offset;
+ float spacing;
+ int margin_x;
+ int margin_y;
+};
+
+extern const struct m_sub_options osd_style_conf;
+
/* now in textform */
extern char * const sub_osd_names[];
extern char * const sub_osd_names_short[];
@@ -181,10 +199,6 @@ extern int sub_utf8;
extern char *sub_cp;
extern int sub_pos;
-extern float text_font_scale_factor;
-
-extern char *font_name;
-extern char *sub_font_name;
extern float sub_delay;
extern float sub_fps;
@@ -192,6 +206,7 @@ extern float sub_fps;
struct osd_state *osd_create(struct MPOpts *opts, struct ass_library *asslib);
void osd_set_text(struct osd_state *osd, const char *text);
void vo_osd_changed(int new_value);
+void osd_subs_changed(struct osd_state *osd);
void osd_free(struct osd_state *osd);
enum mp_osd_draw_flags {