[cairo-commit] 4 commits - src/cairo-font-options.c src/cairo-ft-font.c src/cairo.h src/cairo-surface.c src/cairo-svg-surface.c src/cairo-types-private.h test/ft-color-font.c test/reference

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jun 30 23:00:14 UTC 2022


 src/cairo-font-options.c                       |   50 ++++++++++++++++++++++++-
 src/cairo-ft-font.c                            |   12 +++++-
 src/cairo-surface.c                            |    4 +-
 src/cairo-svg-surface.c                        |   28 ++++++++------
 src/cairo-types-private.h                      |    1 
 src/cairo.h                                    |   30 +++++++++++++++
 test/ft-color-font.c                           |   20 +++++++---
 test/reference/ft-color-font.image16.ref.png   |binary
 test/reference/ft-color-font.pdf.ref.png       |binary
 test/reference/ft-color-font.recording.ref.png |binary
 test/reference/ft-color-font.ref.png           |binary
 test/reference/ft-color-font.script.xfail.png  |binary
 12 files changed, 125 insertions(+), 20 deletions(-)

New commits:
commit ff08edfcc62fef78d9948b3edbb2672a77f7fbd1
Merge: d64f9699e cdb7c298c
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Thu Jun 30 23:00:12 2022 +0000

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

commit cdb7c298c7b89307ad69b94a1126221bd7c06579
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Jun 18 12:50:24 2022 +0930

    svg: Fix invalid output when image size is 0x0
    
    cairo_surface_write_to_png_stream fails if width or height is 0

diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index dfb72b2ad..b39a94a37 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -2118,24 +2118,28 @@ _cairo_svg_surface_emit_surface (cairo_svg_document_t *document,
     assert (is_bounded);
 
     _cairo_svg_stream_printf (&document->xml_node_defs,
-			      "<image id=\"source-%d\" x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" xlink:href=\"",
+			      "<image id=\"source-%d\" x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\"",
 			      source_id,
 			      extents.x, extents.y,
 			      extents.width, extents.height);
 
-    cairo_surface_get_mime_data (surface, CAIRO_MIME_TYPE_URI,
-				 &uri, &uri_len);
-    if (uri != NULL) {
-	_cairo_svg_surface_emit_attr_value (&document->xml_node_defs,
-					    uri, uri_len);
-    } else {
-	status = _cairo_surface_base64_encode (surface,
-					       &document->xml_node_defs);
-	if (unlikely (status))
-	    return status;
+    if (extents.width != 0 && extents.height != 0) {
+	_cairo_svg_stream_printf (&document->xml_node_defs, " xlink:href=\"");
+	cairo_surface_get_mime_data (surface, CAIRO_MIME_TYPE_URI,
+				     &uri, &uri_len);
+	if (uri != NULL) {
+	    _cairo_svg_surface_emit_attr_value (&document->xml_node_defs,
+						uri, uri_len);
+	} else {
+	    status = _cairo_surface_base64_encode (surface,
+						   &document->xml_node_defs);
+	    if (unlikely (status))
+		return status;
+	}
+    _cairo_svg_stream_printf (&document->xml_node_defs, "\"");
     }
 
-    _cairo_svg_stream_printf (&document->xml_node_defs, "\"/>\n");
+    _cairo_svg_stream_printf (&document->xml_node_defs, "/>\n");
 
     return CAIRO_STATUS_SUCCESS;
 }
commit 99d59f00d649c2b347f41e6e24fb0ddb2abb077b
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Jun 18 05:59:38 2022 +0930

    Test color_mode option in ft-color-font test

diff --git a/test/ft-color-font.c b/test/ft-color-font.c
index 58a1dc3ca..d10555dcf 100644
--- a/test/ft-color-font.c
+++ b/test/ft-color-font.c
@@ -27,9 +27,9 @@
 #include "cairo-test.h"
 #include <cairo-ft.h>
 
-#define WIDTH  50
-#define HEIGHT WIDTH
-
+#define SIZE 40
+#define HEIGHT SIZE
+#define WIDTH  (SIZE * 1.5)
 #define FONT "Noto Color Emoji"
 
 static const char smiley_face_utf8[] = { 0xf0, 0x9f, 0x99, 0x82, 0x00 }; /* U+1F642 */
@@ -87,13 +87,23 @@ static cairo_test_status_t
 draw (cairo_t *cr, int width, int height)
 {
     cairo_test_status_t result;
+    cairo_font_options_t *font_options;
 
     result = set_color_emoji_font (cr);
     if (result != CAIRO_TEST_SUCCESS)
         return result;
 
-    cairo_set_font_size (cr, HEIGHT/2);
-    cairo_move_to (cr, width/4, 3*height/4);
+    cairo_set_font_size (cr, SIZE/2);
+    cairo_move_to (cr, SIZE/8, 0.7 * SIZE);
+
+    cairo_show_text(cr, smiley_face_utf8);
+
+    /* Show that the color mode font option can disable color rendering */
+    font_options = cairo_font_options_create ();
+    cairo_get_font_options (cr, font_options);
+    cairo_font_options_set_color_mode (font_options, CAIRO_COLOR_MODE_NO_COLOR);
+    cairo_set_font_options (cr, font_options);
+    cairo_font_options_destroy (font_options);
 
     cairo_show_text(cr, smiley_face_utf8);
 
diff --git a/test/reference/ft-color-font.image16.ref.png b/test/reference/ft-color-font.image16.ref.png
index 579cd69c9..8c7463420 100644
Binary files a/test/reference/ft-color-font.image16.ref.png and b/test/reference/ft-color-font.image16.ref.png differ
diff --git a/test/reference/ft-color-font.pdf.ref.png b/test/reference/ft-color-font.pdf.ref.png
new file mode 100644
index 000000000..3ea9e7850
Binary files /dev/null and b/test/reference/ft-color-font.pdf.ref.png differ
diff --git a/test/reference/ft-color-font.recording.ref.png b/test/reference/ft-color-font.recording.ref.png
index 902a00c17..5035dde11 100644
Binary files a/test/reference/ft-color-font.recording.ref.png and b/test/reference/ft-color-font.recording.ref.png differ
diff --git a/test/reference/ft-color-font.ref.png b/test/reference/ft-color-font.ref.png
index 020a1a501..104f24923 100644
Binary files a/test/reference/ft-color-font.ref.png and b/test/reference/ft-color-font.ref.png differ
diff --git a/test/reference/ft-color-font.script.xfail.png b/test/reference/ft-color-font.script.xfail.png
index f8b166180..238827723 100644
Binary files a/test/reference/ft-color-font.script.xfail.png and b/test/reference/ft-color-font.script.xfail.png differ
commit 6bd549e8df66cc450b40cf26ef56f0ae5d8f37de
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Fri Jun 17 21:54:30 2022 +0930

    Add color mode option

diff --git a/src/cairo-font-options.c b/src/cairo-font-options.c
index 73a1c6b75..30d695894 100644
--- a/src/cairo-font-options.c
+++ b/src/cairo-font-options.c
@@ -57,6 +57,7 @@ static const cairo_font_options_t _cairo_font_options_nil = {
     CAIRO_HINT_METRICS_DEFAULT,
     CAIRO_ROUND_GLYPH_POS_DEFAULT,
     NULL, /* variations */
+    CAIRO_COLOR_MODE_DEFAULT,
     CAIRO_COLOR_PALETTE_DEFAULT
 };
 
@@ -76,6 +77,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->color_mode = CAIRO_COLOR_MODE_DEFAULT;
     options->palette_index = CAIRO_COLOR_PALETTE_DEFAULT;
 }
 
@@ -90,6 +92,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->color_mode = other->color_mode;
     options->palette_index = other->palette_index;
 }
 
