[cairo-commit] cairo/src Makefile.am, 1.53, 1.54 cairo-font-options.c, NONE, 1.1 cairo-font.c, 1.53, 1.54 cairo-ft-font.c, 1.70, 1.71 cairo-ft.h, 1.5, 1.6 cairo-gstate.c, 1.146, 1.147 cairo-pdf-surface.c, 1.51, 1.52 cairo-surface.c, 1.79, 1.80 cairo-win32-font.c, 1.24, 1.25 cairo-xlib-private.h, NONE, 1.1 cairo-xlib-screen.c, NONE, 1.1 cairo-xlib-surface.c, 1.90, 1.91 cairo.h, 1.135, 1.136 cairoint.h, 1.164, 1.165

Owen Taylor commit at pdx.freedesktop.org
Thu Jul 21 06:52:16 PDT 2005


Committed by: otaylor

Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv27923/src

Modified Files:
	Makefile.am cairo-font.c cairo-ft-font.c cairo-ft.h 
	cairo-gstate.c cairo-pdf-surface.c cairo-surface.c 
	cairo-win32-font.c cairo-xlib-surface.c cairo.h cairoint.h 
Added Files:
	cairo-font-options.c cairo-xlib-private.h cairo-xlib-screen.c 
Log Message:
2005-07-13  Owen Taylor  <otaylor at redhat.com>

        reviewed by: cworth

        * src/cairo-font-options.c src/cairo.h src/cairoint.h
        src/Makefile.am: Add an opaque cairo_font_options_t structure.

        * src/cairo-font.c src/cairo.h src/cairoint.h: Add a
        cairo_font_options_t object to cairo_scaled_font_create().

        * src/cairo-surface.c src/cairoint.h: Add virtualized
        cairo_surface_get_font_options() to get the font options for
        a surface.

        * src/cairo-gstate.c: Adapt to cairo_scaled_font_create() change.

        * src/cairo-pdf-surface.c: Add an implementation of
        get_font_options() that turns off metrics hinting.

        * src/cairo-xlib-screen.c src/cairo-xlib-private.h: Add
        a "screen info" structure that holds (for now) information
        about the default font options for the screen.

        * src/cairo-xlib-surface.c: Implement get_font_options()

        * src/cairo-ft-font.c src/cairo-ft.h: Add functions to apply
        a cairo_font_options_t to a FcPattern or get the load flags
        for a cairo_font_options_t.

        * src/cairo-ft-font.c: Adapt to font options additions.
        Add support for non-antialiased rendering of scalable fonts.
        Add support for turning off metrics hinting.

        * src/cairo-win32-font.c: Adapt to font options additions.

        * doc/public/Makefile.am doc/public/cairo-sections.txt: Update.


Index: Makefile.am
===================================================================
RCS file: /cvs/cairo/cairo/src/Makefile.am,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -d -r1.53 -r1.54
--- Makefile.am	1 Jul 2005 19:22:23 -0000	1.53
+++ Makefile.am	21 Jul 2005 13:52:13 -0000	1.54
@@ -17,7 +17,7 @@
 
 if CAIRO_HAS_XLIB_SURFACE
 libcairo_xlib_headers = cairo-xlib.h cairo-xlib-xrender.h
-libcairo_xlib_sources = cairo-xlib-surface.c cairo-xlib-test.h
+libcairo_xlib_sources = cairo-xlib-surface.c cairo-xlib-screen.c cairo-xlib-private.h cairo-xlib-test.h
 endif
 
 if CAIRO_HAS_QUARTZ_SURFACE
@@ -88,6 +88,7 @@
 	cairo-color.c				\
 	cairo-fixed.c				\
 	cairo-font.c				\
+	cairo-font-options.c			\
 	cairo-gstate.c				\
 	cairo-gstate-private.h			\
 	cairo-hull.c				\

--- NEW FILE: cairo-font-options.c ---
(This appears to be a binary file; contents omitted.)

Index: cairo-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-font.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -d -r1.53 -r1.54
--- cairo-font.c	15 Jul 2005 20:59:47 -0000	1.53
+++ cairo-font.c	21 Jul 2005 13:52:13 -0000	1.54
@@ -355,17 +355,18 @@
 }
 
 static cairo_status_t
-_cairo_simple_font_face_create_font (void                 *abstract_face,
-				     const cairo_matrix_t *font_matrix,
-				     const cairo_matrix_t *ctm,
-				     cairo_scaled_font_t **scaled_font)
+_cairo_simple_font_face_create_font (void                        *abstract_face,
+				     const cairo_matrix_t        *font_matrix,
+				     const cairo_matrix_t        *ctm,
+				     const cairo_font_options_t  *options,
+				     cairo_scaled_font_t        **scaled_font)
 {
     const cairo_scaled_font_backend_t * backend = CAIRO_SCALED_FONT_BACKEND_DEFAULT;
 
     cairo_simple_font_face_t *simple_face = abstract_face;
 
     return backend->create (simple_face->family, simple_face->slant, simple_face->weight,
-			    font_matrix, ctm, scaled_font);
+			    font_matrix, ctm, options, scaled_font);
 }
 
 static const cairo_font_face_backend_t _cairo_simple_font_face_backend = {
@@ -444,6 +445,7 @@
     cairo_font_face_t *font_face;
     const cairo_matrix_t *font_matrix;
     const cairo_matrix_t *ctm;
+    cairo_font_options_t options;
 } cairo_font_cache_key_t;
 
 typedef struct {
@@ -554,7 +556,9 @@
 			    sizeof(double) * 4,
 			    hash);
 
-    return hash ^ (unsigned long)k->font_face;
+    return (hash ^
+	    (unsigned long)k->font_face ^
+	    cairo_font_options_hash (&k->options));
 }
 
 static int
@@ -573,7 +577,8 @@
 		    sizeof(double) * 4) == 0 &&
 	    memcmp ((unsigned char *)(&a->ctm->xx),
 		    (unsigned char *)(&b->ctm->xx),
-		    sizeof(double) * 4) == 0);
+		    sizeof(double) * 4) == 0 &&
+	    cairo_font_options_equal (&a->options, &b->options));
 }
 
 /* The cache lookup failed in the outer cache, so we pull
@@ -614,6 +619,7 @@
     entry->key.font_face = entry->scaled_font->font_face;
     entry->key.font_matrix = &entry->scaled_font->font_matrix;
     entry->key.ctm = &entry->scaled_font->ctm;
+    entry->key.options = ((cairo_font_cache_key_t *) key)->options;
     
     *return_entry = entry;
 
@@ -650,6 +656,7 @@
     status = k->font_face->backend->create_font (k->font_face,
 						 k->font_matrix,
 						 k->ctm,
+						 &k->options,
 						 &entry->scaled_font);
     if (status) {
 	free (entry);
@@ -663,6 +670,7 @@
     entry->key.font_face = k->font_face;
     entry->key.font_matrix = &entry->scaled_font->font_matrix;
     entry->key.ctm = &entry->scaled_font->ctm;
+    entry->key.options = k->options;
     
     *return_entry = entry;
 
@@ -712,6 +720,8 @@
  *       cairo_set_font_matrix().
  * @ctm: user to device transformation matrix with which the font will
  *       be used.
+ * @options: options to use when getting metrics for the font and
+ *           rendering with it.
  * 
  * Creates a #cairo_scaled_font_t object from a font face and matrices that
  * describe the size of the font and the environment in which it will
@@ -721,9 +731,10 @@
  *  cairo_scaled_font_destroy()
  **/
 cairo_scaled_font_t *
