diff options
author | Matthias Clasen <mclasen@redhat.com> | 2022-07-01 09:57:35 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2022-07-04 11:24:16 -0400 |
commit | 8ee5fe2707db5013dc53084ec1ac44e91b863f6d (patch) | |
tree | 1535b516d1df78b14be71ee84315a3318687d25c /pango2/pangocairo-font.c | |
parent | 9954891c66a241338cc48d2c2236b12dd2368572 (diff) | |
download | pango-8ee5fe2707db5013dc53084ec1ac44e91b863f6d.tar.gz |
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. Also
add a palette attribute that can be used to override
this.
Make the cairo renderer pick up the palette, and
apply it when installing the font for a run.
Predefined palette names are "default", "light",
"dark", "palette0", "palette1", ...
Additionally, PangoHbFace can associate custom
names with palette indices.
To try this, use the new --palette option of
pango-view.
Fonts to try this with are Amiri Quran Colored
or the Bungee Color family.
Diffstat (limited to 'pango2/pangocairo-font.c')
-rw-r--r-- | pango2/pangocairo-font.c | 84 |
1 files changed, 66 insertions, 18 deletions
diff --git a/pango2/pangocairo-font.c b/pango2/pangocairo-font.c index b9103d97..72c06bdb 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" @@ -36,7 +38,8 @@ #include "pango-font-private.h" static Pango2CairoFontPrivate * _pango2_font_get_cairo_font_private (Pango2Font *font); -static cairo_scaled_font_t * _pango2_font_get_scaled_font (Pango2Font *font); +static cairo_scaled_font_t * _pango2_font_get_scaled_font (Pango2Font *font, + GQuark palette); static void _pango2_cairo_font_private_initialize (Pango2CairoFontPrivate *cf_priv, Pango2Font *font, Pango2Gravity gravity, @@ -92,32 +95,74 @@ create_cairo_font_face (Pango2Font *font) return NULL; } +#ifdef CAIRO_COLOR_PALETTE_DEFAULT + +static int +find_palette_index_for_font (Pango2Font *font, + GQuark palette) +{ + Pango2FontFace *face = pango2_font_get_face (font); + + if (PANGO2_IS_HB_FACE (face)) + return pango2_hb_face_get_palette_index (PANGO2_HB_FACE (face), palette); + + return CAIRO_COLOR_PALETTE_DEFAULT; +} + +#endif + static cairo_scaled_font_t * -_pango2_cairo_font_private_get_scaled_font (Pango2CairoFontPrivate *cf_priv) +_pango2_cairo_font_private_get_scaled_font (Pango2CairoFontPrivate *cf_priv, + GQuark palette) { cairo_font_face_t *font_face; + cairo_font_options_t *options; + cairo_matrix_t _font_matrix, *font_matrix; + cairo_matrix_t _ctm, *ctm; - if (G_LIKELY (cf_priv->scaled_font)) + if (G_LIKELY (cf_priv->palette == palette && cf_priv->scaled_font)) return cf_priv->scaled_font; + if (!cf_priv->data && !cf_priv->scaled_font) + return NULL; + /* need to create it */ - if (G_UNLIKELY (cf_priv->data == NULL)) + if (cf_priv->scaled_font) { - /* we have tried to create and failed before */ - return NULL; + font_face = cairo_scaled_font_get_font_face (cf_priv->scaled_font); + cairo_font_face_reference (font_face); + + options = cairo_font_options_create (); + cairo_scaled_font_get_font_options (cf_priv->scaled_font, options); + cairo_scaled_font_get_font_matrix (cf_priv->scaled_font, &_font_matrix); + font_matrix = &_font_matrix; + cairo_scaled_font_get_ctm (cf_priv->scaled_font, &_ctm); + ctm = &_ctm; + + cairo_scaled_font_destroy (cf_priv->scaled_font); + cf_priv->scaled_font = NULL; + } + else + { + font_face = create_cairo_font_face (cf_priv->cfont); + options = cairo_font_options_copy (cf_priv->data->options); + font_matrix = &cf_priv->data->font_matrix; + ctm = &cf_priv->data->ctm; } - - font_face = create_cairo_font_face (cf_priv->cfont); if (G_UNLIKELY (font_face == NULL)) goto done; - cf_priv->scaled_font = cairo_scaled_font_create (font_face, - &cf_priv->data->font_matrix, - &cf_priv->data->ctm, - cf_priv->data->options); +#ifdef CAIRO_COLOR_PALETTE_DEFAULT + cairo_font_options_set_color_palette (options, + find_palette_index_for_font (cf_priv->cfont, palette)); +#endif + cf_priv->palette = palette; + cf_priv->scaled_font = cairo_scaled_font_create (font_face, font_matrix, ctm, options); + + cairo_font_options_destroy (options); cairo_font_face_destroy (font_face); done: @@ -168,8 +213,9 @@ done: return cf_priv->scaled_font; } -cairo_scaled_font_t * -_pango2_font_get_scaled_font (Pango2Font *font) +static cairo_scaled_font_t * +_pango2_font_get_scaled_font (Pango2Font *font, + GQuark palette) { Pango2CairoFontPrivate *cf_priv; @@ -178,12 +224,13 @@ _pango2_font_get_scaled_font (Pango2Font *font) if (G_UNLIKELY (!cf_priv)) return NULL; - return _pango2_cairo_font_private_get_scaled_font (cf_priv); + return _pango2_cairo_font_private_get_scaled_font (cf_priv, palette); } /** * _pango2_cairo_font_install: * @font: a `Pango2CairoFont` + * @palette: a palette * @cr: a #cairo_t * * Makes @font the current font for rendering in the specified @@ -193,11 +240,12 @@ _pango2_font_get_scaled_font (Pango2Font *font) */ gboolean _pango2_cairo_font_install (Pango2Font *font, + GQuark palette, cairo_t *cr) { cairo_scaled_font_t *scaled_font; - scaled_font = _pango2_font_get_scaled_font (font); + scaled_font = _pango2_font_get_scaled_font (font, palette); if (G_UNLIKELY (scaled_font == NULL || cairo_scaled_font_status (scaled_font) != CAIRO_STATUS_SUCCESS)) return FALSE; @@ -239,7 +287,7 @@ _pango2_cairo_font_private_get_hex_box_info (Pango2CairoFontPrivate *cf_priv) if (cf_priv->hbi) return cf_priv->hbi; - scaled_font = _pango2_cairo_font_private_get_scaled_font (cf_priv); + scaled_font = _pango2_cairo_font_private_get_scaled_font (cf_priv, 0); if (G_UNLIKELY (scaled_font == NULL || cairo_scaled_font_status (scaled_font) != CAIRO_STATUS_SUCCESS)) return NULL; @@ -352,7 +400,7 @@ _pango2_cairo_font_private_get_hex_box_info (Pango2CairoFontPrivate *cf_priv) pango2_font_description_free (desc); cairo_font_options_destroy (font_options); - scaled_mini_font = _pango2_font_get_scaled_font (mini_font); + scaled_mini_font = _pango2_font_get_scaled_font (mini_font, 0); if (G_UNLIKELY (scaled_mini_font == NULL || cairo_scaled_font_status (scaled_mini_font) != CAIRO_STATUS_SUCCESS)) return NULL; |