[pango/pango2-color-palette: 2/4] Support color palettes in fonts




commit bd90e900054ffa621138300ae17e20cd59fda0bb
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Jul 1 09:57:35 2022 -0400

    Support color palettes in fonts
    
    Add a pango_context_set_palette to select whether
    we prefer the default palette, the palette for light
    background, or the palette for dark background. Wire
    this through PangoFontSetCached and PangoFont, and
    apply in when we create a scaled font for cairo.
    
    Also add a palette field to PangoFontDescription,
    and treat it similarly.
    
    PangoHbFace gained a map from palette names
    to palette indices, which is used to find the
    palette to use.
    
    To try this, use the new --palette option of
    pango-view.
    
    The only font I've found with such color palettes
    is Amiri Quran Colored.

 pango2/pango-color-palette-private.h    |  25 ++++
 pango2/pango-context-private.h          |   2 +
 pango2/pango-context.c                  |  76 +++++++++++-
 pango2/pango-context.h                  |   8 ++
 pango2/pango-font-description-private.h |   2 +
 pango2/pango-font-description.c         | 201 ++++++++++++++++++++++++--------
 pango2/pango-font-description.h         |   7 ++
 pango2/pango-font-private.h             |  14 ++-
 pango2/pango-fontmap.c                  |   7 +-
 pango2/pango-fontset-cached-private.h   |   1 +
 pango2/pango-fontset-cached.c           |  69 +++++------
 pango2/pango-hbface-private.h           |  10 ++
 pango2/pango-hbface.c                   | 135 +++++++++++++++++++++
 pango2/pango-hbface.h                   |   4 +
 pango2/pango-hbfont.c                   |   2 +-
 pango2/pango-types.h                    |  23 ++++
 pango2/pangocairo-font.c                |  23 +++-
 tests/test-font.c                       |  70 ++++++++++-
 utils/viewer-pangocairo.c               |   9 +-
 19 files changed, 584 insertions(+), 104 deletions(-)
---
diff --git a/pango2/pango-color-palette-private.h b/pango2/pango-color-palette-private.h
new file mode 100644
index 000000000..283c221d0
--- /dev/null
+++ b/pango2/pango-color-palette-private.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 Red Hat Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "pango-color-palette.h"
+
+struct _Pango2ColorPalette {
+  GQuark name;
+  unsigned int index;
+};
diff --git a/pango2/pango-context-private.h b/pango2/pango-context-private.h
index 07b4b506b..4ec65da6e 100644
--- a/pango2/pango-context-private.h
+++ b/pango2/pango-context-private.h
@@ -48,6 +48,8 @@ struct _Pango2Context
 
   gboolean round_glyph_positions;
 
+  GQuark palette;
+
 #ifdef HAVE_CAIRO
   gboolean set_options_explicit;
 
diff --git a/pango2/pango-context.c b/pango2/pango-context.c
index 371c8405f..8a69ffb89 100644
--- a/pango2/pango-context.c
+++ b/pango2/pango-context.c
@@ -69,6 +69,7 @@ enum {
   PROP_GRAVITY_HINT,
   PROP_MATRIX,
   PROP_ROUND_GLYPH_POSITIONS,
+  PROP_PALETTE,
   N_PROPERTIES
 };
 
@@ -88,6 +89,7 @@ pango2_context_init (Pango2Context *context)
   context->language = pango2_language_get_default ();
   context->font_map = NULL;
   context->round_glyph_positions = TRUE;
+  context->palette = g_quark_from_static_string (PANGO2_COLOR_PALETTE_NORMAL);
 
   context->font_desc = pango2_font_description_new ();
   pango2_font_description_set_family_static (context->font_desc, "serif");
@@ -140,6 +142,10 @@ pango2_context_set_property (GObject      *object,
       pango2_context_set_round_glyph_positions (context, g_value_get_boolean (value));
       break;
 
+    case PROP_PALETTE:
+      pango2_context_set_color_palette (context, g_value_get_string (value));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
     }
@@ -187,6 +193,10 @@ pango2_context_get_property (GObject    *object,
       g_value_set_boolean (value, pango2_context_get_round_glyph_positions (context));
       break;
 
+    case PROP_PALETTE:
+      g_value_set_string (value, pango2_context_get_color_palette (context));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
     }
