wmf: handle deletion

Huw D M Davies h.davies1 at physics.ox.ac.uk
Tue Nov 25 11:24:10 CST 2003


        Mike McCormack <mike at codeweavers.com>
        Use the handle deletion mechanism in wmfs
-- 
Huw Davies
huw at codeweavers.com
Index: dlls/gdi/mfdrv/graphics.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/mfdrv/graphics.c,v
retrieving revision 1.7
diff -u -r1.7 graphics.c
--- dlls/gdi/mfdrv/graphics.c	12 May 2003 03:27:24 -0000	1.7
+++ dlls/gdi/mfdrv/graphics.c	25 Nov 2003 17:19:19 -0000
@@ -335,7 +335,7 @@
         WARN("MFDRV_WriteRecord failed\n");
 	return -1;
     }
-    return MFDRV_AddHandleDC( dev );
+    return MFDRV_AddHandle( dev, hrgn );
 }
 
 
@@ -378,7 +378,7 @@
     if(iRgn == -1)
         return FALSE;
     iBrush = MFDRV_CreateBrushIndirect( dev, hbrush );
-    if(iBrush == -1)
+    if(!iBrush)
         return FALSE;
     return MFDRV_MetaParam2( dev, META_FILLREGION, iRgn, iBrush );
 }
@@ -394,7 +394,7 @@
     if(iRgn == -1)
         return FALSE;
     iBrush = MFDRV_CreateBrushIndirect( dev, hbrush );
-    if(iBrush == -1)
+    if(!iBrush)
         return FALSE;
     return MFDRV_MetaParam4( dev, META_FRAMEREGION, iRgn, iBrush, x, y );
 }
Index: dlls/gdi/mfdrv/init.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/mfdrv/init.c,v
retrieving revision 1.27
diff -u -r1.27 init.c
--- dlls/gdi/mfdrv/init.c	25 Nov 2003 05:03:09 -0000	1.27
+++ dlls/gdi/mfdrv/init.c	25 Nov 2003 17:19:19 -0000
@@ -48,7 +48,7 @@
     NULL,                            /* pCreateDIBSection */
     NULL,                            /* pDeleteBitmap */
     NULL,                            /* pDeleteDC */
-    NULL,                            /* pDeleteObject */
+    MFDRV_DeleteObject,              /* pDeleteObject */
     NULL,                            /* pDescribePixelFormat */
     NULL,                            /* pDeviceCapabilities */
     MFDRV_Ellipse,                   /* pEllipse */
@@ -182,7 +182,10 @@
         return NULL;
     }
 
-    physDev->nextHandle = 0;
+    physDev->handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HANDLE_LIST_INC * sizeof(physDev->handles[0]));
+    physDev->handles_size = HANDLE_LIST_INC;
+    physDev->cur_handles = 0;
+
     physDev->hFile = 0;
 
     physDev->mh->mtHeaderSize   = sizeof(METAHEADER) / sizeof(WORD);
@@ -203,8 +206,13 @@
 {
     METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
     DC *dc = physDev->dc;
+    DWORD index;
 
     if (physDev->mh) HeapFree( GetProcessHeap(), 0, physDev->mh );
+    for(index = 0; index < physDev->handles_size; index++)
+        if(physDev->handles[index])
+            GDI_hdc_not_using_object(physDev->handles[index], physDev->hdc);
+    HeapFree( GetProcessHeap(), 0, physDev->handles );
     HeapFree( GetProcessHeap(), 0, physDev );
     dc->physDev = NULL;
     GDI_FreeObject( dc->hSelf, dc );
@@ -532,20 +540,6 @@
     return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
 }
 
