From 08d372d657368711038f6c9c328cde18a6582123 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 31 Jul 2020 13:43:02 -0400 Subject: pango-color: Tweak semantics of _pango_parse_color_with_alpha Make it return 0xffff if alpha is not present (this will be more convenient when we use this function in GdkRGBA). Update all users. --- pango/pango-color.c | 5 +++-- pango/pango-markup.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pango/pango-color.c b/pango/pango-color.c index 3c37c3d0..f06756fe 100644 --- a/pango/pango-color.c +++ b/pango/pango-color.c @@ -210,7 +210,7 @@ hex (const char *spec, /* Like pango_color_parse, but allow strings of the form * '#rgba', '#rrggbbaa', '#rrrrggggbbbbaaaa', * if alpha is not NULL. If no alpha component is found - * in the string, *alpha is set to 0. + * in the string, *alpha is set to 0xffff. */ gboolean _pango_color_parse_with_alpha (PangoColor *color, @@ -220,7 +220,7 @@ _pango_color_parse_with_alpha (PangoColor *color, g_return_val_if_fail (spec != NULL, FALSE); if (alpha) - *alpha = 0; + *alpha = 0xffff; if (spec[0] == '#') { @@ -294,6 +294,7 @@ _pango_color_parse_with_alpha (PangoColor *color, } return TRUE; } + /** * pango_color_parse: * @color: (nullable): a #PangoColor structure in which to store the diff --git a/pango/pango-markup.c b/pango/pango-markup.c index a67e10fd..5375a8e0 100644 --- a/pango/pango-markup.c +++ b/pango/pango-markup.c @@ -1622,7 +1622,7 @@ span_parse_func (MarkupData *md G_GNUC_UNUSED, goto error; add_attribute (tag, pango_attr_foreground_new (color.red, color.green, color.blue)); - if (alpha != 0) + if (alpha != 0xffff) add_attribute (tag, pango_attr_foreground_alpha_new (alpha)); } @@ -1635,7 +1635,7 @@ span_parse_func (MarkupData *md G_GNUC_UNUSED, goto error; add_attribute (tag, pango_attr_background_new (color.red, color.green, color.blue)); - if (alpha != 0) + if (alpha != 0xffff) add_attribute (tag, pango_attr_background_alpha_new (alpha)); } -- cgit v1.2.1 From 09111969bd5aef2b424c515a1f41bb857ca436d6 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 31 Jul 2020 14:28:02 -0400 Subject: Export pango_parse_color_with_alpha This will be useful to make GdkRGBA support hex formats with alpha. --- docs/pango-sections.txt | 1 + pango/pango-attributes.h | 7 +++- pango/pango-color.c | 86 +++++++++++++++++++++++++++----------------- pango/pango-markup.c | 2 +- pango/pango-utils-internal.h | 4 --- 5 files changed, 61 insertions(+), 39 deletions(-) diff --git a/docs/pango-sections.txt b/docs/pango-sections.txt index 4648816b..04b6b442 100644 --- a/docs/pango-sections.txt +++ b/docs/pango-sections.txt @@ -423,6 +423,7 @@ PangoShowFlags pango_attr_show_new PangoColor pango_color_parse +pango_color_parse_with_alpha pango_color_copy pango_color_free pango_color_to_string diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h index 6f6622ab..dd38aee2 100644 --- a/pango/pango-attributes.h +++ b/pango/pango-attributes.h @@ -65,7 +65,12 @@ PANGO_AVAILABLE_IN_ALL void pango_color_free (PangoColor *color); PANGO_AVAILABLE_IN_ALL gboolean pango_color_parse (PangoColor *color, - const char *spec); + const char *spec); +PANGO_AVAILABLE_IN_1_46 +gboolean pango_color_parse_with_alpha + (PangoColor *color, + guint16 *alpha, + const char *spec); PANGO_AVAILABLE_IN_1_16 gchar *pango_color_to_string(const PangoColor *color); diff --git a/pango/pango-color.c b/pango/pango-color.c index f06756fe..9c044810 100644 --- a/pango/pango-color.c +++ b/pango/pango-color.c @@ -207,15 +207,35 @@ hex (const char *spec, } -/* Like pango_color_parse, but allow strings of the form +/** + * pango_color_parse_with_alpha: + * @color: (nullable): a #PangoColor structure in which to store the + * result, or %NULL + * @alpha: (nullable): return location for alpha, or %NULL + * @spec: a string specifying the new color + * + * Fill in the fields of a color from a string specification. The + * string can either one of a large set of standard names. (Taken + * from the CSS specification), or it can be a hexadecimal + * value in the + * form '#rgb' '#rrggbb' '#rrrgggbbb' or '#rrrrggggbbbb' where + * 'r', 'g' and 'b' are hex digits of the red, green, and blue + * components of the color, respectively. (White in the four + * forms is '#fff' '#ffffff' '#fffffffff' and '#ffffffffffff') + * + * Additionally, parse strings of the form * '#rgba', '#rrggbbaa', '#rrrrggggbbbbaaaa', - * if alpha is not NULL. If no alpha component is found - * in the string, *alpha is set to 0xffff. + * if @alpha is not %NULL, and set @alpha to the value specified + * by the hex digits for 'a'. If no alpha component is found + * in @spec, @alpha is set to 0xffff (for a solid color). + * + * Return value: %TRUE if parsing of the specifier succeeded, + * otherwise false. */ gboolean -_pango_color_parse_with_alpha (PangoColor *color, - guint16 *alpha, - const char *spec) +pango_color_parse_with_alpha (PangoColor *color, + guint16 *alpha, + const char *spec) { g_return_val_if_fail (spec != NULL, FALSE); @@ -248,49 +268,49 @@ _pango_color_parse_with_alpha (PangoColor *color, has_alpha = TRUE; break; default: - return FALSE; + return FALSE; } if (!hex (spec, len, &r) || - !hex (spec + len, len, &g) || - !hex (spec + len * 2, len, &b) || + !hex (spec + len, len, &g) || + !hex (spec + len * 2, len, &b) || (has_alpha && !hex (spec + len * 3, len, &a))) - return FALSE; + return FALSE; if (color) - { - int bits = len * 4; - r <<= 16 - bits; - g <<= 16 - bits; - b <<= 16 - bits; - while (bits < 16) - { - r |= (r >> bits); - g |= (g >> bits); - b |= (b >> bits); - bits *= 2; - } - color->red = r; - color->green = g; - color->blue = b; - } + { + int bits = len * 4; + r <<= 16 - bits; + g <<= 16 - bits; + b <<= 16 - bits; + while (bits < 16) + { + r |= (r >> bits); + g |= (g >> bits); + b |= (b >> bits); + bits *= 2; + } + color->red = r; + color->green = g; + color->blue = b; + } if (alpha && has_alpha) { - int bits = len * 4; + int bits = len * 4; a <<= 16 - bits; - while (bits < 16) - { + while (bits < 16) + { a |= (a >> bits); - bits *= 2; - } + bits *= 2; + } *alpha = a; } } else { if (!find_color (spec, color)) - return FALSE; + return FALSE; } return TRUE; } @@ -317,5 +337,5 @@ gboolean pango_color_parse (PangoColor *color, const char *spec) { - return _pango_color_parse_with_alpha (color, NULL, spec); + return pango_color_parse_with_alpha (color, NULL, spec); } diff --git a/pango/pango-markup.c b/pango/pango-markup.c index 5375a8e0..b74c1ad4 100644 --- a/pango/pango-markup.c +++ b/pango/pango-markup.c @@ -1199,7 +1199,7 @@ span_parse_color (const char *attr_name, int line_number, GError **error) { - if (!_pango_color_parse_with_alpha (color, alpha, attr_val)) + if (!pango_color_parse_with_alpha (color, alpha, attr_val)) { g_set_error (error, G_MARKUP_ERROR, diff --git a/pango/pango-utils-internal.h b/pango/pango-utils-internal.h index 56340215..0bc355e0 100644 --- a/pango/pango-utils-internal.h +++ b/pango/pango-utils-internal.h @@ -43,10 +43,6 @@ gboolean pango_parse_flags (GType type, char *_pango_trim_string (const char *str); -gboolean _pango_color_parse_with_alpha (PangoColor *color, - guint16 *alpha, - const char *spec); - G_END_DECLS -- cgit v1.2.1 From 77c8408675c6e8aaded386932aad66004004060a Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 31 Jul 2020 14:28:34 -0400 Subject: tests: Add tests for pango_parse_color_with_alpha --- tests/testcolor.c | 114 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 40 deletions(-) diff --git a/tests/testcolor.c b/tests/testcolor.c index 36f2dbf3..62bbe4bf 100644 --- a/tests/testcolor.c +++ b/tests/testcolor.c @@ -25,57 +25,92 @@ typedef struct _ColorSpec { const gchar *spec; gboolean valid; + int color_or_alpha; guint16 red; guint16 green; guint16 blue; + guint16 alpha; } ColorSpec; -static gboolean test_one_color (ColorSpec *spec) +#define COLOR 1 +#define ALPHA 2 +#define BOTH 3 + +static void +test_one_color (ColorSpec *spec) { PangoColor color; gboolean accepted; + guint16 alpha; - accepted = pango_color_parse (&color, spec->spec); + if (spec->color_or_alpha & COLOR) + { + accepted = pango_color_parse (&color, spec->spec); - if (accepted == spec->valid && - (!accepted || - (color.red == spec->red && - color.green == spec->green && - color.blue == spec->blue))) - return TRUE; - else - return FALSE; -} + if (!spec->valid) + { + g_assert_false (accepted); + } + else + { + g_assert_true (accepted); + g_assert_cmpuint (color.red, ==, spec->red); + g_assert_cmpuint (color.green, ==, spec->green); + g_assert_cmpuint (color.blue, ==, spec->blue); + } + } + if (spec->color_or_alpha & ALPHA) + { + accepted = pango_color_parse_with_alpha (&color, &alpha, spec->spec); + + if (!spec->valid) + { + g_assert_false (accepted); + } + else + { + g_assert_true (accepted); + g_assert_cmpuint (color.red, ==, spec->red); + g_assert_cmpuint (color.green, ==, spec->green); + g_assert_cmpuint (color.blue, ==, spec->blue); + g_assert_cmpuint (alpha, ==, spec->alpha); + } + } +} ColorSpec specs [] = { - { "#abc", 1, 0xaaaa, 0xbbbb, 0xcccc }, - { "#aabbcc", 1, 0xaaaa, 0xbbbb, 0xcccc }, - { "#aaabbbccc", 1, 0xaaaa, 0xbbbb, 0xcccc }, - { "#100100100", 1, 0x1001, 0x1001, 0x1001 }, - { "#aaaabbbbcccc", 1, 0xaaaa, 0xbbbb, 0xcccc }, - { "#fff", 1, 0xffff, 0xffff, 0xffff }, - { "#ffffff", 1, 0xffff, 0xffff, 0xffff }, - { "#fffffffff", 1, 0xffff, 0xffff, 0xffff }, - { "#ffffffffffff", 1, 0xffff, 0xffff, 0xffff }, - { "#000", 1, 0x0000, 0x0000, 0x0000 }, - { "#000000", 1, 0x0000, 0x0000, 0x0000 }, - { "#000000000", 1, 0x0000, 0x0000, 0x0000 }, - { "#000000000000", 1, 0x0000, 0x0000, 0x0000 }, - { "#AAAABBBBCCCC", 1, 0xaaaa, 0xbbbb, 0xcccc }, - { "#aa bb cc ", 0, 0, 0, 0 }, - { "#aa bb ccc", 0, 0, 0, 0 }, - { "#ab", 0, 0, 0, 0 }, - { "#aabb", 0, 0, 0, 0 }, - { "#aaabb", 0, 0, 0, 0 }, - { "aaabb", 0, 0, 0, 0 }, - { "", 0, 0, 0, 0 }, - { "#", 0, 0, 0, 0 }, - { "##fff", 0, 0, 0, 0 }, - { "#0000ff+", 0, 0, 0, 0 }, - { "#0000f+", 0, 0, 0, 0 }, - { "#0x00x10x2", 0, 0, 0, 0 }, - { NULL, 0, 0, 0, 0 } + { "#abc", 1, BOTH, 0xaaaa, 0xbbbb, 0xcccc, 0xffff }, + { "#aabbcc", 1, BOTH, 0xaaaa, 0xbbbb, 0xcccc, 0xffff }, + { "#aaabbbccc", 1, BOTH, 0xaaaa, 0xbbbb, 0xcccc, 0xffff }, + { "#100100100", 1, BOTH, 0x1001, 0x1001, 0x1001, 0xffff }, + { "#aaaabbbbcccc", 1, COLOR, 0xaaaa, 0xbbbb, 0xcccc, 0xffff }, + { "#fff", 1, BOTH, 0xffff, 0xffff, 0xffff, 0xffff }, + { "#ffffff", 1, BOTH, 0xffff, 0xffff, 0xffff, 0xffff }, + { "#fffffffff", 1, BOTH, 0xffff, 0xffff, 0xffff, 0xffff }, + { "#ffffffffffff", 1, COLOR, 0xffff, 0xffff, 0xffff, 0xffff }, + { "#000", 1, BOTH, 0x0000, 0x0000, 0x0000, 0xffff }, + { "#000000", 1, BOTH, 0x0000, 0x0000, 0x0000, 0xffff }, + { "#000000000", 1, BOTH, 0x0000, 0x0000, 0x0000, 0xffff }, + { "#000000000000", 1, COLOR, 0x0000, 0x0000, 0x0000, 0xffff }, + { "#AAAABBBBCCCC", 1, COLOR, 0xaaaa, 0xbbbb, 0xcccc, 0xffff }, + { "#aa bb cc ", 0, BOTH, 0, 0, 0, 0 }, + { "#aa bb ccc", 0, BOTH, 0, 0, 0, 0 }, + { "#ab", 0, BOTH, 0, 0, 0, 0 }, + { "#aabb", 0, COLOR, 0, 0, 0, 0 }, + { "#aaabb", 0, BOTH, 0, 0, 0, 0 }, + { "aaabb", 0, BOTH, 0, 0, 0, 0 }, + { "", 0, BOTH, 0, 0, 0, 0 }, + { "#", 0, BOTH, 0, 0, 0, 0 }, + { "##fff", 0, BOTH, 0, 0, 0, 0 }, + { "#0000ff+", 0, BOTH, 0, 0, 0, 0 }, + { "#0000f+", 0, BOTH, 0, 0, 0, 0 }, + { "#0x00x10x2", 0, BOTH, 0, 0, 0, 0 }, + { "#abcd", 1, ALPHA, 0xaaaa, 0xbbbb, 0xcccc, 0xdddd }, + { "#aabbccdd", 1, ALPHA, 0xaaaa, 0xbbbb, 0xcccc, 0xdddd }, + { "#aaaabbbbccccdddd", + 1, ALPHA, 0xaaaa, 0xbbbb, 0xcccc, 0xdddd }, + { NULL, 0, BOTH, 0, 0, 0, 0 } }; static void @@ -84,8 +119,7 @@ test_color (void) ColorSpec *spec; for (spec = specs; spec->spec; spec++) - g_assert (test_one_color (spec)); - + test_one_color (spec); } int -- cgit v1.2.1