-cairo_scaled_font_create (cairo_font_face_t    *font_face,
-			  const cairo_matrix_t *font_matrix,
-			  const cairo_matrix_t *ctm)
+cairo_scaled_font_create (cairo_font_face_t          *font_face,
+			  const cairo_matrix_t       *font_matrix,
+			  const cairo_matrix_t       *ctm,
+			  const cairo_font_options_t *options)
 {
     cairo_font_cache_entry_t *entry;
     cairo_font_cache_key_t key;
@@ -733,6 +744,7 @@
     key.font_face = font_face;
     key.font_matrix = font_matrix;
     key.ctm = ctm;
+    key.options = *options;
     
     _lock_global_font_cache ();
     cache = _get_outer_font_cache ();

Index: cairo-ft-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-ft-font.c,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -d -r1.70 -r1.71
--- cairo-ft-font.c	13 Jul 2005 18:01:25 -0000	1.70
+++ cairo-ft-font.c	21 Jul 2005 13:52:13 -0000	1.71
@@ -51,6 +51,19 @@
 #define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
 #define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0)
 
+/* We pack some of our own information into the bits unused
+ * by FreeType's load flags. If FreeType ever uses up all
+ * the load flag bits, we'll have to do something else.
+ * (probably just store what we care about in load_flags
+ * then convert into FreeType terms.
+ */
+#define PRIVATE_FLAG_HINT_METRICS (0x01 << 24)
+#define PRIVATE_FLAGS_MASK        (0xff << 24)
+
+ /* This is the max number of FT_face objects we keep open at once
+  */
+ #define MAX_OPEN_FACES 10
+
 /* This is the max number of FT_face objects we keep open at once
  */
 #define MAX_OPEN_FACES 10
@@ -551,6 +564,87 @@
     }
 }
 
+/* Fills in val->image with an image surface created from @bitmap
+ */
+static cairo_status_t
+_get_bitmap_surface (cairo_image_glyph_cache_entry_t *val,
+		     FT_Bitmap                       *bitmap,
+		     cairo_bool_t                     own_buffer)
+{
+    int width, height, stride;
+    unsigned char *data;
+    int i, j;
+    
+    width = bitmap->width;
+    height = bitmap->rows;
+    
+    if (width * height == 0) {
+	if (own_buffer && bitmap->buffer)
+	    free (bitmap->buffer);
+	
+	val->image = NULL;
+    } else {
+	switch (bitmap->pixel_mode) {
+	case FT_PIXEL_MODE_MONO:
+	    stride = (width + 3) & ~3;
+	    data = calloc (stride * height, 1);
+	    if (!data)
+		return CAIRO_STATUS_NO_MEMORY;
+	    for (j = 0; j < height; j++) {
+		const unsigned char *p = bitmap->buffer + j * bitmap->pitch;
+		unsigned char *q = data + j * stride;
+		for (i = 0; i < width; i++) {
+		    /* FreeType bitmaps are always stored MSB */
+		    unsigned char byte = p[i >> 3];
+		    unsigned char bit = 1 << (7 - (i % 8));
+		    
+		    if (byte & bit)
+			q[i] = 0xff;
+		}
+	    }
+	    if (own_buffer)
+		free (bitmap->buffer);
+	    break;
+	case FT_PIXEL_MODE_GRAY:
+	    stride = bitmap->pitch;
+	    if (own_buffer) {
+		data = bitmap->buffer;
+	    } else {
+		data = malloc (stride * height);
+		if (!data)
+		    return CAIRO_STATUS_NO_MEMORY;
+		memcpy (data, bitmap->buffer, stride * height);
+	    }
+	    break; 
+	case FT_PIXEL_MODE_GRAY2:
+	case FT_PIXEL_MODE_GRAY4:
+	    /* These could be triggered by very rare types of TrueType fonts */
+	case FT_PIXEL_MODE_LCD:
+	case FT_PIXEL_MODE_LCD_V:
+	    /* These should never be triggered unless we ask for them */
+	default:
+	    return CAIRO_STATUS_NO_MEMORY;
+	}
+    
+	val->image = (cairo_image_surface_t *)
+	    cairo_image_surface_create_for_data (data,
+						 CAIRO_FORMAT_A8,
+						 width, height, stride);
+	if (val->image == NULL) {
+	    free (data);
+	    
+	    return CAIRO_STATUS_NO_MEMORY;
+	}
+	
+	_cairo_image_surface_assume_ownership_of_data (val->image);
+    }
+
+    val->size.width = width;
+    val->size.height = height;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
 /* Converts an outline FT_GlyphSlot into an image
  * 
  * This could go through _render_glyph_bitmap as well, letting
@@ -586,17 +680,23 @@
     
     width = (unsigned int) ((cbox.xMax - cbox.xMin) >> 6);
     height = (unsigned int) ((cbox.yMax - cbox.yMin) >> 6);
-    stride = (width + 3) & -4;
     
     if (width * height == 0) {
 	val->image = NULL;
     } else  {
 
-	bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
-	bitmap.num_grays  = 256;
+	if ((val->key.flags & FT_LOAD_MONOCHROME) != 0) {
+	    bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
+	    bitmap.num_grays  = 1;
+	    stride = ((width + 31) & -32) >> 3;
+	} else {
+	    bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
+	    bitmap.num_grays  = 256;
+	    stride = (width + 3) & -4;
+	}
+	bitmap.pitch = stride;   
 	bitmap.width = width;
 	bitmap.rows = height;
-	bitmap.pitch = stride;   
 	bitmap.buffer = calloc (1, stride * height);
 	
 	if (bitmap.buffer == NULL) {
@@ -609,17 +709,10 @@
 	    free (bitmap.buffer);
 	    return CAIRO_STATUS_NO_MEMORY;
 	}
-	
-	val->image = (cairo_image_surface_t *)
-	cairo_image_surface_create_for_data (bitmap.buffer,
-					     CAIRO_FORMAT_A8,
-					     width, height, stride);
-	if (val->image == NULL) {
-	    free (bitmap.buffer);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
-	
-	_cairo_image_surface_assume_ownership_of_data (val->image);
+
+	status = _get_bitmap_surface (val, &bitmap, TRUE);
+	if (status)
+	    return status;
     }
 
     /*
@@ -627,8 +720,6 @@
      * Y coordinate of the control box needs to be negated.
      */
 
-    val->size.width = (unsigned short) width;
-    val->size.height = (unsigned short) height;
     val->size.x =   (short) (cbox.xMin >> 6);
     val->size.y = - (short) (cbox.yMax >> 6);
 
@@ -655,12 +746,8 @@
 		      cairo_image_glyph_cache_entry_t *val)
 {
     FT_GlyphSlot glyphslot = face->glyph;
-    FT_Bitmap *bitmap;
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
-    int width, height, stride;
-    unsigned char *data;
     FT_Error error;
-    int i, j;
 
     /* According to the FreeType docs, glyphslot->format could be
      * something other than FT_GLYPH_FORMAT_OUTLINE or
@@ -673,64 +760,8 @@
     if (error)
 	return CAIRO_STATUS_NO_MEMORY;
 
-    bitmap = &glyphslot->bitmap;
-
-    width = bitmap->width;
-    height = bitmap->rows;
-
-    if (width * height == 0) {
-	val->image = NULL;
-    } else {
-	switch (bitmap->pixel_mode) {
-	case FT_PIXEL_MODE_MONO:
-	    stride = (width + 3) & ~3;
-	    data = calloc (stride * height, 1);
-	    if (!data)
-		return CAIRO_STATUS_NO_MEMORY;
-	    for (j = 0; j < height; j++) {
-		const unsigned char *p = bitmap->buffer + j * bitmap->pitch;
-		unsigned char *q = data + j * stride;
-		for (i = 0; i < width; i++) {
-		    /* FreeType bitmaps are always stored MSB */
-		    unsigned char byte = p[i >> 3];
-		    unsigned char bit = 1 << (7 - (i % 8));
-
-		    if (byte & bit)
-			q[i] = 0xff;
-		}
-	    }
-	    break;
-	case FT_PIXEL_MODE_GRAY:
-	    stride = bitmap->pitch;
-	    data = malloc (stride * height);
-	    if (!data)
-		return CAIRO_STATUS_NO_MEMORY;
-	    memcpy (data, bitmap->buffer, stride * height);
-	    break;
-	case FT_PIXEL_MODE_GRAY2:
-	case FT_PIXEL_MODE_GRAY4:
-	    /* These could be triggered by very rare types of TrueType fonts */
-	case FT_PIXEL_MODE_LCD:
-	case FT_PIXEL_MODE_LCD_V:
-	    /* These should never be triggered unless we ask for them */
-	default:
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
-	
-	val->image = (cairo_image_surface_t *)
-	    cairo_image_surface_create_for_data (data,
-						 CAIRO_FORMAT_A8,
-						 width, height, stride);
-	if (val->image == NULL) {
-	    free (data);
-	    return CAIRO_STATUS_NO_MEMORY;
-	}
-
-	_cairo_image_surface_assume_ownership_of_data (val->image);
-    }
+    _get_bitmap_surface (val, &glyphslot->bitmap, FALSE);
 
