diff -urbN cairo-1.0.4-org/src/cairo-font.c cairo-1.0.4-new/src/cairo-font.c
--- cairo-1.0.4-org/src/cairo-font.c	2006-03-15 17:43:51.000000000 +0100
+++ cairo-1.0.4-new/src/cairo-font.c	2006-09-30 19:07:14.000000000 +0200
@@ -1173,6 +1173,7 @@
 	^ ((unsigned long) in->scale.xy) 
 	^ ((unsigned long) in->scale.yy)
         ^ (in->flags * 1451) /* 1451 is just an abitrary prime */
+        ^ (in->flags2 * 371)  /* wathever */
 	^ in->index;
 }
 
@@ -1187,6 +1188,7 @@
     return (a->index == b->index)
 	&& (a->unscaled == b->unscaled)
 	&& (a->flags == b->flags)
+        && (a->flags2 == b->flags2)
 	&& (a->scale.xx == b->scale.xx)
 	&& (a->scale.yx == b->scale.yx)
 	&& (a->scale.xy == b->scale.xy)
diff -urbN cairo-1.0.4-org/src/cairo-ft-font.c cairo-1.0.4-new/src/cairo-ft-font.c
--- cairo-1.0.4-org/src/cairo-ft-font.c	2006-03-15 17:43:51.000000000 +0100
+++ cairo-1.0.4-new/src/cairo-ft-font.c	2006-09-30 23:42:51.000000000 +0200
@@ -52,6 +52,12 @@
 #include FT_SYNTHESIS_H
 #endif
 
+#if FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH < 20202
+#  error  "FreeType 2.2.2 or later required to compile this version of libXft"
+#endif
+
+#include FT_LCD_FILTER_H
+
 #define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
 #define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
 #define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
@@ -68,6 +74,8 @@
 #define PRIVATE_FLAG_BGR          (0x04 << 24)
 #define PRIVATE_FLAGS_MASK        (0xff << 24)
 
+#define OTHER_FLAGS_TO_RENDER_MODE(x)  ((FT_Render_Mode)((x) & 15)
+
  /* This is the max number of FT_face objects we keep open at once
   */
  #define MAX_OPEN_FACES 10
@@ -128,6 +136,8 @@
     cairo_font_face_t base;
     cairo_ft_unscaled_font_t *unscaled;
     int load_flags;
+    int                       other_flags;
+
     cairo_ft_font_face_t *next;
 };
 
@@ -678,23 +688,297 @@
     assert (error == 0);
 }
 
