[cairo-commit] 3 commits - src/win32
Bryce Harrington
bryce at kemper.freedesktop.org
Tue Feb 6 23:13:10 UTC 2018
src/win32/cairo-win32-display-surface.c | 54 ++++++++++++++++++++++++++------
src/win32/cairo-win32-private.h | 28 +++++++++++++---
2 files changed, 67 insertions(+), 15 deletions(-)
New commits:
commit 62b724ac848aecbbb35a70c2f7d4685c6c2605f9
Author: Bryce Harrington <bryce at osg.samsung.com>
Date: Tue Feb 6 15:09:08 2018 -0800
win32: Fix a few typos in comments
diff --git a/src/win32/cairo-win32-private.h b/src/win32/cairo-win32-private.h
index 15be69200..e3e13d5b1 100644
--- a/src/win32/cairo-win32-private.h
+++ b/src/win32/cairo-win32-private.h
@@ -79,7 +79,7 @@ enum {
/* Whether we can use the CHECKJPEGFORMAT escape function */
CAIRO_WIN32_SURFACE_CAN_CHECK_JPEG = (1<<7),
- /* Whether we can use the CHECKJPEGFORMAT escape function */
+ /* Whether we can use the CHECKPNGFORMAT escape function */
CAIRO_WIN32_SURFACE_CAN_CHECK_PNG = (1<<8),
};
@@ -102,18 +102,18 @@ typedef struct _cairo_win32_surface {
cairo_rectangle_int_t extents;
/* Offset added to extents, used when the extents start with a negative
- * offset, which occur on Windows for, and only for, desktop DC. This
+ * offset, which can occur on Windows for, and only for, desktop DC. This
* occurs when you have multiple monitors, and at least one monitor
* extends to the left, or above, the primaty monitor. The primary
- * monitor on Windows always start with offset (0,0), and any other points
- * to the left, or above, have negative offset. So the 'desktop DC' is
+ * monitor on Windows always starts with offset (0,0), and any other points
+ * to the left, or above, have negative offsets. So the 'desktop DC' is
* in fact a 'virtual desktop' which can start with extents in the negative
* range.
*
* Why use new variables, and not the device transform? Simply because since
* the device transform functions are exposed, a lot of 3rd party libraries
* simply overwrite those, disregarding the prior content, instead of actually
- * adding the offset. GTK for example simply reset the device transform of the
+ * adding the offset. GTK for example simply resets the device transform of the
* desktop cairo surface to zero. So make some private member variables for
* this, which will not be fiddled with externally.
*/
@@ -125,7 +125,7 @@ typedef struct _cairo_win32_display_surface {
cairo_win32_surface_t win32;
/* We create off-screen surfaces as DIBs or DDBs, based on what we created
- * originally*/
+ * originally */
HBITMAP bitmap;
cairo_bool_t is_dib;
@@ -133,7 +133,7 @@ typedef struct _cairo_win32_display_surface {
* select back into the DC before deleting the DC and our
* bitmap. For Windows XP, this doesn't seem to be necessary
* ... we can just delete the DC and that automatically unselects
- * out bitmap. But it's standard practice so apparently is needed
+ * our bitmap. But it's standard practice so apparently is needed
* on some versions of Windows.
*/
HBITMAP saved_dc_bitmap;
commit dbe3d9ea517da51e6be5a19d87f2d02176f0ba00
Author: Bryce Harrington <bryce at osg.samsung.com>
Date: Tue Feb 6 15:08:17 2018 -0800
win32: Whitespace cleanup
diff --git a/src/win32/cairo-win32-display-surface.c b/src/win32/cairo-win32-display-surface.c
index 1e3e05981..ccfad10dd 100644
--- a/src/win32/cairo-win32-display-surface.c
+++ b/src/win32/cairo-win32-display-surface.c
@@ -214,10 +214,10 @@ _create_dc_and_bitmap (cairo_win32_display_surface_t *surface,
goto FAIL;
surface->bitmap = CreateDIBSection (surface->win32.dc,
- bitmap_info,
- DIB_RGB_COLORS,
- &bits,
- NULL, 0);
+ bitmap_info,
+ DIB_RGB_COLORS,
+ &bits,
+ NULL, 0);
if (!surface->bitmap)
goto FAIL;
@@ -289,8 +289,8 @@ _create_dc_and_bitmap (cairo_win32_display_surface_t *surface,
static cairo_surface_t *
_cairo_win32_display_surface_create_for_dc (HDC original_dc,
cairo_format_t format,
- int width,
- int height)
+ int width,
+ int height)
{
cairo_status_t status;
cairo_device_t *device;
@@ -325,7 +325,7 @@ _cairo_win32_display_surface_create_for_dc (HDC original_dc,
surface->win32.extents.y = 0;
surface->win32.extents.width = width;
surface->win32.extents.height = height;
- surface->win32.x_ofs = 0;
+ surface->win32.x_ofs = 0;
surface->win32.y_ofs = 0;
surface->initial_clip_rgn = NULL;
@@ -634,26 +634,26 @@ _cairo_win32_save_initial_clip (HDC hdc, cairo_win32_display_surface_t *surface)
surface->win32.extents.height = rect.bottom - rect.top;
/* On multi-monitor setup, under Windows, the primary monitor always
- * have origin (0,0). Any monitors that extends to the left or above
+ * have origin (0,0). Any monitors that extends to the left or above
* will have coordinates in the negative range. Take this into
- * account, by forcing our Win32 surface to start at extent (0,0) and
- * using a device offset. Cairo does not handle extents with negative
+ * account, by forcing our Win32 surface to start at extent (0,0) and
+ * using a device offset. Cairo does not handle extents with negative
* offsets.
- */
+ */
surface->win32.x_ofs = 0;
surface->win32.y_ofs = 0;
if ((surface->win32.extents.x < 0) ||
(surface->win32.extents.y < 0)) {
/* Negative offsets occurs for (and ONLY for) the desktop DC (virtual
- * desktop), when a monitor extend to the left or above the primary
- * monitor.
- *
- * More info @ https://www.microsoft.com/msj/0697/monitor/monitor.aspx
- *
- * Note that any other DC, including memory DC created with
+ * desktop), when a monitor extend to the left or above the primary
+ * monitor.
+ *
+ * More info @ https://www.microsoft.com/msj/0697/monitor/monitor.aspx
+ *
+ * Note that any other DC, including memory DC created with
* CreateCompatibleDC(<virtual desktop DC>) will have extents in the
- * positive range. This will be taken into account later when we perform
- * raster operations between the DC (may have to perform offset
+ * positive range. This will be taken into account later when we perform
+ * raster operations between the DC (may have to perform offset
* translation).
*/
surface->win32.x_ofs = surface->win32.extents.x;
diff --git a/src/win32/cairo-win32-private.h b/src/win32/cairo-win32-private.h
index 87ef38521..15be69200 100644
--- a/src/win32/cairo-win32-private.h
+++ b/src/win32/cairo-win32-private.h
@@ -102,20 +102,20 @@ typedef struct _cairo_win32_surface {
cairo_rectangle_int_t extents;
/* Offset added to extents, used when the extents start with a negative
- * offset, which occur on Windows for, and only for, desktop DC. This
- * occurs when you have multiple monitors, and at least one monitor
- * extends to the left, or above, the primaty monitor. The primary
- * monitor on Windows always start with offset (0,0), and any other points
- * to the left, or above, have negative offset. So the 'desktop DC' is
- * in fact a 'virtual desktop' which can start with extents in the negative
- * range.
- *
- * Why use new variables, and not the device transform? Simply because since
- * the device transform functions are exposed, a lot of 3rd party libraries
- * simply overwrite those, disregarding the prior content, instead of actually
- * adding the offset. GTK for example simply reset the device transform of the
- * desktop cairo surface to zero. So make some private member variables for
- * this, which will not be fiddled with externally.
+ * offset, which occur on Windows for, and only for, desktop DC. This
+ * occurs when you have multiple monitors, and at least one monitor
+ * extends to the left, or above, the primaty monitor. The primary
+ * monitor on Windows always start with offset (0,0), and any other points
+ * to the left, or above, have negative offset. So the 'desktop DC' is
+ * in fact a 'virtual desktop' which can start with extents in the negative
+ * range.
+ *
+ * Why use new variables, and not the device transform? Simply because since
+ * the device transform functions are exposed, a lot of 3rd party libraries
+ * simply overwrite those, disregarding the prior content, instead of actually
+ * adding the offset. GTK for example simply reset the device transform of the
+ * desktop cairo surface to zero. So make some private member variables for
+ * this, which will not be fiddled with externally.
*/
int x_ofs, y_ofs;
} cairo_win32_surface_t;
@@ -200,7 +200,7 @@ cairo_private void
_cairo_win32_display_surface_discard_fallback (cairo_win32_display_surface_t *surface);
cairo_bool_t
-_cairo_win32_surface_get_extents (void *abstract_surface,
+_cairo_win32_surface_get_extents (void *abstract_surface,
cairo_rectangle_int_t *rectangle);
uint32_t
@@ -216,7 +216,7 @@ _cairo_win32_surface_emit_glyphs (cairo_win32_surface_t *dst,
static inline void
_cairo_matrix_to_win32_xform (const cairo_matrix_t *m,
- XFORM *xform)
+ XFORM *xform)
{
xform->eM11 = (FLOAT) m->xx;
xform->eM21 = (FLOAT) m->xy;
commit 4d07b57c168b88019a5510eaa7e9467149c53f12
Author: Eric Hoffman <ehoffman at videotron.ca>
Date: Wed Apr 26 04:22:25 2017 +0000
win32: Fix multi-monitor virtual desktop with negative monitor coords
Under Win32, when you have a multiple-monitor setup, Windows creates a
'virtual desktop', which is a rectangle surface that extends across all
monitors.
The primary monitor always starts with the top-left corner at coordinate
(0,0). If you have any other monitors which extend to the left or
above the primary monitor, the virtual desktop's top-left corner will
actually have coordinates which are negative.
This creates an issue in Cairo with the desktop DC, i.e. when you use a
DC from the function GetDC(NULL). The same thing can occur with other
third party libraries like GTK, when you access the Cairo surface from
the root window.
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=100793
Reviewed-by: Bryce Harrington <bryce at osg.samsung.com>
diff --git a/src/win32/cairo-win32-display-surface.c b/src/win32/cairo-win32-display-surface.c
index 92d1f6ce4..1e3e05981 100644
--- a/src/win32/cairo-win32-display-surface.c
+++ b/src/win32/cairo-win32-display-surface.c
@@ -325,6 +325,8 @@ _cairo_win32_display_surface_create_for_dc (HDC original_dc,
surface->win32.extents.y = 0;
surface->win32.extents.width = width;
surface->win32.extents.height = height;
+ surface->win32.x_ofs = 0;
+ surface->win32.y_ofs = 0;
surface->initial_clip_rgn = NULL;
surface->had_simple_clip = FALSE;
@@ -466,7 +468,8 @@ _cairo_win32_display_surface_map_to_image (void *abstract_sur
surface->win32.extents.width,
surface->win32.extents.height,
surface->win32.dc,
- surface->win32.extents.x, surface->win32.extents.y,
+ surface->win32.extents.x + surface->win32.x_ofs, /* Handling multi-monitor... */
+ surface->win32.extents.y + surface->win32.y_ofs, /* ... setup on Win32 */
SRCCOPY)) {
status = _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
goto err;
@@ -544,11 +547,12 @@ _cairo_win32_display_surface_flush (void *abstract_surface, unsigned flags)
if (damage->status) {
if (!BitBlt (surface->win32.dc,
- 0, 0,
+ surface->win32.extents.x + surface->win32.x_ofs, /* Handling multi-monitor... */
+ surface->win32.extents.y + surface->win32.y_ofs, /* ... setup on Win32 */
surface->win32.extents.width,
surface->win32.extents.height,
fallback->win32.dc,
- 0, 0,
+ surface->win32.extents.x, surface->win32.extents.y,
SRCCOPY))
status = _cairo_win32_print_gdi_error (__FUNCTION__);
} else if (damage->region) {
@@ -561,7 +565,8 @@ _cairo_win32_display_surface_flush (void *abstract_surface, unsigned flags)
rect.x, rect.y,
rect.width, rect.height));
if (!BitBlt (surface->win32.dc,
- rect.x, rect.y,
+ rect.x + surface->win32.x_ofs, /* Handling multi-monitor... */
+ rect.y + surface->win32.y_ofs, /* ... setup on Win32 */
rect.width, rect.height,
fallback->win32.dc,
rect.x, rect.y,
@@ -628,6 +633,35 @@ _cairo_win32_save_initial_clip (HDC hdc, cairo_win32_display_surface_t *surface)
surface->win32.extents.width = rect.right - rect.left;
surface->win32.extents.height = rect.bottom - rect.top;
+ /* On multi-monitor setup, under Windows, the primary monitor always
+ * have origin (0,0). Any monitors that extends to the left or above
+ * will have coordinates in the negative range. Take this into
+ * account, by forcing our Win32 surface to start at extent (0,0) and
+ * using a device offset. Cairo does not handle extents with negative
+ * offsets.
+ */
+ surface->win32.x_ofs = 0;
+ surface->win32.y_ofs = 0;
+ if ((surface->win32.extents.x < 0) ||
+ (surface->win32.extents.y < 0)) {
+ /* Negative offsets occurs for (and ONLY for) the desktop DC (virtual
+ * desktop), when a monitor extend to the left or above the primary
+ * monitor.
+ *
+ * More info @ https://www.microsoft.com/msj/0697/monitor/monitor.aspx
+ *
+ * Note that any other DC, including memory DC created with
+ * CreateCompatibleDC(<virtual desktop DC>) will have extents in the
+ * positive range. This will be taken into account later when we perform
+ * raster operations between the DC (may have to perform offset
+ * translation).
+ */
+ surface->win32.x_ofs = surface->win32.extents.x;
+ surface->win32.y_ofs = surface->win32.extents.y;
+ surface->win32.extents.x = 0;
+ surface->win32.extents.y = 0;
+ }
+
surface->initial_clip_rgn = NULL;
surface->had_simple_clip = FALSE;
diff --git a/src/win32/cairo-win32-private.h b/src/win32/cairo-win32-private.h
index 6fdf96f87..87ef38521 100644
--- a/src/win32/cairo-win32-private.h
+++ b/src/win32/cairo-win32-private.h
@@ -100,6 +100,24 @@ typedef struct _cairo_win32_surface {
* that match bounds of the clipped region.
*/
cairo_rectangle_int_t extents;
+
+ /* Offset added to extents, used when the extents start with a negative
+ * offset, which occur on Windows for, and only for, desktop DC. This
+ * occurs when you have multiple monitors, and at least one monitor
+ * extends to the left, or above, the primaty monitor. The primary
+ * monitor on Windows always start with offset (0,0), and any other points
+ * to the left, or above, have negative offset. So the 'desktop DC' is
+ * in fact a 'virtual desktop' which can start with extents in the negative
+ * range.
+ *
+ * Why use new variables, and not the device transform? Simply because since
+ * the device transform functions are exposed, a lot of 3rd party libraries
+ * simply overwrite those, disregarding the prior content, instead of actually
+ * adding the offset. GTK for example simply reset the device transform of the
+ * desktop cairo surface to zero. So make some private member variables for
+ * this, which will not be fiddled with externally.
+ */
+ int x_ofs, y_ofs;
} cairo_win32_surface_t;
#define to_win32_surface(S) ((cairo_win32_surface_t *)(S))
More information about the cairo-commit
mailing list