From 36f6e6b82677fb19374995ffb88cf76975ef2b5a Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 31 Jan 2014 00:41:54 +0100 Subject: options: alternative way to specify color options Try to make it more intuitive by not requiring hex values. The new way uses float values in the range 0.0-1.0, separated by '/' (':' was suggested, but that wouldn't allow color options in sub-options). Example: --osd-color=1.0/0.0/0.0/0.75 Using the range 0.0-1.0 has the advantage that it could be easily extended to colors beyond 8 bit. Details see manpage. Suggestions for alternative syntax or value ranges are welcome, but be quick with it. --- DOCS/man/en/options.rst | 32 ++++++++++++++++++++++---------- options/m_option.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 12 deletions(-) diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst index 20e8ea4a9d..0a66f325c5 100644 --- a/DOCS/man/en/options.rst +++ b/DOCS/man/en/options.rst @@ -1485,13 +1485,13 @@ OPTIONS ``--osd-bar-h=<0.1-50>`` Height of the OSD bar, in percentage of the screen height (default: 3.125). -``--osd-back-color=<#RRGGBB>``, ``--sub-text-back-color=<#RRGGBB>`` +``--osd-back-color=``, ``--sub-text-back-color=`` See ``--osd-color``. Color used for OSD/sub text background. ``--osd-blur=<0..20.0>``, ``--sub-text-blur=<0..20.0>`` Gaussian blur factor. 0 means no blur applied (default). -``--osd-border-color=<#RRGGBB>``, ``--sub-text-border-color=<#RRGGBB>`` +``--osd-border-color=``, ``--sub-text-border-color=`` See ``--osd-color``. Color used for the OSD/sub font border. .. note:: @@ -1506,16 +1506,28 @@ OPTIONS Default: 2.5. -``--osd-color=<#RRGGBB|#AARRGGBB>``, ``--sub-text-color=<#RRGGBB|#AARRGGBB>`` +``--osd-color=``, ``--sub-text-color=`` Specify the color used for OSD/unstyled text subtitles. - The color is specified as a RGB hex triplet, and each 2-digit group - expresses a color value in the range 0 (``00``) to 255 (``FF``). - For example, ``#FF0000`` is red. This is similar to web colors. + The color is specified in the form ``r/g/b``, where each color component + is specified as number in the range 0.0 to 1.0. It's also possible to + specify the transparency by using ``r/g/b/a``, where the alpha value 0 + means fully transparent, and 1.0 means opaque. If the alpha component is + not given, the color is 100% opaque. - You can specify transparency by specifying an alpha value in the form - ``#AARRGGBB``. ``00`` is fully transparent, while ``FF`` is opaque (opaque - is default with the shorter color specification). + Passing a single number to the option sets the OSD to gray, and the form + ``gray/a`` lets you specify alpha additionally. + + .. admonition:: Examples + + - ``--osd-color=1.0/0.0/0.0`` set OSD to opaque red + - ``--osd-color=1.0/0.0/0.0/0.75`` set OSD to opaque red with 75% alpha + - ``--osd-color=0.5/0.75`` set OSD to 50% gray with 75% alpha + + Alternatively, the color can be specified as a RGB hex triplet in the form + ``#RRGGBB``, where each 2-digit group expresses a color value in the + range 0 (``00``) to 255 (``FF``). For example, ``#FF0000`` is red. + This is similar to web colors. .. admonition:: Examples @@ -1587,7 +1599,7 @@ OPTIONS are always in actual pixels. The effect is that changing the window size won't change the OSD font size. -``--osd-shadow-color=<#RRGGBB>, --sub-text-shadow-color=<#RRGGBB>`` +``--osd-shadow-color=, --sub-text-shadow-color=`` See ``--osd-color``. Color used for OSD/sub text shadow. ``--osd-shadow-offset=, --sub-text-shadow-offset=`` diff --git a/options/m_option.c b/options/m_option.c index 339449b9b6..e0ab4ed6c8 100644 --- a/options/m_option.c +++ b/options/m_option.c @@ -1410,6 +1410,28 @@ const m_option_type_t m_option_type_msglevels = { #undef VAL +// Split the string on the given split character. +// out_arr is at least max entries long. +// Return number of out_arr entries filled. +static int split_char(bstr str, unsigned char split, int max, bstr *out_arr) +{ + if (max < 1) + return 0; + + int count = 0; + while (1) { + int next = bstrchr(str, split); + if (next >= 0 && max - count > 1) { + out_arr[count++] = bstr_splice(str, 0, next); + str = bstr_cut(str, next + 1); + } else { + out_arr[count++] = str; + break; + } + } + return count; +} + static int parse_color(struct mp_log *log, const m_option_t *opt, struct bstr name, struct bstr param, void *dst) { @@ -1434,7 +1456,24 @@ static int parse_color(struct mp_log *log, const m_option_t *opt, has_alpha ? (c >> 24) & 0xFF : 0xFF, }; } else { - goto error; + bstr comp_str[5]; + int num = split_char(param, '/', 5, comp_str); + if (num < 1 || num > 4) + goto error; + double comp[4] = {0, 0, 0, 1}; + for (int n = 0; n < num; n++) { + bstr rest; + double d = bstrtod(comp_str[n], &rest); + if (rest.len || !comp_str[n].len || d < 0 || d > 1 || !isnormal(d)) + goto error; + comp[n] = d; + } + if (num == 2) + comp[3] = comp[1]; + if (num < 3) + comp[2] = comp[1] = comp[0]; + color = (struct m_color) { comp[0] * 0xFF, comp[1] * 0xFF, + comp[2] * 0xFF, comp[3] * 0xFF }; } if (dst) @@ -1445,7 +1484,9 @@ static int parse_color(struct mp_log *log, const m_option_t *opt, error: mp_err(log, "Option %.*s: invalid color: '%.*s'\n", BSTR_P(name), BSTR_P(param)); - mp_err(log, "Valid colors must be in the form #RRRGGBB or #AARRGGBB (in hex)\n"); + mp_err(log, "Valid colors must be in the form #RRGGBB or #AARRGGBB (in hex)\n" + "Or in the form 'r/g/b/a', where each component is a value in the\n" + "range 0.0-1.0. (Also allowed: 'gray', 'gray/a', 'r/g/b'.\n"); return M_OPT_INVALID; } -- cgit v1.2.3