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