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,7 @@ typedef enum _cairo_surface_type { CAIRO_SURFACE_TYPE_TEE, CAIRO_SURFACE_TYPE_XML, CAIRO_SURFACE_TYPE_SKIA, - 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