Make EnumEnhMetaFile work.

This commit is contained in:
Dmitry Timoshkov 2000-10-24 01:37:49 +00:00 committed by Alexandre Julliard
parent 1fc70a94c5
commit ff59c33d49

View file

@ -1207,25 +1207,51 @@ BOOL WINAPI EnumEnhMetaFile(
const RECT *lpRect /* bounding rectangle for rendered metafile */ const RECT *lpRect /* bounding rectangle for rendered metafile */
) )
{ {
BOOL ret = TRUE; BOOL ret;
LPENHMETAHEADER emh = EMF_GetEnhMetaHeader(hmf); ENHMETAHEADER *emh, *emhTemp;
INT count, i; ENHMETARECORD *emr;
DWORD offset;
INT i;
HANDLETABLE *ht; HANDLETABLE *ht;
INT savedMode = 0; INT savedMode = 0;
FLOAT xSrcPixSize, ySrcPixSize, xscale, yscale; FLOAT xSrcPixSize, ySrcPixSize, xscale, yscale;
XFORM savedXform, xform; XFORM savedXform, xform;
HPEN hPen;
HBRUSH hBrush;
HFONT hFont;
if(!lpRect)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
emh = EMF_GetEnhMetaHeader(hmf);
if(!emh) { if(!emh) {
SetLastError(ERROR_INVALID_HANDLE); SetLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
if(!lpRect) {
SetLastError(ERROR_INVALID_PARAMETER); /* Copy the metafile into memory, because we need to avoid deadlock. */
emhTemp = HeapAlloc(GetProcessHeap(), 0, emh->nSize + emh->nBytes);
if(!emhTemp)
{
EMF_ReleaseEnhMetaHeader(hmf);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE; return FALSE;
} }
count = emh->nHandles; memcpy(emhTemp, emh, emh->nSize + emh->nBytes);
emh = emhTemp;
EMF_ReleaseEnhMetaHeader(hmf);
ht = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, ht = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(HANDLETABLE) * count ); sizeof(HANDLETABLE) * emh->nHandles );
if(!ht)
{
HeapFree(GetProcessHeap(), 0, emhTemp);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
ht->objectHandle[0] = hmf; ht->objectHandle[0] = hmf;
xSrcPixSize = (FLOAT) emh->szlMillimeters.cx / emh->szlDevice.cx; xSrcPixSize = (FLOAT) emh->szlMillimeters.cx / emh->szlDevice.cx;
@ -1250,18 +1276,39 @@ BOOL WINAPI EnumEnhMetaFile(
ERR("World transform failed!\n"); ERR("World transform failed!\n");
} }
while (ret) { /* save the current pen, brush and font */
ret = (*callback)(hdc, ht, (LPENHMETARECORD) emh, count, data); hPen = GetCurrentObject(hdc, OBJ_PEN);
if (emh->iType == EMR_EOF) break; hBrush = GetCurrentObject(hdc, OBJ_BRUSH);
emh = (LPENHMETAHEADER) ((char *) emh + emh->nSize); hFont = GetCurrentObject(hdc, OBJ_FONT);
TRACE("nSize = %ld, nBytes = %ld, nHandles = %d, nRecords = %ld, nPalEntries = %ld\n",
emh->nSize, emh->nBytes, emh->nHandles, emh->nRecords, emh->nPalEntries);
ret = TRUE;
offset = 0;
while(ret && offset < emh->nBytes)
{
emr = (ENHMETARECORD *)((char *)emh + offset);
TRACE("Calling EnumFunc with record type %ld, size %ld\n", emr->iType, emr->nSize);
ret = (*callback)(hdc, ht, emr, emh->nRecords, data);
offset += emr->nSize;
} }
for(i = 1; i < count; i++) /* Don't delete element 0 (hmf) */
/* restore pen, brush and font */
SelectObject(hdc, hBrush);
SelectObject(hdc, hPen);
SelectObject(hdc, hFont);
for(i = 1; i < emh->nRecords; i++) /* Don't delete element 0 (hmf) */
if( (ht->objectHandle)[i] ) if( (ht->objectHandle)[i] )
DeleteObject( (ht->objectHandle)[i] ); DeleteObject( (ht->objectHandle)[i] );
HeapFree( GetProcessHeap(), 0, ht ); HeapFree( GetProcessHeap(), 0, ht );
EMF_ReleaseEnhMetaHeader(hmf); HeapFree(GetProcessHeap(), 0, emhTemp);
SetWorldTransform(hdc, &savedXform); SetWorldTransform(hdc, &savedXform);
if (savedMode) SetGraphicsMode(hdc, savedMode); if (savedMode) SetGraphicsMode(hdc, savedMode);
return ret; return ret;
} }