-/* Empirically-derived subpixel filtering values thanks to Keith
- * Packard and libXft. */
-static const int    filters[3][3] = {
-    /* red */
-#if 0
-    {    65538*4/7,65538*2/7,65538*1/7 },
-    /* green */
-    {    65536*1/4, 65536*2/4, 65537*1/4 },
-    /* blue */
-    {    65538*1/7,65538*2/7,65538*4/7 },
-#endif
-    {    65538*9/13,65538*3/13,65538*1/13 },
-    /* green */
-    {    65538*1/6, 65538*4/6, 65538*1/6 },
-    /* blue */
-    {    65538*1/13,65538*3/13,65538*9/13 },
-};
+
+
+/* we sometimes need to convert the glyph bitmap in a FT_GlyphSlot
+ * into a different format. For example, we want to convert a
+ * FT_PIXEL_MODE_LCD or FT_PIXEL_MODE_LCD_V bitmap into a 32-bit
+ * ARGB or ABGR bitmap.
+ *
+ * this function prepares a target descriptor for this operation.
+ *
+ * input :: target bitmap descriptor. The function will set its
+ *          'width', 'rows' and 'pitch' fields, and only these
+ *
+ * slot  :: the glyph slot containing the source bitmap. this
+ *          function assumes that slot->format == FT_GLYPH_FORMAT_BITMAP
+ *
+ * mode  :: the requested final rendering mode. supported values are
+ *          MONO, NORMAL (i.e. gray), LCD and LCD_V
+ *
+ * the function returns the size in bytes of the corresponding buffer,
+ * it's up to the caller to allocate the corresponding memory block
+ * before calling _fill_xrender_bitmap
+ *
+ * it also returns -1 in case of error (e.g. incompatible arguments,
+ * like trying to convert a gray bitmap into a monochrome one)
+ */
+static int
+_compute_xrender_bitmap_size( FT_Bitmap*      target,
+                              FT_GlyphSlot    slot,
+                              FT_Render_Mode  mode )
+{
+    FT_Bitmap*  ftbit;
+    int         width, height, pitch;
+
+    if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
+        return -1;
+
+    // compute the size of the final bitmap
+    ftbit  = &slot->bitmap;
+
+    width  = ftbit->width;
+    height = ftbit->rows;
+    pitch  = (width+3) & ~3;
+
+    switch ( ftbit->pixel_mode )
+    {
+    case FT_PIXEL_MODE_MONO:
+        if ( mode == FT_RENDER_MODE_MONO )
+        {
+            pitch = (((width+31) & ~31) >> 3);
+            break;
+        }
+        /* fall-through */
+
+    case FT_PIXEL_MODE_GRAY:
+        if ( mode == FT_RENDER_MODE_LCD   ||
+             mode == FT_RENDER_MODE_LCD_V )
+        {
+          /* each pixel is replicated into a 32-bit ARGB value */
+          pitch = width*4;
+        }
+        break;
+
+    case FT_PIXEL_MODE_LCD:
+        if ( mode != FT_RENDER_MODE_LCD )
+            return -1;
+
+        /* horz pixel triplets are packed into 32-bit ARGB values */
+        width   /= 3;
+        pitch    = width*4;
+        break;
+
+    case FT_PIXEL_MODE_LCD_V:
+        if ( mode != FT_RENDER_MODE_LCD_V )
+            return -1;
+
+        /* vert pixel triplets are packed into 32-bit ARGB values */
+        height  /= 3;
+        pitch    = width*4;
+        break;
+
+    default:  /* unsupported source format */
+        return -1;
+    }
+
+    target->width  = width;
+    target->rows   = height;
+    target->pitch  = pitch;
+    target->buffer = NULL;
+
+    return pitch * height;
+}
+
+/* this functions converts the glyph bitmap found in a FT_GlyphSlot
+ * into a different format (see _compute_xrender_bitmap_size)
+ *
+ * you should call this function after _compute_xrender_bitmap_size
+ *
+ * target :: target bitmap descriptor. Note that its 'buffer' pointer
+ *           must point to memory allocated by the caller
+ *
+ * slot   :: the glyph slot containing the source bitmap
+ *
+ * mode   :: the requested final rendering mode
+ *
+ * bgr    :: boolean, set if BGR or VBGR pixel ordering is needed
+ */
+static void
+_fill_xrender_bitmap( FT_Bitmap*      target,
+                      FT_GlyphSlot    slot,
+                      FT_Render_Mode  mode,
+                      int             bgr )
+{
+    FT_Bitmap*   ftbit = &slot->bitmap;
+    unsigned char*   srcLine   = ftbit->buffer;
+    unsigned char*   dstLine   = target->buffer;
+    int              src_pitch = ftbit->pitch;
+    int              width     = target->width;
+    int              height    = target->rows;
+    int              pitch     = target->pitch;
+    int              subpixel;
+    int              h;
+
+    subpixel = ( mode == FT_RENDER_MODE_LCD ||
+                 mode == FT_RENDER_MODE_LCD_V );
+
+    if ( src_pitch < 0 )
+        srcLine -= src_pitch*(ftbit->rows-1);
+
+    target->pixel_mode = ftbit->pixel_mode;
+
+    switch ( ftbit->pixel_mode )
+    {
+    case FT_PIXEL_MODE_MONO:
+        if ( subpixel )  /* convert mono to ARGB32 values */
+        {
+            for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+            {
+                int  x;
+
+                for ( x = 0; x < width; x++ )
+                {
+                    if ( srcLine[(x >> 3)] & (0x80 >> (x & 7)) )
+                        ((unsigned int*)dstLine)[x] = 0xffffffffU;
+                }
+            }
+            target->pixel_mode = FT_PIXEL_MODE_LCD;
+        }
+        else if ( mode == FT_RENDER_MODE_NORMAL )  /* convert mono to 8-bit gray */
+        {
+            for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+            {
+                int  x;
+
+                for ( x = 0; x < width; x++ )
+                {
+                    if ( srcLine[(x >> 3)] & (0x80 >> (x & 7)) )
+                        dstLine[x] = 0xff;
+                }
+            }
+            target->pixel_mode = FT_PIXEL_MODE_GRAY;
+        }
+        else  /* copy mono to mono */
+        {
+            int  bytes = (width+7) >> 3;
+
+            for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+                memcpy( dstLine, srcLine, bytes );
+        }
+        break;
+
+    case FT_PIXEL_MODE_GRAY:
+        if ( subpixel )  /* convert gray to ARGB32 values */
+        {
+            for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+            {
+                int            x;
+                unsigned int*  dst = (unsigned int*)dstLine;
+
+                for ( x = 0; x < width; x++ )
+                {
+                    unsigned int  pix = srcLine[x];
+
+                    pix |= (pix << 8);
+                    pix |= (pix << 16);
+
+                    dst[x] = pix;
+                }
+            }
+            target->pixel_mode = FT_PIXEL_MODE_LCD;
+        }
+        else  /* copy gray into gray */
+        {
+            for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+                memcpy( dstLine, srcLine, width );
+        }
+        break;
+
+    case FT_PIXEL_MODE_LCD:
+        if ( !bgr )
+        {
+            /* convert horizontal RGB into ARGB32 */
+            for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+            {
+                int            x;
+                unsigned char* src = srcLine;
+                unsigned int*  dst = (unsigned int*)dstLine;
+
+                for ( x = 0; x < width; x++, src += 3 )
+                {
+                    unsigned int  pix;
+
+                    pix = ((unsigned int)src[0] << 16) |
+                          ((unsigned int)src[1] <<  8) |
+                          ((unsigned int)src[2]      ) |
+                          ((unsigned int)src[1] << 24) ;
+
+                    dst[x] = pix;
+                }
+            }
+        }
+        else
+        {
+            /* convert horizontal BGR into ARGB32 */
+            for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+            {
+                int            x;
+                unsigned char* src = srcLine;
+                unsigned int*  dst = (unsigned int*)dstLine;
+
+                for ( x = 0; x < width; x++, src += 3 )
+                {
+                    unsigned int  pix;
+
+                    pix = ((unsigned int)src[2] << 16) |
+                          ((unsigned int)src[1] <<  8) |
+                          ((unsigned int)src[0]      ) |
+                          ((unsigned int)src[1] << 24) ;
+
+                    dst[x] = pix;
+                }
+            }
+        }
+        break;
+
+    default:  /* FT_PIXEL_MODE_LCD_V */
+        /* convert vertical RGB into ARGB32 */
+        if ( !bgr )
+        {
+            for ( h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch )
+            {
+                int            x;
+                unsigned char* src = srcLine;
+                unsigned int*  dst = (unsigned int*)dstLine;
+
+                for ( x = 0; x < width; x++, src += 1 )
+                {
+                    unsigned int  pix;
+
+                    pix = ((unsigned int)src[0]           << 16) |
+                          ((unsigned int)src[src_pitch]   <<  8) |
+                          ((unsigned int)src[src_pitch*2]      ) |
+                          ((unsigned int)src[src_pitch]   << 24) ;
+
+                    dst[x] = pix;
+                }
+            }
+        }
+        else
+        {
+            for ( h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch )
+            {
+                int            x;
+                unsigned char* src = srcLine;
+                unsigned int*  dst = (unsigned int*)dstLine;
+
+                for ( x = 0; x < width; x++, src += 1 )
+                {
+                    unsigned int  pix;
+
+                    pix = ((unsigned int)src[src_pitch*2] << 16) |
+                          ((unsigned int)src[src_pitch]   <<  8) |
+                          ((unsigned int)src[0]                ) |
+                          ((unsigned int)src[src_pitch]   << 24) ;
+
+                    dst[x] = pix;
+                }
+            }
+        }
+    }
+}
+
 
 static cairo_bool_t
 _native_byte_order_lsb (void)