-    val->size.width = width;
-    val->size.height = height;
     val->size.x = - glyphslot->bitmap_left;
     val->size.y = - glyphslot->bitmap_top;
     
@@ -875,7 +906,7 @@
 
     _ft_unscaled_font_set_scale (unscaled, &val->key.scale);
 
-    if (FT_Load_Glyph (face, val->key.index, val->key.flags) != 0) {
+    if (FT_Load_Glyph (face, val->key.index, val->key.flags & ~PRIVATE_FLAGS_MASK) != 0) {
 	status = CAIRO_STATUS_NO_MEMORY;
 	goto FAIL;
     }
@@ -886,22 +917,46 @@
      *
      * Scale metrics back to glyph space from the scaled glyph space returned
      * by FreeType
+     *
+     * If we want hinted metrics but aren't asking for hinted glyphs from
+     * FreeType, then we need to do the metric hinting ourselves.
      */
-
-    val->extents.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX) / unscaled->x_scale;
-    val->extents.y_bearing = -DOUBLE_FROM_26_6 (metrics->horiBearingY) / unscaled->y_scale;
-
-    val->extents.width  = DOUBLE_FROM_26_6 (metrics->width) / unscaled->x_scale;
-    val->extents.height = DOUBLE_FROM_26_6 (metrics->height) / unscaled->y_scale;
-
-    /*
-     * use untransformed advance values
-     * XXX uses horizontal advance only at present;
-     should provide FT_LOAD_VERTICAL_LAYOUT
-     */
-
-    val->extents.x_advance = DOUBLE_FROM_26_6 (face->glyph->metrics.horiAdvance) / unscaled->x_scale;
-    val->extents.y_advance = 0 / unscaled->y_scale;
+    
+    if ((val->key.flags & PRIVATE_FLAG_HINT_METRICS) &&
+ 	(val->key.flags & FT_LOAD_NO_HINTING)) {
+ 	FT_Pos x1, x2;
+ 	FT_Pos y1, y2;
+ 	FT_Pos advance;
+	
+ 	x1 = (metrics->horiBearingX) & -64;
+ 	x2 = (metrics->horiBearingX + metrics->width + 63) & -64;
+ 	y1 = (metrics->horiBearingY) & -64;
+ 	y2 = (metrics->horiBearingY + metrics->height + 63) & -64;
+ 
+ 	advance = ((metrics->horiAdvance + 32) & -64);
+ 	
+ 	val->extents.x_bearing = DOUBLE_FROM_26_6 (x1) / unscaled->x_scale;
+	val->extents.y_bearing = -DOUBLE_FROM_26_6 (y1) / unscaled->y_scale;
+	
+ 	val->extents.width  = DOUBLE_FROM_26_6 (x2 - x1) / unscaled->x_scale;
+ 	val->extents.height  = DOUBLE_FROM_26_6 (y2 - y1) / unscaled->y_scale;
+ 	
+ 	/*
+ 	 * use untransformed advance values
+ 	 * XXX uses horizontal advance only at present; should provide FT_LOAD_VERTICAL_LAYOUT
+ 	 */
+ 	val->extents.x_advance = DOUBLE_FROM_26_6 (advance) / unscaled->x_scale;
+ 	val->extents.y_advance = 0;
+     } else {
+	 val->extents.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX) / unscaled->x_scale;
+	 val->extents.y_bearing = -DOUBLE_FROM_26_6 (metrics->horiBearingY) / unscaled->y_scale;
+	 
+	 val->extents.width  = DOUBLE_FROM_26_6 (metrics->width) / unscaled->x_scale;
+	 val->extents.height = DOUBLE_FROM_26_6 (metrics->height) / unscaled->y_scale;
+	 
+	 val->extents.x_advance = DOUBLE_FROM_26_6 (face->glyph->metrics.horiAdvance) / unscaled->x_scale;
+	 val->extents.y_advance = 0 / unscaled->y_scale;
+     }
 
     if (glyphslot->format == FT_GLYPH_FORMAT_OUTLINE)
 	status = _render_glyph_outline (face, val);
@@ -933,23 +988,19 @@
 typedef struct {
     cairo_scaled_font_t base;
     int load_flags;
+    cairo_font_options_t options;
     ft_unscaled_font_t *unscaled;
 } cairo_ft_scaled_font_t;
 
 const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend;
 
-/* for compatibility with older freetype versions */
-#ifndef FT_LOAD_TARGET_MONO
-#define FT_LOAD_TARGET_MONO  FT_LOAD_MONOCHROME
-#endif
-
 /* The load flags passed to FT_Load_Glyph control aspects like hinting and
  * antialiasing. Here we compute them from the fields of a FcPattern.
  */
 static int
-_get_load_flags (FcPattern *pattern)
+_get_pattern_load_flags (FcPattern *pattern)
 {
-    FcBool antialias, hinting, autohint;
+    FcBool antialias, vertical_layout, hinting, autohint;
 #ifdef FC_HINT_STYLE    
     int hintstyle;
 #endif    
@@ -959,17 +1010,17 @@
     if (FcPatternGetBool (pattern,
 			  FC_ANTIALIAS, 0, &antialias) != FcResultMatch)
 	antialias = FcTrue;
-    
+
     if (antialias)
 	load_flags |= FT_LOAD_NO_BITMAP;
     else
-	load_flags |= FT_LOAD_TARGET_MONO;
+	load_flags |= FT_LOAD_MONOCHROME;
     
     /* disable hinting if requested */
     if (FcPatternGetBool (pattern,
 			  FC_HINTING, 0, &hinting) != FcResultMatch)
  	hinting = FcTrue;
-    
+
 #ifdef FC_HINT_STYLE    
     if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch)
 	hintstyle = FC_HINT_FULL;
@@ -977,20 +1028,26 @@
     if (!hinting || hintstyle == FC_HINT_NONE)
 	load_flags |= FT_LOAD_NO_HINTING;
     