-
-/******************************************************************
- *         MFDRV_AddHandleDC
- *
- * Note: this function assumes that we never delete objects.
- * If we do someday, we'll need to maintain a table to re-use deleted
- * handles.
- */
-int MFDRV_AddHandleDC( PHYSDEV dev )
-{
-    METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
-    physDev->mh->mtNoObjects++;
-    return physDev->nextHandle++;
-}
 
 /**********************************************************************
  *           MFDRV_ExtEscape
Index: dlls/gdi/mfdrv/metafiledrv.h
===================================================================
RCS file: /home/wine/wine/dlls/gdi/mfdrv/metafiledrv.h,v
retrieving revision 1.10
diff -u -r1.10 metafiledrv.h
--- dlls/gdi/mfdrv/metafiledrv.h	5 Sep 2003 23:08:38 -0000	1.10
+++ dlls/gdi/mfdrv/metafiledrv.h	25 Nov 2003 17:19:19 -0000
@@ -35,10 +35,13 @@
     HDC          hdc;
     DC          *dc;
     METAHEADER  *mh;           /* Pointer to metafile header */
-    UINT       nextHandle;     /* Next handle number */
+    UINT       handles_size, cur_handles;
+    HGDIOBJ   *handles;
     HANDLE     hFile;          /* Handle for disk based MetaFile */
 } METAFILEDRV_PDEVICE;
 
+#define HANDLE_LIST_INC 20
+
 
 extern BOOL MFDRV_MetaParam0(PHYSDEV dev, short func);
 extern BOOL MFDRV_MetaParam1(PHYSDEV dev, short func, short param1);
@@ -52,7 +55,7 @@
                              short param3, short param4, short param5,
                              short param6, short param7, short param8);
 extern BOOL MFDRV_WriteRecord(PHYSDEV dev, METARECORD *mr, DWORD rlen);
-extern int MFDRV_AddHandleDC( PHYSDEV dev );
+extern UINT MFDRV_AddHandle( PHYSDEV dev, HGDIOBJ obj );
 extern INT16 MFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush );
 
 /* Metafile driver functions */
@@ -68,6 +71,7 @@
                          INT bottom, INT xstart, INT ystart, INT xend,
                          INT yend );
 extern BOOL MFDRV_CloseFigure( PHYSDEV dev );
+extern BOOL MFDRV_DeleteObject( PHYSDEV dev, HGDIOBJ obj );
 extern BOOL MFDRV_Ellipse( PHYSDEV dev, INT left, INT top,
                            INT right, INT bottom );
 extern BOOL MFDRV_EndPath( PHYSDEV dev );
Index: dlls/gdi/mfdrv/objects.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/mfdrv/objects.c,v
retrieving revision 1.8
diff -u -r1.8 objects.c
--- dlls/gdi/mfdrv/objects.c	30 Aug 2003 00:15:12 -0000	1.8
+++ dlls/gdi/mfdrv/objects.c	25 Nov 2003 17:19:19 -0000
@@ -29,6 +29,89 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(metafile);
 
