[pango: 5/6] Allow rgba colors in markup



commit 194f4668b32a86993d969bccfed59186c08f63dd
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Aug 14 22:51:46 2015 -0400

    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 8fa38c4..c2ba377 100644
--- a/docs/pango_markup.sgml
+++ b/docs/pango_markup.sgml
@@ -136,8 +136,10 @@ syntax as accepted by CSS. E.g: <literal>font_features='dlig=1, -kern, afrc on'<
 <term>fgcolor<footnoteref linkend='since_1_21'/></term>
 <term>color</term>
 <listitem><para>
-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.
 </para></listitem>
 </varlistentry>
 
@@ -145,8 +147,10 @@ An RGB color specification such as '#00FF00' or a color name such as
 <term>background</term>
 <term>bgcolor<footnoteref linkend='since_1_21'/></term>
 <listitem><para>
-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.
 </para></listitem>
 </varlistentry>
 
diff --git a/pango/pango-color.c b/pango/pango-color.c
index 47a9823..2f34476 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 <ulink url="http://dev.w3.org/csswg/css-color/#named-colors";>specification</ulink>), or it 
can be a hexadecimal
- * value in the
- * form '&num;rgb' '&num;rrggbb' '&num;rrrgggbbb' or '&num;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 '&num;fff' '&num;ffffff' '&num;fffffffff' and '&num;ffffffffffff')
- *
- * Return value: %TRUE if parsing of the specifier succeeded,
- *   otherwise false.
- **/
+
+/* Like pango_color_parse, but allow strings of the form
+ * '&num;rgba', '&num;rrggbbaa', '&num;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 <ulink url="http://dev.w3.org/csswg/css-color/#named-colors";>specification</ulink>), or it 
can be a hexadecimal
+ * value in the
+ * form '&num;rgb' '&num;rrggbb' '&num;rrrgggbbb' or '&num;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 '&num;fff' '&num;ffffff' '&num;fffffffff' and '&num;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 7e2b7dd..b4fe881 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));


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]