[cairo-commit] cairo/src Makefile.am, 1.36, 1.37 cairo-win32.h, 1.1, 1.2 cairo.c, 1.49, 1.50 cairo.h, 1.70, 1.71 cairo_ft_font.c, 1.39, 1.40 cairo_gstate.c, 1.78, 1.79 cairo_traps.c, 1.20, 1.21 cairo_win32_font.c, 1.1, 1.2 cairo_win32_surface.c, 1.1, 1.2 cairoint.h, 1.93, 1.94

Owen Taylor commit at pdx.freedesktop.org
Tue Feb 1 15:06:43 PST 2005


Committed by: otaylor

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

Modified Files:
	Makefile.am cairo-win32.h cairo.c cairo.h cairo_ft_font.c 
	cairo_gstate.c cairo_traps.c cairo_win32_font.c 
	cairo_win32_surface.c cairoint.h 
Log Message:
2005-02-01  Owen Taylor  <otaylor at redhat.com>

        * src/cairo_unicode.c src/cairoint.h src/Makefile.am: Add
        _cairo_utf8_to_utf16(), _cairo_utf8_to_ucs4() based on code from GLib.

        * src/cairo.[ch]: Add CAIRO_STATUS_INVALID_STRING

        * src/cairo_ft_font.c: Use _cairo_utf8_to_ucs4().

        * src/cairo.h: Add cairo_bool_t

        * src/cairoint.h: Add TRUE/FALSE definitions.

        * src/cairo.[ch] src/cairoint.h src/cairo_gstate.c: switch
        cairo_in_stroke/cairo_in_fill and all the functions used to
        implement them over to cairo_bool_t.


Index: Makefile.am
===================================================================
RCS file: /cvs/cairo/cairo/src/Makefile.am,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -d -r1.36 -r1.37
--- Makefile.am	1 Feb 2005 00:11:37 -0000	1.36
+++ Makefile.am	1 Feb 2005 23:06:36 -0000	1.37
@@ -100,6 +100,7 @@
 	cairo_surface.c		\
 	cairo_traps.c		\
 	cairo_pattern.c		\
+	cairo_unicode.c		\
 	cairo_wideint.c		\
 	cairo-wideint.h		\
 	$(libcairo_atsui_sources)\

Index: cairo-win32.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-win32.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cairo-win32.h	1 Feb 2005 00:11:37 -0000	1.1
+++ cairo-win32.h	1 Feb 2005 23:06:36 -0000	1.2
@@ -37,16 +37,12 @@
 
 #include <cairo.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef CAIRO_HAS_WIN32_SURFACE
-#error "cairo-win32.h included in a Cairo without the Win32 backend"
-#endif
+#ifdef CAIRO_HAS_WIN32_SURFACE
 
 #include <windows.h>
 
+CAIRO_BEGIN_DECLS
+
 void 
 cairo_set_target_win32 (cairo_t *cr,
 			HDC      hdc);
@@ -54,8 +50,12 @@
 cairo_surface_t *
 cairo_win32_surface_create (HDC hdc);
 
-#ifdef __cplusplus
-}
-#endif
+cairo_font_t *
+cairo_win32_font_create_for_logfont (LOGFONT        *logfont,
+				     cairo_matrix_t *scale);
+
+#endif /* CAIRO_HAS_WIN32_SURFACE */
+
+CAIRO_END_DECLS
 
 #endif /* _CAIRO_WIN32_H_ */

Index: cairo.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -d -r1.49 -r1.50
--- cairo.c	27 Jan 2005 23:46:17 -0000	1.49
+++ cairo.c	1 Feb 2005 23:06:36 -0000	1.50
@@ -923,7 +923,7 @@
     CAIRO_CHECK_SANITY (cr);
 }
 
-int
+cairo_bool_t
 cairo_in_stroke (cairo_t *cr, double x, double y)
 {
     int inside;
@@ -1414,6 +1414,8 @@
 	return "no target surface has been set";
     case CAIRO_STATUS_NULL_POINTER:
 	return "NULL pointer";
+    case CAIRO_STATUS_INVALID_STRING:
+	return "input string not valid UTF-8";
     }
 
     return "<unknown error status>";

Index: cairo.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.h,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -d -r1.70 -r1.71
--- cairo.h	27 Jan 2005 23:46:17 -0000	1.70
+++ cairo.h	1 Feb 2005 23:06:36 -0000	1.71
@@ -51,6 +51,22 @@
 CAIRO_BEGIN_DECLS
 
 /**
+ * cairo_bool_t:
+ *
+ * #cairo_bool_t is used for boolean values. Returns of type
+ * #cairo_bool_t will always be either 0 or 1, but testing against
+ * these values explicitely is not encouraged; just use the
+ * value as a boolean condition.
+ *
+ * <informalexample><programlisting>
+ *  if (cairo_in_stroke (cr, x, y)) {
+ *      /<!-- -->* do something *<!-- -->/
+ *  }
+ * </programlisting></informalexample>
+ */
+typedef int cairo_bool_t;
+
+/**
  * cairo_t:
  *
  * A #cairo_t contains the current state of the rendering device,
@@ -388,10 +404,10 @@
 cairo_show_page (cairo_t *cr);
 
 /* Insideness testing */
-int
+cairo_bool_t
 cairo_in_stroke (cairo_t *cr, double x, double y);
 
-int
+cairo_bool_t
 cairo_in_fill (cairo_t *cr, double x, double y);
 
 /* Rectangular extents */
@@ -674,7 +690,8 @@
     CAIRO_STATUS_NO_CURRENT_POINT,
     CAIRO_STATUS_INVALID_MATRIX,
     CAIRO_STATUS_NO_TARGET_SURFACE,
-    CAIRO_STATUS_NULL_POINTER
+    CAIRO_STATUS_NULL_POINTER,
+    CAIRO_STATUS_INVALID_STRING
 } cairo_status_t;
 
 cairo_status_t

Index: cairo_ft_font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_ft_font.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -d -r1.39 -r1.40
--- cairo_ft_font.c	27 Jan 2005 23:46:17 -0000	1.39
+++ cairo_ft_font.c	1 Feb 2005 23:06:36 -0000	1.40
@@ -706,40 +706,6 @@
     free (unscaled);
 }
 
