[pango/pango2-color-palette] wip: support color palettes in fonts
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pango/pango2-color-palette] wip: support color palettes in fonts
- Date: Fri, 24 Jun 2022 23:27:55 +0000 (UTC)
commit de2cf0afae7f5e488f54515b789665091a738c45
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Jun 24 19:24:19 2022 -0400
wip: 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.
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.
pango/pango-context-private.h | 2 +
pango/pango-context.c | 17 ++++++++
pango/pango-context.h | 7 ++++
pango/pango-font-private.h | 9 +++++
pango/pango-fontmap.c | 4 ++
pango/pango-fontset-cached-private.h | 2 +
pango/pango-fontset-cached.c | 77 +++++++++++++++---------------------
pango/pango-types.h | 6 +++
pango/pangocairo-font.c | 51 +++++++++++++++++++++++-
utils/viewer-pangocairo.c | 22 +++++++++++
10 files changed, 150 insertions(+), 47 deletions(-)
---
diff --git a/pango/pango-context-private.h b/pango/pango-context-private.h
index d9d07712b..1af412be5 100644
--- a/pango/pango-context-private.h
+++ b/pango/pango-context-private.h
@@ -48,6 +48,8 @@ struct _PangoContext
gboolean round_glyph_positions;
+ PangoColorPalette palette;
+
#ifdef HAVE_CAIRO
gboolean set_options_explicit;
diff --git a/pango/pango-context.c b/pango/pango-context.c
index 915dd032c..f62d15389 100644
--- a/pango/pango-context.c
+++ b/pango/pango-context.c
@@ -1066,3 +1066,20 @@ pango_context_get_round_glyph_positions (PangoContext *context)
{
return context->round_glyph_positions;
}
+
+void
+pango_context_set_color_palette (PangoContext *context,
+ PangoColorPalette palette)
+{
+ g_return_if_fail (PANGO_IS_CONTEXT (context));
+
+ context->palette = palette;
+}
+
+PangoColorPalette
+pango_context_get_color_palette (PangoContext *context)
+{
+ g_return_val_if_fail (PANGO_IS_CONTEXT (context), PANGO_COLOR_PALETTE_DEFAULT);
+
+ return context->palette;
+}
diff --git a/pango/pango-context.h b/pango/pango-context.h
index 99400fefc..5f63088c1 100644
--- a/pango/pango-context.h
+++ b/pango/pango-context.h
@@ -99,4 +99,11 @@ void pango_context_set_round_glyph_positions (PangoContext
PANGO_AVAILABLE_IN_ALL
gboolean pango_context_get_round_glyph_positions (PangoContext *context);
+PANGO_AVAILABLE_IN_ALL
+void pango_context_set_color_palette (PangoContext *context,
+ PangoColorPalette palette);
+PANGO_AVAILABLE_IN_ALL
+PangoColorPalette pango_context_get_color_palette (PangoContext *context);
+
+
G_END_DECLS
diff --git a/pango/pango-font-private.h b/pango/pango-font-private.h
index db4720dcf..cd98cb7e3 100644
--- a/pango/pango-font-private.h
+++ b/pango/pango-font-private.h
@@ -22,6 +22,7 @@
#include <pango/pango-font-family.h>
#include <pango/pango-font.h>
#include <pango/pango-types.h>
+#include <pango/pango-context.h>
#include <glib-object.h>
@@ -42,6 +43,7 @@ struct _PangoFont
PangoGravity gravity;
PangoMatrix ctm;
+ PangoColorPalette palette;
#ifdef HAVE_CAIRO
cairo_font_options_t *options;
#endif
@@ -107,6 +109,13 @@ pango_font_set_ctm (PangoFont *font,
font->ctm = ctm ? *ctm : matrix_init;
}
+static inline void
+pango_font_set_color_palette (PangoFont *font,
+ PangoColorPalette palette)
+{
+ font->palette = palette;
+}
+
gboolean pango_font_is_hinted (PangoFont *font);
void pango_font_get_scale_factors (PangoFont *font,
double *x_scale,
diff --git a/pango/pango-fontmap.c b/pango/pango-fontmap.c
index cefc3b203..5355f19f8 100644
--- a/pango/pango-fontmap.c
+++ b/pango/pango-fontmap.c
@@ -167,6 +167,7 @@ pango_fontset_cached_hash (const PangoFontsetCached *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 @@ pango_fontset_cached_equal (const PangoFontsetCached *a,
const PangoFontsetCached *b)
{
return a->language == b->language &&
+ a->palette == b->palette &&
#ifdef HAVE_CAIRO
cairo_font_options_equal (a->font_options, b->font_options) &&
#endif
@@ -528,6 +530,7 @@ pango_font_map_default_load_fontset (PangoFontMap *self,
lookup.language = language;
lookup.description = (PangoFontDescription *)description;
lookup.ctm = ctm;
+ lookup.palette = pango_context_get_color_palette (context);
#ifdef HAVE_CAIRO
lookup.font_options = (cairo_font_options_t *)pango_cairo_context_get_merged_font_options (context);
#endif
@@ -537,6 +540,7 @@ pango_font_map_default_load_fontset (PangoFontMap *self,
goto done;
fontset = pango_fontset_cached_new (description, language, self->dpi, ctm);
+ fontset->palette = pango_context_get_color_palette (context);
#ifdef HAVE_CAIRO
fontset->font_options = cairo_font_options_copy (pango_cairo_context_get_merged_font_options (context));
#endif
diff --git a/pango/pango-fontset-cached-private.h b/pango/pango-fontset-cached-private.h
index 2f3c7ac3f..00fad4808 100644
--- a/pango/pango-fontset-cached-private.h
+++ b/pango/pango-fontset-cached-private.h
@@ -44,6 +44,8 @@ struct _PangoFontsetCached
GList cache_link;
GHashTable *cache;
+ PangoColorPalette palette;
+
#ifdef HAVE_CAIRO
cairo_font_options_t *font_options;
#endif
diff --git a/pango/pango-fontset-cached.c b/pango/pango-fontset-cached.c
index 2692ac24b..09a48c587 100644
--- a/pango/pango-fontset-cached.c
+++ b/pango/pango-fontset-cached.c
@@ -27,6 +27,7 @@
#include "pango-font-private.h"
#include "pango-font-face-private.h"
#include "pango-generic-family-private.h"
+#include "pango-context.h"
#ifdef HAVE_CAIRO
#include "pangocairo-font.h"
@@ -40,6 +41,7 @@ pango_fontset_cached_init (PangoFontsetCached *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 = PANGO_COLOR_PALETTE_DEFAULT;
#ifdef HAVE_CAIRO
fontset->font_options = NULL;
#endif
@@ -81,6 +83,31 @@ find_font_for_face (PangoFontsetCached *self,
return NULL;
}
+static PangoFont *
+create_font_for_face (PangoFontsetCached *self,
+ PangoFontFace *face)
+{
+ PangoFont *font;
+
+ font = pango_font_face_create_font (face,
+ self->description,
+ self->dpi,
+ self->ctm);
+ pango_font_set_color_palette (font, self->palette);
+#ifdef HAVE_CAIRO
+ pango_cairo_font_set_font_options (font, self->font_options);
+#endif
+
+ return font;
+}
+
+void
+pango_fontset_cached_add_face (PangoFontsetCached *self,
+ PangoFontFace *face)
+{
+ g_ptr_array_add (self->items, create_font_for_face (self, face));
+}
+
static PangoFont *
pango_fontset_cached_get_font (PangoFontset *fontset,
guint wc)
@@ -129,19 +156,9 @@ pango_fontset_cached_get_font (PangoFontset *fontset,
font = find_font_for_face (self, face);
if (font)
- {
- retval = g_object_ref (font);
- }
+ retval = g_object_ref (font);
else
- {
- retval = pango_font_face_create_font (face,
- self->description,
- self->dpi,
- self->ctm);
-#ifdef HAVE_CAIRO
- pango_cairo_font_set_font_options (retval, self->font_options);
-#endif
- }
+ retval = create_font_for_face (self, face);
break;
}
}
@@ -175,15 +192,7 @@ pango_fontset_cached_get_first_font (PangoFontsetCached *self)
if (font)
g_object_ref (font);
else
- {
- font = pango_font_face_create_font (face,
- self->description,
- self->dpi,
- self->ctm);
-#ifdef HAVE_CAIRO
- pango_cairo_font_set_font_options (font, self->font_options);
-#endif
- }
+ font = create_font_for_face (self, face);
return font;
}
@@ -249,15 +258,7 @@ pango_fontset_cached_foreach (PangoFontset *fontset,
if (font)
g_object_ref (font);
else
- {
- font = pango_font_face_create_font (face,
- self->description,
- self->dpi,
- self->ctm);
-#ifdef HAVE_CAIRO
- pango_cairo_font_set_font_options (font, self->font_options);
-#endif
- }
+ font = create_font_for_face (self, face);
}
if ((*func) (fontset, font, data))
@@ -300,22 +301,6 @@ pango_fontset_cached_new (const PangoFontDescription *description,
return self;
}
-void
-pango_fontset_cached_add_face (PangoFontsetCached *self,
- PangoFontFace *face)
-{
- PangoFont *font;
-
- font = pango_font_face_create_font (face,
- self->description,
- self->dpi,
- self->ctm);
-#ifdef HAVE_CAIRO
- pango_cairo_font_set_font_options (font, self->font_options);
-#endif
- g_ptr_array_add (self->items, font);
-}
-
void
pango_fontset_cached_add_family (PangoFontsetCached *self,
PangoGenericFamily *family)
diff --git a/pango/pango-types.h b/pango/pango-types.h
index f39f35b29..250409a3f 100644
--- a/pango/pango-types.h
+++ b/pango/pango-types.h
@@ -319,6 +319,12 @@ typedef enum
*/
#define PANGO_LEADING_TRIM_BOTH (PANGO_LEADING_TRIM_START|PANGO_LEADING_TRIM_END)
+typedef enum {
+ PANGO_COLOR_PALETTE_DEFAULT,
+ PANGO_COLOR_PALETTE_FOR_LIGHT_BACKGROUND,
+ PANGO_COLOR_PALETTE_FOR_DARK_BACKGROUND
+} PangoColorPalette;
+
/*
* PANGO_DECLARE_INTERNAL_TYPE:
* @ModuleObjName: The name of the new type, in camel case (like GtkWidget)
diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c
index d23d006a8..b87194388 100644
--- a/pango/pangocairo-font.c
+++ b/pango/pangocairo-font.c
@@ -268,10 +268,51 @@ create_cairo_font_face_for_hb_font (PangoFont *font)
#endif
+static int
+find_palette_for_font (PangoFont *font)
+{
+ hb_font_t *hbfont = pango_font_get_hb_font (font);
+ hb_face_t *hbface = hb_font_get_face (hbfont);
+
+ if (hb_ot_color_has_palettes (hbface))
+ {
+ for (int i = 0; i < hb_ot_color_palette_get_count (hbface); i++)
+ {
+ hb_ot_color_palette_flags_t flags;
+
+ flags = hb_ot_color_palette_get_flags (hbface, i);
+
+ switch (font->palette)
+ {
+ case PANGO_COLOR_PALETTE_DEFAULT:
+ if (flags & HB_OT_COLOR_PALETTE_FLAG_DEFAULT)
+ return i;
+ break;
+
+ case PANGO_COLOR_PALETTE_FOR_LIGHT_BACKGROUND:
+ if (flags & HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND)
+ return i;
+ break;
+
+ case PANGO_COLOR_PALETTE_FOR_DARK_BACKGROUND:
+ if (flags & HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND)
+ return i;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ return CAIRO_COLOR_PALETTE_DEFAULT;
+}
+
static cairo_scaled_font_t *
_pango_cairo_font_private_get_scaled_font (PangoCairoFontPrivate *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;
@@ -292,10 +333,18 @@ _pango_cairo_font_private_get_scaled_font (PangoCairoFontPrivate *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_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/utils/viewer-pangocairo.c b/utils/viewer-pangocairo.c
index 2bf2e0d69..a7aee380f 100644
--- a/utils/viewer-pangocairo.c
+++ b/utils/viewer-pangocairo.c
@@ -34,6 +34,24 @@
static int opt_annotate = 0;
static gboolean opt_userfont = 0;
static char **opt_font_file = NULL;
+static char *opt_palette = NULL;
+
+static PangoColorPalette
+parse_palette (const char *palette)
+{
+ if (palette == NULL ||
+ strcmp (palette, "default") == 0)
+ return PANGO_COLOR_PALETTE_DEFAULT;
+ else if (strcmp (palette, "for-dark-bg") == 0)
+ return PANGO_COLOR_PALETTE_FOR_DARK_BACKGROUND;
+ else if (strcmp (palette, "for-light-bg") == 0)
+ return PANGO_COLOR_PALETTE_FOR_LIGHT_BACKGROUND;
+ else
+ {
+ g_warning ("Unsupported palette value: %s", palette);
+ return PANGO_COLOR_PALETTE_DEFAULT;
+ }
+}
typedef struct
{
@@ -44,6 +62,7 @@ typedef struct
PangoFontMap *fontmap;
cairo_font_options_t *font_options;
gboolean subpixel_positions;
+ PangoColorPalette palette;
} CairoViewer;
static gpointer
@@ -119,6 +138,7 @@ pangocairo_view_create (const PangoViewer *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 = parse_palette (opt_palette);
return instance;
}
@@ -146,6 +166,7 @@ pangocairo_view_get_context (gpointer instance)
context = pango_context_new_with_font_map (c->fontmap);
pango_cairo_context_set_font_options (context, c->font_options);
pango_context_set_round_glyph_positions (context, !c->subpixel_positions);
+ pango_context_set_color_palette (context, c->palette);
return context;
}
@@ -973,6 +994,7 @@ pangocairo_view_get_option_group (const PangoViewer *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]