[cairo-commit] 2 commits - configure.ac meson.build src/cairo-font-options.c src/cairo-ft-font.c src/cairo.h src/cairo-types-private.h src/win32 test/font-options.c

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jun 17 12:58:43 UTC 2022


 configure.ac                       |    2 -
 meson.build                        |    2 -
 src/cairo-font-options.c           |   54 +++++++++++++++++++++++++++++++++++--
 src/cairo-ft-font.c                |   12 +++++++-
 src/cairo-types-private.h          |    1 
 src/cairo.h                        |    9 ++++++
 src/win32/cairo-dwrite-font.cpp    |   13 +++++++-
 src/win32/cairo-dwrite-private.hpp |    1 
 test/font-options.c                |    4 ++
 9 files changed, 91 insertions(+), 7 deletions(-)

New commits:
commit f408ae9269c9e45dcf48b9b2e466dee4b3b2771e
Merge: b5d2395a5 f0ba2165a
Author: Uli Schlachter <psychon at znc.in>
Date:   Fri Jun 17 12:58:42 2022 +0000

    Merge branch 'palette-option' into 'master'
    
    Add color palette font option
    
    See merge request cairo/cairo!332

commit f0ba2165a6a23bdbc9d6e93da4231c2cac77a2c2
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Thu Jun 16 21:44:04 2022 +0930

    Add color palette option

diff --git a/configure.ac b/configure.ac
index c75648779..c30ce0916 100644
--- a/configure.ac
+++ b/configure.ac
@@ -466,7 +466,7 @@ if test "x$use_ft" = "xyes"; then
   LIBS="$LIBS $ft_LIBS"
   CFLAGS="$CFLAGS $ft_CFLAGS"
 
