[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