+/******************************************************************
+ *         MFDRV_AddHandle
+ */
+UINT MFDRV_AddHandle( PHYSDEV dev, HGDIOBJ obj )
+{
+    METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
+    INT16 index;
+
+    for(index = 0; index < physDev->handles_size; index++)
+        if(physDev->handles[index] == 0) break; 
+    if(index == physDev->handles_size) {
+        physDev->handles_size += HANDLE_LIST_INC;
+        physDev->handles = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                       physDev->handles,
+                                       physDev->handles_size * sizeof(physDev->handles[0]));
+    }
+    physDev->handles[index] = obj;
+
+    physDev->cur_handles++; 
+    if(physDev->cur_handles > physDev->mh->mtNoObjects)
+        physDev->mh->mtNoObjects++;
+
+    return index ; /* index 0 is not reserved for metafiles */
+}
+
+/******************************************************************
+ *         MFDRV_FindObject
+ */
+static INT16 MFDRV_FindObject( PHYSDEV dev, HGDIOBJ obj )
+{
+    METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
+    INT16 index;
+
+    for(index = 0; index < physDev->handles_size; index++)
+        if(physDev->handles[index] == obj) break;
+
+    if(index == physDev->handles_size) return -1;
+
+    return index ;
+}
+
+
+/******************************************************************
+ *         MFDRV_DeleteObject
+ */
+BOOL MFDRV_DeleteObject( PHYSDEV dev, HGDIOBJ obj )
+{   
+    METARECORD mr;
+    METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
+    INT16 index;
+    BOOL ret = TRUE;
+
+    index = MFDRV_FindObject(dev, obj);
+    if( index < 0 )
+        return 0;
+
+    mr.rdSize = sizeof mr / 2;
+    mr.rdFunction = META_DELETEOBJECT;
+    mr.rdParm[0] = index;
+
+    if(!MFDRV_WriteRecord( dev, &mr, mr.rdSize*2 ))
+        ret = FALSE;
+
+    physDev->handles[index] = 0;
+    physDev->cur_handles--;
+    return ret;
+}
+
+
+/***********************************************************************
+ *           MFDRV_SelectObject
+ */
+static BOOL MFDRV_SelectObject( PHYSDEV dev, INT16 index)
+{
+    METARECORD mr;
+
+    mr.rdSize = sizeof mr / 2;
+    mr.rdFunction = META_SELECTOBJECT;
+    mr.rdParm[0] = index;
+
+    return MFDRV_WriteRecord( dev, &mr, mr.rdSize*2 );
+}
+
 
 /***********************************************************************
  *           MFDRV_SelectBitmap
@@ -45,11 +128,11 @@
 
 INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush )
 {
-    INT16 index = -1;
     DWORD size;
     METARECORD *mr;
     LOGBRUSH logbrush;
     METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
+    BOOL r;
 
     if (!GetObjectA( hBrush, sizeof(logbrush), &logbrush )) return -1;
 
@@ -68,7 +151,7 @@
 	    mr = HeapAlloc( GetProcessHeap(), 0, size );
 	    mr->rdSize = size / 2;
 	    mr->rdFunction = META_CREATEBRUSHINDIRECT;
-        memcpy( mr->rdParm, &lb16, sizeof(LOGBRUSH16));
+	    memcpy( mr->rdParm, &lb16, sizeof(LOGBRUSH16));
 	    break;
 	}
     case BS_PATTERN:
@@ -136,14 +219,14 @@
 	}
 	default:
 	    FIXME("Unkonwn brush style %x\n", logbrush.lbStyle);
-	    return -1;
+	    return 0;
     }
-    index = MFDRV_AddHandleDC( dev );
-    if(!MFDRV_WriteRecord( dev, mr, mr->rdSize * 2))
-        index = -1;
+    r = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
     HeapFree(GetProcessHeap(), 0, mr);
+    if( !r )
+        return -1;
 done:
-    return index;
+    return MFDRV_AddHandle( dev, hBrush );
 }
 
 
@@ -152,39 +235,35 @@
  */
 HBRUSH MFDRV_SelectBrush( PHYSDEV dev, HBRUSH hbrush )
 {
+    METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
     INT16 index;
-    METARECORD mr;
 
-    index = MFDRV_CreateBrushIndirect( dev, hbrush );
-    if(index == -1) return 0;
-
-    mr.rdSize = sizeof(mr) / 2;
-    mr.rdFunction = META_SELECTOBJECT;
-    mr.rdParm[0] = index;
-    return MFDRV_WriteRecord( dev, &mr, mr.rdSize * 2) ? hbrush : 0;
+    index = MFDRV_FindObject(dev, hbrush);
+    if( index < 0 )
+    {
+        index = MFDRV_CreateBrushIndirect( dev, hbrush );
+        if( index < 0 )
+            return 0;
+        GDI_hdc_using_object(hbrush, physDev->hdc);
+    }
+    return MFDRV_SelectObject( dev, index ) ? hbrush : HGDI_ERROR;
 }
 
 /******************************************************************
  *         MFDRV_CreateFontIndirect
  */
 
-static BOOL MFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont, LOGFONT16 *logfont)
+static UINT16 MFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont, LOGFONT16 *logfont)
 {
-    int index;
     char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT16)];
     METARECORD *mr = (METARECORD *)&buffer;
 
     mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT16) - 2) / 2;
     mr->rdFunction = META_CREATEFONTINDIRECT;
     memcpy(&(mr->rdParm), logfont, sizeof(LOGFONT16));