-    switch (hintstyle) {
-    case FC_HINT_SLIGHT:
-    case FC_HINT_MEDIUM:
-	load_flags |= FT_LOAD_TARGET_LIGHT;
-	break;
-    default:
-	load_flags |= FT_LOAD_TARGET_NORMAL;
-	break;
+    if (antialias) {
+	switch (hintstyle) {
+	case FC_HINT_SLIGHT:
+	case FC_HINT_MEDIUM:
+	    load_flags |= FT_LOAD_TARGET_LIGHT;
+	    break;
+	default:
+	    load_flags |= FT_LOAD_TARGET_NORMAL;
+	    break;
+	}
+    } else {
+#ifdef FT_LOAD_TARGET_MONO
+	load_flags |= FT_LOAD_TARGET_MONO;
+#endif	
     }
 #else /* !FC_HINT_STYLE */
     if (!hinting)
 	load_flags |= FT_LOAD_NO_HINTING;
 #endif /* FC_FHINT_STYLE */
-    
+
     /* force autohinting if requested */
     if (FcPatternGetBool (pattern,
 			  FC_AUTOHINT, 0, &autohint) != FcResultMatch)
@@ -999,14 +1056,51 @@
     if (autohint)
 	load_flags |= FT_LOAD_FORCE_AUTOHINT;
     
+    if (FcPatternGetBool (pattern,
+			  FC_VERTICAL_LAYOUT, 0, &vertical_layout) != FcResultMatch)
+	vertical_layout = FcFalse;
+    
+    if (vertical_layout)
+	load_flags |= FT_LOAD_VERTICAL_LAYOUT;
+    
+    return load_flags;
+}
+
+static int
+_get_options_load_flags (const cairo_font_options_t *options)
+{
+    int load_flags = 0;
+
+    /* disable antialiasing if requested */
+    if (options->antialias == CAIRO_ANTIALIAS_NONE)
+	load_flags |= FT_LOAD_TARGET_MONO;
+    else
+	load_flags |= FT_LOAD_NO_BITMAP;
+     
+    /* disable hinting if requested */
+    switch (options->hint_style) {
+    case CAIRO_HINT_STYLE_NONE:
+	load_flags |= FT_LOAD_NO_HINTING;
+	break;
+    case CAIRO_HINT_STYLE_SLIGHT:
+    case CAIRO_HINT_STYLE_MEDIUM:
+ 	load_flags |= FT_LOAD_TARGET_LIGHT;
+ 	break;
+    case CAIRO_HINT_STYLE_FULL:
+    default:
+ 	load_flags |= FT_LOAD_TARGET_NORMAL;
+ 	break;
+    }
+     
     return load_flags;
 }
 
 static cairo_scaled_font_t *
-_ft_scaled_font_create (ft_unscaled_font_t   *unscaled,
-			int                   load_flags,
-			const cairo_matrix_t *font_matrix,
-			const cairo_matrix_t *ctm)
+_ft_scaled_font_create (ft_unscaled_font_t         *unscaled,
+			const cairo_matrix_t       *font_matrix,
+			const cairo_matrix_t       *ctm,
+			const cairo_font_options_t *options,
+			int                         load_flags)
 {    
     cairo_ft_scaled_font_t *f = NULL;
 
@@ -1017,6 +1111,11 @@
     f->unscaled = unscaled;
     _cairo_unscaled_font_reference (&unscaled->base);
     
+    f->options = *options;
+
+    if (options->hint_metrics != CAIRO_HINT_METRICS_OFF)
+	load_flags |= PRIVATE_FLAG_HINT_METRICS;
+
     f->load_flags = load_flags;
 
     _cairo_scaled_font_init (&f->base, font_matrix, ctm, &cairo_ft_scaled_font_backend);
@@ -1031,12 +1130,13 @@
 }
 
 static cairo_status_t
-_cairo_ft_scaled_font_create (const char	   *family, 
-			      cairo_font_slant_t    slant, 
-			      cairo_font_weight_t   weight,
-			      const cairo_matrix_t *font_matrix,
-			      const cairo_matrix_t *ctm,
-			      cairo_scaled_font_t **font)
+_cairo_ft_scaled_font_create (const char	         *family, 
+			      cairo_font_slant_t          slant, 
+			      cairo_font_weight_t         weight,
+			      const cairo_matrix_t       *font_matrix,
+			      const cairo_matrix_t       *ctm,
+			      const cairo_font_options_t *options,
+			      cairo_scaled_font_t       **font)
 {
     FcPattern *pattern, *resolved;
     ft_unscaled_font_t *unscaled;
@@ -1089,6 +1189,7 @@
     FcPatternAddInteger (pattern, FC_PIXEL_SIZE, sf.y_scale);
 
     FcConfigSubstitute (NULL, pattern, FcMatchPattern);
+    cairo_ft_font_options_substitute (options, pattern);
     FcDefaultSubstitute (pattern);
     
     resolved = FcFontMatch (NULL, pattern, &result);
@@ -1099,8 +1200,9 @@
     if (!unscaled)
 	goto FREE_RESOLVED;
     
-    new_font = _ft_scaled_font_create (unscaled, _get_load_flags (pattern),
-				       font_matrix, ctm);
+    new_font = _ft_scaled_font_create (unscaled, 
+				       font_matrix, ctm,
+				       options, _get_pattern_load_flags (pattern));
     _cairo_unscaled_font_destroy (&unscaled->base);
 
     FcPatternDestroy (resolved);
@@ -1230,15 +1332,24 @@
     metrics = &face->size->metrics;
 
     _ft_unscaled_font_set_scale (scaled_font->unscaled, &scaled_font->base.scale);
-    
+
     /*
      * Get to unscaled metrics so that the upper level can get back to
      * user space
      */
-    extents->ascent =        DOUBLE_FROM_26_6(metrics->ascender) / scaled_font->unscaled->y_scale;
-    extents->descent =       DOUBLE_FROM_26_6(- metrics->descender) / scaled_font->unscaled->y_scale;
-    extents->height =        DOUBLE_FROM_26_6(metrics->height) / scaled_font->unscaled->y_scale;
-    extents->max_x_advance = DOUBLE_FROM_26_6(metrics->max_advance) / scaled_font->unscaled->x_scale;
+    if (scaled_font->options.hint_metrics != CAIRO_HINT_METRICS_OFF) {
+	extents->ascent =        DOUBLE_FROM_26_6(metrics->ascender) / scaled_font->unscaled->y_scale;
+	extents->descent =       DOUBLE_FROM_26_6(- metrics->descender) / scaled_font->unscaled->y_scale;
+	extents->height =        DOUBLE_FROM_26_6(metrics->height) / scaled_font->unscaled->y_scale;
+	extents->max_x_advance = DOUBLE_FROM_26_6(metrics->max_advance) / scaled_font->unscaled->x_scale;
+    } else {
+	double scale = face->units_per_EM;
+      
+	extents->ascent =        face->ascender / scale;
+	extents->descent =       - face->descender / scale;
+	extents->height =        face->height / scale;
+	extents->max_x_advance = face->max_advance_width / scale;
+    }
 
     /* FIXME: this doesn't do vertical layout atm. */
     extents->max_y_advance = 0.0;
@@ -1688,16 +1799,32 @@
 }
 
 static cairo_status_t
