[cairo-commit] 3 commits - src/cairo-ft-font.c

罗晶华 Jinghua Luo jinghua at kemper.freedesktop.org
Sun Jun 18 02:30:41 PDT 2006


 src/cairo-ft-font.c |  272 ++++++++++++++++++++++++++++------------------------
 1 files changed, 151 insertions(+), 121 deletions(-)

New commits:
diff-tree 1e0e56e0223116bf48e5acd4a974f16fae824df2 (from 117b062756de9fc99f635b3e712ea3e258c53165)
Author: Jinghua Luo <sunmoon1997 at gmail.com>
Date:   Sun Jun 18 17:30:39 2006 +0800

    freetype: Fix warnings in _decompose_glyph_outline.

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 72f14b4..9c94929 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -1713,10 +1713,10 @@ _decompose_glyph_outline (FT_Face		  fac
 			  cairo_path_fixed_t	**pathp)
 {
     static const FT_Outline_Funcs outline_funcs = {
-	_move_to,
-	_line_to,
-	_conic_to,
-	_cubic_to,
+	(FT_Outline_MoveToFunc)_move_to,
+	(FT_Outline_LineToFunc)_line_to,
+	(FT_Outline_ConicToFunc)_conic_to,
+	(FT_Outline_CubicToFunc)_cubic_to,
 	0, /* shift */
 	0, /* delta */
     };
diff-tree 117b062756de9fc99f635b3e712ea3e258c53165 (from 54b4a2fccdcaa4fbc126818c7cb7b96a1a8acf35)
Author: Jinghua Luo <sunmoon1997 at gmail.com>
Date:   Sun Jun 18 17:26:19 2006 +0800

    freetype: cleanup _cairo_ft_scaled_glyph_init.

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 1ad4f26..72f14b4 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -1777,6 +1777,7 @@ _cairo_ft_scaled_glyph_init (void			*abs
     FT_Glyph_Metrics *metrics;
     double x_factor, y_factor;
     cairo_bool_t vertical_layout = FALSE;
+    cairo_status_t status = CAIRO_STATUS_SUCCESS;
 
     face = cairo_ft_scaled_font_lock_face (abstract_font);
     if (!face)
@@ -1803,8 +1804,8 @@ _cairo_ft_scaled_glyph_init (void			*abs
 			   load_flags);
 
     if (error) {
-	cairo_ft_scaled_font_unlock_face (abstract_font);
-	return CAIRO_STATUS_NO_MEMORY;
+	status = CAIRO_STATUS_NO_MEMORY;
+	goto FAIL;
     }
 
     glyph = face->glyph;
@@ -1913,7 +1914,6 @@ _cairo_ft_scaled_glyph_init (void			*abs
 
     if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
 	cairo_image_surface_t	*surface;
-	cairo_status_t status;
 
 	if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
 	    status = _render_glyph_outline (face, &scaled_font->ft_options.base,
@@ -1925,10 +1925,9 @@ _cairo_ft_scaled_glyph_init (void			*abs
 		status = _transform_glyph_bitmap (&unscaled->current_shape,
 						  &surface);
 	}
-	if (status) {
-	    cairo_ft_scaled_font_unlock_face (abstract_font);
-	    return status;
-	}
+	if (status)
+	    goto FAIL;
+
 	_cairo_scaled_glyph_set_surface (scaled_glyph,
 					 &scaled_font->base,
 					 surface);
@@ -1936,7 +1935,6 @@ _cairo_ft_scaled_glyph_init (void			*abs
 
     if (info & CAIRO_SCALED_GLYPH_INFO_PATH) {
 	cairo_path_fixed_t *path;
-	cairo_status_t status;
 
 	/*
 	 * A kludge -- the above code will trash the outline,
@@ -1951,6 +1949,13 @@ _cairo_ft_scaled_glyph_init (void			*abs
 		cairo_ft_scaled_font_unlock_face (abstract_font);
 		return CAIRO_STATUS_NO_MEMORY;
 	    }
+#if HAVE_FT_GLYPHSLOT_EMBOLDEN
+	    /*
+	     * embolden glyphs if requested
+	     */
+	    if (scaled_font->ft_options.extra_flags & CAIRO_FT_OPTIONS_EMBOLDEN)
+		FT_GlyphSlot_Embolden (glyph);
+#endif
 	    if (vertical_layout)
 		_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (glyph);
 
@@ -1961,18 +1966,17 @@ _cairo_ft_scaled_glyph_init (void			*abs
 	else
 	    status = CAIRO_INT_STATUS_UNSUPPORTED;
 
-	if (status) {
-	    cairo_ft_scaled_font_unlock_face (abstract_font);
-	    return status;
-	}
+	if (status)
+	    goto FAIL;
+
 	_cairo_scaled_glyph_set_path (scaled_glyph,
 				      &scaled_font->base,
 				      path);
     }
-
+ FAIL:
     cairo_ft_scaled_font_unlock_face (abstract_font);
 
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
 
 static unsigned long
diff-tree 54b4a2fccdcaa4fbc126818c7cb7b96a1a8acf35 (from 4b2b8f939a9e786ead080f85d1b101680230f168)
Author: Jinghua Luo <sunmoon1997 at gmail.com>
Date:   Sun Jun 18 17:20:38 2006 +0800

    freetype: Respect configurations in font pattern.
    
    cairo freetype font backend doesn't handle fontconfig configurations
    quiet well, it always renders glyphs using configurations in
    scaled_font->base.options which usually isn't corresponding to
    font pattern used to create the font face and the load flags. As a
    result, turning antialias off with fontconfig doesn't work with cairo
    HEAD, subpixel order either.
    
    This commit make cairo respect configurations in font pattern and handle
    load flags correctly. The ft-text-antialias-none test case passess now.
    And should fix bug #6759 and #4792.

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index c5fb728..1ad4f26 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -116,6 +116,7 @@ typedef enum _cairo_ft_extra_flags {
 } cairo_ft_extra_flags_t;
 
 typedef struct _cairo_ft_options {
+    cairo_font_options_t    base;
     int			    load_flags;	 /* flags for FT_Load_Glyph */
     cairo_ft_extra_flags_t  extra_flags; /* other flags that affect results */
 } cairo_ft_options_t;
@@ -1228,15 +1229,15 @@ const cairo_scaled_font_backend_t cairo_
 static cairo_ft_options_t
 _get_pattern_ft_options (FcPattern *pattern)
 {
-    FcBool antialias, vertical_layout, hinting, autohint, bitmap;
+    FcBool antialias, vertical_layout, hinting, autohint, bitmap, embolden;
     cairo_ft_options_t ft_options;
     int rgba;
 #ifdef FC_HINT_STYLE
     int hintstyle;
 #endif
-    int target_flags = 0;
 
-    ft_options.load_flags = 0;
+    _cairo_font_options_init_default (&ft_options.base);
+    ft_options.load_flags = FT_LOAD_DEFAULT;
     ft_options.extra_flags = 0;
 
 #ifndef FC_EMBEDDED_BITMAP
@@ -1252,65 +1253,74 @@ _get_pattern_ft_options (FcPattern *patt
     if (FcPatternGetBool (pattern,
 			  FC_ANTIALIAS, 0, &antialias) != FcResultMatch)
 	antialias = FcTrue;
+    
+    if (antialias) {
+	if (!bitmap)
+	    ft_options.load_flags |= FT_LOAD_NO_BITMAP;
+	
+	/* disable hinting if requested */
+	if (FcPatternGetBool (pattern,
+			      FC_HINTING, 0, &hinting) != FcResultMatch)
+	    hinting = FcTrue;
 
-    if (!bitmap && antialias)
-	ft_options.load_flags |= FT_LOAD_NO_BITMAP;
-    else if (!antialias)
-	ft_options.load_flags |= FT_LOAD_MONOCHROME;
+	if (FcPatternGetInteger (pattern,
+				 FC_RGBA, 0, &rgba) != FcResultMatch)
+	    rgba = FC_RGBA_UNKNOWN;
+
+	switch (rgba) {
+	case FC_RGBA_RGB:
+	    ft_options.base.subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB;
+	    break;
+	case FC_RGBA_BGR:
+	    ft_options.base.subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR;
+	    break;
+	case FC_RGBA_VRGB:
+	    ft_options.base.subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB;
+	    break;
+	case FC_RGBA_VBGR:
+	    ft_options.base.subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR;
+	    break;
+	case FC_RGBA_UNKNOWN:
+	case FC_RGBA_NONE:
+	default:
+	    break;
+	}
 
-    /* disable hinting if requested */
-    if (FcPatternGetBool (pattern,
-			  FC_HINTING, 0, &hinting) != FcResultMatch)
- 	hinting = FcTrue;
+	if (ft_options.base.subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT)
+	    ft_options.base.antialias = CAIRO_ANTIALIAS_SUBPIXEL;
 
-#ifdef FC_HINT_STYLE
-    if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch)
-	hintstyle = FC_HINT_FULL;
+#ifdef FC_HINT_STYLE    
+	if (FcPatternGetInteger (pattern, 
+				 FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch)
+	    hintstyle = FC_HINT_FULL;
 
-    if (!hinting || hintstyle == FC_HINT_NONE)
-	ft_options.load_flags |= FT_LOAD_NO_HINTING;
+	if (!hinting)
+	    hintstyle = FC_HINT_NONE;
 
-    if (antialias) {
 	switch (hintstyle) {
+	case FC_HINT_NONE:
+	    ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE;	
+	    break;
 	case FC_HINT_SLIGHT:
-	case FC_HINT_MEDIUM:
-	    target_flags = FT_LOAD_TARGET_LIGHT;
+	    ft_options.base.hint_style = CAIRO_HINT_STYLE_SLIGHT;
 	    break;
+	case FC_HINT_MEDIUM:
 	default:
-	    target_flags = FT_LOAD_TARGET_NORMAL;
+	    ft_options.base.hint_style = CAIRO_HINT_STYLE_MEDIUM;
+	    break;
+	case FC_HINT_FULL:
+	    ft_options.base.hint_style = CAIRO_HINT_STYLE_FULL;
 	    break;
 	}
-    } else {
-#ifdef FT_LOAD_TARGET_MONO
-	target_flags = FT_LOAD_TARGET_MONO;
-#endif
-    }
 #else /* !FC_HINT_STYLE */
-    if (!hinting)
-	target_flags = FT_LOAD_NO_HINTING;
+	if (!hinting) {
+	    ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE;
+	}
 #endif /* FC_FHINT_STYLE */
-
-    if (FcPatternGetInteger (pattern,
-			     FC_RGBA, 0, &rgba) != FcResultMatch)
-	rgba = FC_RGBA_UNKNOWN;
-
-    switch (rgba) {
-    case FC_RGBA_UNKNOWN:
-    case FC_RGBA_NONE:
-    default:
-	break;
-    case FC_RGBA_RGB:
-    case FC_RGBA_BGR:
-	target_flags = FT_LOAD_TARGET_LCD;
-	break;
-    case FC_RGBA_VRGB:
-    case FC_RGBA_VBGR:
-	target_flags = FT_LOAD_TARGET_LCD_V;
-	break;
+    } else {
+	ft_options.base.antialias = CAIRO_ANTIALIAS_NONE;
     }
 
-    ft_options.load_flags |= target_flags;
-
     /* force autohinting if requested */
     if (FcPatternGetBool (pattern,
 			  FC_AUTOHINT, 0, &autohint) != FcResultMatch)
@@ -1325,71 +1335,88 @@ _get_pattern_ft_options (FcPattern *patt
 
     if (vertical_layout)
 	ft_options.load_flags |= FT_LOAD_VERTICAL_LAYOUT;
-
-#ifdef FC_EMBOLDEN
-    {
-	FcBool embolden;
-
-	if (FcPatternGetBool (pattern,
-			      FC_EMBOLDEN, 0, &embolden) != FcResultMatch)
-	    embolden = FcFalse;
-
-	if (embolden)
-	    ft_options.extra_flags |= CAIRO_FT_OPTIONS_EMBOLDEN;
-    }
+    
+#ifndef FC_EMBOLDEN
+#define FC_EMBOLDEN "embolden"
 #endif
+    if (FcPatternGetBool (pattern,
+			  FC_EMBOLDEN, 0, &embolden) != FcResultMatch)
+	embolden = FcFalse;
+    
+    if (embolden)
+	ft_options.extra_flags |= CAIRO_FT_OPTIONS_EMBOLDEN;
 
     return ft_options;
 }
 
-static int
-_get_options_load_flags (const cairo_font_options_t *options)
+static void
+_cairo_ft_options_merge (cairo_ft_options_t *options,
+			 cairo_ft_options_t *other)
 {
-    int load_flags = 0;
+    int load_flags = other->load_flags;
+    int load_target = FT_LOAD_TARGET_NORMAL;
 
-    /* disable antialiasing if requested */
-    switch (options->antialias) {
-    case CAIRO_ANTIALIAS_NONE:
-#ifdef FT_LOAD_TARGET_MONO
-	load_flags |= FT_LOAD_TARGET_MONO;
-#endif
-	load_flags |= FT_LOAD_MONOCHROME;
-	break;
-    case CAIRO_ANTIALIAS_SUBPIXEL:
-	switch (options->subpixel_order) {
-	case CAIRO_SUBPIXEL_ORDER_DEFAULT:
-	case CAIRO_SUBPIXEL_ORDER_RGB:
-	case CAIRO_SUBPIXEL_ORDER_BGR:
-	    load_flags |= FT_LOAD_TARGET_LCD;
-	    break;
-	case CAIRO_SUBPIXEL_ORDER_VRGB:
-	case CAIRO_SUBPIXEL_ORDER_VBGR:
-	    load_flags |= FT_LOAD_TARGET_LCD_V;
-	    break;
-	}
-	/* fall through ... */
-    case CAIRO_ANTIALIAS_DEFAULT:
-    case CAIRO_ANTIALIAS_GRAY:
-	load_flags |= FT_LOAD_NO_BITMAP;
-	break;
+    /* clear load target mode */
+    load_flags &= ~FT_LOAD_TARGET_MODE(other->load_flags);
+    
+    if (load_flags & FT_LOAD_NO_HINTING)
+	other->base.hint_style = CAIRO_HINT_STYLE_NONE;
+
+    if (other->base.antialias == CAIRO_ANTIALIAS_NONE ||
+	options->base.antialias == CAIRO_ANTIALIAS_NONE) {
+	options->base.antialias = CAIRO_ANTIALIAS_NONE;
+	options->base.subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
+    }
+
+    if (other->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL &&
+	(options->base.antialias == CAIRO_ANTIALIAS_DEFAULT || 
+	 options->base.antialias == CAIRO_ANTIALIAS_GRAY)) {
+	options->base.antialias = CAIRO_ANTIALIAS_SUBPIXEL;
+	options->base.subpixel_order = other->base.subpixel_order;
     }
 
-    /* disable hinting if requested */
-    switch (options->hint_style) {
+    if (options->base.hint_style == CAIRO_HINT_STYLE_DEFAULT)
+	options->base.hint_style = other->base.hint_style;
+
+    if (other->base.hint_style == CAIRO_HINT_STYLE_NONE)
+	options->base.hint_style = CAIRO_HINT_STYLE_NONE;
+
+    switch (options->base.hint_style) {
     case CAIRO_HINT_STYLE_NONE:
 	load_flags |= FT_LOAD_NO_HINTING;
 	break;
     case CAIRO_HINT_STYLE_SLIGHT:
+	load_target = FT_LOAD_TARGET_LIGHT;
+	break;
     case CAIRO_HINT_STYLE_MEDIUM:
- 	load_flags |= FT_LOAD_TARGET_LIGHT;
- 	break;
+	if (options->base.antialias == CAIRO_ANTIALIAS_NONE) {
+	    load_target = FT_LOAD_TARGET_MONO;
+	    load_flags |= FT_LOAD_MONOCHROME;
+	}
+	break;
     case CAIRO_HINT_STYLE_FULL:
-    default:
- 	load_flags |= FT_LOAD_TARGET_NORMAL;
- 	break;
+    case CAIRO_HINT_STYLE_DEFAULT:
+	if (options->base.antialias == CAIRO_ANTIALIAS_NONE) {
+	    load_target = FT_LOAD_TARGET_MONO;
+	    load_flags |= FT_LOAD_MONOCHROME;
+	} else if (options->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL) {
+	    switch (options->base.subpixel_order) {
+	    case CAIRO_SUBPIXEL_ORDER_DEFAULT:
+	    case CAIRO_SUBPIXEL_ORDER_RGB:
+	    case CAIRO_SUBPIXEL_ORDER_BGR:
+		load_target |= FT_LOAD_TARGET_LCD;
+		break;
+	    case CAIRO_SUBPIXEL_ORDER_VRGB:
+	    case CAIRO_SUBPIXEL_ORDER_VBGR:
+		load_target |= FT_LOAD_TARGET_LCD_V;
+		break;
+	    }
+	}
+	break;
     }
 
-    return load_flags;
+    options->load_flags = load_flags | load_target;
+    options->extra_flags = other->extra_flags;
 }
 
 static cairo_scaled_font_t *
@@ -1421,7 +1448,8 @@ _cairo_ft_scaled_font_create (cairo_ft_u
     if (options->hint_metrics != CAIRO_HINT_METRICS_OFF)
 	ft_options.extra_flags |= CAIRO_FT_OPTIONS_HINT_METRICS;
 
-    scaled_font->ft_options = ft_options;
+    _cairo_font_options_init_copy (&scaled_font->ft_options.base, options);
+    _cairo_ft_options_merge (&scaled_font->ft_options, &ft_options);
 
     _cairo_scaled_font_init (&scaled_font->base,
 			     font_face,
@@ -1888,10 +1916,10 @@ _cairo_ft_scaled_glyph_init (void			*abs
 	cairo_status_t status;
 
 	if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
-	    status = _render_glyph_outline (face, &scaled_font->base.options,
+	    status = _render_glyph_outline (face, &scaled_font->ft_options.base,
 					    &surface);
 	} else {
-	    status = _render_glyph_bitmap (face, &scaled_font->base.options,
+	    status = _render_glyph_bitmap (face, &scaled_font->ft_options.base,
 					   &surface);
 	    if (status == CAIRO_STATUS_SUCCESS && unscaled->have_shape)
 		status = _transform_glyph_bitmap (&unscaled->current_shape,
@@ -1928,7 +1956,7 @@ _cairo_ft_scaled_glyph_init (void			*abs
 
 	}
 	if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
-	    status = _decompose_glyph_outline (face, &scaled_font->base.options,
+	    status = _decompose_glyph_outline (face, &scaled_font->ft_options.base,
 					       &path);
 	else
 	    status = CAIRO_INT_STATUS_UNSUPPORTED;
@@ -2072,8 +2100,6 @@ _cairo_ft_font_face_scaled_font_create (
      */
 
     ft_options = font_face->ft_options;
-    if (font_face->unscaled->from_face)
-	ft_options.load_flags |= _get_options_load_flags (options);
 
     *scaled_font = _cairo_ft_scaled_font_create (font_face->unscaled,
 						 &font_face->base,
@@ -2102,8 +2128,7 @@ _cairo_ft_font_face_create (cairo_ft_uns
 	 font_face;
 	 font_face = font_face->next)
     {
-	if (font_face->ft_options.load_flags == ft_options.load_flags &&
-	    font_face->ft_options.extra_flags == ft_options.extra_flags)
+	if (!memcmp (&font_face->ft_options, &ft_options, sizeof (cairo_ft_options_t)))
 	    return cairo_font_face_reference (&font_face->base);
     }
 
@@ -2306,6 +2331,7 @@ cairo_ft_font_face_create_for_ft_face (F
 
     ft_options.load_flags = load_flags;
     ft_options.extra_flags = 0;
+    _cairo_font_options_init_default (&ft_options.base);
 
     font_face = _cairo_ft_font_face_create (unscaled, ft_options);
     _cairo_unscaled_font_destroy (&unscaled->base);


More information about the cairo-commit mailing list