@@ -259,6 +262,8 @@ cairo_font_options_merge (cairo_font_options_t       *options,
       }
     }
 
+    if (other->color_mode != CAIRO_COLOR_MODE_DEFAULT)
+	options->color_mode = other->color_mode;
     if (other->palette_index != CAIRO_COLOR_PALETTE_DEFAULT)
 	options->palette_index = other->palette_index;
 }
@@ -298,6 +303,7 @@ cairo_font_options_equal (const cairo_font_options_t *options,
             ((options->variations == NULL && other->variations == NULL) ||
              (options->variations != NULL && other->variations != NULL &&
               strcmp (options->variations, other->variations) == 0)) &&
+	    options->color_mode == other->color_mode &&
 	    options->palette_index == other->palette_index);
 }
 slim_hidden_def (cairo_font_options_equal);
@@ -333,7 +339,8 @@ cairo_font_options_hash (const cairo_font_options_t *options)
 	    (options->subpixel_order << 4) |
 	    (options->lcd_filter << 8) |
 	    (options->hint_style << 12) |
-	    (options->hint_metrics << 16)) ^ hash;
+	    (options->hint_metrics << 16) |
+            (options->color_mode << 20)) ^ hash;
 }
 slim_hidden_def (cairo_font_options_hash);
 
@@ -631,6 +638,47 @@ cairo_font_options_get_variations (cairo_font_options_t *options)
   return options->variations;
 }
 
