[cairo-commit] 3 commits - src/cairo-ft-font.c test/Makefile.sources test/reference test/text-unhinted-metrics.c

Adrian Johnson ajohnson at kemper.freedesktop.org
Tue Jul 5 10:59:32 UTC 2016


 src/cairo-ft-font.c                              |  142 ++++++++++++++---------
 test/Makefile.sources                            |    1 
 test/reference/text-rotate.pdf.ref.png           |binary
 test/reference/text-rotate.ps.ref.png            |binary
 test/reference/text-rotate.ref.png               |binary
 test/reference/text-unhinted-metrics.pdf.ref.png |binary
 test/reference/text-unhinted-metrics.ps.ref.png  |binary
 test/reference/text-unhinted-metrics.ref.png     |binary
 test/text-unhinted-metrics.c                     |   73 +++++++++++
 9 files changed, 165 insertions(+), 51 deletions(-)

New commits:
commit deb994488ff5f5ca1ad770cef66cad7a04606e94
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Jun 18 13:41:28 2016 +0930

    test: refresh text-rotate ref images

diff --git a/test/reference/text-rotate.pdf.ref.png b/test/reference/text-rotate.pdf.ref.png
index c097386..3b1c95e 100644
Binary files a/test/reference/text-rotate.pdf.ref.png and b/test/reference/text-rotate.pdf.ref.png differ
diff --git a/test/reference/text-rotate.ps.ref.png b/test/reference/text-rotate.ps.ref.png
index cc57d73..a0f8fbe 100644
Binary files a/test/reference/text-rotate.ps.ref.png and b/test/reference/text-rotate.ps.ref.png differ
diff --git a/test/reference/text-rotate.ref.png b/test/reference/text-rotate.ref.png
index a3e3c41..ac8b681 100644
Binary files a/test/reference/text-rotate.ref.png and b/test/reference/text-rotate.ref.png differ
commit bb4595130b2087ae7c32d688267fa32f398de7c7
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Jun 18 13:16:57 2016 +0930

    ft: set font size to em size when retrieving unhinted metrics
    
    fixes text-unhinted-metrics test

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index a0c7beb..74d43cc 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -2209,6 +2209,55 @@ _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (void        *abstract_font,
 }
 
 static cairo_int_status_t
+_cairo_ft_scaled_glyph_load_glyph (cairo_ft_scaled_font_t *scaled_font,
+				   cairo_scaled_glyph_t   *scaled_glyph,
+				   FT_Face                 face,
+				   int                     load_flags,
+				   cairo_bool_t            use_em_size,
+				   cairo_bool_t            vertical_layout)
+{
+    FT_Error error;
+    cairo_status_t status;
+
+    if (use_em_size) {
+	cairo_matrix_t em_size;
+	cairo_matrix_init_scale (&em_size, face->units_per_EM, face->units_per_EM);
+	status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled, &em_size);
+    } else {
+	status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
+						    &scaled_font->base.scale);
+    }
+    if (unlikely (status))
+	return status;
+
+    error = FT_Load_Glyph (face,
+			   _cairo_scaled_glyph_index(scaled_glyph),
+			   load_flags);
+    /* XXX ignoring all other errors for now.  They are not fatal, typically
+     * just a glyph-not-found. */
+    if (error == FT_Err_Out_Of_Memory)
+	return  _cairo_error (CAIRO_STATUS_NO_MEMORY);
+
+    /*
+     * synthesize glyphs if requested
+     */
+#if HAVE_FT_GLYPHSLOT_EMBOLDEN
+    if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_BOLD)
+	FT_GlyphSlot_Embolden (face->glyph);
+#endif
+
+#if HAVE_FT_GLYPHSLOT_OBLIQUE
+    if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_OBLIQUE)
+	FT_GlyphSlot_Oblique (face->glyph);
+#endif
+
+    if (vertical_layout)
+	_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, face->glyph);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
 _cairo_ft_scaled_glyph_init (void			*abstract_font,
 			     cairo_scaled_glyph_t	*scaled_glyph,
 			     cairo_scaled_glyph_info_t	 info)