-_ft_font_face_create_font (void                 *abstract_face,
-			   const cairo_matrix_t *font_matrix,
-			   const cairo_matrix_t *ctm,
-			   cairo_scaled_font_t **scaled_font)
+_ft_font_face_create_font (void                       *abstract_face,
+			   const cairo_matrix_t       *font_matrix,
+			   const cairo_matrix_t       *ctm,
+			   const cairo_font_options_t *options,
+			   cairo_scaled_font_t       **scaled_font)
 {
     ft_font_face_t *font_face = abstract_face;
+    int load_flags;
+
+    /* The handling of font options is different depending on how the
+     * font face was created. When the user creates a font face with
+     * cairo_ft_font_face_create_for_ft_face(), then the load flags
+     * passed in augment the load flags for the options.  But for
+     * cairo_ft_font_face_create_for_pattern(), the load flags are
+     * derived from a pattern where the user has called
+     * cairo_ft_font_options_substitute(), so *just* use those load
+     * flags and ignore the options.
+     */
+    if (font_face->unscaled->from_face)
+	load_flags = _get_options_load_flags (options) | font_face->load_flags;
+    else
+	load_flags = font_face->load_flags;
 
     *scaled_font = _ft_scaled_font_create (font_face->unscaled,
-					   font_face->load_flags,
-					   font_matrix, ctm);
+					   font_matrix, ctm,
+					   options, load_flags);
     if (*scaled_font)
 	return CAIRO_STATUS_SUCCESS;
     else
@@ -1744,6 +1871,92 @@
 /* implement the platform-specific interface */
 
 /**
+ * cairo_ft_font_options_substitute:
+ * @options: a #cairo_font_options_t object
+ * 
+ * Add options to a #FcPattern based on a #cairo_font_options_t font
+ * options object. Options that are already in the pattern, are not
+ * overriden, so you should call this function after calling FcConfigSubstitute()
+ * (the user's settings should override options based on the surface type),
+ * but before calling FcDefaultSubstitute().
+ **/
+void
+cairo_ft_font_options_substitute (const cairo_font_options_t *options,
+				  FcPattern                  *pattern)
+{
+    FcValue v;
+
+    if (options->antialias != CAIRO_ANTIALIAS_DEFAULT)
+    {
+	if (FcPatternGet (pattern, FC_ANTIALIAS, 0, &v) == FcResultNoMatch)
+	{
+	    FcPatternAddBool (pattern, FC_ANTIALIAS, options->antialias != CAIRO_ANTIALIAS_NONE);
+	}
+    }
+
+    if (options->antialias != CAIRO_ANTIALIAS_DEFAULT)
+    {
+	if (FcPatternGet (pattern, FC_RGBA, 0, &v) == FcResultNoMatch)
+	{
+	    int rgba;
+	    
+	    if (options->antialias == CAIRO_ANTIALIAS_SUBPIXEL) {
+		switch (options->subpixel_order) {
+		case CAIRO_SUBPIXEL_ORDER_DEFAULT:
+		case CAIRO_SUBPIXEL_ORDER_RGB:
+		default:
+		    rgba = FC_RGBA_RGB;
+		    break;
+		case CAIRO_SUBPIXEL_ORDER_BGR:
+		    rgba = FC_RGBA_BGR;
+		    break;
+		case CAIRO_SUBPIXEL_ORDER_VRGB:
+		    rgba = FC_RGBA_VRGB;
+		    break;
+		case CAIRO_SUBPIXEL_ORDER_VBGR:
+		    rgba = FC_RGBA_VBGR;
+		    break;
+		}
+	    } else {
+		rgba = FC_RGBA_NONE;
+	    }
+	    
+	    FcPatternAddInteger (pattern, FC_RGBA, rgba);
+	}
+    }
+
+    if (options->hint_style != CAIRO_HINT_STYLE_DEFAULT)
+    {
+	if (FcPatternGet (pattern, FC_HINTING, 0, &v) == FcResultNoMatch)
+	{
+	    FcPatternAddBool (pattern, FC_HINTING, options->hint_style != CAIRO_HINT_STYLE_NONE);
+	}
+
+#ifdef FC_HINT_STYLE	
+	if (FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch)
+	{
+	    int hint_style;
+
+	    switch (options->hint_style) {
+	    case CAIRO_HINT_STYLE_SLIGHT:
+		hint_style = FC_HINT_SLIGHT;
+		break;
+	    case CAIRO_HINT_STYLE_MEDIUM:
+		hint_style = FC_HINT_MEDIUM;
+		break;
+	    case CAIRO_HINT_STYLE_FULL:
+	    default:
+		hint_style = FC_HINT_FULL;
+		break;
+	    }
+	    
+	    FcPatternAddInteger (pattern, FC_HINT_STYLE, hint_style);
+	}
+#endif	
+    }
+}
+
+/**
  * cairo_ft_font_face_create_for_pattern:
  * @pattern: A fully resolved fontconfig
  *   pattern. A pattern can be resolved, by, among other things, calling
@@ -1759,6 +1972,12 @@
  * returned from cairo_font_create() is also for the FreeType backend
  * and can be used with functions such as cairo_ft_font_lock_face().
  *
+ * Font rendering options are representated both here and when you
+ * call cairo_scaled_font_create(). Font options that have a representation
+ * in a #FcPattern must be passed in here; to modify #FcPattern
+ * appropriately to reflect the options in a #cairo_font_options_t, call
+ * cairo_ft_font_options_substitute().
+ *
  * Return value: a newly created #cairo_font_face_t. Free with
  *  cairo_font_face_destroy() when you are done using it.
  **/
@@ -1772,7 +1991,7 @@
     if (unscaled == NULL)
 	return NULL;
 
-    font_face = _ft_font_face_create (unscaled, _get_load_flags (pattern));
+    font_face = _ft_font_face_create (unscaled, _get_pattern_load_flags (pattern));
     _cairo_unscaled_font_destroy (&unscaled->base);
 
     return font_face;
@@ -1786,10 +2005,13 @@
  *   internally to Cairo, the best way to determine when it
  *   is safe to free the face is to pass a
  *   #cairo_destroy_func_t to cairo_font_face_set_user_data()
- * @load_flags: The flags to pass to FT_Load_Glyph when loading
- *   glyphs from the font. These flags control aspects of
- *   rendering such as hinting and antialiasing. See the FreeType
- *   docs for full information.
+ * @load_flags: flags to pass to FT_Load_Glyph when loading
+ *   glyphs from the font. These flags are OR'ed together with
+ *   the flags derived from the #cairo_font_options_t passed
+ *   to cairo_scaled_font_create(), so only a few values such
+ *   as %FT_LOAD_VERTICAL_LAYOUT, and %FT_LOAD_FORCE_AUTOHINT
+ *   are useful. You should not pass any of the flags affecting
+ *   the load target, such as %FT_LOAD_TARGET_LIGHT.
  * 
  * Creates a new font face for the FreeType font backend from a pre-opened
  * FreeType face. This font can then be used with

Index: cairo-ft.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-ft.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- cairo-ft.h	14 May 2005 17:03:56 -0000	1.5
+++ cairo-ft.h	21 Jul 2005 13:52:13 -0000	1.6
@@ -52,6 +52,9 @@
 cairo_font_face_t *
 cairo_ft_font_face_create_for_pattern (FcPattern *pattern);
 
+void cairo_ft_font_options_substitute     (const cairo_font_options_t *options,
+					   FcPattern                  *pattern);
+
 cairo_font_face_t *
 cairo_ft_font_face_create_for_ft_face (FT_Face         face,
 				       int             load_flags);