+/**
+ * cairo_font_options_set_color_mode:
+ * @options: a #cairo_font_options_t
+ * @font_color: the new color mode
+ *
+ * Sets the color mode for the font options object. This controls
+ * whether color fonts are to be rendered in color or as outlines.
+ * See the documentation for #cairo_color_mode_t for full details.
+ *
+ * Since: 1.18
+ **/
+cairo_public void
+cairo_font_options_set_color_mode (cairo_font_options_t *options,
+                                   cairo_color_mode_t    color_mode)
+{
+    if (cairo_font_options_status (options))
+	return;
+
+    options->color_mode = color_mode;
+}
+
+/**
+ * cairo_font_options_get_color_mode:
+ * @options: a #cairo_font_options_t
+ *
+ * Gets the color mode for the font options object.
+ * See the documentation for #cairo_color_mode_t for full details.
+ *
+ * Return value: the color mode for the font options object
+ *
+ * Since: 1.18
+ **/
+cairo_public cairo_color_mode_t
+cairo_font_options_get_color_mode (const cairo_font_options_t *options)
+{
+    if (cairo_font_options_status ((cairo_font_options_t *) options))
+	return CAIRO_COLOR_MODE_DEFAULT;
+
+    return options->color_mode;
+}
+
 /**
  * cairo_font_options_set_color_palette:
  * @options: a #cairo_font_options_t
diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 41a9a8321..cdb02ff65 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -2664,10 +2664,20 @@ _cairo_ft_scaled_glyph_init (void			*abstract_font,
 
 	cairo_bool_t hint_metrics = scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF;
 
+	/* The font metrics for color glyphs should be the same as the
+	 * outline glyphs. But just in case there aren't, request the
+	 * color or outline metrics based on the font option and if
+	 * the font has color.
+	 */
+	int color_flag = 0;
+#ifdef FT_LOAD_COLOR
+	if (unscaled->have_color && scaled_font->base.options.color_mode != CAIRO_COLOR_MODE_NO_COLOR)
+	    color_flag = FT_LOAD_COLOR;
+#endif
 	status = _cairo_ft_scaled_glyph_load_glyph (scaled_font,
 						    scaled_glyph,
 						    face,
-						    load_flags,
+						    load_flags | color_flag,
 						    !hint_metrics,
 						    vertical_layout);
 	if (unlikely (status))
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 0bc0b8c7d..105f4bff1 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -2901,7 +2901,9 @@ _cairo_surface_show_text_glyphs (cairo_surface_t	    *surface,
     if (unlikely (status))
 	return status;
 
-    if (_cairo_scaled_font_has_color_glyphs (scaled_font)) {
+    if (_cairo_scaled_font_has_color_glyphs (scaled_font) &&
+	scaled_font->options.color_mode != CAIRO_COLOR_MODE_NO_COLOR)
+    {
         utf8_copy = malloc (sizeof (char) * utf8_len);
         memcpy (utf8_copy, utf8, sizeof (char) * utf8_len);
         utf8 = utf8_copy;
diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h
index f01afcf2d..a9980f3b9 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;
+    cairo_color_mode_t color_mode;
     unsigned int palette_index;
 };
 
diff --git a/src/cairo.h b/src/cairo.h
index aec16eaed..82e2c69d8 100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -1369,6 +1369,29 @@ typedef enum _cairo_hint_metrics {
     CAIRO_HINT_METRICS_ON
 } cairo_hint_metrics_t;
 
+/**
+ * cairo_color_mode_t:
+ * @CAIRO_COLOR_MODE_DEFAULT: Use the default color mode for
+ * font backend and target device, since 1.18.
+ * @CAIRO_COLOR_MODE_NO_COLOR: Disable rendering color glyphs. Glyphs are
+ * always rendered as outline glyphs, since 1.18.
+ * @CAIRO_COLOR_MODE_COLOR: Enable rendering color glyphs. If the font
+ * contains a color presentation for a glyph, and when supported by
+ * the font backend, the glyph will be rendered in color, since 1.18.
+ *
+ * Specifies if color fonts are to be rendered using the the color
+ * glyphs or outline glyphs. Glyphs that do not have a color
+ * presentation, and non-color fonts are not affected by this font
+ * option.
+ *
+ * Since: 1.18
+ **/
+typedef enum _cairo_color_mode {
+    CAIRO_COLOR_MODE_DEFAULT,
+    CAIRO_COLOR_MODE_NO_COLOR,
+    CAIRO_COLOR_MODE_COLOR
+} cairo_color_mode_t;
+
 /**
  * cairo_font_options_t:
  *
@@ -1448,6 +1471,13 @@ cairo_font_options_set_variations (cairo_font_options_t *options,
 
 #define CAIRO_COLOR_PALETTE_DEFAULT 0
 
+cairo_public void
+cairo_font_options_set_color_mode (cairo_font_options_t *options,
+                                   cairo_color_mode_t    color_mode);
+
+cairo_public cairo_color_mode_t
+cairo_font_options_get_color_mode (const cairo_font_options_t *options);
+
 cairo_public unsigned int
 cairo_font_options_get_color_palette (const cairo_font_options_t *options);
 


More information about the cairo-commit mailing list