-static void 
-_utf8_to_ucs4 (char const *utf8, 
-               FT_ULong **ucs4, 
-               int *nchars)
-{
-    int len = 0, step = 0;
-    int n = 0, alloc = 0;
-    FcChar32 u = 0;
-
-    if (utf8 == NULL || ucs4 == NULL || nchars == NULL)
-        return;
-
-    len = strlen (utf8);
-    alloc = len;
-    *ucs4 = malloc (sizeof (FT_ULong) * alloc);
-    if (*ucs4 == NULL)
-        return;
-  
-    while (len && (step = FcUtf8ToUcs4(utf8, &u, len)) > 0)
-    {
-        if (n == alloc)
-        {
-            alloc *= 2;
-            *ucs4 = realloc (*ucs4, sizeof (FT_ULong) * alloc);
-            if (*ucs4 == NULL)
-                return;
-        }	  
-        (*ucs4)[n++] = u;
-        len -= step;
-        utf8 += step;
-    }
-    *nchars = n;
-}
-
 static void
 _cairo_ft_font_get_glyph_cache_key (void                    *abstract_font,
 				    cairo_glyph_cache_key_t *key)
@@ -759,16 +725,19 @@
 {
     double x = 0., y = 0.;
     size_t i;
-    FT_ULong *ucs4 = NULL;
+    uint32_t *ucs4 = NULL;
     cairo_ft_font_t *font = abstract_font;
     FT_Face face;
     cairo_glyph_cache_key_t key;
     cairo_image_glyph_cache_entry_t *val;
     cairo_cache_t *cache;
+    cairo_status_t status;
 
     _cairo_ft_font_get_glyph_cache_key (font, &key);
 
-    _utf8_to_ucs4 (utf8, &ucs4, nglyphs);
+    status = _cairo_utf8_to_ucs4 (utf8, -1, &ucs4, nglyphs);
+    if (!CAIRO_OK (status))
+	return status;
 
     if (ucs4 == NULL)
         return CAIRO_STATUS_NO_MEMORY;

Index: cairo_gstate.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_gstate.c,v
retrieving revision 1.78
retrieving revision 1.79
diff -u -d -r1.78 -r1.79
--- cairo_gstate.c	28 Jan 2005 20:27:23 -0000	1.78
+++ cairo_gstate.c	1 Feb 2005 23:06:36 -0000	1.79
@@ -1364,7 +1364,7 @@
 _cairo_gstate_in_stroke (cairo_gstate_t	*gstate,
 			 double		x,
 			 double		y,
-			 int		*inside_ret)
+			 cairo_bool_t	*inside_ret)
 {
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_traps_t traps;
@@ -1617,7 +1617,7 @@
 _cairo_gstate_in_fill (cairo_gstate_t	*gstate,
 		       double		x,
 		       double		y,
-		       int		*inside_ret)
+		       cairo_bool_t	*inside_ret)
 {
     cairo_status_t status = CAIRO_STATUS_SUCCESS;
     cairo_traps_t traps;

Index: cairo_traps.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_traps.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- cairo_traps.c	23 Dec 2004 21:49:57 -0000	1.20
+++ cairo_traps.c	1 Feb 2005 23:06:36 -0000	1.21
@@ -667,32 +667,32 @@
     return CAIRO_STATUS_SUCCESS;
 }
 
-static int
+static cairo_bool_t
 _cairo_trap_contains (cairo_trapezoid_t *t, cairo_point_t *pt)
 {
     cairo_slope_t slope_left, slope_pt, slope_right;
     
     if (t->top > pt->y)
-	return 0;
+	return FALSE;
     if (t->bottom < pt->y)
-	return 0;
+	return FALSE;
     
     _cairo_slope_init (&slope_left, &t->left.p1, &t->left.p2);
     _cairo_slope_init (&slope_pt, &t->left.p1, pt);
 
     if (_cairo_slope_compare (&slope_left, &slope_pt) < 0)
-	return 0;
+	return FALSE;
 
     _cairo_slope_init (&slope_right, &t->right.p1, &t->right.p2);
     _cairo_slope_init (&slope_pt, &t->right.p1, pt);
 
     if (_cairo_slope_compare (&slope_pt, &slope_right) < 0)
-	return 0;
+	return FALSE;
 
-    return 1;
+    return TRUE;
 }
 
-int
+cairo_bool_t
 _cairo_traps_contain (cairo_traps_t *traps, double x, double y)
 {
     int i;
@@ -703,10 +703,10 @@
 
     for (i = 0; i < traps->num_traps; i++) {
 	if (_cairo_trap_contains (&traps->traps[i], &point))
-	    return 1;
+	    return TRUE;
     }
 
-    return 0;
+    return FALSE;
 }
 
 void

Index: cairo_win32_font.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_win32_font.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cairo_win32_font.c	1 Feb 2005 00:11:37 -0000	1.1
+++ cairo_win32_font.c	1 Feb 2005 23:06:36 -0000	1.2
@@ -1,153 +1,144 @@
-/*
- * Copyright © 2005 Red Hat Inc.
+/* cairo - a vector graphics library with display and print output
  *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of Red Hat Inc. not be used
- * in advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. Red Hat Inc. makes no
- * representations about the suitability of this software for any purpose.
- * It is provided "as is" without express or implied warranty.
+ * Copyright © 2005 Red Hat, Inc
  *
- * RED HAT INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL RED HAT INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
- * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
  *
- * Author: Owen Taylor <otaylor at redhat.com>
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Red Hat, Inc.
+ *
+ * Contributor(s):
  */
 
-#include "cairoint.h"
+#include "cairo-win32-private.h"
 
 const cairo_font_backend_t cairo_ft_font_backend;
 
-/*
- * The simple 2x2 matrix is converted into separate scale and shape
- * factors so that hinting works right
- */
+#define LOGICAL_SCALE 32
 
 typedef struct {
-    double  x_scale, y_scale;
-    double  shape[2][2];
-} ft_font_transform_t;
+    cairo_font_t base;
 
-static void
-_compute_transform (ft_font_transform_t *sf,
-		    cairo_font_scale_t  *sc)
-{
-    cairo_matrix_t normalized;
-    double tx, ty;
-    
-    /* The font matrix has x and y "scale" components which we extract and
-     * use as character scale values. These influence the way freetype
-     * chooses hints, as well as selecting different bitmaps in
-     * hand-rendered fonts. We also copy the normalized matrix to
-     * freetype's transformation.
-     */
+    LOGFONT logfont;
+    BYTE quality;
 
-    cairo_matrix_set_affine (&normalized,
-			     sc->matrix[0][0],
-			     sc->matrix[0][1],
-			     sc->matrix[1][0],
-			     sc->matrix[1][1], 
-			     0, 0);
+    /* We do drawing and metrics computation in a "logical space" which
+     * is similar to font space, except that it is scaled by a factor
+     * of the (desired font size) * (LOGICAL_SCALE). The multiplication
+     * by LOGICAL_SCALE allows for sub-pixel precision.
+     */
+    double logical_scale;
 
-    _cairo_matrix_compute_scale_factors (&normalized, 
-					 &sf->x_scale, &sf->y_scale,
-					 /* XXX */ 1);
-    cairo_matrix_scale (&normalized, 1.0 / sf->x_scale, 1.0 / sf->y_scale);
-    cairo_matrix_get_affine (&normalized, 
-			     &sf->shape[0][0], &sf->shape[0][1],
-			     &sf->shape[1][0], &sf->shape[1][1],
-			     &tx, &ty);
-}
+    /* The size we should actually request the font at from Windows; differs
+     * from the logical_scale because it is quantized for orthogonal
+     * transformations
+     */
+    double logical_size;
 