Index: cairo-gstate.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-gstate.c,v
retrieving revision 1.146
retrieving revision 1.147
diff -u -d -r1.146 -r1.147
--- cairo-gstate.c	15 Jul 2005 08:05:56 -0000	1.146
+++ cairo-gstate.c	21 Jul 2005 13:52:13 -0000	1.147
@@ -1974,6 +1974,7 @@
 _cairo_gstate_ensure_font (cairo_gstate_t *gstate)
 {
     cairo_status_t status;
+    cairo_font_options_t options;
     
     if (gstate->scaled_font)
 	return CAIRO_STATUS_SUCCESS;
@@ -1982,9 +1983,11 @@
     if (status)
 	return status;
 
+    cairo_surface_get_font_options (gstate->target, &options);
     gstate->scaled_font = cairo_scaled_font_create (gstate->font_face,
 						    &gstate->font_matrix,
-						    &gstate->ctm);
+						    &gstate->ctm,
+						    &options);
     
     if (!gstate->scaled_font)
 	return CAIRO_STATUS_NO_MEMORY;

Index: cairo-pdf-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-pdf-surface.c,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -r1.51 -r1.52
--- cairo-pdf-surface.c	15 Jul 2005 00:52:17 -0000	1.51
+++ cairo-pdf-surface.c	21 Jul 2005 13:52:13 -0000	1.52
@@ -1379,6 +1379,16 @@
     return status;
 }
 
+static void
+_cairo_pdf_surface_get_font_options (void                  *abstract_surface,
+				     cairo_font_options_t  *options)
+{
+  _cairo_font_options_init_default (options);
+
+  cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE);
+  cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
+}
+
 static const cairo_surface_backend_t cairo_pdf_surface_backend = {
     _cairo_pdf_surface_create_similar,
     _cairo_pdf_surface_finish,
@@ -1396,7 +1406,8 @@
     _cairo_pdf_surface_intersect_clip_path,
     _cairo_pdf_surface_get_extents,
     _cairo_pdf_surface_show_glyphs,
-    _cairo_pdf_surface_fill_path
+    _cairo_pdf_surface_fill_path,
+    _cairo_pdf_surface_get_font_options
 };
 
 static cairo_pdf_document_t *

