commit 4a412c0b144ed1fdde668e0e91241bac8bedd579
Author: Jeff Muizelaar <jmuizelaar@mozilla.com>
Date:   Sun Jan 24 14:04:33 2010 -0500

    d2d

diff --git a/src/cairo-fixed-private.h b/src/cairo-fixed-private.h
index c299def..a37ca6a 100644
--- a/src/cairo-fixed-private.h
+++ b/src/cairo-fixed-private.h
@@ -50,6 +50,7 @@
 
 #define CAIRO_FIXED_ONE        ((cairo_fixed_t)(1 << CAIRO_FIXED_FRAC_BITS))
 #define CAIRO_FIXED_ONE_DOUBLE ((double)(1 << CAIRO_FIXED_FRAC_BITS))
+#define CAIRO_FIXED_ONE_FLOAT  ((float)(1 << CAIRO_FIXED_FRAC_BITS))
 #define CAIRO_FIXED_EPSILON    ((cairo_fixed_t)(1))
 
 #define CAIRO_FIXED_FRAC_MASK  (((cairo_fixed_unsigned_t)(-1)) >> (CAIRO_FIXED_BITS - CAIRO_FIXED_FRAC_BITS))
@@ -141,6 +142,12 @@ _cairo_fixed_to_double (cairo_fixed_t f)
     return ((double) f) / CAIRO_FIXED_ONE_DOUBLE;
 }
 