-/* Temporarily scales an unscaled font to the give scale. We catch
- * scaling to the same size, since changing a FT_Face is expensive.
- */
-static void
-_ft_unscaled_font_set_scale (ft_unscaled_font_t *unscaled,
-			     cairo_font_scale_t *scale)
-{
-    int need_scale;
-    ft_font_transform_t sf;
-    FT_Matrix mat;
+    /* Transformations from device <=> logical space
+     */
+    cairo_matrix_t logical_to_device;
+    cairo_matrix_t device_to_logical;
 
-    assert (unscaled->face != NULL);
+    /* We special case combinations of 90-degree-rotations, scales and
+     * flips ... that is transformations that take the axes to the
+     * axes. If preserve_axes is true, then swap_axes/swap_x/swap_y
+     * encode the 8 possibilities for orientation (4 rotation angles with
+     * and without a flip), and scale_x, scale_y the scale components.
+     */
+    cairo_bool_t preserve_axes;
+    cairo_bool_t swap_axes;
+    cairo_bool_t swap_x;
+    cairo_bool_t swap_y;
+    double x_scale;
+    double y_scale;
     
-    if (scale->matrix[0][0] == unscaled->current_scale.matrix[0][0] &&
-	scale->matrix[0][1] == unscaled->current_scale.matrix[0][1] &&
-	scale->matrix[1][0] == unscaled->current_scale.matrix[1][0] &&
-	scale->matrix[1][1] == unscaled->current_scale.matrix[1][1])
-	return;
+} cairo_win32_font_t;
 
-    unscaled->current_scale = *scale;
-	
-    _compute_transform (&sf, scale);
+static void
+_compute_transform (cairo_win32_font_t *font,
+		    cairo_font_scale_t *sc)
+{
+    cairo_matrix_t normalized;
+    int pixel_size;
 
-    unscaled->x_scale = sf.x_scale;
-    unscaled->y_scale = sf.y_scale;
+    if (NEARLY_ZERO (sc->matrix[0][1]) && NEARLY_ZERO (sc->matrix[1][0])) {
+	font->preserve_axes = TRUE;
+	font->x_scale = sc->matrix[0][0];
+	font->swap_x = (sc->matrix[0][0] < 0);
+	font->y_scale = sc->matrix[1][1];
+	font->swap_y = (sc->matrix[1][1] < 0);
+	font->swap_axes = FALSE;
 	
-    mat.xx = DOUBLE_TO_16_16(sf.shape[0][0]);
-    mat.yx = - DOUBLE_TO_16_16(sf.shape[0][1]);
-    mat.xy = - DOUBLE_TO_16_16(sf.shape[1][0]);
-    mat.yy = DOUBLE_TO_16_16(sf.shape[1][1]);
+    } else if (NEARLY_ZERO (sc->matrix[0][0]) && NEARLY_ZERO (sc->matrix[1][1])) {
+	font->preserve_axes = TRUE;
+	font->x_scale = sc->matrix[0][1];
+	font->swap_x = (sc->matrix[0][1] < 0);
+	font->y_scale = sc->matrix[1][0];
+	font->swap_y = (sc->matrix[1][0] < 0);
+	font->swap_axes = TRUE;
+    }
 
-    if (need_scale) {
-	FT_Set_Transform(unscaled->face, &mat, NULL);
+    if (font->preserve_axes) {
+	if (font->swap_x)
+	    font->x_scale = - font->x_scale;
+	if (font->swap_y)
+	    font->y_scale = - font->y_scale;
 	
-	FT_Set_Pixel_Sizes(unscaled->face,
-			   (FT_UInt) sf.x_scale,
-			   (FT_UInt) sf.y_scale);
+	font->logical_scale = LOGICAL_SCALE * font->y_scale;
+	font->logical_size = LOGICAL_SCALE * floor (font->y_scale + 0.5);
     }
-}
 
-/* implement the font backend interface */
+    /* The font matrix has x and y "scale" components which we extract and
+     * use as character scale values.
+     */
+    cairo_matrix_set_affine (&font->logical_to_device,
+			     sc->matrix[0][0],
+			     sc->matrix[0][1],
+			     sc->matrix[1][0],
+			     sc->matrix[1][1], 
+			     0, 0);
 
-typedef struct {
-    cairo_font_t base;
-    FcPattern *pattern;
-    int load_flags;
-    ft_unscaled_font_t *unscaled;
-} cairo_ft_font_t;
+    if (!font->preserve_axes) {
+	double x_scale, y_scale;
+	
+	_cairo_matrix_compute_scale_factors (&font->logical_to_device,
+					     &font->x_scale, &font->y_scale,
+					     TRUE);	/* XXX: Handle vertical text */
 
-static void 
-_utf8_to_ucs4 (char const *utf8, 
-               FT_ULong **ucs4, 
-               size_t *nchars)
-{
-    int len = 0, step = 0;
-    size_t n = 0, alloc = 0;
-    FcChar32 u = 0;
+	font->logical_size = floor (LOGICAL_SCALE * y_scale + 0.5);
+	font->logical_scale = LOGICAL_SCALE * y_scale + 0.5;
+    }
 
-    if (utf8 == NULL || ucs4 == NULL || nchars == NULL)
-        return;
+    cairo_matrix_scale (&font->logical_to_device,
+			1.0 / (LOGICAL_SCALE * font->y_scale),
+			1.0 / (LOGICAL_SCALE * font->y_scale));
 
-    len = strlen (utf8);
-    alloc = len;
-    *ucs4 = malloc (sizeof (FT_ULong) * alloc);
-    if (*ucs4 == NULL)
-        return;
-  
-    while (len && (step = FcUtf8ToUcs4(utf8, &u, len)) > 0)
-    {
-        if (n == alloc)
-        {
-            alloc *= 2;
-            *ucs4 = realloc (*ucs4, sizeof (FT_ULong) * alloc);
-            if (*ucs4 == NULL)
-                return;
-        }	  
-        (*ucs4)[n++] = u;
-        len -= step;
-        utf8 += step;
-    }
-    *nchars = n;
+    font->device_to_logical = font->logical_to_device;
+    if (!CAIRO_OK (cairo_matrix_invert (&font->device_to_logical)))
+	cairo_matrix_set_identity (font->device_to_logical);
 }
 
 static BYTE
@@ -156,7 +147,7 @@
     BOOL font_smoothing;
 
     if (!SystemParametersInfo (SPI_GETFONTSMOOTHING, 0, &font_smoothing, 0)) {
-	_print_gdi_error ();
+	_cairo_win32_print_gdi_error ();
 	return FALSE;
     }
 
@@ -166,7 +157,7 @@
 	version_info.size = sizeof (OSVERSIONINFO);
 	
 	if (!GetVersionEx (&version_info)) {
-	    _print_gdi_error ();
+	    _cairo_win32_print_gdi_error ();
 	    return FALSE;
 	}
 
@@ -177,7 +168,7 @@
 
 	    if (!SystemParametersInfo (SPI_GETFONTSMOOTHINGTYPE,
 				       0, &smoothing_type, 0)) {
-		_print_gdi_error ();
+		_cairo_win32_print_gdi_error ();
 		return FALSE;
 	    }
 
@@ -192,6 +183,29 @@
     
 }
 
