ENHMETAFILE: write EMRPOLYLINE16 if points fit into a SHORT

Mike McCormack mike at codeweavers.com
Mon Mar 29 10:22:42 CST 2004


The EMRPOLYLINE16 is not part of the 16 bit interface... it is a way to 
save space in an enhanced metafile.

Windows 2000 generates an EMRPOLYLINE16 record if it sees that all the 
points in a Polyline can fit into SHORT ints, and generates an 
EMRPOLYLINE record if not.

Mike


ChangeLog:
* write EMRPOLYLINE16 if points fit into a SHORT
-------------- next part --------------
Index: dlls/gdi/enhmfdrv/graphics.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/enhmfdrv/graphics.c,v
retrieving revision 1.12
diff -u -r1.12 graphics.c
--- dlls/gdi/enhmfdrv/graphics.c	11 Mar 2004 00:37:46 -0000	1.12
+++ dlls/gdi/enhmfdrv/graphics.c	29 Mar 2004 15:29:33 -0000
@@ -385,11 +385,70 @@
 
 
 /**********************************************************************
+ *          EMFDRV_Polylinegon16
+ *
+ * Helper for EMFDRV_Poly{line|gon}
+ *
+ *  This is not a legacy function!
+ *  We are using SHORT integers to save space.
+ */
+static BOOL
+EMFDRV_Polylinegon16( PHYSDEV dev, const POINT* pt, INT count, DWORD iType )
+{
+    EMRPOLYLINE16 *emr;
+    DWORD size;
+    INT i;
+    BOOL ret;
+
+    /* check whether all points fit in the SHORT int POINT structure */
+    for(i = 0; i < count; i++) {
+        if( ((pt[i].x+0x8000) & ~0xffff ) || 
+            ((pt[i].y+0x8000) & ~0xffff ) )
+            return FALSE;
+    }
+
+    size = sizeof(EMRPOLYLINE16) + sizeof(POINTS) * (count - 1);
+
+    emr = HeapAlloc( GetProcessHeap(), 0, size );
+    emr->emr.iType = iType;
+    emr->emr.nSize = size;
+
+    emr->rclBounds.left = emr->rclBounds.right = pt[0].x;
+    emr->rclBounds.top = emr->rclBounds.bottom = pt[0].y;
+
+    for(i = 1; i < count; i++) {
+        if(pt[i].x < emr->rclBounds.left)
+	    emr->rclBounds.left = pt[i].x;
+	else if(pt[i].x > emr->rclBounds.right)
+	    emr->rclBounds.right = pt[i].x;
+	if(pt[i].y < emr->rclBounds.top)
+	    emr->rclBounds.top = pt[i].y;
+	else if(pt[i].y > emr->rclBounds.bottom)
+	    emr->rclBounds.bottom = pt[i].y;
+    }
+
+    emr->cpts = count;
+    for(i = 0; i < count; i++ ) {
+        emr->apts[i].x = pt[i].x;
+        emr->apts[i].y = pt[i].y;
+    }
+
+    ret = EMFDRV_WriteRecord( dev, &emr->emr );
+    if(ret)
+        EMFDRV_UpdateBBox( dev, &emr->rclBounds );
+    HeapFree( GetProcessHeap(), 0, emr );
+    return ret;
+}
+
+
+/**********************************************************************
  *          EMFDRV_Polyline
  */
 BOOL
 EMFDRV_Polyline( PHYSDEV dev, const POINT* pt, INT count )
 {
+    if( EMFDRV_Polylinegon16( dev, pt, count, EMR_POLYLINE16 ) )
+        return TRUE;
     return EMFDRV_Polylinegon( dev, pt, count, EMR_POLYLINE );
 }
 


More information about the wine-patches mailing list