From d23b620a89e88b0ec0d6a66c7f05c2e461579647 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 17 Nov 2012 19:58:57 +0100 Subject: m_option: add color option type This accepts HTML-style hex colors in the form #RRGGBB. It's also possible to provide an alpha component with #AARRGGBB. Each 2-digit group is a hex number, which gives the color value from 0-255 (e.g. There is existing code in subassconvert.c, which parses HTML-style color values in SRT subs. This is not used: it's probably better if option parsing is completely separate from code specific to certain subtitle formats, even if a little code is duplicated. --- core/m_option.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ core/m_option.h | 7 +++++++ 2 files changed, 54 insertions(+) (limited to 'core') diff --git a/core/m_option.c b/core/m_option.c index 58e93dfff9..90d8bb0359 100644 --- a/core/m_option.c +++ b/core/m_option.c @@ -1116,6 +1116,53 @@ const m_option_type_t m_option_type_subconfig_struct = { .parse = parse_subconf, }; +static int parse_color(const m_option_t *opt, struct bstr name, + struct bstr param, void *dst) +{ + if (param.len == 0) + return M_OPT_MISSING_PARAM; + + bstr val = param; + struct m_color color = {0}; + + if (bstr_eatstart0(&val, "#")) { + // #[AA]RRGGBB + if (val.len != 6 && val.len != 8) + goto error; + bool has_alpha = val.len == 8; + uint32_t c = bstrtoll(val, &val, 16); + if (val.len) + goto error; + color = (struct m_color) { + (c >> 16) & 0xFF, + (c >> 8) & 0xFF, + c & 0xFF, + has_alpha ? (c >> 24) & 0xFF : 0xFF, + }; + } else { + goto error; + } + + if (dst) + *((struct m_color *)dst) = color; + + return 1; + +error: + mp_msg(MSGT_CFGPARSER, MSGL_ERR, + "Option %.*s: invalid color: '%.*s'\n", + BSTR_P(name), BSTR_P(param)); + mp_msg(MSGT_CFGPARSER, MSGL_ERR, + "Valid colors must be in the form #RRRGGBB or #AARRGGBB (in hex)\n"); + return M_OPT_INVALID; +} + +const m_option_type_t m_option_type_color = { + .name = "Color", + .size = sizeof(struct m_color), + .parse = parse_color, +}; + #include "video/img_format.h" static int parse_imgfmt(const m_option_t *opt, struct bstr name, diff --git a/core/m_option.h b/core/m_option.h index ed9cc33f5f..20bcfba1c2 100644 --- a/core/m_option.h +++ b/core/m_option.h @@ -54,6 +54,7 @@ extern const m_option_type_t m_option_type_subconfig; extern const m_option_type_t m_option_type_subconfig_struct; extern const m_option_type_t m_option_type_imgfmt; extern const m_option_type_t m_option_type_afmt; +extern const m_option_type_t m_option_type_color; // Callback used by m_option_type_print_func options. typedef int (*m_opt_func_full_t)(const m_option_t *, const char *, const char *); @@ -71,6 +72,10 @@ struct m_rel_time { enum m_rel_time_type type; }; +struct m_color { + uint8_t r, g, b, a; +}; + // Extra definition needed for \ref m_option_type_obj_settings_list options. typedef struct { // Pointer to an array of pointer to some object type description struct. @@ -198,6 +203,7 @@ union m_option_value { m_obj_settings_t *obj_settings_list; double time; struct m_rel_time rel_time; + struct m_color color; }; //////////////////////////////////////////////////////////////////////////// @@ -511,6 +517,7 @@ static inline void m_option_free(const m_option_t *opt, void *dst) #define OPT_CHOICE_OR_INT_(optname, varname, flags, minval, maxval, choices, ...) OPT_GENERAL(optname, varname, (flags) | CONF_RANGE, .min = minval, .max = maxval, M_CHOICES(choices), __VA_ARGS__) #define OPT_TIME(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_time) #define OPT_REL_TIME(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_rel_time) +#define OPT_COLOR(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_color) #define OPT_TRACKCHOICE(name, var) OPT_CHOICE_OR_INT(name, var, 0, 0, 8190, ({"no", -2}, {"auto", -1})) -- cgit v1.2.3