+static inline float
+_cairo_fixed_to_float (cairo_fixed_t f)
+{
+    return ((float) f) / CAIRO_FIXED_ONE_FLOAT;
+}
+
 static inline int
 _cairo_fixed_is_integer (cairo_fixed_t f)
 {
diff --git a/src/cairo-win32-private.h b/src/cairo-win32-private.h
index b9926bb..ba57595 100644
--- a/src/cairo-win32-private.h
+++ b/src/cairo-win32-private.h
@@ -231,4 +231,19 @@ inline BOOL ModifyWorldTransform(HDC hdc, CONST XFORM * lpxf, DWORD mode) { retu
 
 #endif
 
+#ifdef CAIRO_HAS_DWRITE_FONT
+CAIRO_BEGIN_DECLS
+
+cairo_public cairo_int_status_t
+cairo_dwrite_show_glyphs_on_surface(void			*surface,
+				    cairo_operator_t	 op,
+				    const cairo_pattern_t	*source,
+				    cairo_glyph_t		*glyphs,
+				    int			 num_glyphs,
+				    cairo_scaled_font_t	*scaled_font,
+				    cairo_rectangle_int_t	*extents);
+
+
+CAIRO_END_DECLS
+#endif /* CAIRO_HAS_DWRITE_FONT */
 #endif /* CAIRO_WIN32_PRIVATE_H */
diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c
index 0dc5e76..bee00b1 100644
--- a/src/cairo-win32-surface.c
+++ b/src/cairo-win32-surface.c
@@ -1547,152 +1547,158 @@ _cairo_win32_surface_show_glyphs (void			*surface,
 				  int			*remaining_glyphs)
 {
 #if defined(CAIRO_HAS_WIN32_FONT) && !defined(WINCE)
-    cairo_win32_surface_t *dst = surface;
-
-    WORD glyph_buf_stack[STACK_GLYPH_SIZE];
-    WORD *glyph_buf = glyph_buf_stack;
-    int dxy_buf_stack[2 * STACK_GLYPH_SIZE];
-    int *dxy_buf = dxy_buf_stack;
-
-    BOOL win_result = 0;
-    int i, j;
+    if (scaled_font->backend->type == CAIRO_FONT_TYPE_DWRITE) {
+#ifdef CAIRO_HAS_DWRITE_FONT
+        return cairo_dwrite_show_glyphs_on_surface(surface, op, source, glyphs, num_glyphs, scaled_font, clip);
+#endif
+    } else {
+	cairo_win32_surface_t *dst = surface;
+        
+	WORD glyph_buf_stack[STACK_GLYPH_SIZE];
+	WORD *glyph_buf = glyph_buf_stack;
+	int dxy_buf_stack[2 * STACK_GLYPH_SIZE];
+	int *dxy_buf = dxy_buf_stack;
 
-    cairo_solid_pattern_t *solid_pattern;
-    COLORREF color;
+	BOOL win_result = 0;
+	int i, j;
 
-    cairo_matrix_t device_to_logical;
+	cairo_solid_pattern_t *solid_pattern;
+	COLORREF color;
 
-    int start_x, start_y;
-    double user_x, user_y;
-    int logical_x, logical_y;
-    unsigned int glyph_index_option;
+	cairo_matrix_t device_to_logical;
 
-    /* We can only handle win32 fonts */
-    if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_WIN32)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+	int start_x, start_y;
+	double user_x, user_y;
+	int logical_x, logical_y;
+	unsigned int glyph_index_option;
 
-    /* We can only handle opaque solid color sources */
-    if (!_cairo_pattern_is_opaque_solid(source))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+	/* We can only handle win32 fonts */
+	if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_WIN32)
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    /* We can only handle operator SOURCE or OVER with the destination
-     * having no alpha */
-    if ((op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_OVER) ||
-	(dst->format != CAIRO_FORMAT_RGB24))
-	return CAIRO_INT_STATUS_UNSUPPORTED;
+	/* We can only handle opaque solid color sources */
+	if (!_cairo_pattern_is_opaque_solid(source))
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    /* If we have a fallback mask clip set on the dst, we have
-     * to go through the fallback path, but only if we're not
-     * doing this for printing */
-    if (clip != NULL) {
-	if ((dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) == 0) {
-	    cairo_region_t *clip_region;
-	    cairo_status_t status;
+	/* We can only handle operator SOURCE or OVER with the destination
+	 * having no alpha */
+	if ((op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_OVER) ||
+	    (dst->format != CAIRO_FORMAT_RGB24))
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
 
-	    status = _cairo_clip_get_region (clip, &clip_region);
-	    assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO);
-	    if (status)
-		return status;
+	/* If we have a fallback mask clip set on the dst, we have
+	 * to go through the fallback path, but only if we're not
+	 * doing this for printing */
+	if (clip != NULL) {
+	    if ((dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) == 0) {
+		cairo_region_t *clip_region;
+		cairo_status_t status;
+
+		status = _cairo_clip_get_region (clip, &clip_region);
+		assert (status != CAIRO_INT_STATUS_NOTHING_TO_DO);
+		if (status)
+		    return status;
 
-	    _cairo_win32_surface_set_clip_region (surface, clip_region);
+		_cairo_win32_surface_set_clip_region (surface, clip_region);
+	    }
 	}
-    }
 
-    solid_pattern = (cairo_solid_pattern_t *)source;
-    color = RGB(((int)solid_pattern->color.red_short) >> 8,
-		((int)solid_pattern->color.green_short) >> 8,
-		((int)solid_pattern->color.blue_short) >> 8);
+	solid_pattern = (cairo_solid_pattern_t *)source;
+	color = RGB(((int)solid_pattern->color.red_short) >> 8,
+		    ((int)solid_pattern->color.green_short) >> 8,
+		    ((int)solid_pattern->color.blue_short) >> 8);
 
-    cairo_win32_scaled_font_get_device_to_logical(scaled_font, &device_to_logical);
+	cairo_win32_scaled_font_get_device_to_logical(scaled_font, &device_to_logical);
 
-    SaveDC(dst->dc);
+	SaveDC(dst->dc);
 
-    cairo_win32_scaled_font_select_font(scaled_font, dst->dc);
-    SetTextColor(dst->dc, color);
-    SetTextAlign(dst->dc, TA_BASELINE | TA_LEFT);
-    SetBkMode(dst->dc, TRANSPARENT);
+	cairo_win32_scaled_font_select_font(scaled_font, dst->dc);
+	SetTextColor(dst->dc, color);
+	SetTextAlign(dst->dc, TA_BASELINE | TA_LEFT);
+	SetBkMode(dst->dc, TRANSPARENT);
 
-    if (num_glyphs > STACK_GLYPH_SIZE) {
-	glyph_buf = (WORD *) _cairo_malloc_ab (num_glyphs, sizeof(WORD));
-        dxy_buf = (int *) _cairo_malloc_abc (num_glyphs, sizeof(int), 2);
-    }
+	if (num_glyphs > STACK_GLYPH_SIZE) {
+	    glyph_buf = (WORD *) _cairo_malloc_ab (num_glyphs, sizeof(WORD));
+	    dxy_buf = (int *) _cairo_malloc_abc (num_glyphs, sizeof(int), 2);
+	}
 
-    /* It is vital that dx values for dxy_buf are calculated from the delta of
-     * _logical_ x coordinates (not user x coordinates) or else the sum of all
-     * previous dx values may start to diverge from the current glyph's x
-     * coordinate due to accumulated rounding error. As a result strings could
-     * be painted shorter or longer than expected. */
+	/* It is vital that dx values for dxy_buf are calculated from the delta of
+	 * _logical_ x coordinates (not user x coordinates) or else the sum of all
+	 * previous dx values may start to diverge from the current glyph's x
+	 * coordinate due to accumulated rounding error. As a result strings could
+	 * be painted shorter or longer than expected. */
 
-    user_x = glyphs[0].x;
-    user_y = glyphs[0].y;
+	user_x = glyphs[0].x;
+	user_y = glyphs[0].y;
 
-    cairo_matrix_transform_point(&device_to_logical,
-                                 &user_x, &user_y);
+	cairo_matrix_transform_point(&device_to_logical,
+				     &user_x, &user_y);
 
-    logical_x = _cairo_lround (user_x);
-    logical_y = _cairo_lround (user_y);
+	logical_x = _cairo_lround (user_x);
+	logical_y = _cairo_lround (user_y);
 
-    start_x = logical_x;
-    start_y = logical_y;
+	start_x = logical_x;
+	start_y = logical_y;
 
-    for (i = 0, j = 0; i < num_glyphs; ++i, j = 2 * i) {
-        glyph_buf[i] = (WORD) glyphs[i].index;
-        if (i == num_glyphs - 1) {
-            dxy_buf[j] = 0;
-            dxy_buf[j+1] = 0;
-        } else {
-            double next_user_x = glyphs[i+1].x;
-            double next_user_y = glyphs[i+1].y;
-            int next_logical_x, next_logical_y;
+	for (i = 0, j = 0; i < num_glyphs; ++i, j = 2 * i) {
+	    glyph_buf[i] = (WORD) glyphs[i].index;
+	    if (i == num_glyphs - 1) {
+		dxy_buf[j] = 0;
+		dxy_buf[j+1] = 0;
+	    } else {
+		double next_user_x = glyphs[i+1].x;
+		double next_user_y = glyphs[i+1].y;
+		int next_logical_x, next_logical_y;
 
-            cairo_matrix_transform_point(&device_to_logical,
-                                         &next_user_x, &next_user_y);
+		cairo_matrix_transform_point(&device_to_logical,
+					     &next_user_x, &next_user_y);
 
-            next_logical_x = _cairo_lround (next_user_x);
-            next_logical_y = _cairo_lround (next_user_y);
+		next_logical_x = _cairo_lround (next_user_x);
+		next_logical_y = _cairo_lround (next_user_y);
 
-            dxy_buf[j] = _cairo_lround (next_logical_x - logical_x);
-            dxy_buf[j+1] = _cairo_lround (logical_y - next_logical_y);
-                /* note that GDI coordinate system is inverted */
+		dxy_buf[j] = _cairo_lround (next_logical_x - logical_x);
+		dxy_buf[j+1] = _cairo_lround (logical_y - next_logical_y);
+		    /* note that GDI coordinate system is inverted */
 
-            logical_x = next_logical_x;
-            logical_y = next_logical_y;
-        }
-    }
+		logical_x = next_logical_x;
+		logical_y = next_logical_y;
+	    }
+	}
 
-    /* Using glyph indices for a Type 1 font does not work on a
-     * printer DC. The win32 printing surface will convert the the
-     * glyph indices of Type 1 fonts to the unicode values.
-     */
-    if ((dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) &&
-	_cairo_win32_scaled_font_is_type1 (scaled_font))
-    {
-	glyph_index_option = 0;
-    }
-    else
-    {
-	glyph_index_option = ETO_GLYPH_INDEX;
-    }
+	/* Using glyph indices for a Type 1 font does not work on a
+	 * printer DC. The win32 printing surface will convert the the
+	 * glyph indices of Type 1 fonts to the unicode values.
+	 */
+	if ((dst->flags & CAIRO_WIN32_SURFACE_FOR_PRINTING) &&
+	    _cairo_win32_scaled_font_is_type1 (scaled_font))
+	{
+	    glyph_index_option = 0;
+	}
+	else
+	{
+	    glyph_index_option = ETO_GLYPH_INDEX;
+	}
 
-    win_result = ExtTextOutW(dst->dc,
-                             start_x,
-                             start_y,
-                             glyph_index_option | ETO_PDY,
-                             NULL,
-                             glyph_buf,
-                             num_glyphs,
-                             dxy_buf);
-    if (!win_result) {
-        _cairo_win32_print_gdi_error("_cairo_win32_surface_show_glyphs(ExtTextOutW failed)");
-    }
+	win_result = ExtTextOutW(dst->dc,
+				 start_x,
+				 start_y,
+				 glyph_index_option | ETO_PDY,
+				 NULL,
+				 glyph_buf,
+				 num_glyphs,
+				 dxy_buf);
+	if (!win_result) {
+	    _cairo_win32_print_gdi_error("_cairo_win32_surface_show_glyphs(ExtTextOutW failed)");
+	}
 
-    RestoreDC(dst->dc, -1);
+	RestoreDC(dst->dc, -1);
 
-    if (glyph_buf != glyph_buf_stack) {
-	free(glyph_buf);
-        free(dxy_buf);
+	if (glyph_buf != glyph_buf_stack) {
+	    free(glyph_buf);
+	    free(dxy_buf);
+	}
+	return (win_result) ? CAIRO_STATUS_SUCCESS : CAIRO_INT_STATUS_UNSUPPORTED;
     }
-    return (win_result) ? CAIRO_STATUS_SUCCESS : CAIRO_INT_STATUS_UNSUPPORTED;
 #else
     return CAIRO_INT_STATUS_UNSUPPORTED;
 #endif
diff --git a/src/cairo-win32.h b/src/cairo-win32.h
index 6b86d4e..fcf20b8 100644
--- a/src/cairo-win32.h
+++ b/src/cairo-win32.h
@@ -109,6 +109,63 @@ cairo_win32_scaled_font_get_device_to_logical (cairo_scaled_font_t *scaled_font,
 
 #endif /* CAIRO_HAS_WIN32_FONT */
 
+#if CAIRO_HAS_DWRITE_FONT
+
+/*
+ * Win32 DirectWrite font support
+ */
+cairo_public cairo_font_face_t *
+cairo_dwrite_font_face_create_for_dwrite_fontface(void *dwrite_font, void *dwrite_font_face);
+
+#endif /* CAIRO_HAS_DWRITE_FONT */
+
+#if CAIRO_HAS_D2D_SURFACE
+
+/**
+ * Create a D2D surface for an HWND
+ *
+ * \param wnd Handle for the window
+ * \return New cairo surface
+ */
+cairo_public cairo_surface_t *
+cairo_d2d_surface_create_for_hwnd(HWND wnd);
+
+/**
+ * Create a D2D surface of a certain size.
+ *
+ * \param format Cairo format of the surface
+ * \param width Width of the surface
+ * \param height Height of the surface
+ * \return New cairo surface
+ */
+cairo_public cairo_surface_t *
+cairo_d2d_surface_create(cairo_format_t format,
+                         int width,
+                         int height);
+
+/**
+ * Present the backbuffer for a surface create for an HWND. This needs
+ * to be called when the owner of the original window surface wants to
+ * actually present the executed drawing operations to the screen.
+ *
+ * \param surface D2D surface.
+ */
+void cairo_d2d_present_backbuffer(cairo_surface_t *surface);
+
+/**
+ * Scroll the surface, this only moves the surface graphics, it does not
+ * actually scroll child windows or anything like that. Nor does it invalidate
+ * that area of the window.
+ *
+ * \param surface The d2d surface this operation should apply to.
+ * \param x The x delta for the movement
+ * \param y The y delta for the movement
+ * \param clip The clip rectangle, the is the 'part' of the surface that needs
+ * scrolling.
+ */
+void cairo_d2d_scroll(cairo_surface_t *surface, int x, int y, cairo_rectangle_t *clip);
+#endif
+
 CAIRO_END_DECLS
 
 #else  /* CAIRO_HAS_WIN32_SURFACE */
diff --git a/src/cairo.h b/src/cairo.h
index 3a8b8a6..21827aa 100644
--- a/src/cairo.h
+++ b/src/cairo.h
@@ -1370,7 +1370,8 @@ typedef enum _cairo_font_type {
     CAIRO_FONT_TYPE_FT,
     CAIRO_FONT_TYPE_WIN32,
     CAIRO_FONT_TYPE_QUARTZ,
-    CAIRO_FONT_TYPE_USER
+    CAIRO_FONT_TYPE_USER,
+    CAIRO_FONT_TYPE_DWRITE
 } cairo_font_type_t;
 
 cairo_public cairo_font_type_t
@@ -2009,7 +2010,8 @@ typedef enum _cairo_surface_type {
     CAIRO_SURFACE_TYPE_TEE,
     CAIRO_SURFACE_TYPE_XML,
     CAIRO_SURFACE_TYPE_SKIA,
-    CAIRO_SURFACE_TYPE_DDRAW
+    CAIRO_SURFACE_TYPE_DDRAW,
+    CAIRO_SURFACE_TYPE_D2D
 } cairo_surface_type_t;
 
 cairo_public cairo_surface_type_t
diff --git a/src/cairoint.h b/src/cairoint.h
index b942b4b..58850ab 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -587,6 +587,12 @@ extern const cairo_private struct _cairo_font_face_backend _cairo_win32_font_fac
 
 #endif
 
+#if CAIRO_HAS_DWRITE_FONT
+
+extern const cairo_private struct _cairo_font_face_backend _cairo_dwrite_font_face_backend;
+
+#endif
+
 #if CAIRO_HAS_QUARTZ_FONT
 
 extern const cairo_private struct _cairo_font_face_backend _cairo_quartz_font_face_backend;
@@ -932,7 +938,12 @@ typedef struct _cairo_traps {
 #define CAIRO_FT_FONT_FAMILY_DEFAULT     ""
 #define CAIRO_USER_FONT_FAMILY_DEFAULT     "@cairo:"
 
-#if   CAIRO_HAS_WIN32_FONT
+#if   CAIRO_HAS_DWRITE_FONT
+
+#define CAIRO_FONT_FAMILY_DEFAULT CAIRO_WIN32_FONT_FAMILY_DEFAULT
+#define CAIRO_FONT_FACE_BACKEND_DEFAULT &_cairo_dwrite_font_face_backend
+
+#elif CAIRO_HAS_WIN32_FONT
 
 #define CAIRO_FONT_FAMILY_DEFAULT CAIRO_WIN32_FONT_FAMILY_DEFAULT
 #define CAIRO_FONT_FACE_BACKEND_DEFAULT &_cairo_win32_font_face_backend
@@ -2617,7 +2628,7 @@ cairo_private int
 _cairo_ucs4_to_utf8 (uint32_t    unicode,
 		     char       *utf8);
 
-#if CAIRO_HAS_WIN32_FONT || CAIRO_HAS_QUARTZ_FONT || CAIRO_HAS_PDF_OPERATORS
+#if CAIRO_HAS_WIN32_FONT || CAIRO_HAS_QUARTZ_FONT || CAIRO_HAS_PDF_OPERATORS || CAIRO_HAS_DW_FONT
 # define CAIRO_HAS_UTF8_TO_UTF16 1
 #endif
 #if CAIRO_HAS_UTF8_TO_UTF16