+static cairo_font_t *
+_win32_font_create (LOGFONT            *logfont,
+		    cairo_font_scale_t *scale)
+{
+    cairo_win32_font_t *f;
+    ft_font_transform_t sf,
+
+    f = malloc (sizeof(cairo_win32_font_t));
+    if (f == NULL) 
+      return NULL;
+
+    f->logfont = *logfont;
+    f->quality = _get_system_quality ();
+
+    _compute_transform (f, scale);
+    
+    _cairo_font_init ((cairo_font_t *)f, &sc, &cairo_win32_font_backend);
+
+    return (cairo_font_t *)f;
+}
+
+/* implement the font backend interface */
+
 static cairo_status_t
 _cairo_ft_font_create (const char          *family, 
                        cairo_font_slant_t   slant, 
@@ -245,7 +259,7 @@
     if (!logfont.lfFaceName)
 	return CAIRO_STATUS_NO_MEMORY;
     
-    font = cairo_win32_font_create_for_logfont (logfont, scale);
+    font = _win32_font_create (logfont, scale);
     if (!font)
 	return CAIRO_STATUS_NO_MEMORY;
 
@@ -269,6 +283,107 @@
     return CAIRO_STATUS_NO_MEMORY;
 }
 
+/* Taken from fontconfig sources, Copyright © 2000 Keith Packard */
+int
+_utf8_to_ucs4 (const char *src_orig,
+	      unsigned long *dst,
+	      int	    len)
+{
+    const FcChar8   *src = src_orig;
+    FcChar8	    s;
+    int		    extra;
+    FcChar32	    result;
+
+    if (len == 0)
+	return 0;
+    
+    s = *src++;
+    len--;
+    
+    if (!(s & 0x80))
+    {
+	result = s;
+	extra = 0;
+    } 
+    else if (!(s & 0x40))
+    {
+	return -1;
+    }
+    else if (!(s & 0x20))
+    {
+	result = s & 0x1f;
+	extra = 1;
+    }
+    else if (!(s & 0x10))
+    {
+	result = s & 0xf;
+	extra = 2;
+    }
+    else if (!(s & 0x08))
+    {
+	result = s & 0x07;
+	extra = 3;
+    }
+    else if (!(s & 0x04))
+    {
+	result = s & 0x03;
+	extra = 4;
+    }
+    else if ( ! (s & 0x02))
+    {
+	result = s & 0x01;
+	extra = 5;
+    }
+    else
+    {
+	return -1;
+    }
+    if (extra > len)
+	return -1;
+    
+    while (extra--)
+    {
+	result <<= 6;
+	s = *src++;
+	
+	if ((s & 0xc0) != 0x80)
+	    return -1;
+	
+	result |= s & 0x3f;
+    }
+    *dst = result;
+    return src - src_orig;
+}
+
+static cairo_status_t
+_utf8_to_utf16 (char const *utf8, 
+               FT_ULong  **ucs4, 
+               size_t     *nchars)
+{
+    int len = 0, step = 0;
+    size_t n = 0, alloc = 0;
+    FcChar32 u = 0;
+
+    if (utf8 == NULL || ucs4 == NULL || nchars == NULL)
+        return;
+
+    len = strlen (utf8);
+    alloc = len;
+    *ucs4 = malloc (sizeof (FT_ULong) * alloc);
+    if (*ucs4 == NULL)
+        return;
+  
+    while (len && (step = FcUtf8ToUcs4(utf8, &u, len)) > 0)
+    {
+        (*ucs4)[n++] = u;
+        len -= step;
+        utf8 += step;
+    }
+    *nchars = n;
+
+    return CAIRO_STATUS_NO_MEMORY;
+}
+
 static cairo_status_t 
 _cairo_ft_font_text_to_glyphs (void			*abstract_font,
 			       const unsigned char	*utf8,
@@ -276,26 +391,145 @@
 			       int			*nglyphs)
 {
     cairo_win32_font_t *font = abstract_font;
+    cairo_status_t status;
+
+    GCP_RESULTSW results;
+    WCHAR glyphs[1024];
+    int dx[1024];
+    DWORD ret;
+
+    status = 
+    
+    results.lStructSize = sizeof (GCP_RESULTS);
+    results.lpOutString = NULL;
+    results.lpOrder = NULL;
+    results.lpDx = dx;
+    results.lpCaretPos = NULL;
+    results.lpClass = NULL;
+    results.lpGlyphs = glyphs;
+    results.nGlyphs = 1024;
+    
+    ret = GetCharacterPlacementW (hdc, strs[i], wcslen(strs[i]),
+				  0,
+				  &results, 
+				  GCP_DIACRITIC | GCP_LIGATE | GCP_GLYPHSHAPE | GCP_REORDER);
+    if (!ret)
+	_print_gdi_error ("GetCharacterPlacement");
+
+    
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t 
-_cairo_ft_font_font_extents (void			*abstract_font,
-                             cairo_font_extents_t	*extents)
+_cairo_win32_font_font_extents (void			*abstract_font,
+				cairo_font_extents_t	*extents)
 {
     cairo_win32_font_t *font = abstract_font;
+    TEXTMETRIC metrics;
+    HDC hdc;
+
+    if (font->preserve_axes) {
+	/* For 90-degree rotations (including 0), we get the metrics
+	 * from the GDI in logical space, then convert back to font space
+	 */
+	hdc = _cairo_win32_font_acquire_scaled_dc (font);
+	GetTextMetrics (hdc, &metrics);
+	_cairo_win32_font_release_scaled_dc (font);
+
+	extents->ascent = metrics.tmAscent / font->logical_scale;
+	extents->descent = metrics.tmDescent / font->logical_scale;
+	extents->height = (metrics.tmHeight + metrics.tmExternalLeading) / font->logical_scale;
+	extents->max_x_advance = metrics.tmMaxCharWidth / font->logical_scale;
+	extents->max_y_advance = 0;
+
+    } else {
+	/* For all other transformations, we use the design metrics
+	 * of the font. The GDI results from GetTextMetrics() on a
+	 * transformed font are inexplicably large and we want to
+	 * avoid them.
+	 */
+	hdc = _cairo_win32_font_acquire_unscaled_dc (font);
+	GetTextMetrics (hdc, &metrics);
+	_cairo_win32_font_release_unscaled_dc (font);
+
+	extents->ascent = (double)metrics.tmAscent / font->em_square;
+	extents->descent = metrics.tmDescent * font->em_square;
+	extents->height = (double)(metrics.tmHeight + mertrics.tmExternalLeading) / font->em_square;
+	extents->max_x_advance = (double)(metrics.tmMaxCharWidth) / font->em_square;
+	extents->max_y_advance = 0;
+	
+    }
 
     return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t 
-_cairo_ft_font_glyph_extents (void			*abstract_font,
-                              cairo_glyph_t		*glyphs, 
-                              int			num_glyphs,
-			      cairo_text_extents_t	*extents)
+_cairo_win32_font_glyph_extents (void			*abstract_font,
+				 cairo_glyph_t		*glyphs, 
+				 int			 num_glyphs,
+				 cairo_text_extents_t	*extents)
 {
     cairo_win32_font_t *font = abstract_font;
+    static const MAT2 matrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 1 } };
+    GLYPHMETRICS metrics;
+    HDC hdc;
+
+    /* We handle only the case num_glyphs == 1, glyphs[i].x == glyphs[0].y == 0.
+     * This is all that the calling code triggers, and the backend interface
+     * will eventually be changed to match
+     */
+    assert (num_glyphs == 1);
+
+    if (font->preserve_axes) {
+	/* If we aren't rotating / skewing the axes, then we get the metrics
+	 * from the GDI in device space and convert to font space.
+	 */
+	hdc = _cairo_win32_font_acquire_scaled_dc (font);
+	GetGlyphOutline(hdc, str[i], GGO_METRICS, &glyph_metrics, 0, NULL, &matrix);
+	_cairo_win32_font_release_scaled_dc (font);
+
+	if (font->swap_axes) {
+	    extents->x_bearing = metrics.gmptGlyphOrigin.y / font->y_scale;
+	    extents->y_bearing = metrics.gmptGlyphOrigin.x / font->x_scale;
+	    extents->width = metrics.gmBlackBoxY / font->y_scale;
+	    extents->height = metrics.gmBlackBoxX / font->x_scale;
+	    extents->x_advance = metrics.gmCellIncY / font->x_scale;
+	    extents->y_advance = metrics.gmCellIncX / font->y_scale;
+	} else {
+	    extents->x_bearing = metrics.gmptGlyphOrigin.x / font->x_scale;
+	    extents->y_bearing = metrics.gmptGlyphOrigin.y / font->y_scale;
+	    extents->width = metrics.gmBlackBoxX / font->x_scale;
+	    extents->height = metrics.gmBlackBoxY / font->y_scale;
+	    extents->x_advance = metrics.gmCellIncX / font->x_scale;
+	    extents->y_advance = metrics.gmCellIncY / font->y_scale;
+	}
+
+	if (font->swap_x) {
+	    extents->x_bearing = (- extents->x_bearing - extents->width);
+	    extents->x_advance = - extents->x_advance;
+	}
+
+	if (font->swap_y) {
+	    extents->y_bearing = (- extents->y_bearing - extents->height);
+	    extents->y_advance = - extents->y_advance;
+	}
+	
+    } else {
+	/* For all other transformations, we use the design metrics
+	 * of the font.
+	 */
+	hdc = _cairo_win32_font_acquire_unscaled_dc (font);
+	GetGlyphOutline(hdc, str[i], GGO_METRICS, &glyph_metrics, 0, NULL, &matrix);
+	_cairo_win32_font_release_unscaled_dc (font);
+
+	extents->x_bearing = (double)metrics.gmptGlyphOrigin.x / font->em_square;
+	extents->y_bearing = (double)metrics.gmptGlyphOrigin.y / font->em_square;
+	extents->width = (double)metrics.gmBlackBoxX / font->em_square;
+	extents->height = (double)metrics.gmBlackBoxY / font->em_square;
+	extents->x_advance = (double)metrics.gmCellIncX / font->em_square;
+	extents->y_advance = (double)metrics.gmCellIncY / font->em_square;
+    }
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -304,26 +538,277 @@
 static cairo_status_t 
 _cairo_ft_font_glyph_bbox (void		       		*abstract_font,
 			   const cairo_glyph_t 		*glyphs,
-			   int                 		num_glyphs,
+			   int                 		 num_glyphs,
 			   cairo_box_t         		*bbox)
 {
+    static const MAT2 matrix = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 1 } };
     cairo_win32_font_t *font = abstract_font;
