From 194f4668b32a86993d969bccfed59186c08f63dd Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 14 Aug 2015 22:51:46 -0400 Subject: Allow rgba colors in markup For foreground and background colors, allow #rrggbbaa to specify a color with alpha. This will be returned as two attributes, for color and alpha. underline_color and strikethrough_color are still limited to #rrggbb, with no alpha component. --- docs/pango_markup.sgml | 12 ++++--- pango/pango-color.c | 98 ++++++++++++++++++++++++++++++++++++-------------- pango/pango-markup.c | 22 +++++++++--- 3 files changed, 97 insertions(+), 35 deletions(-) diff --git a/docs/pango_markup.sgml b/docs/pango_markup.sgml index 8fa38c42..c2ba377c 100644 --- a/docs/pango_markup.sgml +++ b/docs/pango_markup.sgml @@ -136,8 +136,10 @@ syntax as accepted by CSS. E.g: font_features='dlig=1, -kern, afrc on'< fgcolor color -An RGB color specification such as '#00FF00' or a color name such as -'red' +An RGB color specification such as '#00FF00' or a color name such as +'red'. +Since 1.38, an RGBA color specification such as '#00FF007F' will +be interpreted as specifying both a foreground color and foreground alpha. @@ -145,8 +147,10 @@ An RGB color specification such as '#00FF00' or a color name such as background bgcolor -An RGB color specification such as '#00FF00' or a color name such as -'red' +An RGB color specification such as '#00FF00' or a color name such as +'red'. +Since 1.38, an RGBA color specification such as '#00FF007F' will +be interpreted as specifying both a background color and background alpha. diff --git a/pango/pango-color.c b/pango/pango-color.c index 47a98236..2f344765 100644 --- a/pango/pango-color.c +++ b/pango/pango-color.c @@ -205,45 +205,55 @@ hex (const char *spec, return TRUE; } -/** - * pango_color_parse: - * @color: (nullable): a #PangoColor structure in which to store the - * result, 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') - * - * Return value: %TRUE if parsing of the specifier succeeded, - * otherwise false. - **/ + +/* 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. + */ gboolean -pango_color_parse (PangoColor *color, - const char *spec) +_pango_color_parse_with_alpha (PangoColor *color, + guint16 *alpha, + const char *spec) { g_return_val_if_fail (spec != NULL, FALSE); + if (alpha) + *alpha = 0; + if (spec[0] == '#') { size_t len; - unsigned int r, g, b; + unsigned int r, g, b, a; + gboolean has_alpha; spec++; len = strlen (spec); - if (len % 3 || len < 3 || len > 12) - return FALSE; - - len /= 3; + switch (len) + { + case 3: + case 6: + case 9: + case 12: + len /= 3; + has_alpha = FALSE; + break; + case 4: + case 8: + case 16: + if (!alpha) + return FALSE; + len /= 4; + has_alpha = TRUE; + break; + default: + return FALSE; + } if (!hex (spec, len, &r) || !hex (spec + len, len, &g) || - !hex (spec + len * 2, len, &b)) + !hex (spec + len * 2, len, &b) || + (has_alpha && !hex (spec + len * 3, len, &a))) return FALSE; if (color) @@ -263,6 +273,18 @@ pango_color_parse (PangoColor *color, color->green = g; color->blue = b; } + + if (alpha && has_alpha) + { + int bits = len * 4; + a <<= 16 - bits; + while (bits < 16) + { + a |= (a >> bits); + bits *= 2; + } + *alpha = a; + } } else { @@ -271,3 +293,27 @@ pango_color_parse (PangoColor *color, } return TRUE; } +/** + * pango_color_parse: + * @color: (nullable): a #PangoColor structure in which to store the + * result, 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') + * + * Return value: %TRUE if parsing of the specifier succeeded, + * otherwise false. + **/ +gboolean +pango_color_parse (PangoColor *color, + const char *spec) +{ + return _pango_color_parse_with_alpha (color, NULL, spec); +} diff --git a/pango/pango-markup.c b/pango/pango-markup.c index 7e2b7dd1..b4fe881e 100644 --- a/pango/pango-markup.c +++ b/pango/pango-markup.c @@ -999,14 +999,20 @@ span_parse_boolean (const char *attr_name, return TRUE; } +extern gboolean +_pango_color_parse_with_alpha (PangoColor *color, + guint16 *alpha, + const char *spec); + static gboolean span_parse_color (const char *attr_name, const char *attr_val, PangoColor *color, + guint16 *alpha, int line_number, GError **error) { - if (!pango_color_parse (color, attr_val)) + if (!_pango_color_parse_with_alpha (color, alpha, attr_val)) { g_set_error (error, G_MARKUP_ERROR, @@ -1383,21 +1389,27 @@ span_parse_func (MarkupData *md G_GNUC_UNUSED, if (G_UNLIKELY (foreground)) { PangoColor color; + guint16 alpha; - if (!span_parse_color ("foreground", foreground, &color, line_number, error)) + if (!span_parse_color ("foreground", foreground, &color, &alpha, line_number, error)) goto error; add_attribute (tag, pango_attr_foreground_new (color.red, color.green, color.blue)); + if (alpha != 0) + add_attribute (tag, pango_attr_foreground_alpha_new (alpha)); } if (G_UNLIKELY (background)) { PangoColor color; + guint16 alpha; - if (!span_parse_color ("background", background, &color, line_number, error)) + if (!span_parse_color ("background", background, &color, &alpha, line_number, error)) goto error; add_attribute (tag, pango_attr_background_new (color.red, color.green, color.blue)); + if (alpha != 0) + add_attribute (tag, pango_attr_background_alpha_new (alpha)); } if (G_UNLIKELY (alpha)) @@ -1434,7 +1446,7 @@ span_parse_func (MarkupData *md G_GNUC_UNUSED, { PangoColor color; - if (!span_parse_color ("underline_color", underline_color, &color, line_number, error)) + if (!span_parse_color ("underline_color", underline_color, &color, NULL, line_number, error)) goto error; add_attribute (tag, pango_attr_underline_color_new (color.red, color.green, color.blue)); @@ -1474,7 +1486,7 @@ span_parse_func (MarkupData *md G_GNUC_UNUSED, { PangoColor color; - if (!span_parse_color ("strikethrough_color", strikethrough_color, &color, line_number, error)) + if (!span_parse_color ("strikethrough_color", strikethrough_color, &color, NULL, line_number, error)) goto error; add_attribute (tag, pango_attr_strikethrough_color_new (color.red, color.green, color.blue)); -- cgit v1.2.1