@@ -197,6 +207,10 @@ pango2_context_class_init (Pango2ContextClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+  g_intern_static_string (PANGO2_COLOR_PALETTE_NORMAL);
+  g_intern_static_string (PANGO2_COLOR_PALETTE_LIGHT);
+  g_intern_static_string (PANGO2_COLOR_PALETTE_DARK);
+
   object_class->finalize = pango2_context_finalize;
   object_class->set_property = pango2_context_set_property;
   object_class->get_property = pango2_context_get_property;
@@ -303,15 +317,22 @@ pango2_context_class_init (Pango2ContextClass *klass)
     g_param_spec_boolean ("round-glyph-positions", NULL, NULL, TRUE,
                           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
+  /**
+   * Pango2Context:palette: (attributes org.gtk.Property.get=pango2_context_get_palette 
org.gtk.Property.set=pango2_context_set_palette)
+   *
+   * The name of the palette to use for color fonts.
+   */
+  properties[PROP_PALETTE] =
+    g_param_spec_string ("palette", NULL, NULL, "normal",
+                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
   g_object_class_install_properties (object_class, N_PROPERTIES, properties);
 }
 
 static void
 pango2_context_finalize (GObject *object)
 {
-  Pango2Context *context;
-
-  context = PANGO2_CONTEXT (object);
+  Pango2Context *context = PANGO2_CONTEXT (object);
 
   if (context->font_map)
     g_object_unref (context->font_map);
@@ -1044,3 +1065,52 @@ pango2_context_get_round_glyph_positions (Pango2Context *context)
 {
   return context->round_glyph_positions;
 }
+
+/**
+ * pango2_context_set_color_palette:
+ * @context: a `Pango2Context`
+ * @palette: the name of the palette to use
+ *
+ * Sets the palette to use for color fonts.
+ *
+ * This can either be one of the predefined names
+ * "normal", "light" or "dark", or a custom name.
+ *
+ * Some color fonts include metadata that indicates
+ * the default palette, as well as palettes that work
+ * well on light or dark backgrounds. The predefined
+ * names select those.
+ */
+void
+pango2_context_set_color_palette (Pango2Context *context,
+                                  const char    *palette)
+{
+  GQuark quark;
+
+  g_return_if_fail (PANGO2_IS_CONTEXT (context));
+
+  quark = g_quark_from_string (palette);
+  if (context->palette == quark)
+    return;
+
+  context->palette = quark;
+  g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_PALETTE]);
+}
+
+/**
+ * pango2_context_get_color_palette:
+ * @context: a `Pango2Context`
+ *
+ * Returns the palette to use for color fonts.
+ *
+ * See [method@Pango2.Context.set_color_palette].
+ *
+ * Return value: (nullable): the palette name
+ */
+const char *
+pango2_context_get_color_palette (Pango2Context *context)
+{
+  g_return_val_if_fail (PANGO2_IS_CONTEXT (context), PANGO2_COLOR_PALETTE_NORMAL);
+
+  return g_quark_to_string (context->palette);
+}
diff --git a/pango2/pango-context.h b/pango2/pango-context.h
index 902e840dc..d9746d725 100644
--- a/pango2/pango-context.h
+++ b/pango2/pango-context.h
@@ -99,4 +99,12 @@ void                     pango2_context_set_round_glyph_positions (Pango2Context
 PANGO2_AVAILABLE_IN_ALL
 gboolean                 pango2_context_get_round_glyph_positions (Pango2Context                 *context);
 
+PANGO2_AVAILABLE_IN_ALL
+void                     pango2_context_set_color_palette         (Pango2Context                 *context,
+                                                                   const char                    *palette);
+PANGO2_AVAILABLE_IN_ALL
+const char *             pango2_context_get_color_palette         (Pango2Context                 *context);
+
+
+
 G_END_DECLS
diff --git a/pango2/pango-font-description-private.h b/pango2/pango-font-description-private.h
index 11b09d00d..231a28007 100644
--- a/pango2/pango-font-description-private.h
+++ b/pango2/pango-font-description-private.h
@@ -28,6 +28,8 @@ gboolean pango2_font_description_is_similar       (const Pango2FontDescription *
 int      pango2_font_description_compute_distance (const Pango2FontDescription *a,
                                                    const Pango2FontDescription *b);
 
+GQuark   pango2_font_description_get_palette_quark (const Pango2FontDescription *desc);
+
 gboolean pango2_parse_style              (const char    *str,
                                           Pango2Style   *style,
                                           gboolean       warn);
diff --git a/pango2/pango-font-description.c b/pango2/pango-font-description.c
index 20421c893..cc9aedab9 100644
--- a/pango2/pango-font-description.c
+++ b/pango2/pango-font-description.c
@@ -39,6 +39,8 @@ struct _Pango2FontDescription
   char *variations;
   char *faceid;
 
+  GQuark palette;
+
   guint16 mask;
   guint static_family : 1;
   guint static_variations : 1;
@@ -61,6 +63,7 @@ static const Pango2FontDescription pfd_defaults = {
   0,                    /* size */
   NULL,                 /* variations */
   NULL,                 /* faceid */
+  0,                    /* palette */
 
   0,                    /* mask */
   0,                    /* static_family */
@@ -733,6 +736,8 @@ pango2_font_description_merge_static (Pango2FontDescription       *desc,
     pango2_font_description_set_variations_static (desc, desc_to_merge->variations);
   if (new_mask & PANGO2_FONT_MASK_FACEID)
     pango2_font_description_set_faceid_static (desc, desc_to_merge->faceid);
+  if (new_mask & PANGO2_FONT_MASK_PALETTE)
+    desc->palette = desc_to_merge->palette;
 
   desc->mask |= new_mask;
 }
@@ -872,7 +877,8 @@ pango2_font_description_equal (const Pango2FontDescription *desc1,
          (desc1->family_name == desc2->family_name ||
           (desc1->family_name && desc2->family_name && g_ascii_strcasecmp (desc1->family_name, 
desc2->family_name) == 0)) &&
          (g_strcmp0 (desc1->variations, desc2->variations) == 0) &&
-         (g_strcmp0 (desc1->faceid, desc2->faceid) == 0);
+         (g_strcmp0 (desc1->faceid, desc2->faceid) == 0) &&
+         desc1->palette == desc2->palette;
 }
 
 #define TOLOWER(c) \
@@ -924,6 +930,7 @@ pango2_font_description_hash (const Pango2FontDescription *desc)
   hash ^= desc->weight << 16;
   hash ^= desc->stretch << 26;
   hash ^= desc->gravity << 28;
+  hash ^= desc->palette;
 
   return hash;
 }
@@ -1184,6 +1191,46 @@ parse_size (const char *word,
   return FALSE;
 }
 
+static gboolean
+parse_palette (const char  *word,
+               size_t       wordlen,
+               GQuark      *palette)
+{
+  const char *p, *q;
+  char *s;
+
+  if (!g_str_has_prefix (word, "@palette="))
+    return FALSE;
+
+  p = word + strlen ("@palette=");
+  q = word + wordlen;
+  s = g_strndup (p, q - p);
+
+  *palette = g_quark_from_string (s);
+
+  g_free (s);
+
+  return TRUE;
+}
+
+static gboolean
+parse_faceid (const char  *word,
+              size_t       wordlen,
+              char       **faceid)
+{
+  const char *p, *q;
+
+  if (!g_str_has_prefix (word, "@faceid="))
+    return FALSE;
+
+  p = word + strlen ("@faceid=");
+  q = word + wordlen;
+
+  *faceid = g_strndup (p, q - p);
+
+  return TRUE;
+}
+
 static gboolean
 parse_variations (const char  *word,
                   size_t       wordlen,
@@ -1201,40 +1248,6 @@ parse_variations (const char  *word,
   return TRUE;
 }
 
-static void
-faceid_from_variations (Pango2FontDescription *desc)
-{
-  const char *p, *q;
-
-  p = desc->variations;
-
-  if (g_str_has_prefix (p, "faceid="))
-    {
-      p += strlen ("faceid=");
-      q = strchr (p, ',');
-      if (q)
-        {
-          desc->faceid = g_strndup (p, q - p);
-          p = q + 1;
-        }
-      else
-        {
-          desc->faceid = g_strdup (p);
-          p = NULL;
-        }
-      desc->mask |= PANGO2_FONT_MASK_FACEID;
-    }
-
-  if (p != desc->variations)
-    {
-      char *variations = g_strdup (p);
-      g_free (desc->variations);
-      desc->variations = variations;
-      if (variations == NULL || *variations == '\0')
-        desc->mask &= ~PANGO2_FONT_MASK_VARIATIONS;
-    }
-}
-
 /**
  * pango2_font_description_from_string:
  * @str: string representation of a font description.
@@ -1243,15 +1256,30 @@ faceid_from_variations (Pango2FontDescription *desc)
  *
  * The string must have the form
  *
- *     "\[FAMILY-LIST] \[STYLE-OPTIONS] \[SIZE] \[VARIATIONS]",
+ *     "\[FAMILY-LIST] \[STYLE-OPTIONS] \[SIZE] \[VARIATIONS] \[FACEID] \[PALETTE]",
  *
  * where FAMILY-LIST is a comma-separated list of families optionally
  * terminated by a comma, STYLE_OPTIONS is a whitespace-separated list
  * of words where each word describes one of style, variant, weight,
  * stretch, or gravity, and SIZE is a decimal number (size in points)
  * or optionally followed by the unit modifier "px" for absolute size.
+ *
  * VARIATIONS is a comma-separated list of font variation
- * specifications of the form "\@axis=value" (the = sign is optional).
+ * specifications of the form "\@axis=value" (the = sign is optional),
+ * where "axis" is a 3-character name of an OpenType variation axis
+ * like "wght", "wdth" or "opsz".
+ *
+ * FACEID must have the form "\@faceid=string" with the literal string
+ * "faceid".
+ *
+ * PALETTE must have the form "\@palette=name" with the literal string
+ * "palette", and the name of a color palette. The name can either be
+ * one of the standard names "normal", "light" or "dark", or a custom
+ * name. See [method@Pango2.HbFace.new_synthetic] for information on
+ * how to associate custom names with palettes in the font.
+ *
+ * The VARIATION, FACEID and PALETTE parts can appear in any order,
+ * as long as they are at the end.
  *
  * The following words are understood as styles:
  * "Normal", "Roman", "Oblique", "Italic".
@@ -1304,18 +1332,39 @@ pango2_font_description_from_string (const char *str)
 
   len = strlen (str);
   last = str + len;
-  p = getword (str, last, &wordlen, "");
-  /* Look for variations at the end of the string */
-  if (wordlen != 0)
+
+  do
     {
-      if (parse_variations (p, wordlen, &desc->variations))
+      p = getword (str, last, &wordlen, "");
+
+      if (wordlen == 0 || p[0] != '@')
+        break;
+
+      /* Look for palettes, faceid and variations at the end of the string */
+      if (parse_palette (p, wordlen, &desc->palette))
+        {
+          desc->mask |= PANGO2_FONT_MASK_PALETTE;
+          last = p;
+        }
+      else if (parse_faceid (p, wordlen, &desc->faceid))
+        {
+          desc->mask |= PANGO2_FONT_MASK_FACEID;
+          last = p;
+        }
+      else if (parse_variations (p, wordlen, &desc->variations))
         {
           desc->mask |= PANGO2_FONT_MASK_VARIATIONS;
           last = p;
-
-          faceid_from_variations (desc);
         }
+      else
+        break;
     }
+  while ((desc->mask & (PANGO2_FONT_MASK_PALETTE |
+                        PANGO2_FONT_MASK_FACEID |
+                        PANGO2_FONT_MASK_VARIATIONS)) !=
+                       (PANGO2_FONT_MASK_PALETTE |
+                        PANGO2_FONT_MASK_FACEID |
+                        PANGO2_FONT_MASK_VARIATIONS));
 
   p = getword (str, last, &wordlen, ",");
   /* Look for a size */
@@ -1428,7 +1477,6 @@ char *
 pango2_font_description_to_string (const Pango2FontDescription *desc)
 {
   GString *result;
-  gboolean in_variations = FALSE;
 
   g_return_val_if_fail (desc != NULL, NULL);
 
@@ -1488,18 +1536,20 @@ pango2_font_description_to_string (const Pango2FontDescription *desc)
 
   if (desc->mask & PANGO2_FONT_MASK_FACEID)
     {
-      in_variations = TRUE;
       g_string_append (result, " @");
       g_string_append_printf (result, "faceid=%s", desc->faceid);
     }
 
+  if (desc->mask & PANGO2_FONT_MASK_PALETTE)
+    {
+      g_string_append (result, " @");
+      g_string_append_printf (result, "palette=%s", g_quark_to_string (desc->palette));
+    }
+
   if ((desc->variations && desc->mask & PANGO2_FONT_MASK_VARIATIONS) &&
       desc->variations[0] != '\0')
     {
-      if (!in_variations)
-        g_string_append (result, " @");
-      else
-        g_string_append (result, ",");
+      g_string_append (result, " @");
       g_string_append (result, desc->variations);
     }
 
@@ -1741,3 +1791,56 @@ pango2_font_description_get_faceid (const Pango2FontDescription *desc)
 
   return desc->faceid;
 }
+
+/**
+ * pango2_font_description_set_palette:
+ * @palette: the name of the palette
+ *
+ * Sets the palette field of a font description.
+ *
+ * Predefined palette names are "normal", "light" and "dark".
+ * Other names can be associated with palettes when constructing
+ * [class@Pango2.HbFace] objects.
+ */
+void
+pango2_font_description_set_palette (Pango2FontDescription *desc,
+                                     const char            *palette)
+{
+  g_return_if_fail (desc != NULL);
+
+  desc->palette = g_quark_from_string (palette);
+  desc->mask |= PANGO2_FONT_MASK_PALETTE;
+}
+
+/**
+ * pango2_font_description_get_palette:
+ * @desc: a `Pango2FontDescription`
+ *
+ * Gets the palette field of a font description.
+ *
+ * Return value: (nullable): the palette field of the font description
+ */
+const char *
+pango2_font_description_get_palette (const Pango2FontDescription *desc)
+{
+  g_return_val_if_fail (desc != NULL, NULL);
+
+  if (desc->palette)
+    return g_quark_to_string (desc->palette);
+
+  return NULL;
+}
+
+/*< private >
+ * pango2_font_description_get_palette_quark:
+ * @desc: a `Pango2FontDescription
+ *
+ * Gets the palette field as a `GQuark`.
+ *
+ * Return value: the palette field as a quark
+ */
+GQuark
+pango2_font_description_get_palette_quark (const Pango2FontDescription *desc)
+{
+  return desc->palette;
+}
diff --git a/pango2/pango-font-description.h b/pango2/pango-font-description.h
index 160ee50dc..a8fbcc458 100644
--- a/pango2/pango-font-description.h
+++ b/pango2/pango-font-description.h
@@ -171,6 +171,7 @@ typedef enum {
   PANGO2_FONT_MASK_GRAVITY    = 1 << 6,
   PANGO2_FONT_MASK_VARIATIONS = 1 << 7,
   PANGO2_FONT_MASK_FACEID     = 1 << 8,
+  PANGO2_FONT_MASK_PALETTE    = 1 << 9,
 } Pango2FontMask;
 
 /* CSS scale factors (1.2 factor between each size) */
@@ -298,6 +299,12 @@ void                    pango2_font_description_set_faceid_static (Pango2FontDes
 PANGO2_AVAILABLE_IN_ALL
 const char *            pango2_font_description_get_faceid        (const Pango2FontDescription *desc) 
G_GNUC_PURE;
 
+PANGO2_AVAILABLE_IN_ALL
+void                    pango2_font_description_set_palette       (Pango2FontDescription *desc,
+                                                                   const char            *palette);
+PANGO2_AVAILABLE_IN_ALL
+const char *            pango2_font_description_get_palette       (const Pango2FontDescription *desc) 
G_GNUC_PURE;
+
 PANGO2_AVAILABLE_IN_ALL
 Pango2FontMask          pango2_font_description_get_set_fields    (const Pango2FontDescription *desc) 
G_GNUC_PURE;
 PANGO2_AVAILABLE_IN_ALL
diff --git a/pango2/pango-font-private.h b/pango2/pango-font-private.h
index ca8d3a775..4278be5f5 100644
--- a/pango2/pango-font-private.h
+++ b/pango2/pango-font-private.h
@@ -42,6 +42,7 @@ struct _Pango2Font
   Pango2Gravity gravity;
   Pango2Matrix ctm;
 
+  GQuark palette;
 #ifdef HAVE_CAIRO
   cairo_font_options_t *options;
 #endif
@@ -107,6 +108,13 @@ pango2_font_set_ctm (Pango2Font         *font,
   font->ctm = ctm ? *ctm : matrix_init;
 }
 
+static inline void
+pango2_font_set_color_palette (Pango2Font *font,
+                               GQuark      palette)
+{
+  font->palette = palette;
+}
+
 gboolean pango2_font_is_hinted         (Pango2Font  *font);
 void     pango2_font_get_scale_factors (Pango2Font  *font,
                                         double      *x_scale,
@@ -114,12 +122,6 @@ void     pango2_font_get_scale_factors (Pango2Font  *font,
 void     pango2_font_get_transform     (Pango2Font  *font,
                                        Pango2Matrix *matrix);
 
-gboolean pango2_font_description_is_similar       (const Pango2FontDescription *a,
-                                                   const Pango2FontDescription *b);
-
-int      pango2_font_description_compute_distance (const Pango2FontDescription *a,
-                                                   const Pango2FontDescription *b);
-
 /* We use these values in a few places as a fallback size for an
  * unknown glyph, if we have no better information.
  */
diff --git a/pango2/pango-fontmap.c b/pango2/pango-fontmap.c
index c3359130f..07fef32a3 100644
--- a/pango2/pango-fontmap.c
+++ b/pango2/pango-fontmap.c
@@ -34,7 +34,7 @@
 #include "pango-fontset.h"
 #include "pango-font-face-private.h"
 #include "pango-trace-private.h"
-#include "pango-context.h"
+#include "pango-context-private.h"
 
 #ifdef HAVE_CORE_TEXT
 #include "pangocoretext-fontmap.h"
@@ -167,6 +167,7 @@ pango2_fontset_cached_hash (const Pango2FontsetCached *fontset)
 
   return (hash ^
           GPOINTER_TO_UINT (fontset->language) ^
+          fontset->palette ^
 #ifdef HAVE_CAIRO
           cairo_font_options_hash (fontset->font_options) ^
 #endif
@@ -178,6 +179,7 @@ pango2_fontset_cached_equal (const Pango2FontsetCached *a,
                              const Pango2FontsetCached *b)
 {
   return a->language == b->language &&
+         a->palette == b->palette &&
 #ifdef HAVE_CAIRO
          cairo_font_options_equal (a->font_options, b->font_options) &&
 #endif
@@ -553,6 +555,8 @@ pango2_font_map_default_load_fontset (Pango2FontMap               *self,
   lookup.language = language;
   lookup.description = (Pango2FontDescription *)description;
   lookup.ctm = ctm;
+  lookup.palette = context->palette;
+
 #ifdef HAVE_CAIRO
   lookup.font_options = (cairo_font_options_t *)pango2_cairo_context_get_merged_font_options (context);
 #endif
@@ -562,6 +566,7 @@ pango2_font_map_default_load_fontset (Pango2FontMap               *self,
     goto done;
 
   fontset = pango2_fontset_cached_new (description, language, self->dpi, ctm);
+  fontset->palette = context->palette;
 #ifdef HAVE_CAIRO
   fontset->font_options = cairo_font_options_copy (pango2_cairo_context_get_merged_font_options (context));
 #endif
diff --git a/pango2/pango-fontset-cached-private.h b/pango2/pango-fontset-cached-private.h
index 95059a791..c1c74f5f0 100644
--- a/pango2/pango-fontset-cached-private.h
+++ b/pango2/pango-fontset-cached-private.h
@@ -44,6 +44,7 @@ struct _Pango2FontsetCached
   GList cache_link;
   GHashTable *cache;
 
+  GQuark palette;
 #ifdef HAVE_CAIRO
   cairo_font_options_t *font_options;
 #endif
diff --git a/pango2/pango-fontset-cached.c b/pango2/pango-fontset-cached.c
index 9feaca795..0031cee27 100644
--- a/pango2/pango-fontset-cached.c
+++ b/pango2/pango-fontset-cached.c
@@ -26,7 +26,9 @@
 #include "pango-fontset-cached-private.h"
 #include "pango-font-private.h"
 #include "pango-font-face-private.h"
+#include "pango-font-description-private.h"
 #include "pango-generic-family-private.h"
+#include "pango-context.h"
 
 #ifdef HAVE_CAIRO
 #include "pangocairo-font.h"
@@ -40,6 +42,7 @@ pango2_fontset_cached_init (Pango2FontsetCached *fontset)
   fontset->items = g_ptr_array_new_with_free_func (g_object_unref);
   fontset->cache = g_hash_table_new_full (NULL, NULL, NULL, g_object_unref);
   fontset->language = NULL;
+  fontset->palette = g_quark_from_static_string (PANGO2_COLOR_PALETTE_NORMAL);
 #ifdef HAVE_CAIRO
   fontset->font_options = NULL;
 #endif
@@ -81,6 +84,27 @@ find_font_for_face (Pango2FontsetCached *self,
   return NULL;
 }
 
+static Pango2Font *
+create_font_for_face (Pango2FontsetCached *self,
+                      Pango2FontFace      *face)
+{
+  Pango2Font *font;
+
+  font = pango2_font_face_create_font (face,
+                                       self->description,
+                                       self->dpi,
+                                       self->ctm);
+  if (pango2_font_description_get_set_fields  (self->description) & PANGO2_FONT_MASK_PALETTE)
+    pango2_font_set_color_palette (font, pango2_font_description_get_palette_quark (self->description));
+  else
+    pango2_font_set_color_palette (font, self->palette);
+#ifdef HAVE_CAIRO
+  pango2_cairo_font_set_font_options (font, self->font_options);
+#endif
+
+  return font;
+}
+
 static Pango2Font *
 pango2_fontset_cached_get_font (Pango2Fontset *fontset,
                                 guint          wc)
@@ -129,19 +153,9 @@ pango2_fontset_cached_get_font (Pango2Fontset *fontset,
 
               font = find_font_for_face (self, face);
               if (font)
-                {
-                  retval = g_object_ref (font);
-                }
+                retval = g_object_ref (font);
               else
-                {
-                  retval = pango2_font_face_create_font (face,
-                                                         self->description,
-                                                         self->dpi,
-                                                         self->ctm);
-#ifdef HAVE_CAIRO
-                  pango2_cairo_font_set_font_options (retval, self->font_options);
-#endif
-                }
+                retval = create_font_for_face (self, face);
               break;
             }
         }
@@ -175,15 +189,7 @@ pango2_fontset_cached_get_first_font (Pango2FontsetCached *self)
       if (font)
         g_object_ref (font);
       else
-        {
-          font = pango2_font_face_create_font (face,
-                                               self->description,
-                                               self->dpi,
-                                               self->ctm);
-#ifdef HAVE_CAIRO
-          pango2_cairo_font_set_font_options (font, self->font_options);
-#endif
-        }
+        font = create_font_for_face (self, face);
 
       return font;
     }
@@ -249,15 +255,7 @@ pango2_fontset_cached_foreach (Pango2Fontset            *fontset,
           if (font)
             g_object_ref (font);
           else
-            {
-              font = pango2_font_face_create_font (face,
-                                                   self->description,
-                                                   self->dpi,
-                                                   self->ctm);
-#ifdef HAVE_CAIRO
-              pango2_cairo_font_set_font_options (font, self->font_options);
-#endif
-            }
+            font = create_font_for_face (self, face);
         }
 
       if ((*func) (fontset, font, data))
@@ -304,16 +302,7 @@ void
 pango2_fontset_cached_add_face (Pango2FontsetCached *self,
                                 Pango2FontFace      *face)
 {
-  Pango2Font *font;
-
-  font = pango2_font_face_create_font (face,
-                                       self->description,
-                                       self->dpi,
-                                       self->ctm);
-#ifdef HAVE_CAIRO
-  pango2_cairo_font_set_font_options (font, self->font_options);
-#endif
-  g_ptr_array_add (self->items, font);
+  g_ptr_array_add (self->items, create_font_for_face (self, face));
 }
 
 void
diff --git a/pango2/pango-hbface-private.h b/pango2/pango-hbface-private.h
index e29203887..2cc0e562e 100644
--- a/pango2/pango-hbface-private.h
+++ b/pango2/pango-hbface-private.h
@@ -25,6 +25,11 @@
 #include "pango-language-set-private.h"
 #include <hb.h>
 
+typedef struct {
+  GQuark name;
+  unsigned int index;
+} PaletteMapEntry;
+
 struct _Pango2HbFace
 {
   Pango2FontFace parent_instance;
@@ -41,6 +46,8 @@ struct _Pango2HbFace
   Pango2LanguageSet *languages;
   gboolean embolden;
   gboolean synthetic;
+  PaletteMapEntry *palettes;
+  unsigned int n_palettes;
 };
 
 Pango2LanguageSet *     pango2_hb_face_get_language_set  (Pango2HbFace          *self);
@@ -50,3 +57,6 @@ void                    pango2_hb_face_set_language_set  (Pango2HbFace
 
 void                    pango2_hb_face_set_matrix        (Pango2HbFace          *self,
                                                           const Pango2Matrix    *matrix);
+
+unsigned int            pango2_hb_face_get_palette_index (Pango2HbFace          *self,
+                                                          GQuark                 palette);
diff --git a/pango2/pango-hbface.c b/pango2/pango-hbface.c
index dbe68e176..03e6997dd 100644
--- a/pango2/pango-hbface.c
+++ b/pango2/pango-hbface.c
@@ -48,6 +48,21 @@
 
  /* {{{ Utilities */
 
+static struct {
+  GQuark name;
+  hb_ot_color_palette_flags_t flag;
+} default_palettes[3];
+
+static void
+init_default_palettes (void)
+{
+  default_palettes[0].name = g_quark_from_static_string (PANGO2_COLOR_PALETTE_NORMAL);
+  default_palettes[0].flag = HB_OT_COLOR_PALETTE_FLAG_DEFAULT;
+  default_palettes[1].name = g_quark_from_static_string (PANGO2_COLOR_PALETTE_LIGHT);
+  default_palettes[1].flag = HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND;
+  default_palettes[2].name = g_quark_from_static_string (PANGO2_COLOR_PALETTE_DARK);
+  default_palettes[2].flag = HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND;
+};
 static void
 get_name_from_hb_face (hb_face_t       *face,
                        hb_ot_name_id_t  name_id,
@@ -314,6 +329,7 @@ pango2_hb_face_finalize (GObject *object)
 {
   Pango2HbFace *self = PANGO2_HB_FACE (object);
 
+  g_free (self->palettes);
   g_free (self->faceid);
   if (self->face)
     hb_face_destroy (self->face);
@@ -483,6 +499,8 @@ pango2_hb_face_class_init (Pango2HbFaceClass *class)
   GObjectClass *object_class = G_OBJECT_CLASS (class);
   Pango2FontFaceClass *face_class = PANGO2_FONT_FACE_CLASS (class);
 
+  init_default_palettes ();
+
   object_class->finalize = pango2_hb_face_finalize;
   object_class->get_property = pango2_hb_face_get_property;
 
@@ -627,6 +645,44 @@ pango2_hb_face_set_matrix (Pango2HbFace       *self,
   pango2_matrix_scale (self->transform, 1./self->x_scale, 1./self->y_scale);
 }
 
+static unsigned int
+find_palette_index_by_flag (hb_face_t                   *hbface,
+                            hb_ot_color_palette_flags_t  flag)
+{
+  for (unsigned int i = 0; i < hb_ot_color_palette_get_count (hbface); i++)
+    {
+      if (hb_ot_color_palette_get_flags (hbface, i) & flag)
+        return i;
+    }
+
+  return 0;
+}
+
+unsigned int
+pango2_hb_face_get_palette_index (Pango2HbFace *self,
+                                  GQuark        palette)
+{
+
+  for (unsigned int i = 0; i < self->n_palettes; i++)
+    {
+      if (self->palettes[i].name == palette)
+        return self->palettes[i].index;
+    }
+
+  ensure_hb_face (self);
+
+  if (hb_ot_color_has_palettes (self->face))
+    {
+      for (unsigned int i = 0; i < G_N_ELEMENTS (default_palettes); i++)
+        {
+          if (palette == default_palettes[i].name)
+            return find_palette_index_by_flag (self->face, default_palettes[i].flag);
+        }
+    }
+
+  return 0;
+}
+
 /* }}} */
   /* {{{ Public API */
 
@@ -896,6 +952,7 @@ struct _Pango2HbFaceBuilder {
   unsigned int n_variations;
   char *name;
   Pango2FontDescription *description;
+  GArray *palettes;
 };
 
 G_DEFINE_BOXED_TYPE (Pango2HbFaceBuilder, pango2_hb_face_builder,
@@ -917,6 +974,7 @@ face_builder_new (void)
   builder->n_variations = 0;
   builder->name = NULL;
   builder->description = NULL;
+  builder->palettes = NULL;
 
   return builder;
 }
@@ -947,6 +1005,8 @@ pango2_hb_face_builder_copy (const Pango2HbFaceBuilder *src)
   builder->name = g_strdup (src->name);
   if (src->description)
     builder->description = pango2_font_description_copy_static (src->description);
+  if (src->palettes)
+    builder->palettes = g_array_copy (src->palettes);
 
   return builder;
 }
@@ -969,6 +1029,8 @@ pango2_hb_face_builder_free (Pango2HbFaceBuilder *builder)
   g_free (builder->name);
   if (builder->description)
     pango2_font_description_free (builder->description);
+  if (builder->palettes)
+    g_array_free (builder->palettes, TRUE);
 
   g_free (builder);
 }
@@ -1025,6 +1087,11 @@ pango2_hb_face_builder_new (Pango2HbFace *face)
   builder->n_variations = face->n_variations;
   builder->name = g_strdup (font_face->name);
   builder->description = pango2_font_description_copy_static (font_face->description);
+  if (face->palettes)
+    {
+      builder->palettes = g_array_new (FALSE, FALSE, sizeof (PaletteMapEntry));
+      g_array_append_vals (builder->palettes, face->palettes, face->n_palettes);
+    }
 
   return builder;
 }
@@ -1070,6 +1137,12 @@ pango2_hb_face_builder_get_face (Pango2HbFaceBuilder *builder)
 
   set_name_and_description (self, builder->name, builder->description);
 
+  if (builder->palettes)
+    {
+      self->palettes = g_memdup2 (builder->palettes->data, sizeof (PaletteMapEntry) * 
builder->palettes->len);
+      self->n_palettes = builder->palettes->len;
+    }
+
   return self;
 }
 
@@ -1189,6 +1262,68 @@ pango2_hb_face_builder_set_variations (Pango2HbFaceBuilder  *builder,
   builder->n_variations = n_variations;
 }
 
+static gboolean
+name_is_valid (const char *name)
+{
+  /* First character must be a letter. */
+  if ((name[0] < 'A' || name[0] > 'Z') &&
+      (name[0] < 'a' || name[0] > 'z'))
+    return FALSE;
+
+  for (const char *p = name; *p != 0; p++)
+    {
+      const char c = *p;
+
+      if (c != '-' && c != '_' &&
+          (c < '0' || c > '9') &&
+          (c < 'A' || c > 'Z') &&
+          (c < 'a' || c > 'z'))
+        return FALSE;
+    }
+
+  return TRUE;
+}
+
+/**
+ * pango2_hb_face_builder_add_palette:
+ * @builder: a `Pango2HbFaceBuilder`
+ * @name: the name for the palette
+ * @palette_index: palette index
+ *
+ * Assigns a name to the palette index.
+ *
+ * Names must consists of ASCII letters and digits,
+ * separated by either '-' or '_'. The first character
+ * must be a letter.
+ */
+void
+pango2_hb_face_builder_add_palette (Pango2HbFaceBuilder *builder,
+                                    const char          *name,
+                                    unsigned int         palette_index)
+{
+  PaletteMapEntry add;
+
+  g_return_if_fail (name_is_valid (name));
+
+  add.name = g_quark_from_string (name);
+  add.index = palette_index;
+
+  if (!builder->palettes)
+    builder->palettes = g_array_new (FALSE, FALSE, sizeof (PaletteMapEntry));
+
+  for (int i = 0; i < builder->palettes->len; i++)
+    {
+      PaletteMapEntry *entry = &g_array_index (builder->palettes, PaletteMapEntry, i);
+      if (entry->name == add.name)
+        {
+          entry->index = add.index;
+          return;
+        }
+    }
+
+  g_array_append_val (builder->palettes, add);
+}
+
 /* }}} */
 
 /* vim:set foldmethod=marker expandtab: */
diff --git a/pango2/pango-hbface.h b/pango2/pango-hbface.h
index b110ff99e..22d3adcfd 100644
--- a/pango2/pango-hbface.h
+++ b/pango2/pango-hbface.h
@@ -108,5 +108,9 @@ PANGO2_AVAILABLE_IN_ALL
 void                    pango2_hb_face_builder_set_variations   (Pango2HbFaceBuilder         *builder,
                                                                  const hb_variation_t        *variations,
                                                                  unsigned int                 n_variations);
+PANGO2_AVAILABLE_IN_ALL
+void                    pango2_hb_face_builder_add_palette      (Pango2HbFaceBuilder         *builder,
+                                                                 const char                  *name,
+                                                                 unsigned int                 palette_index);
 
 G_END_DECLS
diff --git a/pango2/pango-hbfont.c b/pango2/pango-hbfont.c
index a88762247..326c2def8 100644
--- a/pango2/pango-hbfont.c
+++ b/pango2/pango-hbfont.c
@@ -215,7 +215,7 @@ count_variations (const char *string)
 
   n = 1;
   p = string;
-  while ((p = strchr (p, ',')) != NULL)
+  while ((p = strchr (p + 1, ',')) != NULL)
     n++;
 
   return n;
diff --git a/pango2/pango-types.h b/pango2/pango-types.h
index 56cf3dbfd..0d2990416 100644
--- a/pango2/pango-types.h
+++ b/pango2/pango-types.h
@@ -319,6 +319,29 @@ typedef enum
  */
 #define PANGO2_LEADING_TRIM_BOTH (PANGO2_LEADING_TRIM_START|PANGO2_LEADING_TRIM_END)
 
+/**
+ * PANGO2_COLOR_PALETTE_NORMAL:
+ *
+ * The name for the default color palette.
+ */
+#define PANGO2_COLOR_PALETTE_NORMAL "normal"
+
+/**
+ * PANGO2_COLOR_PALETTE_LIGHT:
+ *
+ * The name for a color palette suitable for use on
+ * a light background.
+ */
+#define PANGO2_COLOR_PALETTE_LIGHT  "light"
+
+/**
+ * PANGO2_COLOR_PALETTE_DARK:
+ *
+ * The name for a color palette suitable for use on
+ * a dark background.
+ */
+#define PANGO2_COLOR_PALETTE_DARK   "dark"
+
 /*
  * PANGO2_DECLARE_INTERNAL_TYPE:
  * @ModuleObjName: The name of the new type, in camel case (like GtkWidget)
diff --git a/pango2/pangocairo-font.c b/pango2/pangocairo-font.c
index b9103d977..cb1dc83ca 100644
--- a/pango2/pangocairo-font.c
+++ b/pango2/pangocairo-font.c
@@ -24,6 +24,8 @@
 #include <math.h>
 #include <string.h>
 
+#include <hb-ot.h>
+
 #include "pangocairo.h"
 #include "pangocairo-private.h"
 #include "pango-font-private.h"
@@ -92,10 +94,22 @@ create_cairo_font_face (Pango2Font *font)
   return NULL;
 }
 
+static int
+find_palette_index_for_font (Pango2Font *font)
+{
+  Pango2FontFace *face = pango2_font_get_face (font);
+
+  if (PANGO2_IS_HB_FACE (face))
+    return pango2_hb_face_get_palette_index (PANGO2_HB_FACE (face), font->palette);
+
+  return CAIRO_COLOR_PALETTE_DEFAULT;
+}
+
 static cairo_scaled_font_t *
 _pango2_cairo_font_private_get_scaled_font (Pango2CairoFontPrivate *cf_priv)
 {
   cairo_font_face_t *font_face;
+  cairo_font_options_t *options;
 
   if (G_LIKELY (cf_priv->scaled_font))
     return cf_priv->scaled_font;
@@ -113,10 +127,17 @@ _pango2_cairo_font_private_get_scaled_font (Pango2CairoFontPrivate *cf_priv)
   if (G_UNLIKELY (font_face == NULL))
     goto done;
 
+  options = cairo_font_options_copy (cf_priv->data->options);
+  if (cairo_font_options_get_color_palette (options) == CAIRO_COLOR_PALETTE_DEFAULT)
+    cairo_font_options_set_color_palette (options,
+                                          find_palette_index_for_font (cf_priv->cfont));
+
   cf_priv->scaled_font = cairo_scaled_font_create (font_face,
                                                    &cf_priv->data->font_matrix,
                                                    &cf_priv->data->ctm,
-                                                   cf_priv->data->options);
+                                                   options);
+
+  cairo_font_options_destroy (options);
 
   cairo_font_face_destroy (font_face);
 
diff --git a/tests/test-font.c b/tests/test-font.c
index dd3ef1b54..19bebacf4 100644
--- a/tests/test-font.c
+++ b/tests/test-font.c
@@ -499,7 +499,7 @@ test_set_gravity (void)
 static void
 test_faceid (void)
 {
-  const char *test = "Cantarell Bold Italic 32 @faceid=Cantarell-Regular:0:-1:0,wght=600";
+  const char *test = "Cantarell Bold Italic 32 @faceid=Cantarell-Regular:0:-1:0 @wght=600";
   Pango2FontDescription *desc;
   char *s;
 
@@ -528,6 +528,72 @@ test_faceid (void)
   pango2_font_description_free (desc);
 }
 
+static void
+test_palette (void)
+{
+  const char *test = "Cantarell Bold Italic 32 @palette=light @wght=600";
+  Pango2FontDescription *desc;
+  char *s;
+
+  desc = pango2_font_description_from_string (test);
+  g_assert_cmpint (pango2_font_description_get_set_fields (desc), ==, PANGO2_FONT_MASK_FAMILY|
+                                                                     PANGO2_FONT_MASK_STYLE|
+                                                                     PANGO2_FONT_MASK_WEIGHT|
+                                                                     PANGO2_FONT_MASK_VARIANT|
+                                                                     PANGO2_FONT_MASK_STRETCH|
+                                                                     PANGO2_FONT_MASK_SIZE|
+                                                                     PANGO2_FONT_MASK_PALETTE|
+                                                                     PANGO2_FONT_MASK_VARIATIONS);
+  g_assert_cmpstr (pango2_font_description_get_family (desc), ==, "Cantarell");
+  g_assert_cmpint (pango2_font_description_get_size (desc), ==, 32 * PANGO2_SCALE);
+  g_assert_cmpint (pango2_font_description_get_style (desc), ==, PANGO2_STYLE_ITALIC);
+  g_assert_cmpint (pango2_font_description_get_variant (desc), ==, PANGO2_VARIANT_NORMAL);
+  g_assert_cmpint (pango2_font_description_get_weight (desc), ==, PANGO2_WEIGHT_BOLD);
+  g_assert_cmpint (pango2_font_description_get_stretch (desc), ==, PANGO2_STRETCH_NORMAL);
+  g_assert_cmpstr (pango2_font_description_get_palette (desc), ==, "light");
+  g_assert_cmpstr (pango2_font_description_get_variations (desc), ==, "wght=600");
+
+  s = pango2_font_description_to_string (desc);
+  g_assert_cmpstr (s, ==, test);
+  g_free (s);
+
+  pango2_font_description_free (desc);
+}
+
+static void
+test_all (void)
+{
+  const char *test = "Cantarell Bold Italic 32 @faceid=Cantarell-Regular:0:-1:0 @palette=dark @wght=600";
+  Pango2FontDescription *desc;
+  char *s;
+
+  desc = pango2_font_description_from_string (test);
+  g_assert_cmpint (pango2_font_description_get_set_fields (desc), ==, PANGO2_FONT_MASK_FAMILY|
+                                                                     PANGO2_FONT_MASK_STYLE|
+                                                                     PANGO2_FONT_MASK_WEIGHT|
+                                                                     PANGO2_FONT_MASK_VARIANT|
+                                                                     PANGO2_FONT_MASK_STRETCH|
+                                                                     PANGO2_FONT_MASK_SIZE|
+                                                                     PANGO2_FONT_MASK_PALETTE|
+                                                                     PANGO2_FONT_MASK_FACEID|
+                                                                     PANGO2_FONT_MASK_VARIATIONS);
+  g_assert_cmpstr (pango2_font_description_get_family (desc), ==, "Cantarell");
+  g_assert_cmpint (pango2_font_description_get_size (desc), ==, 32 * PANGO2_SCALE);
+  g_assert_cmpint (pango2_font_description_get_style (desc), ==, PANGO2_STYLE_ITALIC);
+  g_assert_cmpint (pango2_font_description_get_variant (desc), ==, PANGO2_VARIANT_NORMAL);
+  g_assert_cmpint (pango2_font_description_get_weight (desc), ==, PANGO2_WEIGHT_BOLD);
+  g_assert_cmpint (pango2_font_description_get_stretch (desc), ==, PANGO2_STRETCH_NORMAL);
+  g_assert_cmpstr (pango2_font_description_get_palette (desc), ==, "dark");
+  g_assert_cmpstr (pango2_font_description_get_faceid (desc), ==, "Cantarell-Regular:0:-1:0");
+  g_assert_cmpstr (pango2_font_description_get_variations (desc), ==, "wght=600");
+
+  s = pango2_font_description_to_string (desc);
+  g_assert_cmpstr (s, ==, test);
+  g_free (s);
+
+  pango2_font_description_free (desc);
+}
+
 static gboolean
 font_info_cb (Pango2UserFace     *face,
               int                size,
@@ -657,6 +723,8 @@ main (int argc, char *argv[])
   g_test_add_func ("/pango/fontdescription/empty-variations", test_empty_variations);
   g_test_add_func ("/pango/fontdescription/set-gravity", test_set_gravity);
   g_test_add_func ("/pango/fontdescription/faceid", test_faceid);
+  g_test_add_func ("/pango/fontdescription/palette", test_palette);
+  g_test_add_func ("/pango/fontdescription/all", test_all);
   g_test_add_func ("/pango/font/metrics", test_metrics);
   g_test_add_func ("/pango/font/extents", test_extents);
   g_test_add_func ("/pango/font/glyph-extents", test_glyph_extents);
diff --git a/utils/viewer-pangocairo.c b/utils/viewer-pangocairo.c
index d51b20552..e4b81ff6e 100644
--- a/utils/viewer-pangocairo.c
+++ b/utils/viewer-pangocairo.c
@@ -34,6 +34,7 @@
 static int opt_annotate = 0;
 static gboolean opt_userfont = 0;
 static char **opt_font_file = NULL;
+static char *opt_palette = NULL;
 
 typedef struct
 {
@@ -44,6 +45,7 @@ typedef struct
   Pango2FontMap *fontmap;
   cairo_font_options_t *font_options;
   gboolean subpixel_positions;
+  const char *palette;
 } CairoViewer;
 
 static gpointer
@@ -66,8 +68,8 @@ pangocairo_view_create (const Pango2Viewer *klass G_GNUC_UNUSED)
           Pango2FontFace *face;
 
           face = PANGO2_FONT_FACE (pango2_hb_face_new_from_file (opt_font_file[i],
-                                                               0, -1,
-                                                               NULL, NULL));
+                                                                 0, -1,
+                                                                 NULL, NULL));
 
           pango2_font_map_add_face (instance->fontmap, face);
 
@@ -119,6 +121,7 @@ pangocairo_view_create (const Pango2Viewer *klass G_GNUC_UNUSED)
     cairo_font_options_set_antialias (instance->font_options, (cairo_antialias_t)opt_antialias);
 
   instance->subpixel_positions = opt_subpixel_positions;
+  instance->palette = opt_palette;
 
   return instance;
 }
@@ -146,6 +149,7 @@ pangocairo_view_get_context (gpointer instance)
   context = pango2_context_new_with_font_map (c->fontmap);
   pango2_cairo_context_set_font_options (context, c->font_options);
   pango2_context_set_round_glyph_positions (context, !c->subpixel_positions);
+  pango2_context_set_color_palette (context, c->palette);
 
   return context;
 }
@@ -973,6 +977,7 @@ pangocairo_view_get_option_group (const Pango2Viewer *klass G_GNUC_UNUSED)
     {"annotate", 0, 0, G_OPTION_ARG_CALLBACK, parse_annotate_arg, annotate_arg_help, "FLAGS"},
     { "font-file", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_font_file, "Create a fontmap with this font", 
"FILE" },
     { "userfont", 0, 0, G_OPTION_ARG_NONE, &opt_userfont, "Add userfont" },
+    { "palette", 0, 0, G_OPTION_ARG_STRING, &opt_palette, "Preferred palette", "PALETTE" },
     {NULL}
   };
   GOptionGroup *group;


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