diff options
Diffstat (limited to 'gfx/cairo/win32-d3dsurface9.patch')
-rw-r--r-- | gfx/cairo/win32-d3dsurface9.patch | 465 |
1 files changed, 465 insertions, 0 deletions
diff --git a/gfx/cairo/win32-d3dsurface9.patch b/gfx/cairo/win32-d3dsurface9.patch new file mode 100644 index 000000000..b0e80252f --- /dev/null +++ b/gfx/cairo/win32-d3dsurface9.patch @@ -0,0 +1,465 @@ +diff --git a/gfx/cairo/cairo/src/cairo-rename.h b/gfx/cairo/cairo/src/cairo-rename.h +--- a/gfx/cairo/cairo/src/cairo-rename.h ++++ b/gfx/cairo/cairo/src/cairo-rename.h +@@ -335,16 +335,17 @@ + #define cairo_win32_font_face_create_for_logfontw_hfont _moz_cairo_win32_font_face_create_for_logfontw_hfont + #define cairo_win32_printing_surface_create _moz_cairo_win32_printing_surface_create + #define cairo_win32_scaled_font_done_font _moz_cairo_win32_scaled_font_done_font + #define cairo_win32_scaled_font_get_device_to_logical _moz_cairo_win32_scaled_font_get_device_to_logical + #define cairo_win32_scaled_font_get_logical_to_device _moz_cairo_win32_scaled_font_get_logical_to_device + #define cairo_win32_scaled_font_get_metrics_factor _moz_cairo_win32_scaled_font_get_metrics_factor + #define cairo_win32_scaled_font_select_font _moz_cairo_win32_scaled_font_select_font + #define cairo_win32_surface_create _moz_cairo_win32_surface_create ++#define cairo_win32_surface_create_with_d3dsurface9 _moz_cairo_win32_surface_create_with_d3dsurface9 + #define cairo_win32_surface_create_with_ddb _moz_cairo_win32_surface_create_with_ddb + #define cairo_win32_surface_create_with_dib _moz_cairo_win32_surface_create_with_dib + #define cairo_win32_surface_get_dc _moz_cairo_win32_surface_get_dc + #define cairo_win32_surface_get_image _moz_cairo_win32_surface_get_image + #define cairo_xcb_surface_create _moz_cairo_xcb_surface_create + #define cairo_xcb_surface_create_for_bitmap _moz_cairo_xcb_surface_create_for_bitmap + #define cairo_xcb_surface_create_with_xrender_format _moz_cairo_xcb_surface_create_with_xrender_format + #define cairo_xcb_surface_set_size _moz_cairo_xcb_surface_set_size +diff --git a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c +--- a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c ++++ b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c +@@ -1852,16 +1852,17 @@ cairo_win32_printing_surface_create (HDC + } + + _cairo_surface_clipper_init (&surface->clipper, + _cairo_win32_printing_surface_clipper_intersect_clip_path); + + surface->image = NULL; + surface->format = CAIRO_FORMAT_RGB24; + surface->content = CAIRO_CONTENT_COLOR_ALPHA; ++ surface->d3d9surface = NULL; + + surface->dc = hdc; + surface->bitmap = NULL; + surface->is_dib = FALSE; + surface->saved_dc_bitmap = NULL; + surface->brush = NULL; + surface->old_brush = NULL; + surface->font_subsets = _cairo_scaled_font_subsets_create_scaled (); +diff --git a/gfx/cairo/cairo/src/cairo-win32-private.h b/gfx/cairo/cairo/src/cairo-win32-private.h +--- a/gfx/cairo/cairo/src/cairo-win32-private.h ++++ b/gfx/cairo/cairo/src/cairo-win32-private.h +@@ -54,16 +54,18 @@ CAIRO_BEGIN_DECLS + + typedef struct _cairo_win32_surface { + cairo_surface_t base; + + cairo_format_t format; + + HDC dc; + ++ struct IDirect3DSurface9 *d3d9surface; ++ + /* We create off-screen surfaces as DIBs or DDBs, based on what we created + * originally*/ + HBITMAP bitmap; + cairo_bool_t is_dib; + + /* Used to save the initial 1x1 monochrome bitmap for the DC to + * select back into the DC before deleting the DC and our + * bitmap. For Windows XP, this doesn't seem to be necessary +diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cairo-win32-surface.c +--- a/gfx/cairo/cairo/src/cairo-win32-surface.c ++++ b/gfx/cairo/cairo/src/cairo-win32-surface.c +@@ -54,16 +54,17 @@ + #include "cairo-win32-private.h" + #include "cairo-scaled-font-subsets-private.h" + #include "cairo-surface-fallback-private.h" + #include "cairo-surface-clipper-private.h" + #include "cairo-gstate-private.h" + #include "cairo-private.h" + #include <wchar.h> + #include <windows.h> ++#include <d3d9.h> + + #if defined(__MINGW32__) && !defined(ETO_PDY) + # define ETO_PDY 0x2000 + #endif + + #undef DEBUG_COMPOSITE + + /* for older SDKs */ +@@ -384,16 +385,17 @@ static cairo_surface_t * + + surface->image = cairo_image_surface_create_for_data (bits, format, + width, height, rowstride); + status = surface->image->status; + if (status) + goto FAIL; + + surface->format = format; ++ surface->d3d9surface = NULL; + + surface->clip_rect.x = 0; + surface->clip_rect.y = 0; + surface->clip_rect.width = width; + surface->clip_rect.height = height; + + surface->initial_clip_rgn = NULL; + surface->had_simple_clip = FALSE; +@@ -481,26 +483,73 @@ cairo_status_t + if (surface->bitmap) { + SelectObject (surface->dc, surface->saved_dc_bitmap); + DeleteObject (surface->bitmap); + DeleteDC (surface->dc); + } else { + _cairo_win32_restore_initial_clip (surface); + } + ++ if (surface->d3d9surface) { ++ IDirect3DSurface9_ReleaseDC (surface->d3d9surface, surface->dc); ++ IDirect3DSurface9_Release (surface->d3d9surface); ++ } ++ + if (surface->initial_clip_rgn) + DeleteObject (surface->initial_clip_rgn); + + if (surface->font_subsets != NULL) + _cairo_scaled_font_subsets_destroy (surface->font_subsets); + + return CAIRO_STATUS_SUCCESS; + } + + static cairo_status_t ++_cairo_win32_surface_d3d9_lock_rect (cairo_win32_surface_t *surface, ++ int x, ++ int y, ++ int width, ++ int height, ++ cairo_image_surface_t **local_out) ++{ ++ cairo_image_surface_t *local; ++ cairo_int_status_t status; ++ ++ RECT rectin = { x, y, x+width, y+height }; ++ D3DLOCKED_RECT rectout; ++ HRESULT hr; ++ hr = IDirect3DSurface9_ReleaseDC (surface->d3d9surface, surface->dc); ++ hr = IDirect3DSurface9_LockRect (surface->d3d9surface, ++ &rectout, &rectin, 0); ++ surface->dc = 0; // Don't use the DC when this is locked! ++ if (hr) { ++ IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc); ++ return CAIRO_INT_STATUS_UNSUPPORTED; ++ } ++ local = cairo_image_surface_create_for_data (rectout.pBits, ++ surface->format, ++ width, height, ++ rectout.Pitch); ++ if (local == NULL) { ++ IDirect3DSurface9_UnlockRect (surface->d3d9surface); ++ IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc); ++ return CAIRO_INT_STATUS_UNSUPPORTED; ++ } ++ if (local->base.status) { ++ IDirect3DSurface9_UnlockRect (surface->d3d9surface); ++ IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc); ++ return local->base.status; ++ } ++ ++ *local_out = local; ++ ++ return CAIRO_STATUS_SUCCESS; ++} ++ ++static cairo_status_t + _cairo_win32_surface_get_subimage (cairo_win32_surface_t *surface, + int x, + int y, + int width, + int height, + cairo_win32_surface_t **local_out) + { + cairo_win32_surface_t *local; +@@ -599,17 +648,16 @@ static void + } + + static cairo_status_t + _cairo_win32_surface_acquire_source_image (void *abstract_surface, + cairo_image_surface_t **image_out, + void **image_extra) + { + cairo_win32_surface_t *surface = abstract_surface; +- cairo_win32_surface_t *local; + cairo_status_t status; + + if (!surface->image && !surface->is_dib && surface->bitmap && + (surface->flags & CAIRO_WIN32_SURFACE_CAN_CONVERT_TO_DIB) != 0) + { + /* This is a DDB, and we're being asked to use it as a source for + * something that we couldn't support natively. So turn it into + * a DIB, so that we have an equivalent image surface, as long +@@ -619,69 +667,109 @@ static cairo_status_t + } + + if (surface->image) { + *image_out = (cairo_image_surface_t *)surface->image; + *image_extra = NULL; + return CAIRO_STATUS_SUCCESS; + } + +- status = _cairo_win32_surface_get_subimage (abstract_surface, 0, 0, +- surface->extents.width, +- surface->extents.height, &local); +- if (status) +- return status; +- +- *image_out = (cairo_image_surface_t *)local->image; +- *image_extra = local; ++ if (surface->d3d9surface) { ++ cairo_image_surface_t *local; ++ status = _cairo_win32_surface_d3d9_lock_rect (abstract_surface, 0, 0, ++ surface->extents.width, ++ surface->extents.height, &local); ++ if (status) ++ return status; ++ ++ *image_out = local; ++ *image_extra = surface; ++ } else { ++ cairo_win32_surface_t *local; ++ status = _cairo_win32_surface_get_subimage (abstract_surface, 0, 0, ++ surface->extents.width, ++ surface->extents.height, &local); ++ if (status) ++ return status; ++ ++ *image_out = (cairo_image_surface_t *)local->image; ++ *image_extra = local; ++ } ++ // image_extra is always of type cairo_win32_surface_t. For d3d9surface it points ++ // to the original surface to get back the d3d9surface and properly unlock. ++ + return CAIRO_STATUS_SUCCESS; + } + + static void + _cairo_win32_surface_release_source_image (void *abstract_surface, + cairo_image_surface_t *image, + void *image_extra) + { ++ cairo_win32_surface_t *surface = abstract_surface; + cairo_win32_surface_t *local = image_extra; + +- if (local) ++ if (local && local->d3d9surface) { ++ IDirect3DSurface9_UnlockRect (local->d3d9surface); ++ IDirect3DSurface9_GetDC (local->d3d9surface, &local->dc); ++ cairo_surface_destroy ((cairo_surface_t *)image); ++ } else { + cairo_surface_destroy ((cairo_surface_t *)local); ++ } + } + + static cairo_status_t + _cairo_win32_surface_acquire_dest_image (void *abstract_surface, + cairo_rectangle_int_t *interest_rect, + cairo_image_surface_t **image_out, + cairo_rectangle_int_t *image_rect, + void **image_extra) + { + cairo_win32_surface_t *surface = abstract_surface; +- cairo_win32_surface_t *local = NULL; + cairo_status_t status; + + if (surface->image) { + GdiFlush(); + + *image_out = (cairo_image_surface_t *) surface->image; + *image_extra = NULL; + *image_rect = surface->extents; + return CAIRO_STATUS_SUCCESS; + } + +- status = _cairo_win32_surface_get_subimage (abstract_surface, ++ if (surface->d3d9surface) { ++ cairo_image_surface_t *local = NULL; ++ status = _cairo_win32_surface_d3d9_lock_rect (abstract_surface, + interest_rect->x, + interest_rect->y, + interest_rect->width, +- interest_rect->height, +- &local); +- if (status) +- return status; +- +- *image_out = (cairo_image_surface_t *) local->image; +- *image_extra = local; ++ interest_rect->height, &local); ++ ++ if (status) ++ return status; ++ ++ *image_out = local; ++ *image_extra = surface; ++ } else { ++ cairo_win32_surface_t *local = NULL; ++ status = _cairo_win32_surface_get_subimage (abstract_surface, ++ interest_rect->x, ++ interest_rect->y, ++ interest_rect->width, ++ interest_rect->height, &local); ++ ++ if (status) ++ return status; ++ ++ *image_out = (cairo_image_surface_t *) local->image; ++ *image_extra = local; ++ } ++ // image_extra is always of type cairo_win32_surface_t. For d3d9surface it points ++ // to the original surface to get back the d3d9surface and properly unlock. ++ + *image_rect = *interest_rect; + return CAIRO_STATUS_SUCCESS; + } + + static void + _cairo_win32_surface_release_dest_image (void *abstract_surface, + cairo_rectangle_int_t *interest_rect, + cairo_image_surface_t *image, +@@ -689,29 +777,37 @@ static void + void *image_extra) + { + cairo_win32_surface_t *surface = abstract_surface; + cairo_win32_surface_t *local = image_extra; + + if (!local) + return; + +- /* clear any clip that's currently set on the surface +- so that we can blit uninhibited. */ +- _cairo_win32_surface_set_clip_region (surface, NULL); +- +- if (!BitBlt (surface->dc, +- image_rect->x, image_rect->y, +- image_rect->width, image_rect->height, +- local->dc, +- 0, 0, +- SRCCOPY)) +- _cairo_win32_print_gdi_error ("_cairo_win32_surface_release_dest_image"); +- +- cairo_surface_destroy ((cairo_surface_t *)local); ++ if (local->d3d9surface) { ++ IDirect3DSurface9_UnlockRect (local->d3d9surface); ++ IDirect3DSurface9_GetDC (local->d3d9surface, &local->dc); ++ cairo_surface_destroy ((cairo_surface_t *)image); ++ } else { ++ ++ /* clear any clip that's currently set on the surface ++ so that we can blit uninhibited. */ ++ _cairo_win32_surface_set_clip_region (surface, NULL); ++ ++ if (!BitBlt (surface->dc, ++ image_rect->x, image_rect->y, ++ image_rect->width, image_rect->height, ++ local->dc, ++ 0, 0, ++ SRCCOPY)) ++ _cairo_win32_print_gdi_error ("_cairo_win32_surface_release_dest_image"); ++ ++ cairo_surface_destroy ((cairo_surface_t *)local); ++ } ++ + } + + cairo_status_t + _cairo_win32_surface_set_clip_region (void *abstract_surface, + cairo_region_t *region) + { + cairo_win32_surface_t *surface = abstract_surface; + cairo_status_t status = CAIRO_STATUS_SUCCESS; +@@ -1849,16 +1945,17 @@ cairo_win32_surface_create_internal (HDC + free (surface); + return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); + } + + surface->clip_region = NULL; + surface->image = NULL; + surface->format = format; + ++ surface->d3d9surface = NULL; + surface->dc = hdc; + surface->bitmap = NULL; + surface->is_dib = FALSE; + surface->saved_dc_bitmap = NULL; + surface->brush = NULL; + surface->old_brush = NULL; + surface->font_subsets = NULL; + +@@ -2009,16 +2106,29 @@ cairo_win32_surface_create_with_ddb (HDC + + FINISH: + if (screen_dc) + ReleaseDC (NULL, screen_dc); + + return (cairo_surface_t*) new_surf; + } + ++cairo_public cairo_surface_t * ++cairo_win32_surface_create_with_d3dsurface9 (IDirect3DSurface9 *surface) ++{ ++ HDC dc; ++ cairo_win32_surface_t *win_surface; ++ ++ IDirect3DSurface9_AddRef (surface); ++ IDirect3DSurface9_GetDC (surface, &dc); ++ win_surface = cairo_win32_surface_create_internal(dc, CAIRO_FORMAT_RGB24); ++ win_surface->d3d9surface = surface; ++ return (cairo_surface_t*) win_surface; ++ ++} + /** + * _cairo_surface_is_win32: + * @surface: a #cairo_surface_t + * + * Checks if a surface is a win32 surface. This will + * return False if this is a win32 printing surface; use + * _cairo_surface_is_win32_printing() to check for that. + * +diff --git a/gfx/cairo/cairo/src/cairo-win32.h b/gfx/cairo/cairo/src/cairo-win32.h +--- a/gfx/cairo/cairo/src/cairo-win32.h ++++ b/gfx/cairo/cairo/src/cairo-win32.h +@@ -59,17 +59,16 @@ cairo_win32_surface_create_with_ddb (HDC hdc, + cairo_format_t format, + int width, + int height); + + cairo_public cairo_surface_t * + cairo_win32_surface_create_with_dib (cairo_format_t format, + int width, + int height); +- + cairo_public HDC + cairo_win32_surface_get_dc (cairo_surface_t *surface); + + cairo_public HDC + cairo_win32_get_dc_with_clip (cairo_t *cr); + + cairo_public cairo_surface_t * + cairo_win32_surface_get_image (cairo_surface_t *surface); +@@ -143,16 +142,21 @@ cairo_dwrite_scaled_font_get_force_GDI_classic(cairo_scaled_font_t *dwrite_scale + void + cairo_dwrite_set_cleartype_params(FLOAT gamma, FLOAT contrast, FLOAT level, int geometry, int mode); + + int + cairo_dwrite_get_cleartype_rendering_mode(); + + #endif /* CAIRO_HAS_DWRITE_FONT */ + ++struct IDirect3DSurface9; ++cairo_public cairo_surface_t * ++cairo_win32_surface_create_with_d3dsurface9 (struct IDirect3DSurface9 *surface); ++ ++ + #if CAIRO_HAS_D2D_SURFACE + + struct _cairo_device + { + int type; + int refcount; + }; + |