+    int x1 = 0, x2 = 0, y1 = 0, y2 = 0;
+
+    if (num_glyphs > 0) {
+	HDC hdc = _cairo_win32_font_acquire_scaled_dc (font);
+	int i;
+
+	for (i = 0; i < num_glyphs; i++) {
+	    int x = floor (0.5 + glyphs[i].x);
+	    int y = floor (0.5 + glyphs[i].y);
+
+	    GetGlyphOutline (hdc, glyphs[i], GGO_METRICS | GGO_GLYPH_INDEX,
+			     &glyph_metrics, 0, NULL, &matrix);
+
+	    if (i == 0 || x1 > x + metrics.gmptGlyphOrigin.x)
+		x1 = x + metrics.gmptGlyphOrigin.x;
+	    if (i == 0 || y1 > y + metrics.gmptGlyphOrigin.y)
+		y1 = x + metrics.gmptGlyphOrigin.y;
+	    if (i == 0 || x2 < x + metrics.gmptGlyphOrigin.x + metrics.gmBlackBoxX)
+		x2 = x + metrics.gmptGlyphOrigin.x + metrics.gmBlackBoxX;
+	    if (i == 0 || y2 < y + metrics.gmptGlyphOrigin.y + metrics.gmBlackBoxY)
+		y2 = y + metrics.gmptGlyphOrigin.x + metrics.gmBlackBoxY;
+	}
+	
+	_cairo_win32_font_release_scaled_dc (font);
+    }
+
+    bbox->p1.x = _cairo_fixed_from_int (x1);
+    bbox->p1.y = _cairo_fixed_from_int (y1);
+    bbox->p2.x = _cairo_fixed_from_int (x2);
+    bbox->p2.y = _cairo_fixed_from_int (y2);
     
     return CAIRO_STATUS_SUCCESS;
 }
 
