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