@@ -2218,22 +2267,17 @@ _cairo_ft_scaled_glyph_init (void			*abstract_font,
     cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
     FT_GlyphSlot glyph;
     FT_Face face;
-    FT_Error error;
     int load_flags = scaled_font->ft_options.load_flags;
     FT_Glyph_Metrics *metrics;
     double x_factor, y_factor;
     cairo_bool_t vertical_layout = FALSE;
-    cairo_status_t status;
+    cairo_status_t status = CAIRO_STATUS_SUCCESS;
+    cairo_bool_t scaled_glyph_loaded = FALSE;
 
     face = _cairo_ft_unscaled_font_lock_face (unscaled);
     if (!face)
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
-    status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
-				                &scaled_font->base.scale);
-    if (unlikely (status))
-	goto FAIL;
-
     /* Ignore global advance unconditionally */
     load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
 
@@ -2264,37 +2308,23 @@ _cairo_ft_scaled_glyph_init (void			*abstract_font,
     /* load_flags |= FT_LOAD_COLOR; */
 #endif
 
-    error = FT_Load_Glyph (face,
-			   _cairo_scaled_glyph_index(scaled_glyph),
-			   load_flags);
-    /* XXX ignoring all other errors for now.  They are not fatal, typically
-     * just a glyph-not-found. */
-    if (error == FT_Err_Out_Of_Memory) {
-	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	goto FAIL;
-    }
-
-    glyph = face->glyph;
 
-    /*
-     * synthesize glyphs if requested
-     */
-#if HAVE_FT_GLYPHSLOT_EMBOLDEN
-    if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_BOLD)
-	FT_GlyphSlot_Embolden (glyph);
-#endif
+    if (info & CAIRO_SCALED_GLYPH_INFO_METRICS) {
 
-#if HAVE_FT_GLYPHSLOT_OBLIQUE
-    if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_OBLIQUE)
-	FT_GlyphSlot_Oblique (glyph);
-#endif
+	cairo_bool_t hint_metrics = scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF;
 
-    if (vertical_layout)
-	_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, glyph);
+	status = _cairo_ft_scaled_glyph_load_glyph (scaled_font,
+						    scaled_glyph,
+						    face,
+						    load_flags,
+						    !hint_metrics,
+						    vertical_layout);
+	if (unlikely (status))
+	    goto FAIL;
 
-    if (info & CAIRO_SCALED_GLYPH_INFO_METRICS) {
+	glyph = face->glyph;
+	scaled_glyph_loaded = hint_metrics;
 
-	cairo_bool_t hint_metrics = scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF;
 	/*
 	 * Compute font-space metrics
 	 */
@@ -2392,6 +2422,20 @@ _cairo_ft_scaled_glyph_init (void			*abstract_font,
     if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
 	cairo_image_surface_t	*surface;
 
+	if (!scaled_glyph_loaded) {
+	    status = _cairo_ft_scaled_glyph_load_glyph (scaled_font,
+							scaled_glyph,
+							face,
+							load_flags,
+							FALSE,
+							vertical_layout);
+	    if (unlikely (status))
+		goto FAIL;
+
+	    glyph = face->glyph;
+	    scaled_glyph_loaded = TRUE;
+	}
+
 	if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
 	    status = _render_glyph_outline (face, &scaled_font->ft_options.base,
 					    &surface);
@@ -2423,27 +2467,23 @@ _cairo_ft_scaled_glyph_init (void			*abstract_font,
 	 * so reload it. This will probably never occur though
 	 */
 	if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
-	    error = FT_Load_Glyph (face,
-				   _cairo_scaled_glyph_index(scaled_glyph),
-				   load_flags | FT_LOAD_NO_BITMAP);
-	    /* XXX ignoring all other errors for now.  They are not fatal, typically
-	     * just a glyph-not-found. */
-	    if (error == FT_Err_Out_Of_Memory) {
-		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    scaled_glyph_loaded = FALSE;
+	    load_flags |= FT_LOAD_NO_BITMAP;
+	}
+
+	if (!scaled_glyph_loaded) {
+	    status = _cairo_ft_scaled_glyph_load_glyph (scaled_font,
+							scaled_glyph,
+							face,
+							load_flags,
+							FALSE,
+							vertical_layout);
+	    if (unlikely (status))
 		goto FAIL;
-	    }
-#if HAVE_FT_GLYPHSLOT_EMBOLDEN
-	    if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_BOLD)
-		FT_GlyphSlot_Embolden (glyph);
-#endif
-#if HAVE_FT_GLYPHSLOT_OBLIQUE
-	    if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_OBLIQUE)
-		FT_GlyphSlot_Oblique (glyph);
-#endif
-	    if (vertical_layout)
-		_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, glyph);
 