Index: cairo-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-surface.c,v
retrieving revision 1.79
retrieving revision 1.80
diff -u -d -r1.79 -r1.80
--- cairo-surface.c	15 Jul 2005 20:59:47 -0000	1.79
+++ cairo-surface.c	21 Jul 2005 13:52:13 -0000	1.80
@@ -257,6 +257,33 @@
 }
 
 /**
+ * cairo_surface_get_font_options:
+ * @surface: a #cairo_surface_t
+ * @options: a #cairo_font_options_t object into which to store
+ *   the retrieved options. All existing values are overwritten
+ * 
+ * Retrieves the default font rendering options for the surface.
+ * This allows display surfaces to report the correct subpixel order
+ * for rendering on them, print surfaces to disable hinting of
+ * metrics and so forth. The result can then be used with
+ * cairo_scaled_font_create().
+ **/
+void
+cairo_surface_get_font_options (cairo_surface_t       *surface,
+				cairo_font_options_t  *options)
+{
+    
+    if (!surface->finished && surface->backend->get_font_options) {
+	surface->backend->get_font_options (surface, options);
+    } else {
+	options->antialias = CAIRO_ANTIALIAS_DEFAULT;
+	options->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
+	options->hint_style = CAIRO_HINT_STYLE_DEFAULT;
+	options->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
+    }
+}
+
+/**
  * cairo_surface_set_device_offset:
  * @surface: a #cairo_surface_t
  * @x_offset: the offset in the X direction, in device units

Index: cairo-win32-font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-win32-font.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- cairo-win32-font.c	28 Jun 2005 22:03:53 -0000	1.24
+++ cairo-win32-font.c	21 Jul 2005 13:52:13 -0000	1.25
@@ -55,6 +55,7 @@
     cairo_scaled_font_t base;
 
     LOGFONTW logfont;
+    cairo_font_options_t options;
 
     BYTE quality;
 
@@ -162,6 +163,24 @@
 	cairo_matrix_init_identity (&scaled_font->device_to_logical);
 }
 
+static cairo_bool_t
+_have_cleartype_quality (void)
+{
+    OSVERSIONINFO version_info;
+    
+    version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+    
+    if (!GetVersionEx (&version_info)) {
+	_cairo_win32_print_gdi_error ("_have_cleartype_quality");
+	return FALSE;
+    }
+    
+    return (version_info.dwMajorVersion > 5 ||
+	    (version_info.dwMajorVersion == 5 &&
+	     version_info.dwMinorVersion >= 1));	/* XP or newer */
+}
+
+
 static BYTE
 _get_system_quality (void)
 {
@@ -169,28 +188,15 @@
 
     if (!SystemParametersInfo (SPI_GETFONTSMOOTHING, 0, &font_smoothing, 0)) {
 	_cairo_win32_print_gdi_error ("_get_system_quality");
-	return FALSE;
+	return DEFAULT_QUALITY;
     }
 
     if (font_smoothing) {
-	OSVERSIONINFO version_info;
-
-	version_info.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
-	
-	if (!GetVersionEx (&version_info)) {
-	    _cairo_win32_print_gdi_error ("_get_system_quality");
-	    return FALSE;
-	}
-
-	if (version_info.dwMajorVersion > 5 ||
-	    (version_info.dwMajorVersion == 5 &&
-	     version_info.dwMinorVersion >= 1))	{ /* XP or newer */
-	    UINT smoothing_type;
-
+	if (_have_cleartype_quality ()) {
 	    if (!SystemParametersInfo (SPI_GETFONTSMOOTHINGTYPE,
 				       0, &smoothing_type, 0)) {
 		_cairo_win32_print_gdi_error ("_get_system_quality");
-		return FALSE;
+		return DEFAULT_QUALITY;
 	    }
 
 	    if (smoothing_type == FE_FONTSMOOTHINGCLEARTYPE)
@@ -204,9 +210,10 @@
 }
 
 static cairo_scaled_font_t *
-_win32_scaled_font_create (LOGFONTW             *logfont,
-			   const cairo_matrix_t *font_matrix,
-			   const cairo_matrix_t *ctm)
+_win32_scaled_font_create (LOGFONTW                   *logfont,
+			   const cairo_matrix_t       *font_matrix,
+			   const cairo_matrix_t       *ctm,
+			   const cairo_font_options_t *options)			  
 {
     cairo_win32_scaled_font_t *f;
     cairo_matrix_t scale;
@@ -216,7 +223,35 @@
       return NULL;
 
     f->logfont = *logfont;
-    f->quality = _get_system_quality ();
+    f->options = *options;
+
+    /* We don't have any control over the hinting style or subpixel
+     * order in the Win32 font API, so we ignore those parts of
+     * cairo_font_options_t. We use the 'antialias' field to set
+     * the 'quality'.
+     * 
+     * XXX: The other option we could pay attention to, but don't
+     *      here is the hint_metrics options.
+     */
+    if (options->antialias == CAIRO_ANTIALIAS_DEFAULT)
+	f->quality = _get_system_quality ();
+    else {
+	switch (options->antialias) {
+	case CAIRO_ANTIALIAS_NONE:
+	    f->quality = NONANTIALIASED_QUALITY;
+	    break;
+	case CAIRO_ANTIALIAS_GRAY:
+	    f->quality = ANTIALIASED_QUALITY;
+	    break;
+	case CAIRO_ANTIALIAS_SUBPIXEL:
+	    if (_have_cleartype_quality ())
+		f->quality = CLEARTYPE_QUALITY;
+	    else
+		f->quality = ANTIALIASED_QUALITY;
+	    break;
+	}
+    }
+    
     f->em_square = 0;
     f->scaled_hfont = NULL;
     f->unscaled_hfont = NULL;
@@ -390,12 +425,13 @@
 /* implement the font backend interface */
 
 static cairo_status_t
-_cairo_win32_scaled_font_create (const char            *family, 
-				 cairo_font_slant_t     slant, 
-				 cairo_font_weight_t    weight,
-				 const cairo_matrix_t  *font_matrix,
-				 const cairo_matrix_t  *ctm,
-				 cairo_scaled_font_t  **scaled_font_out)
+_cairo_win32_scaled_font_create (const char                  *family, 
+				 cairo_font_slant_t          slant, 
+				 cairo_font_weight_t         weight,
+				 const cairo_matrix_t       *font_matrix,
+				 const cairo_matrix_t       *ctm,
+				 const cairo_font_options_t *options,
+				 cairo_scaled_font_t       **scaled_font_out)
 {
     LOGFONTW logfont;
     cairo_scaled_font_t *scaled_font;
@@ -456,7 +492,7 @@
     if (!logfont.lfFaceName)
 	return CAIRO_STATUS_NO_MEMORY;
     
-    scaled_font = _win32_scaled_font_create (&logfont, font_matrix, ctm);
+    scaled_font = _win32_scaled_font_create (&logfont, font_matrix, ctm, options);
     if (!scaled_font)
 	return CAIRO_STATUS_NO_MEMORY;
 
@@ -1262,15 +1298,16 @@
 }
 
 static cairo_status_t
-_cairo_win32_font_face_create_font (void                  *abstract_face,
-				    const cairo_matrix_t  *font_matrix,
-				    const cairo_matrix_t  *ctm,
-				    cairo_scaled_font_t  **font)
+_cairo_win32_font_face_create_font (void                       *abstract_face,
+				    const cairo_matrix_t       *font_matrix,
+				    const cairo_matrix_t       *ctm,
+				    const cairo_font_options_t *options,
+				    cairo_scaled_font_t       **font)
 {
     cairo_win32_font_face_t *font_face = abstract_face;
 
     *font = _win32_scaled_font_create (&font_face->logfont,
-				       font_matrix, ctm);
+				       font_matrix, ctm, options);
     if (*font)
 	return CAIRO_STATUS_SUCCESS;
     else

--- NEW FILE: cairo-xlib-private.h ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: cairo-xlib-screen.c ---
(This appears to be a binary file; contents omitted.)

Index: cairo-xlib-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-xlib-surface.c,v
retrieving revision 1.90
retrieving revision 1.91
diff -u -d -r1.90 -r1.91
--- cairo-xlib-surface.c	21 Jul 2005 01:52:31 -0000	1.90
+++ cairo-xlib-surface.c	21 Jul 2005 13:52:13 -0000	1.91
@@ -38,6 +38,7 @@
 #include "cairo-xlib.h"
 #include "cairo-xlib-xrender.h"
 #include "cairo-xlib-test.h"
+#include "cairo-xlib-private.h"
 #include <X11/extensions/Xrender.h>
 
 /* Xlib doesn't define a typedef, so define one ourselves */
@@ -70,6 +71,8 @@
     cairo_surface_t base;
 
     Display *dpy;
+    cairo_xlib_screen_info_t *screen_info;
+  
     GC gc;
     Drawable drawable;
     Screen *screen;
@@ -1321,6 +1324,15 @@
     return CAIRO_STATUS_SUCCESS;
 }
 
+static void
+_cairo_xlib_surface_get_font_options (void                  *abstract_surface,
+				      cairo_font_options_t  *options)
+{
+  cairo_xlib_surface_t *surface = abstract_surface;
+
+  *options = surface->screen_info->font_options;
+}
+
 static cairo_int_status_t
 _cairo_xlib_surface_show_glyphs (cairo_scaled_font_t    *scaled_font,
 				 cairo_operator_t       operator,
@@ -1351,7 +1363,9 @@
     _cairo_xlib_surface_set_clip_region,
     NULL, /* intersect_clip_path */
     _cairo_xlib_surface_get_extents,
-    _cairo_xlib_surface_show_glyphs
+    _cairo_xlib_surface_show_glyphs,
+    NULL, /* fill_path */
+    _cairo_xlib_surface_get_font_options
 };
 
 /**
@@ -1379,6 +1393,11 @@
 				     int			depth)
 {
     cairo_xlib_surface_t *surface;
+    cairo_xlib_screen_info_t *screen_info;
+
+    screen_info = _cairo_xlib_screen_info_get (dpy, DefaultScreen (dpy));
+    if (!screen_info)
+	return NULL;
 
     surface = malloc (sizeof (cairo_xlib_surface_t));
     if (surface == NULL)
@@ -1387,6 +1406,7 @@
     _cairo_surface_init (&surface->base, &cairo_xlib_surface_backend);
 
     surface->dpy = dpy;
+    surface->screen_info = screen_info;
 
     surface->gc = NULL;
     surface->drawable = drawable;

Index: cairo.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.h,v
retrieving revision 1.135
retrieving revision 1.136
diff -u -d -r1.135 -r1.136
--- cairo.h	21 Jul 2005 02:23:19 -0000	1.135
+++ cairo.h	21 Jul 2005 13:52:13 -0000	1.136
@@ -635,7 +635,148 @@
   CAIRO_FONT_WEIGHT_NORMAL,
   CAIRO_FONT_WEIGHT_BOLD
 } cairo_font_weight_t;
-  
+
+/**
+ * cairo_antialias_t:
+ * @CAIRO_ANTIALIAS_DEFAULT: Use the default antialiasing for
+ *   the font subsystem and target device
+ * @CAIRO_ANTIALIAS_NONE: Do no antialiasing of fonts; use bilevel text
+ * @CAIRO_ANTIALIAS_GRAY: Perform single-color antialiasing (using
+ *  shades of gray for black text on a white background, for example).
+ * @CAIRO_ANTIALIAS_SUBPIXEL: Perform antialiasing by taking
+ *  advantage of the order of subpixel elements on devices
+ *  such as LCD panels
+ * 
+ * Specifies the type of antialiasing to do when rendering text.
+ **/
+typedef enum _cairo_antialias {
+    CAIRO_ANTIALIAS_DEFAULT,
+    CAIRO_ANTIALIAS_NONE,
+    CAIRO_ANTIALIAS_GRAY,
+    CAIRO_ANTIALIAS_SUBPIXEL
+} cairo_antialias_t;
+
+/**
+ * cairo_subpixel_order_t:
+ * @CAIRO_SUBPIXEL_ORDER_DEFAULT: Use the default subpixel order for
+ *   for the target device
+ * @CAIRO_SUBPIXEL_ORDER_RGB: Subpixel elements are arranged horizontally
+ *   with red at the left
+ * @CAIRO_SUBPIXEL_ORDER_BGR:  Subpixel elements are arranged horizontally
+ *   with blue at the left
+ * @CAIRO_SUBPIXEL_ORDER_VRGB: Subpixel elements are arranged vertically
+ *   with red at the top
+ * @CAIRO_SUBPIXEL_ORDER_VBGR: Subpixel elements are arranged vertically
+ *   with blue at the top
+ * 
+ * The subpixel order specifies the order of color elements within
+ * each pixel on the display device when rendering with an
+ * antialiasing mode of %CAIRO_ANTIALIAS_SUBPIXEL.
+ **/
+typedef enum _cairo_subpixel_order {
+    CAIRO_SUBPIXEL_ORDER_DEFAULT,
+    CAIRO_SUBPIXEL_ORDER_RGB,
+    CAIRO_SUBPIXEL_ORDER_BGR,
+    CAIRO_SUBPIXEL_ORDER_VRGB,
+    CAIRO_SUBPIXEL_ORDER_VBGR
+} cairo_subpixel_order_t;
+
+/**
+ * cairo_hint_style_t:
+ * @CAIRO_HINT_STYLE_DEFAULT: Use the default hint style for
+ *   for font backend and target device
+ * @CAIRO_HINT_STYLE_NONE: Do not hint outlines
+ * @CAIRO_HINT_STYLE_SLIGHT: Hint outlines slightly to improve
+ *   contrast while retaining good fidelity to the original
+ *   shapes.
+ * @CAIRO_HINT_STYLE_MEDIUM: Hint outlines with medium strength
+ *   giving a compromise between fidelity to the original shapes
+ *   and contrast
+ * @CAIRO_HINT_STYLE_FULL: Hint outlines to maximize contrast
+ *
+ * Specifies the type of hinting to do on font outlines. Hinting
+ * is the process of fitting outlines to the pixel grid in order
+ * to improve the appearance of the result. Since hinting outlines
+ * involves distorting them, it also reduces the faithfulness
+ * to the original outline shapes. Not all of the outline hinting
+ * styles are supported by all font backends.
+ */
+typedef enum _cairo_hint_style {
+    CAIRO_HINT_STYLE_DEFAULT,
+    CAIRO_HINT_STYLE_NONE,
+    CAIRO_HINT_STYLE_SLIGHT,
+    CAIRO_HINT_STYLE_MEDIUM,
+    CAIRO_HINT_STYLE_FULL
+} cairo_hint_style_t;
+
+/**
+ * cairo_hint_metrics_t:
+ * @CAIRO_HINT_METRICS_DEFAULT: Hint metrics in the default
+ *  manner for the font backend and target device
+ * @CAIRO_HINT_METRICS_OFF: Do not hint font metrics
+ * @CAIRO_HINT_METRICS_ON: Hint font metrics
+ *
+ * Specifies whether to hint font metrics; hinting font metrics
+ * means quantizing them so that they are integer values in
+ * device space. Doing this improves the consistency of
+ * letter and line spacing, however it also means that text
+ * will be laid out differently at different zoom factors.
+ */
+typedef enum _cairo_hint_metrics {
+    CAIRO_HINT_METRICS_DEFAULT,
+    CAIRO_HINT_METRICS_OFF,
+    CAIRO_HINT_METRICS_ON
+} cairo_hint_metrics_t;
+
+typedef struct _cairo_font_options cairo_font_options_t;
+
+cairo_font_options_t *
+cairo_font_options_create (void);
+
+cairo_font_options_t *
+cairo_font_options_copy (const cairo_font_options_t *original);
+
+void 
+cairo_font_options_destroy (cairo_font_options_t *options);
+
+cairo_status_t
+cairo_font_options_status (cairo_font_options_t *options);
+
+void
+cairo_font_options_merge (cairo_font_options_t       *options,
+			  const cairo_font_options_t *other);
+cairo_bool_t
+cairo_font_options_equal (const cairo_font_options_t *options,
+			  const cairo_font_options_t *other);
+
+unsigned long
+cairo_font_options_hash (const cairo_font_options_t *options);
+
+void
+cairo_font_options_set_antialias (cairo_font_options_t *options,
+				  cairo_antialias_t     antialias);
+cairo_antialias_t
+cairo_font_options_get_antialias (const cairo_font_options_t *options);
+
+void
+cairo_font_options_set_subpixel_order (cairo_font_options_t   *options,
+				       cairo_subpixel_order_t  subpixel_order);
+cairo_subpixel_order_t
+cairo_font_options_get_subpixel_order (const cairo_font_options_t *options);
+			 
+void
+cairo_font_options_set_hint_style (cairo_font_options_t *options,
+				   cairo_hint_style_t     hint_style);
+cairo_hint_style_t
+cairo_font_options_get_hint_style (const cairo_font_options_t *options);
+
+void
+cairo_font_options_set_hint_metrics (cairo_font_options_t *options,
+				     cairo_hint_metrics_t  hint_metrics);
+cairo_hint_metrics_t
+cairo_font_options_get_hint_metrics (const cairo_font_options_t *options);
+
+
 /* This interface is for dealing with text as text, not caring about the
    font object inside the the cairo_t. */
 
@@ -710,9 +851,10 @@
 /* Portable interface to general font features. */
 
 cairo_scaled_font_t *
-cairo_scaled_font_create (cairo_font_face_t    *font_face,
-			  const cairo_matrix_t *font_matrix,
-			  const cairo_matrix_t *ctm);
+cairo_scaled_font_create (cairo_font_face_t          *font_face,
+			  const cairo_matrix_t       *font_matrix,
+			  const cairo_matrix_t       *ctm,
+			  const cairo_font_options_t *options);
 
 void
 cairo_scaled_font_reference (cairo_scaled_font_t *scaled_font);
@@ -952,6 +1094,10 @@
 			     cairo_destroy_func_t	 destroy);
 
 void
+cairo_surface_get_font_options (cairo_surface_t      *surface,
+				cairo_font_options_t *options);
+
+void
 cairo_surface_set_device_offset (cairo_surface_t *surface,
 				 double           x_offset,
 				 double           y_offset);

Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.164
retrieving revision 1.165
diff -u -d -r1.164 -r1.165
--- cairoint.h	14 Jul 2005 22:10:48 -0000	1.164
+++ cairoint.h	21 Jul 2005 13:52:13 -0000	1.165
@@ -476,6 +476,13 @@
     const cairo_font_face_backend_t *backend;
 };
 
+struct _cairo_font_options {
+    cairo_antialias_t antialias;
+    cairo_subpixel_order_t subpixel_order;
+    cairo_hint_style_t hint_style;
+    cairo_hint_metrics_t hint_metrics;
+};
+
 /* cairo_font.c is responsible for a global glyph cache: 
  *  
  *   - glyph entries: [[[base], cairo_unscaled_font_t, scale, flags, index],
@@ -534,6 +541,7 @@
 				      cairo_font_weight_t	weight,
 				      const cairo_matrix_t     *font_matrix,
 				      const cairo_matrix_t     *ctm,
+				      const cairo_font_options_t *options,
 				      cairo_scaled_font_t      **font);
     
     void (*destroy)                   (void		       *font);
@@ -585,6 +593,7 @@
     cairo_status_t (*create_font) (void                 *font_face,
 				   const cairo_matrix_t *font_matrix,
 				   const cairo_matrix_t *ctm,
+				   const cairo_font_options_t *options,
 				   cairo_scaled_font_t **scaled_font);
 };
 
@@ -766,6 +775,9 @@
 				 cairo_fill_rule_t	fill_rule,
 				 double			tolerance);
    
+    void
+    (*get_font_options)         (void                  *surface,
+				 cairo_font_options_t  *options);
 } cairo_surface_backend_t;
 
 typedef struct _cairo_format_masks {
@@ -1348,6 +1360,11 @@
 _cairo_scaled_font_get_glyph_cache_key (cairo_scaled_font_t     *scaled_font,
 					cairo_glyph_cache_key_t *key);
 
+/* cairo-font-options.c */
+
+cairo_private void
+_cairo_font_options_init_default (cairo_font_options_t *options);
+
 /* cairo_hull.c */
 cairo_private cairo_status_t
 _cairo_hull_compute (cairo_pen_vertex_t *vertices, int *num_vertices);




More information about the cairo-commit mailing list