+#define FIXED_BUF_SIZE 1024
+
+typedef struct {
+    cairo_win32_font_t *font;
+    HDC dc;
+    
+    cairo_array_t glyphs;
+    cairo_array_t dx;
+    
+    int last_x;
+    int last_y;
+} cairo_glyph_state_t;
+
+static void
+_start_glyphs (cairo_glyph_state_t *state,
+	       cairo_win32_font_t  *font,
+	       HDC                  dc)
+{
+    state->dc = dc;
+    state->font = font;
+
+    _cairo_array_init (&state->glyphs, sizeof (WCHAR));
+    _cairo_array_init (&state->dx, sizeof (int));
+}
+
+static void
+_flush_glyphs (cairo_glyph_state_t *state)
+{
+    ExtTextOutW (state->dc,
+		 state->start_x, state->last_y,
+		 ETO_CLIPPED,
+		 NULL,
+		 (WCHAR *)state->glyphs.elements,
+		 state->glyphs.num_elements,
+		 (int *)state->dx.elements);
+    
+    _cairo_array_truncate (&state->glyphs, 0);
+    _cairo_array_truncate (&state->dx, 0);
+}
+
+static void
+_add_glyph (cairo_glyph_state_t *state,
+	    unsigned long        index,
+	    double               device_x,
+	    double               device_y)
+{
+    double user_x = device_x;
+    double user_y = device_y;
+    WCHAR glyph_index = index;
+    int logical_x, logical_y;
+
+    cairo_matrix_transform_point (&state->font->device_to_logical, &user_x, &user_y);
+
+    logical_x = DOUBLE_TO_LOGICAL (user_x);
+    logical_y = DOUBLE_TO_LOGICAL (user_y);
+
+    if (state->glyphs.num_elements > 0) {
+	int dx;
+	
+	if (logical_y != state->last_y) {
+	    _flush_glyphs (state);
+	    state->start_x = logical_x;
+	}
+	
+	dx = logical_x - state->last_x;
+	_cairo_array_append (&state->dx, &logical_x, 1);
+    } else {
+	state->start_x = logical_x;
+    }
+
+    state->last_x = logical_x;
+    state->last_y = logical_y;
+    
+    _cairo_array_append (&state->glyphs, &glyph_index, 1);
+}
+
+static void
+_finish_glyphs (cairo_glyph_state_t *state,
+		HDC                  dc)
+{
+    state->dc = dc;
+
+    _flush_glyphs (state);
+
+    _cairo_array_fini (&state->glyphs);
+    _cairo_array_init (&state->dx);
+}
+
+static cairo_status_t
+_draw_glyphs_on_surface (cairo_win32_surface_t *surface,
+			 HBRUSH                 brush,
+			 int                    x_offset,
+			 int                    y_offset,
+			 const cairo_glyph_t   *glyphs,
+			 int                 	num_glyphs)
+{
+    cairo_glyph_state_t state;
+    cairo_status status;
+    int prev_mode;
+    XFORM xform;
+    XFORM prev_xform;
+    BRUSH old_brush;
+
+    old_brush = SelectObject (tmp_surface->dc, brush);
+    if (!old_brush)
+	return _print_gdi_error ();l
+
+    prev_mode = GetGraphicsMode (surface->dc);
+    SetGraphicsMode (surface->dc, GM_ADVANCED);
+    
+    GetWorldTransform (surface->dc, &prev_xform);
+    
+    xForm.eM11 = font->logical_to_device->m[0][0];
+    xForm.eM21 = font->logical_to_device->m[1][0];
+    xForm.eM12 = font->logical_to_device->m[0][1];
+    xForm.eM22 = font->logical_to_device->m[1][1];
+    xForm.eDx = matrix->m[2][0];
+    xForm.eDy = matrix->m[2][1];
+
+    SetWorldTransform (surface->dc, &xform);
+  
+    _start_glyphs (&glyph_state, tmp_surface->dc);
+
+    for (i = 0; i < num_glyphs; i++) {
+	status = _add_glyph (&glyph_state, glyphs[i].glyph, glyphs[i].x - x, glyphs[i].y - y);
+	if (!CAIRO_OK (status))
+	    goto FAIL;
+    }
+
+ FAIL:
+    _finish_glyphs (&glyph_state);
+
+    SetWorldTransform (surface>dc, &prev_xform);
+
+    SetGraphicsMode (surface->dc, prev_mode);
+    
+    SelectObject (tmp_surface->dc, old_brush);
+}
+			 
 
 static cairo_status_t 