+	    glyph = face->glyph;
 	}
+
 	if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
 	    status = _decompose_glyph_outline (face, &scaled_font->ft_options.base,
 					       &path);
commit d92015e4f9e654580c1dac6adf860eafd804a4ba
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Jun 18 13:15:37 2016 +0930

    add test text-unhinted-metrics
    
    Based on bug report in https://lists.cairographics.org/archives/cairo/2016-April/027334.html

diff --git a/test/Makefile.sources b/test/Makefile.sources
index 8a11c0b..479b2ca 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -354,6 +354,7 @@ test_sources = \
 	text-pattern.c					\
 	text-rotate.c					\
 	text-transform.c				\
+	text-unhinted-metrics.c				\
 	text-zero-len.c					\
 	thin-lines.c                                    \
 	tighten-bounds.c				\
diff --git a/test/reference/text-unhinted-metrics.pdf.ref.png b/test/reference/text-unhinted-metrics.pdf.ref.png
new file mode 100644
index 0000000..ac89521
Binary files /dev/null and b/test/reference/text-unhinted-metrics.pdf.ref.png differ
diff --git a/test/reference/text-unhinted-metrics.ps.ref.png b/test/reference/text-unhinted-metrics.ps.ref.png
new file mode 100644
index 0000000..d34ea34
Binary files /dev/null and b/test/reference/text-unhinted-metrics.ps.ref.png differ
diff --git a/test/reference/text-unhinted-metrics.ref.png b/test/reference/text-unhinted-metrics.ref.png
new file mode 100644
index 0000000..7bfe2f6
Binary files /dev/null and b/test/reference/text-unhinted-metrics.ref.png differ
diff --git a/test/text-unhinted-metrics.c b/test/text-unhinted-metrics.c
new file mode 100644
index 0000000..352ab4e
--- /dev/null
+++ b/test/text-unhinted-metrics.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright © 2016 Adrian Johnson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Red Hat, Inc. not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Adrian Johnson <ajohnson at redneon.com>
+ */
+
+/* Test CAIRO_HINT_METRICS_OFF with a TrueType font.
+ *
+ * Based on the test case in https://lists.cairographics.org/archives/cairo/2016-April/027334.html
+ */
+
+#include "cairo-test.h"
+
+#define WIDTH  100
+#define HEIGHT 100
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    cairo_font_options_t *font_options;
+    double size, y;
+
+    cairo_set_source_rgb (cr, 1, 1, 1);
+    cairo_paint (cr);
+
+    cairo_select_font_face (cr, CAIRO_TEST_FONT_FAMILY "DejaVu Sans Mono",
+			    CAIRO_FONT_SLANT_NORMAL,
+			    CAIRO_FONT_WEIGHT_NORMAL);
+
+    font_options = cairo_font_options_create();
+    cairo_get_font_options (cr, font_options);
+    cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);
+    cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
+    cairo_set_font_options (cr, font_options);
+    cairo_font_options_destroy (font_options);
+
+    y = 0.0;
+    cairo_set_source_rgb (cr, 0, 0, 0);
+    for (size = 8.0; size <= 10.0; size += 0.25) {
+	cairo_set_font_size (cr, size);
+	y += 10.0;
+	cairo_move_to (cr, 5, y);
+	cairo_show_text (cr, "abcdefghijklm");
+    }
+
+    return CAIRO_TEST_SUCCESS;
+}
+
+CAIRO_TEST (text_unhinted_metrics,
+	    "Test CAIRO_HINT_METRICS_OFF",
+	    "text, font", /* keywords */
+	    NULL, /* requirements */
+	    WIDTH, HEIGHT,
+	    NULL, draw)


More information about the cairo-commit mailing list