-    if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * 2))) return FALSE;
-
-    mr->rdSize = sizeof(METARECORD) / 2;
-    mr->rdFunction = META_SELECTOBJECT;
-
-    if ((index = MFDRV_AddHandleDC( dev )) == -1) return FALSE;
-    *(mr->rdParm) = index;
-    return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
+    if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * 2)))
+        return 0;
+    return MFDRV_AddHandle( dev, hFont );
 }
 
 
@@ -193,33 +272,37 @@
  */
 HFONT MFDRV_SelectFont( PHYSDEV dev, HFONT hfont )
 {
+    METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
     LOGFONT16 lf16;
+    INT16 index;
 
-    if (!GetObject16( HFONT_16(hfont), sizeof(lf16), &lf16 )) return HGDI_ERROR;
-    if (MFDRV_CreateFontIndirect(dev, hfont, &lf16)) return 0;
-    return HGDI_ERROR;
+    index = MFDRV_FindObject(dev, hfont);
+    if( index < 0 )
+    {
+        if (!GetObject16( HFONT_16(hfont), sizeof(lf16), &lf16 ))
+            return HGDI_ERROR;
+        index = MFDRV_CreateFontIndirect(dev, hfont, &lf16);
+        if( index < 0 )
+            return HGDI_ERROR;
+        GDI_hdc_using_object(hfont, physDev->hdc);
+    }
+    return MFDRV_SelectObject( dev, index ) ? hfont : HGDI_ERROR;
 }
 
 /******************************************************************
  *         MFDRV_CreatePenIndirect
  */
-static BOOL MFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen, LOGPEN16 *logpen)
+static UINT16 MFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen, LOGPEN16 *logpen)
 {
-    int index;
     char buffer[sizeof(METARECORD) - 2 + sizeof(*logpen)];
     METARECORD *mr = (METARECORD *)&buffer;
 
     mr->rdSize = (sizeof(METARECORD) + sizeof(*logpen) - 2) / 2;
     mr->rdFunction = META_CREATEPENINDIRECT;
     memcpy(&(mr->rdParm), logpen, sizeof(*logpen));
-    if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * 2))) return FALSE;
-
-    mr->rdSize = sizeof(METARECORD) / 2;
-    mr->rdFunction = META_SELECTOBJECT;
-
-    if ((index = MFDRV_AddHandleDC( dev )) == -1) return FALSE;
-    *(mr->rdParm) = index;
-    return MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
+    if (!(MFDRV_WriteRecord( dev, mr, mr->rdSize * 2)))
+        return 0;
+    return MFDRV_AddHandle( dev, hPen );
 }
 
 
@@ -228,11 +311,21 @@
  */
 HPEN MFDRV_SelectPen( PHYSDEV dev, HPEN hpen )
 {
+    METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
     LOGPEN16 logpen;
+    INT16 index;
 
-    if (!GetObject16( HPEN_16(hpen), sizeof(logpen), &logpen )) return 0;
-    if (MFDRV_CreatePenIndirect( dev, hpen, &logpen )) return hpen;
-    return 0;
+    index = MFDRV_FindObject(dev, hpen);
+    if( index < 0 )
+    {
+        if (!GetObject16( HPEN_16(hpen), sizeof(logpen), &logpen ))
+            return 0;
+        index = MFDRV_CreatePenIndirect( dev, hpen, &logpen );
+        if( index < 0 )
+            return 0;
+        GDI_hdc_using_object(hpen, physDev->hdc);
+    }
+    return MFDRV_SelectObject( dev, index ) ? hpen : HGDI_ERROR;
 }
 
 
@@ -258,7 +351,7 @@
     mr->rdSize = sizeof(METARECORD) / sizeof(WORD);
     mr->rdFunction = META_SELECTPALETTE;
 
-    if ((index = MFDRV_AddHandleDC( dev )) == -1) ret = FALSE;
+    if ((index = MFDRV_AddHandle( dev, hPalette )) == -1) ret = FALSE;
     else
     {
         *(mr->rdParm) = index;



More information about the wine-patches mailing list