@@ -715,7 +999,6 @@
     int width, height, stride;
     unsigned char *data;
     int format = CAIRO_FORMAT_A8;
-    cairo_bool_t subpixel = FALSE;
     
     width = bitmap->width;
     height = bitmap->rows;
@@ -782,92 +1065,14 @@
 		}
 		format = CAIRO_FORMAT_A8;
 	    } else {
-		int		    x, y;
-		unsigned char   *in_line, *out_line, *in;
-		unsigned int    *out;
-		unsigned int    red, green, blue;
-		int		    rf, gf, bf;
-		int		    s;
-		int		    o, os;
-		unsigned char   *data_rgba;
-		unsigned int    width_rgba, stride_rgba;
-		int		    vmul = 1;
-		int		    hmul = 1;
+                // if we get there, the  data from the source bitmap
+                // really comes from _fill_xrender_bitmap, and is
+                // made of 32-bit ARGB or ABGR values
+                assert(own_buffer != 0);
+                assert(bitmap->pixel_mode != FT_PIXEL_MODE_GRAY);
 		
-		switch (rgba) {
-		case FC_RGBA_RGB:
-		case FC_RGBA_BGR:
-		default:
-		    width /= 3;
-		    hmul = 3;
-		    break;
-		case FC_RGBA_VRGB:
-		case FC_RGBA_VBGR:
-		    vmul = 3;
-		    height /= 3;
-		    break;
-		}
-		subpixel = TRUE;
-		/*
-		 * Filter the glyph to soften the color fringes
-		 */
-		width_rgba = width;
+		data   = bitmap->buffer;
 		stride = bitmap->pitch;
-		stride_rgba = (width_rgba * 4 + 3) & ~3;
-		data_rgba = calloc (1, stride_rgba * height);
-    
-		os = 1;
-		switch (rgba) {
-		case FC_RGBA_VRGB:
-		    os = stride;
-		case FC_RGBA_RGB:
-		default:
-		    rf = 0;
-		    gf = 1;
-		    bf = 2;
-		    break;
-		case FC_RGBA_VBGR:
-		    os = stride;
-		case FC_RGBA_BGR:
-		    bf = 0;
-		    gf = 1;
-		    rf = 2;
-		    break;
-		}
-		in_line = bitmap->buffer;
-		out_line = data_rgba;
-		for (y = 0; y < height; y++)
-		{
-		    in = in_line;
-		    out = (unsigned int *) out_line;
-		    in_line += stride * vmul;
-		    out_line += stride_rgba;
-		    for (x = 0; x < width * hmul; x += hmul)
-		    {
-			red = green = blue = 0;
-			o = 0;
-			for (s = 0; s < 3; s++)
-			{
-			    red += filters[rf][s]*in[x+o];
-			    green += filters[gf][s]*in[x+o];
-			    blue += filters[bf][s]*in[x+o];
-			    o += os;
-			}
-			red = red / 65536;
-			green = green / 65536;
-			blue = blue / 65536;
-			*out++ = (green << 24) | (red << 16) | (green << 8) | blue;
-		    }
-		}
-    
-		/* Images here are stored in native format. The
-		 * backend must convert to its own format as needed
-		 */
-    
-		if (own_buffer)
-		    free (bitmap->buffer);
-		data = data_rgba;
-		stride = stride_rgba;
 		format = CAIRO_FORMAT_ARGB32;
 	    }
 	    break;