-_cairo_ft_font_show_glyphs (void			*abstract_font,
-                            cairo_operator_t    	operator,
-                            cairo_surface_t     	*source,
-			    cairo_surface_t     	*surface,
-			    int                 	source_x,
-			    int                 	source_y,
-                            const cairo_glyph_t 	*glyphs,
-                            int                 	num_glyphs)
+_cairo_win32_font_show_glyphs (void		       *abstract_font,
+			       cairo_operator_t    	operator,
+			       cairo_pattern_t     	*pattern,
+			       cairo_surface_t     	*surface,
+			       int                 	source_x,
+			       int                 	source_y,
+			       int				dest_x,
+			       int				dest_y,
+			       unsigned int		width,
+			       unsigned int		height,
+			       const cairo_glyph_t 	*glyphs,
+			       int                 	num_glyphs)
 {
     cairo_win32_font_t *font = abstract_font;
+    cairo_bbox_t bbox;
+    cairo_win32_surface_t *win32_surface = (cairo_win32_surface_t *)surface;
+    cairo_win32_surface_t *tmp_surface;
+    int i;
+    RECT r;
+
+    if (_cairo_surface_is_win32 (surface) &&
+	win32_surface->format == CAIRO_FORMAT_RGB24 &&
+	operator == CAIRO_OPERATOR_OVER &&
+	pattern->type == CAIRO_PATTERN_SOLID &&
+	(pattern->color.alpha_short >> 8) == 255) {
+
+	/* When compositing OVER on a GDI-understood surface, with a
+	 * solid opaque color, we can just call ExtTextOut directly.
+	 */
+	COLORREF new_color;
+	HBRUSH brush;
+	
+	new_color = RGB (pattern->color.red_short >> 8,
+			 pattern->color.green_short >> 8,
+			 pattern->color.blue_short >> 8);
+
+	brush = CreateSolidBrush (new_color);
+	if (!brush)
+	    return _cairo_win32_print_gdi_error ("_cairo_win32_font_show_glyphs");
+	
+	_draw_glyphs_on_surface (win32_surface, brush, glyphs, num_glyphs, 0, 0);
+	
+	DeleteObject (new_brush);
+    } else {
+	
+	/* Otherwise, we need to draw using software fallbacks. We create a mask 
+	/* surface by drawing the the glyphs onto a DIB, white-on-black.
+	 */
+	tmp_surface = (cairo_win32_surface_t *)_cairo_win32_surface_create_dib (CAIRO_FORMAT_ARGB32, width, height);
+
+	r.left = 0;
+	r.top = 0;
+	r.right = width;
+	r.height = height;
+	FillRect (hdc, &r, GetStockObject (BLACK_BRUSH));
+
+	_draw_glyphs_on_surface (win32_surface, GetStockObject (WHITE_BRUSH),
+				 glyphs, num_glyphs, x, y);
+
+	if (font->quality == CLEARTYPE_QUALITY) {
+	    /* For ClearType, we need a 4-channel mask. If we are compositing on
+	     * a surface with alpha, we need to compute the alpha channel of
+	     * the mask as the average of the other channels. But for a destination
+	     * surface without alpha the alpha channel of the mask is ignored
+	     */
+
+	    if (win32_surface->format != CAIRO_FORMAT_ARGB24)
+		_compute_argb32_mask_alpha (tmp_surface);
+	    
+	    mask_surface = tmp_surface;
+	    
+	} else {
+	    mask_surface = _compute_a8_mask (tmp_surface);
+	    cairo_suface_destroy (tmp_surface);
+	}
+
+	/* For operator == OVER, no-cleartype, a possible optimization here is to
+	 * draw onto an intermediate ARGB32 surface and alpha-blend that with the
+	 * destination
+	 */
+	status = _cairo_surface_composite (operator, pattern, 
+					   &(mask_surface->base), 
+					   surface,
+					   source_x, source_y,
+					   0, 0,
+					   x, y,
+					   width, height);
+	
+	cairo_surface_destroy (mask_surface);
+    }
+    
 
     return CAIRO_STATUS_SUCCESS;
 }
@@ -365,16 +850,12 @@
 cairo_win32_font_create_for_logfont (LOGFONT        *logfont,
 				     cairo_matrix_t *scale)
 {
-    cairo_win32_font_t *f;
-
-    f = malloc (sizeof(cairo_win32_font_t));
-    if (f == NULL) 
-      return NULL;
-
-    f->logfont = *logfont;
-
-
-    _cairo_font_init ((cairo_font_t *)f, &sc, &cairo_win32_font_backend);
+    cairo_font_scale_t sc;
+    
+    cairo_matrix_get_affine (scale,
+			     &sc.matrix[0][0], &sc.matrix[0][1],
+			     &sc.matrix[1][0], &sc.matrix[1][1],
+			     NULL, NULL);
 
-    return (cairo_font_t *)f;
+    return _win32_font_create (logfont, &sc);
 }

Index: cairo_win32_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_win32_surface.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cairo_win32_surface.c	1 Feb 2005 00:11:37 -0000	1.1
+++ cairo_win32_surface.c	1 Feb 2005 23:06:36 -0000	1.2
@@ -47,8 +47,17 @@
 
 static const cairo_surface_backend_t cairo_win32_surface_backend;
 
-static void
-_print_gdi_error (const char *context)
+/**
+ * _cairo_win32_print_gdi_error:
+ * @context: context string to display along with the error
+ * 
+ * Helper function to dump out a human readable form of the
+ * current error code.
+ *
+ * Return value: A Cairo status code for the error code
+ **/
+cairo_status_t
+_cairo_win32_print_gdi_error (const char *context)
 {
     void *lpMsgBuf;
     DWORD last_error = GetLastError ();
@@ -66,12 +75,8 @@
 	
 	LocalFree (lpMsgBuf);
     }
-}
 
-static cairo_status_t
-_get_cairo_error (void)
-{
-    /* We should switch off of GetLastError, but we'd either return
+    /* We should switch off of last_status, but we'd either return
      * CAIRO_STATUS_NO_MEMORY or CAIRO_STATUS_UNKNOWN_ERROR and there
      * is no CAIRO_STATUS_UNKNOWN_ERROR.
      */
@@ -79,6 +84,11 @@
     return CAIRO_STATUS_NO_MEMORY;
 }
 
+static cairo_status_t
+_get_cairo_error (void)
+{
+}
+
 void
 cairo_set_target_win32 (cairo_t *cr,
 			HDC      hdc)
@@ -130,6 +140,7 @@
 {
     HDC dc = NULL;
     HBITMAP bitmap = NULL;
+    cairo_status_t status;
 
     BITMAPINFO *bitmap_info = NULL;
     struct {
@@ -257,7 +268,7 @@
     return CAIRO_STATUS_SUCCESS;
 
  FAIL:
-    _print_gdi_error ("_create_dc_and_bitmap");
+    status = _cairo_win32_print_gdi_error ("_create_dc_and_bitmap");
     
     if (bitmap_info && num_palette > 2)
 	free (bitmap_info);
@@ -268,7 +279,7 @@
     if (dc)
 	DeleteDC (dc);
     
-    return _get_cairo_error ();
+    return status;
 }
 
 static cairo_surface_t *
@@ -360,6 +371,7 @@
 				   cairo_win32_surface_t **local_out)
 {
     cairo_win32_surface_t *local;
+    cairo_status_t status;
 
     local = 
 	(cairo_win32_surface_t *) _cairo_win32_surface_create_similar (surface,
@@ -382,12 +394,12 @@
     return CAIRO_STATUS_SUCCESS;
 
  FAIL:
-    _print_gdi_error ("_cairo_win32_surface_get_subimage");
+    status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_get_subimage");
 
     if (local)
 	cairo_surface_destroy (&local->base);
-    
-    return _get_cairo_error ();
+
+    return status;
 }
 
 static cairo_status_t
@@ -457,10 +469,8 @@
 	return CAIRO_STATUS_SUCCESS;
     }
 
