pjs/gfx/cairo/d2d.patch

466 строки
15 KiB
Diff
Исходник Обычный вид История

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