@@ -887,7 +1092,7 @@
 	    return CAIRO_STATUS_NO_MEMORY;
 	}
 	
-	if (subpixel)
+	if (format == CAIRO_FORMAT_ARGB32)
 	    pixman_image_set_component_alpha (val->image->pixman_image, TRUE);
 
 	_cairo_image_surface_assume_ownership_of_data (val->image);
@@ -923,13 +1128,12 @@
     FT_Outline *outline = &glyphslot->outline;
     FT_Bitmap bitmap;
     FT_BBox cbox;
-    FT_Matrix matrix;
-    int hmul = 1;
-    int vmul = 1;
     unsigned int width, height, stride;
     cairo_format_t format;
-    cairo_bool_t subpixel = FALSE;
     cairo_status_t status;
+    FT_Error  fterror;
+    FT_Library  library = glyphslot->library;
+    FT_Render_Mode  render_mode = (FT_Render_Mode)(val->key.flags2 & 15);
 
     FT_Outline_Get_CBox (outline, &cbox);
 
@@ -940,103 +1144,89 @@
 
     width = (unsigned int) ((cbox.xMax - cbox.xMin) >> 6);
     height = (unsigned int) ((cbox.yMax - cbox.yMin) >> 6);
-    stride = (width * hmul + 3) & ~3;
+    stride = (width + 3) & ~3;
 
     if (width * height == 0) {
 	/* Looks like fb handles zero-sized images just fine */
-	if ((val->key.flags & FT_LOAD_MONOCHROME) != 0)
-	    format = CAIRO_FORMAT_A8;
-	else if (FT_LOAD_TARGET_MODE (val->key.flags) == FT_RENDER_MODE_LCD ||
-		 FT_LOAD_TARGET_MODE (val->key.flags) == FT_RENDER_MODE_LCD_V)
-	    format= CAIRO_FORMAT_ARGB32;
-	else
+        switch (render_mode)
+        {
+        case FT_RENDER_MODE_LCD:
+        case FT_RENDER_MODE_LCD_V:
+            format = CAIRO_FORMAT_ARGB32;
+
+        default:
 	    format = CAIRO_FORMAT_A8;
+        }
 
 	val->image = (cairo_image_surface_t *)
 	    cairo_image_surface_create_for_data (NULL, format, 0, 0, 0);
 	if (val->image->base.status)
 	    return CAIRO_STATUS_NO_MEMORY;
-    } else  {
 
-	matrix.xx = matrix.yy = 0x10000L;
-	matrix.xy = matrix.yx = 0;
+        val->size.x = 0;
+        val->size.y = 0;
 	
-	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 {
-	    /* XXX not a complete set of flags. This code
-	     * will go away when cworth rewrites the glyph
-	     * cache code */
-	    if (FT_LOAD_TARGET_MODE (val->key.flags) == FT_RENDER_MODE_LCD) {
-		    if (val->key.flags & PRIVATE_FLAG_BGR) {
+
+        int  bitmap_size;
+
+        switch (render_mode)
+        {
+        case FT_RENDER_MODE_LCD:
+              if (val->key.flags2 & PRIVATE_FLAG_BGR) {
 		        rgba = FC_RGBA_BGR;
 		    } else {
 			rgba = FC_RGBA_RGB;
 		    }
-	    }
-	    else if (FT_LOAD_TARGET_MODE (val->key.flags) == FT_RENDER_MODE_LCD_V) {
-		       if (val->key.flags & PRIVATE_FLAG_BGR) {
+              break;
+
+        case FT_RENDER_MODE_LCD_V:
+              if (val->key.flags2 & PRIVATE_FLAG_BGR) {
 			rgba = FC_RGBA_VBGR;
 		    } else {
 			rgba = FC_RGBA_VRGB;
 		    }
-	    }
-	    switch (rgba) {
-	    case FC_RGBA_RGB:
-	    case FC_RGBA_BGR:
-		matrix.xx *= 3;
-		hmul = 3;
-		subpixel = TRUE;
-		break;
-	    case FC_RGBA_VRGB:
-	    case FC_RGBA_VBGR:
-		matrix.yy *= 3;
-		vmul = 3;
-		subpixel = TRUE;
 		break;
+
+          default:
+              ;
 	    }
-	    if (subpixel)
-		format = CAIRO_FORMAT_ARGB32;
-	    else
-		format = CAIRO_FORMAT_A8;
 	    
-	    if (subpixel)
-		FT_Outline_Transform (outline, &matrix);
+        FT_Library_SetLcdFilter( library, FT_LCD_FILTER_DEFAULT );
 
-	    bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
-	    bitmap.num_grays  = 256;
-	    stride = (width * hmul + 3) & -4;
-	}
-	bitmap.pitch = stride;   
-	bitmap.width = width * hmul;
-	bitmap.rows = height * vmul;
-	bitmap.buffer = calloc (1, stride * bitmap.rows);
+        fterror = FT_Render_Glyph( face->glyph, render_mode );
 	
-	if (bitmap.buffer == NULL) {
+        FT_Library_SetLcdFilter( library, FT_LCD_FILTER_NONE );
+
+        if (fterror != 0)
 	    return CAIRO_STATUS_NO_MEMORY;
-	}
 	
-	FT_Outline_Translate (outline, -cbox.xMin*hmul, -cbox.yMin*vmul);
+        bitmap_size = _compute_xrender_bitmap_size( &bitmap,
+                                                    face->glyph,
+                                                    render_mode );
+        if ( bitmap_size < 0 )
+            return CAIRO_STATUS_NO_MEMORY;
 	
-	if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) {
-	    free (bitmap.buffer);
+        bitmap.buffer = calloc(1, bitmap_size);
+	if (bitmap.buffer == NULL) {
 	    return CAIRO_STATUS_NO_MEMORY;
 	}
 
+        _fill_xrender_bitmap( &bitmap, face->glyph, render_mode,
+                              (rgba == FC_RGBA_BGR || rgba == FC_RGBA_VBGR) );
+
+        // NOTE: _get_bitmap_surface will free bitmap.buffer if there is an error
 	status = _get_bitmap_surface (val, &bitmap, TRUE, rgba);
 	if (status)
 	    return status;
-    }
 
     /*
      * Note: the font's coordinate system is upside down from ours, so the
      * Y coordinate of the control box needs to be negated.
      */
-
-    val->size.x =   (short) (cbox.xMin >> 6);
-    val->size.y = - (short) (cbox.yMax >> 6);
+        val->size.x =   (short) glyphslot->bitmap_left;
+        val->size.y = - (short) glyphslot->bitmap_top;
+    }
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -1224,13 +1414,13 @@
 
     _cairo_ft_unscaled_font_set_scale (unscaled, &val->key.scale);
 
-    if (FT_Load_Glyph (face, val->key.index, val->key.flags & ~PRIVATE_FLAGS_MASK) != 0) {
+    if (FT_Load_Glyph (face, val->key.index, val->key.flags) != 0) {
 	status = CAIRO_STATUS_NO_MEMORY;
 	goto FAIL;
     }
 
 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
-    if (val->key.flags & PRIVATE_FLAG_EMBOLDEN &&
+    if (val->key.flags2 & PRIVATE_FLAG_EMBOLDEN &&
 	(face->style_flags & FT_STYLE_FLAG_BOLD) == 0) {
 	FT_GlyphSlot_Embolden (glyphslot);
     }
@@ -1257,7 +1447,7 @@
      * FreeType, then we need to do the metric hinting ourselves.
      */
     
-    if ((val->key.flags & PRIVATE_FLAG_HINT_METRICS) &&
+    if ((val->key.flags2 & PRIVATE_FLAG_HINT_METRICS) &&
  	(val->key.flags & FT_LOAD_NO_HINTING)) {
  	FT_Pos x1, x2;
  	FT_Pos y1, y2;
@@ -1325,6 +1515,7 @@
     cairo_scaled_font_t base;
     cairo_ft_unscaled_font_t *unscaled;
     int load_flags;
+    int other_flags;
 } cairo_ft_scaled_font_t;
 
 const cairo_scaled_font_backend_t cairo_ft_scaled_font_backend;
@@ -1333,7 +1524,7 @@
  * antialiasing. Here we compute them from the fields of a FcPattern.
  */
 static int
-_get_pattern_load_flags (FcPattern *pattern)
+_get_pattern_load_flags (FcPattern *pattern, int *p_other_flags)
 {
     FcBool antialias, vertical_layout, hinting, autohint;
     int rgba;
@@ -1341,17 +1532,15 @@
     int hintstyle;
 #endif    
     int load_flags = FT_LOAD_DEFAULT;
+    int hint_mode   = FT_LOAD_TARGET_NORMAL;
+    int render_mode = FT_RENDER_MODE_NORMAL;
+    int other_flags = 0;
 
     /* disable antialiasing if requested */
     if (FcPatternGetBool (pattern,
 			  FC_ANTIALIAS, 0, &antialias) != FcResultMatch)
 	antialias = FcTrue;
 
-    if (antialias)
-	load_flags |= FT_LOAD_NO_BITMAP;
-    else
-	load_flags |= FT_LOAD_MONOCHROME;
-    
     /* disable hinting if requested */
     if (FcPatternGetBool (pattern,
 			  FC_HINTING, 0, &hinting) != FcResultMatch)
@@ -1360,50 +1549,66 @@
 #ifdef FC_HINT_STYLE    
     if (FcPatternGetInteger (pattern, FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch)
 	hintstyle = FC_HINT_FULL;
+#endif
 
-    if (!hinting || hintstyle == FC_HINT_NONE)
-	load_flags |= FT_LOAD_NO_HINTING;
-    
-    if (antialias) {
     	if (FcPatternGetInteger (pattern,
 			     FC_RGBA, 0, &rgba) != FcResultMatch)
 		rgba = FC_RGBA_UNKNOWN;
 
-	switch (rgba) {
-	    case FC_RGBA_UNKNOWN:
-	    case FC_RGBA_NONE:
-		switch (hintstyle) {
+
+    if (!antialias)
+    {
+        hint_mode   = FT_LOAD_TARGET_MONO;
+        render_mode = FT_RENDER_MODE_MONO;
+    }
+    else
+    {
+        load_flags |= FT_LOAD_NO_BITMAP;
+
+        /* determine hinting mode */
+        switch (hintstyle)
+        {
 			case FC_HINT_NONE:
+            load_flags |= FT_LOAD_NO_HINTING;
 				break;
+
 			case FC_HINT_SLIGHT:
-			case FC_HINT_MEDIUM:
-				load_flags |= FT_LOAD_TARGET_LIGHT;
+            hint_mode = FT_LOAD_TARGET_LIGHT;
 		    		break;
-			default:
-				load_flags |= FT_LOAD_TARGET_NORMAL;
+
+        case FC_HINT_FULL:
+            switch (rgba)
+            {
+            case FC_RGBA_RGB:
+            case FC_RGBA_BGR:
+                hint_mode = FT_LOAD_TARGET_LCD;
 			break;
-		}
+
+            case FC_RGBA_VRGB:
+            case FC_RGBA_VBGR:
+                hint_mode = FT_LOAD_TARGET_LCD_V;
 		break;
+            }
+        }
+
+        /* determine rendering mode */
+        switch (rgba)
+        {
 	    case FC_RGBA_BGR:
-	    	load_flags |= PRIVATE_FLAG_BGR;
+            other_flags |= PRIVATE_FLAG_BGR;
+            /* fall-through */
 	    case FC_RGBA_RGB:
-			load_flags |= FT_LOAD_TARGET_LCD;
+            render_mode = FT_RENDER_MODE_LCD;
 			break;
+
 	    case FC_RGBA_VBGR:
-	    	load_flags |= PRIVATE_FLAG_BGR;
+            other_flags |= PRIVATE_FLAG_BGR;
+            /* fall-through */
 	    case FC_RGBA_VRGB:
-			load_flags |= FT_LOAD_TARGET_LCD_V;
+            render_mode = FT_RENDER_MODE_LCD_V;
 			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,
@@ -1429,65 +1634,89 @@
 	    embolden = FcFalse;
 	
 	if (embolden)
-	    load_flags |= PRIVATE_FLAG_EMBOLDEN;
+	    other_flags |= PRIVATE_FLAG_EMBOLDEN;
     }
 #endif
     
-    return load_flags;
+    *p_other_flags = (other_flags | render_mode);
+
+    return (load_flags | hint_mode);
 }
 
 static int
-_get_options_load_flags (const cairo_font_options_t *options)
+_get_options_load_flags (const cairo_font_options_t *options,
+                         int                        *p_other_flags)
 {
     int load_flags = FT_LOAD_DEFAULT;
+    int hint_mode   = FT_LOAD_TARGET_NORMAL;
+    int render_mode = FT_RENDER_MODE_NORMAL;
+    int other_flags = 0;
 
-    /* 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;
+    if (options->antialias == CAIRO_ANTIALIAS_NONE)
+    {
+        hint_mode   = FT_LOAD_TARGET_MONO;
+        render_mode = FT_RENDER_MODE_MONO;
+    }
+    else
+    {
+
+        /* determine hinting style */
+        switch (options->hint_style)
+        {
+        case CAIRO_HINT_STYLE_NONE:
+            load_flags |= FT_LOAD_NO_HINTING;
 	break;
-    case CAIRO_ANTIALIAS_SUBPIXEL:
-	load_flags |= FT_LOAD_NO_BITMAP;
-	switch (options->subpixel_order) {
+
+        case CAIRO_HINT_STYLE_SLIGHT:
+            hint_mode = FT_LOAD_TARGET_LIGHT;
+            break;
+
+        case CAIRO_HINT_STYLE_FULL:
+            if (options->antialias == CAIRO_ANTIALIAS_SUBPIXEL)
+            {
+                switch (options->subpixel_order)
+                {
 	case CAIRO_SUBPIXEL_ORDER_BGR:
-	    load_flags |= PRIVATE_FLAG_BGR;
-	case CAIRO_SUBPIXEL_ORDER_DEFAULT:
+                    other_flags |= PRIVATE_FLAG_BGR;
+                    /* fall-through */
 	case CAIRO_SUBPIXEL_ORDER_RGB:
-	    load_flags |= FT_LOAD_TARGET_LCD;
+                    hint_mode = FT_LOAD_TARGET_LCD;
 	    break;
+
 	case CAIRO_SUBPIXEL_ORDER_VBGR:
-	    load_flags |= PRIVATE_FLAG_BGR;
+                    other_flags |= PRIVATE_FLAG_BGR;
+                    /* fall-through */
 	case CAIRO_SUBPIXEL_ORDER_VRGB:
-	    load_flags |= FT_LOAD_TARGET_LCD_V;
+                    hint_mode = FT_LOAD_TARGET_LCD_V;
 	    break;
+                default:
+                    ;
+                }
+            }
+        default:
+            ;
 	}
-	break;
 
-	/* fall through ... */
-    case CAIRO_ANTIALIAS_DEFAULT:
-    case CAIRO_ANTIALIAS_GRAY:
-	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;
+        /* determine rendering style */
+        switch (options->antialias)
+        {
+        case CAIRO_SUBPIXEL_ORDER_RGB:
+        case CAIRO_SUBPIXEL_ORDER_BGR:
+            render_mode = FT_RENDER_MODE_LCD;
 	      	break;
-	  case CAIRO_HINT_STYLE_SLIGHT:
-	  case CAIRO_HINT_STYLE_MEDIUM:
-	 	load_flags |= FT_LOAD_TARGET_LIGHT;
+
+        case CAIRO_SUBPIXEL_ORDER_VRGB:
+        case CAIRO_SUBPIXEL_ORDER_VBGR:
+            render_mode = FT_RENDER_MODE_LCD_V;
 	 	break;
-	  case CAIRO_HINT_STYLE_FULL:
+
 	  default:
-	 	load_flags |= FT_LOAD_TARGET_NORMAL;
-	 	break;
+            ;
 	}
-	break;
     }
      
-    return load_flags;
+   *p_other_flags = render_mode | other_flags;
+   return load_flags | hint_mode;
 }
 
 static cairo_scaled_font_t *
@@ -1496,7 +1725,8 @@
 			      const cairo_matrix_t	 *font_matrix,
 			      const cairo_matrix_t	 *ctm,
 			      const cairo_font_options_t *options,
-			      int			  load_flags)
+			      int			  load_flags,
+                              int                         other_flags )
 {    
     cairo_ft_scaled_font_t *scaled_font = NULL;
 
@@ -1513,9 +1743,10 @@
     scaled_font->unscaled = unscaled;
 
     if (options->hint_metrics != CAIRO_HINT_METRICS_OFF)
-	load_flags |= PRIVATE_FLAG_HINT_METRICS;
+	other_flags |= PRIVATE_FLAG_HINT_METRICS;
 
     scaled_font->load_flags = load_flags;
+    scaled_font->other_flags = other_flags;
 
     return &scaled_font->base;
 }
@@ -1542,6 +1773,7 @@
     cairo_matrix_t scale;
     cairo_ft_font_transform_t sf;
     int load_flags;
+    int other_flags;
     unsigned char *family = (unsigned char*) toy_face->family;
 
     pattern = FcPatternCreate ();
@@ -1597,12 +1829,13 @@
     if (!unscaled)
 	goto FREE_RESOLVED;
 
-    load_flags = _get_pattern_load_flags (resolved);
+    load_flags = _get_pattern_load_flags (resolved, &other_flags);
 
     new_font = _cairo_ft_scaled_font_create (unscaled,
 					     &toy_face->base,
 					     font_matrix, ctm,
-					     options, load_flags);
+					     options, load_flags,
+                                             other_flags);
 
     _cairo_unscaled_font_destroy (&unscaled->base);
 
@@ -1640,6 +1873,7 @@
     key->unscaled = &scaled_font->unscaled->base;
     key->scale = scaled_font->base.scale;
     key->flags = scaled_font->load_flags;
+    key->flags2 = scaled_font->other_flags;
 }
 
 static cairo_status_t 
@@ -1978,6 +2212,7 @@
     key.unscaled = &scaled_font->unscaled->base;
     key.scale = scaled_font->base.scale;
     key.flags = scaled_font->load_flags;
+    key.flags2 = scaled_font->other_flags;
 
     entries = malloc (num_glyphs * sizeof (cairo_image_glyph_cache_entry_t));
     if (!entries)
@@ -2176,10 +2411,10 @@
     FT_Face face;
     FT_Error error;
     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_ConicTo_Func) _conic_to,
+	(FT_Outline_CubicToFunc)  _cubic_to,
 	0, /* shift */
 	0, /* delta */
     };
@@ -2309,7 +2544,7 @@
 					cairo_scaled_font_t       **scaled_font)
 {
     cairo_ft_font_face_t *font_face = abstract_face;
-    int load_flags;
+    int load_flags, other_flags;
 
     /* The handling of font options is different depending on how the
      * font face was created. When the user creates a font face with
@@ -2321,14 +2556,18 @@
      * flags and ignore the options.
      */
     if (font_face->unscaled->from_face)
-	load_flags = _get_options_load_flags (options) | font_face->load_flags;
+	load_flags = _get_options_load_flags (options, &other_flags); /* | font_face->load_flags; */
     else
+    {
 	load_flags = font_face->load_flags;
+        other_flags = font_face->other_flags;
+    }
 
     *scaled_font = _cairo_ft_scaled_font_create (font_face->unscaled,
 						 &font_face->base,
 						 font_matrix, ctm,
-						 options, load_flags);
+						 options, load_flags,
+                                                 other_flags);
     if (*scaled_font)
 	return CAIRO_STATUS_SUCCESS;
     else
@@ -2342,7 +2581,8 @@
 
 static cairo_font_face_t *
 _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,
-			    int			      load_flags)
+			    int			      load_flags,
+                            int                       other_flags)
 {
     cairo_ft_font_face_t *font_face;
 
@@ -2364,6 +2604,7 @@
     _cairo_unscaled_font_reference (&unscaled->base);
     
     font_face->load_flags = load_flags;
+    font_face->other_flags = other_flags;
 
     font_face->next = unscaled->faces;
     unscaled->faces = font_face;
@@ -2492,6 +2733,7 @@
 {
     cairo_ft_unscaled_font_t *unscaled;
     cairo_font_face_t *font_face;
+    int  load_flags, other_flags;
 
     unscaled = _cairo_ft_unscaled_font_create_for_pattern (pattern);
     if (unscaled == NULL) {
@@ -2499,8 +2741,9 @@
 	return (cairo_font_face_t *)&_cairo_font_face_nil;
     }
 
+    load_flags = _get_pattern_load_flags (pattern, &other_flags);
     font_face = _cairo_ft_font_face_create (unscaled,
-					    _get_pattern_load_flags (pattern));
+					    load_flags, other_flags);
     _cairo_unscaled_font_destroy (&unscaled->base);
 
     if (font_face)
@@ -2549,7 +2792,8 @@
 	return (cairo_font_face_t *)&_cairo_font_face_nil;
     }
 
-    font_face = _cairo_ft_font_face_create (unscaled, load_flags);
+    font_face = _cairo_ft_font_face_create (unscaled, load_flags,
+                                            FT_LOAD_TARGET_MODE(load_flags) );
     _cairo_unscaled_font_destroy (&unscaled->base);
 
     if (font_face) {
diff -urbN cairo-1.0.4-org/src/cairoint.h cairo-1.0.4-new/src/cairoint.h
--- cairo-1.0.4-org/src/cairoint.h	2006-03-15 17:48:01.000000000 +0100
+++ cairo-1.0.4-new/src/cairoint.h	2006-09-30 18:58:47.000000000 +0200
@@ -522,6 +522,7 @@
     cairo_unscaled_font_t *unscaled;
     cairo_matrix_t scale;	/* translation is ignored */
     int flags;
+    int flags2;
     unsigned long index;
 } cairo_glyph_cache_key_t;
 