-    if (GetClipBox (surface->dc, &clip_box) == ERROR) {
-	_print_gdi_error ("_cairo_win3_surface_acquire_dest_image");
-	return _get_cairo_error ();
-    }
+    if (GetClipBox (surface->dc, &clip_box) == ERROR)
+	return _cairo_win32_print_gdi_error ("_cairo_win3_surface_acquire_dest_image");
     
     x1 = clip_box.left;
     x2 = clip_box.right;
@@ -517,9 +527,8 @@
 		 image_rect->width, image_rect->height,
 		 local->dc,
 		 0, 0,
-		 SRCCOPY)) {
-	_print_gdi_error ("_cairo_win32_surface_release_dest_image");
-    }
+		 SRCCOPY))
+	_cairo_win32_print_gdi_error ("_cairo_win32_surface_release_dest_image");
 
     cairo_surface_destroy ((cairo_surface_t *)local);
 }
@@ -613,10 +622,8 @@
 		     width, height,
 		     src->dc,
 		     src_x + itx, src_y + ity,
-		     SRCCOPY)) {
-	    _print_gdi_error ("_cairo_win32_surface_composite");
-	    return _get_cairo_error ();
-	}
+		     SRCCOPY))
+	    return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite");
 
 	return CAIRO_STATUS_SUCCESS;
 	
@@ -641,10 +648,8 @@
 			 src->dc,
 			 src_x + itx, src_y + ity,
 			 width, height,
-			 blend_function)) {
-	    _print_gdi_error ("_cairo_win32_surface_composite");
-	    return _get_cairo_error ();
-	}
+			 blend_function))
+	    return _cairo_win32_print_gdi_error ("_cairo_win32_surface_composite");
 
 	return CAIRO_STATUS_SUCCESS;
     }
@@ -660,6 +665,7 @@
 				      int			num_rects)
 {
     cairo_win32_surface_t *surface = abstract_surface;
+    cairo_status_t status;
     COLORREF new_color;
     HBRUSH new_brush;
     int i;
@@ -681,10 +687,8 @@
     new_color = RGB (color->red_short >> 8, color->green_short >> 8, color->blue_short >> 8);
 
     new_brush = CreateSolidBrush (new_color);
-    if (!new_brush) {
-	_print_gdi_error ("_cairo_win32_surface_fill_rectangles");
-	return _get_cairo_error ();
-    }
+    if (!new_brush)
+	return _cairo_win32_print_gdi_error ("_cairo_win32_surface_fill_rectangles");
     
     for (i = 0; i < num_rects; i++) {
 	RECT rect;
@@ -703,11 +707,11 @@
     return CAIRO_STATUS_SUCCESS;
 
  FAIL:
-    _print_gdi_error ("_cairo_win32_surface_fill_rectangles");
+    status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_fill_rectangles");
     
     DeleteObject (new_brush);
     
-    return _get_cairo_error ();
+    return status;
 }
 
 static cairo_int_status_t
@@ -744,6 +748,7 @@
 				      pixman_region16_t *region)
 {
     cairo_win32_surface_t *surface = abstract_surface;
+    cairo_status_t status;
 
     /* If we are in-memory, then we set the clip on the image surface
      * as well as on the underlying GDI surface.
@@ -761,10 +766,8 @@
 	/* Clear any clip set by Cairo, return to the original */
 	
 	if (surface->set_clip) {
-	    if (SelectClipRgn (surface->dc, surface->saved_clip) == ERROR) {
-		_print_gdi_error ("_cairo_win32_surface_set_clip_region");
-		return _get_cairo_error ();
-	    }
+	    if (SelectClipRgn (surface->dc, surface->saved_clip) == ERROR)
+		return _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region");
 
 	    if (surface->saved_clip) {
 		DeleteObject (surface->saved_clip);
@@ -851,9 +854,9 @@
 	return CAIRO_STATUS_SUCCESS;
 
     FAIL:
-	_print_gdi_error ("_cairo_win32_surface_set_clip_region");
+	status = _cairo_win32_print_gdi_error ("_cairo_win32_surface_set_clip_region");
 	DeleteObject (gdi_region);
-	return _get_cairo_error ();
+	return status;
     }
 }
 
@@ -883,7 +886,7 @@
     /* Try to figure out the drawing bounds for the Device context
      */
     if (GetClipBox (hdc, &rect) == ERROR) {
-	_print_gdi_error ("cairo_win32_surface_create");
+	_cairo_win32_print_gdi_error ("cairo_win32_surface_create");
 	return NULL;
     }
     

Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.93
retrieving revision 1.94
diff -u -d -r1.93 -r1.94
--- cairoint.h	1 Feb 2005 00:11:37 -0000	1.93
+++ cairoint.h	1 Feb 2005 23:06:36 -0000	1.94
@@ -111,6 +111,14 @@
 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
 #include "cairo-wideint.h"
 
 typedef int32_t		cairo_fixed_16_16_t;
@@ -1136,13 +1144,13 @@
 _cairo_gstate_in_stroke (cairo_gstate_t	*gstate,
 			 double		x,
 			 double		y,
-			 int		*inside_ret);
+			 cairo_bool_t	*inside_ret);
 
 cairo_private cairo_status_t
 _cairo_gstate_in_fill (cairo_gstate_t	*gstate,
 		       double		x,
 		       double		y,
-		       int		*inside_ret);
+		       cairo_bool_t	*inside_ret);
 
 cairo_private cairo_status_t
 _cairo_gstate_init_clip (cairo_gstate_t *gstate);
@@ -1731,6 +1739,20 @@
 _cairo_pattern_end_draw (cairo_pattern_t      *pattern,
 			 cairo_pattern_info_t *info);
 
+/* cairo_unicode.c */
+
+cairo_private cairo_status_t
+_cairo_utf8_to_ucs4 (const char  *str,
+		     int          len,
+		     uint32_t   **result,
+		     int         *items_written);
+
+cairo_private cairo_status_t
+_cairo_utf8_to_utf16 (const char  *str,
+		      int          len,
+		      uint16_t   **result,
+		      int         *items_written);
+
 /* Avoid unnecessary PLT entries.  */
 
 slim_hidden_proto(cairo_close_path)




More information about the cairo-commit mailing list