From 7eab865d9911abbccf07613ba8c76fb16131d6e4 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 26 Nov 2003 03:38:11 +0000 Subject: [PATCH] Use the handle deletion mechanism in wmfs. --- dlls/gdi/mfdrv/graphics.c | 6 +- dlls/gdi/mfdrv/init.c | 26 ++--- dlls/gdi/mfdrv/metafiledrv.h | 8 +- dlls/gdi/mfdrv/objects.c | 177 ++++++++++++++++++++++++++--------- 4 files changed, 154 insertions(+), 63 deletions(-) diff --git a/dlls/gdi/mfdrv/graphics.c b/dlls/gdi/mfdrv/graphics.c index bbfb3ae7ff4..4442c224d42 100644 --- a/dlls/gdi/mfdrv/graphics.c +++ b/dlls/gdi/mfdrv/graphics.c @@ -335,7 +335,7 @@ static INT16 MFDRV_CreateRegion(PHYSDEV dev, HRGN hrgn) WARN("MFDRV_WriteRecord failed\n"); return -1; } - return MFDRV_AddHandleDC( dev ); + return MFDRV_AddHandle( dev, hrgn ); } @@ -378,7 +378,7 @@ MFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush ) 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 @@ MFDRV_FrameRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush, INT x, INT y ) 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 ); } diff --git a/dlls/gdi/mfdrv/init.c b/dlls/gdi/mfdrv/init.c index 75e0e647fa7..35c5de1ebf8 100644 --- a/dlls/gdi/mfdrv/init.c +++ b/dlls/gdi/mfdrv/init.c @@ -48,7 +48,7 @@ static const DC_FUNCTIONS MFDRV_Funcs = NULL, /* pCreateDIBSection */ NULL, /* pDeleteBitmap */ NULL, /* pDeleteDC */ - NULL, /* pDeleteObject */ + MFDRV_DeleteObject, /* pDeleteObject */ NULL, /* pDescribePixelFormat */ NULL, /* pDeviceCapabilities */ MFDRV_Ellipse, /* pEllipse */ @@ -182,7 +182,10 @@ static DC *MFDRV_AllocMetaFile(void) 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 @@ static BOOL MFDRV_DeleteDC( PHYSDEV dev ) { 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 ); @@ -533,20 +541,6 @@ BOOL MFDRV_MetaParam8(PHYSDEV dev, short func, short param1, short param2, } -/****************************************************************** - * 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 */ diff --git a/dlls/gdi/mfdrv/metafiledrv.h b/dlls/gdi/mfdrv/metafiledrv.h index 28f61df1277..bb275521ae0 100644 --- a/dlls/gdi/mfdrv/metafiledrv.h +++ b/dlls/gdi/mfdrv/metafiledrv.h @@ -35,10 +35,13 @@ typedef struct 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 @@ extern BOOL MFDRV_MetaParam8(PHYSDEV dev, short func, short param1, short param2 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 @@ extern BOOL MFDRV_Chord( PHYSDEV dev, INT left, INT top, INT right, 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 ); diff --git a/dlls/gdi/mfdrv/objects.c b/dlls/gdi/mfdrv/objects.c index 89ce51cacb1..adcf7b4fb14 100644 --- a/dlls/gdi/mfdrv/objects.c +++ b/dlls/gdi/mfdrv/objects.c @@ -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 @@ HBITMAP MFDRV_SelectBitmap( PHYSDEV dev, HBITMAP hbitmap ) 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 @@ INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush ) 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 @@ INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush ) } 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 @@ done: */ 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 @@ static BOOL MFDRV_CreateFontIndirect(PHYSDEV dev, HFONT hFont, LOGFONT16 *logfon */ 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 @@ static BOOL MFDRV_CreatePenIndirect(PHYSDEV dev, HPEN hPen, LOGPEN16 *logpen) */ 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 @@ static BOOL MFDRV_CreatePalette(PHYSDEV dev, HPALETTE hPalette, LOGPALETTE* logP 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;