[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