mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 18:08:58 +00:00
466 lines
15 KiB
Diff
466 lines
15 KiB
Diff
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;
|
|
};
|
|
|