-  AC_CHECK_FUNCS(FT_Get_X11_Font_Format FT_GlyphSlot_Embolden FT_GlyphSlot_Oblique FT_Load_Sfnt_Table FT_Library_SetLcdFilter FT_Get_Var_Design_Coordinates FT_Done_MM_Var FT_Palette_Set_Foreground_Color)
+  AC_CHECK_FUNCS(FT_Get_X11_Font_Format FT_GlyphSlot_Embolden FT_GlyphSlot_Oblique FT_Load_Sfnt_Table FT_Library_SetLcdFilter FT_Get_Var_Design_Coordinates FT_Done_MM_Var FT_Palette_Select)
 
   AC_MSG_CHECKING(for FT_HAS_COLOR)
   AC_LINK_IFELSE([AC_LANG_PROGRAM([
diff --git a/meson.build b/meson.build
index 35ae65b59..1080c6614 100644
--- a/meson.build
+++ b/meson.build
@@ -326,7 +326,7 @@ if freetype_dep.found()
     'FT_Library_SetLcdFilter',
     'FT_Get_Var_Design_Coordinates',
     'FT_Done_MM_Var',
-    'FT_Palette_Set_Foreground_Color',
+    'FT_Palette_Select',
   ]
 
   if freetype_dep.type_name() == 'internal'
diff --git a/src/cairo-font-options.c b/src/cairo-font-options.c
index 0c4e462b8..73a1c6b75 100644
--- a/src/cairo-font-options.c
+++ b/src/cairo-font-options.c
@@ -56,7 +56,8 @@ static const cairo_font_options_t _cairo_font_options_nil = {
     CAIRO_HINT_STYLE_DEFAULT,
     CAIRO_HINT_METRICS_DEFAULT,
     CAIRO_ROUND_GLYPH_POS_DEFAULT,
-    NULL
+    NULL, /* variations */
+    CAIRO_COLOR_PALETTE_DEFAULT
 };
 
 /**
@@ -75,6 +76,7 @@ _cairo_font_options_init_default (cairo_font_options_t *options)
     options->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
     options->round_glyph_positions = CAIRO_ROUND_GLYPH_POS_DEFAULT;
     options->variations = NULL;
+    options->palette_index = CAIRO_COLOR_PALETTE_DEFAULT;
 }
 
 void
@@ -88,6 +90,7 @@ _cairo_font_options_init_copy (cairo_font_options_t		*options,
     options->hint_metrics = other->hint_metrics;
     options->round_glyph_positions = other->round_glyph_positions;
     options->variations = other->variations ? strdup (other->variations) : NULL;
+    options->palette_index = other->palette_index;
 }
 
 /**
@@ -255,6 +258,9 @@ cairo_font_options_merge (cairo_font_options_t       *options,
         options->variations = strdup (other->variations);
       }
     }
+
+    if (other->palette_index != CAIRO_COLOR_PALETTE_DEFAULT)
+	options->palette_index = other->palette_index;
 }
 slim_hidden_def (cairo_font_options_merge);
 
@@ -291,7 +297,8 @@ cairo_font_options_equal (const cairo_font_options_t *options,
 	    options->round_glyph_positions == other->round_glyph_positions &&
             ((options->variations == NULL && other->variations == NULL) ||
              (options->variations != NULL && other->variations != NULL &&
-              strcmp (options->variations, other->variations) == 0)));
+              strcmp (options->variations, other->variations) == 0)) &&
+	    options->palette_index == other->palette_index);
 }
 slim_hidden_def (cairo_font_options_equal);
 
@@ -320,6 +327,8 @@ cairo_font_options_hash (const cairo_font_options_t *options)
     if (options->variations)
       hash = _cairo_string_hash (options->variations, strlen (options->variations));
 
+    hash ^= options->palette_index;
+
     return ((options->antialias) |
 	    (options->subpixel_order << 4) |
 	    (options->lcd_filter << 8) |
@@ -621,3 +630,44 @@ cairo_font_options_get_variations (cairo_font_options_t *options)
 {
   return options->variations;
 }
+
+/**
+ * cairo_font_options_set_color_palette:
+ * @options: a #cairo_font_options_t
+ * @palette_index: the palette index in the CPAL table
+ *
+ * Sets the OpenType font color palette for the font options
+ * object. OpenType color fonts with a CPAL table may contain multiple
+ * palettes. The default color palette index is %CAIRO_COLOR_PALETTE_DEFAULT. If
+ * @palette_index is invalid, the default palette is used.
+ *
+ * Since: 1.18
+ **/
+void
+cairo_font_options_set_color_palette (cairo_font_options_t *options,
+                                      unsigned int          palette_index)
+{
+    if (cairo_font_options_status (options))
+	return;
+
+    options->palette_index = palette_index;
+}
+
+/**
+ * cairo_font_options_get_color_palette:
+ * @options: a #cairo_font_options_t
+ *
+ * Gets the OpenType color font palette for the font options object.
+ *
+ * Return value: the palette index
+ *
+ * Since: 1.18
+ **/
+unsigned int
+cairo_font_options_get_color_palette (const cairo_font_options_t *options)
+{
+    if (cairo_font_options_status ((cairo_font_options_t *) options))
+	return CAIRO_COLOR_PALETTE_DEFAULT;
+
+    return options->palette_index;
+}
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 3733d8073..41a9a8321 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -176,6 +176,7 @@ struct _cairo_ft_unscaled_font {
     unsigned int have_color_set  : 1;
     unsigned int have_color      : 1;  /* true if the font contains color glyphs */
     FT_Fixed *variations;              /* variation settings that FT_Face came */
+    unsigned int num_palettes;
 
     cairo_mutex_t mutex;
     int lock_count;
@@ -2510,11 +2511,12 @@ _cairo_ft_scaled_glyph_init_surface (cairo_ft_scaled_font_t     *scaled_font,
 	    return CAIRO_INT_STATUS_UNSUPPORTED;
 	}
 
-#ifdef HAVE_FT_PALETTE_SET_FOREGROUND_COLOR
+#ifdef HAVE_FT_PALETTE_SELECT
 	FT_LayerIterator  iterator;
 	FT_UInt layer_glyph_index;
 	FT_UInt layer_color_index;
 	FT_Color color;
+	FT_Palette_Data palette_data;
 
 	/* Check if there is a layer that uses the foreground color */
 	iterator.p  = NULL;
@@ -2536,6 +2538,14 @@ _cairo_ft_scaled_glyph_init_surface (cairo_ft_scaled_font_t     *scaled_font,
 	    color.alpha = (FT_Byte)(foreground_color->alpha * 0xFF);
 	    FT_Palette_Set_Foreground_Color (face, color);
 	}
+
+	if (FT_Palette_Data_Get(face, &palette_data) == 0 && palette_data.num_palettes > 0) {
+	    FT_UShort palette_index = CAIRO_COLOR_PALETTE_DEFAULT;
+	    if (scaled_font->base.options.palette_index < palette_data.num_palettes)
+		palette_index = scaled_font->base.options.palette_index;
+
+	    FT_Palette_Select (face, palette_index, NULL);
+	}
 #endif
 
         load_flags &= ~FT_LOAD_MONOCHROME;
diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h
index 8612172d8..f01afcf2d 100644
--- a/src/cairo-types-private.h
+++ b/src/cairo-types-private.h
@@ -195,6 +195,7 @@ struct _cairo_font_options {
     cairo_hint_metrics_t hint_metrics;
     cairo_round_glyph_positions_t round_glyph_positions;
     char *variations;
+    unsigned int palette_index;
 };
 
 struct _cairo_glyph_text_info {
diff --git a/src/cairo.h b/src/cairo.h
index 32ffc6b3d..aec16eaed 100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -1446,6 +1446,15 @@ cairo_public void
 cairo_font_options_set_variations (cairo_font_options_t *options,
                                    const char           *variations);
 
+#define CAIRO_COLOR_PALETTE_DEFAULT 0
+
+cairo_public unsigned int
+cairo_font_options_get_color_palette (const cairo_font_options_t *options);
+
+cairo_public void
+cairo_font_options_set_color_palette (cairo_font_options_t *options,
+                                      unsigned int          palette_index);
+
 /* This interface is for dealing with text as text, not caring about the
    font object inside the the cairo_t. */
 
diff --git a/src/win32/cairo-dwrite-font.cpp b/src/win32/cairo-dwrite-font.cpp
index edac72c5f..c58827555 100644
--- a/src/win32/cairo-dwrite-font.cpp
+++ b/src/win32/cairo-dwrite-font.cpp
@@ -924,6 +924,15 @@ _cairo_dwrite_scaled_font_init_glyph_color_surface(cairo_dwrite_scaled_font_t *s
         DWRITE_GLYPH_IMAGE_FORMATS_TIFF |
         DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8;
 
+    RefPtr<IDWriteFontFace2> fontFace2;
+    UINT32 palette_count = 0;
+    if (SUCCEEDED(dwrite_font_face->dwriteface->QueryInterface(&fontFace2)))
+	palette_count = fontFace2->GetColorPaletteCount();
+
+    UINT32 palette_index = CAIRO_COLOR_PALETTE_DEFAULT;
+    if (scaled_font->base.options.palette_index < palette_count)
+	palette_index = scaled_font->base.options.palette_index;
+
     hr = DWriteFactory::Instance4()->TranslateColorGlyphRun(
 	origin,
 	&run,
@@ -931,7 +940,7 @@ _cairo_dwrite_scaled_font_init_glyph_color_surface(cairo_dwrite_scaled_font_t *s
 	supported_formats,
 	DWRITE_MEASURING_MODE_NATURAL,
 	&matrix,
-	0,
+	palette_index,
 	&run_enumerator);
 
     if (hr == DWRITE_E_NOCOLOR) {
@@ -1028,7 +1037,7 @@ _cairo_dwrite_scaled_font_init_glyph_color_surface(cairo_dwrite_scaled_font_t *s
 				     &color_run->glyphRun,
 				     foreground_color_brush,
 				     nullptr,
-				     0,
+				     palette_index,
 				     DWRITE_MEASURING_MODE_NATURAL);
 		uses_foreground_color = TRUE;
 		break;
diff --git a/src/win32/cairo-dwrite-private.hpp b/src/win32/cairo-dwrite-private.hpp
index 34f86e8f1..92b096857 100644
--- a/src/win32/cairo-dwrite-private.hpp
+++ b/src/win32/cairo-dwrite-private.hpp
@@ -37,6 +37,7 @@
 #include "cairoint.h"
 #include "cairo-win32-refptr.hpp"
 #include <dwrite.h>
+#include <dwrite_2.h>
 #include <d2d1.h>
 
 /* If either of the dwrite_3.h or d2d1_3.h headers required for color fonts
diff --git a/test/font-options.c b/test/font-options.c
index 873a5c398..cfa7584d9 100644
--- a/test/font-options.c
+++ b/test/font-options.c
@@ -74,6 +74,10 @@ preamble (cairo_test_context_t *ctx)
     cairo_font_options_get_hint_metrics (NULL);
     assert (cairo_font_options_get_hint_metrics (default_options) == CAIRO_HINT_METRICS_DEFAULT);
 
+    cairo_font_options_set_color_palette (NULL, CAIRO_COLOR_PALETTE_DEFAULT);
+    cairo_font_options_get_color_palette (NULL);
+    assert (cairo_font_options_get_color_palette (default_options) == CAIRO_COLOR_PALETTE_DEFAULT);
+
     cairo_font_options_destroy (NULL);
     cairo_font_options_destroy (default_options);
     cairo_font_options_destroy (nil_options);


More information about the cairo-commit mailing list