Fixes and cleans up some of the GetEnhMetaFile* functions.

Fixes scaling of EMFs in playback.  Will probably be right
when World Transforms work properly...
This commit is contained in:
Huw D M Davies 2000-04-13 15:57:34 +00:00 committed by Alexandre Julliard
parent c43fdb75b3
commit 2cf4ebc1aa
1 changed files with 62 additions and 74 deletions

View File

@ -157,9 +157,9 @@ HENHMETAFILE WINAPI GetEnhMetaFileW(
/***************************************************************************** /*****************************************************************************
* GetEnhMetaFileHeader (GDI32.178) * GetEnhMetaFileHeader (GDI32.178)
* *
* If _buf_ is NULL, returns the size of buffer required. * If buf is NULL, returns the size of buffer required.
* Otherwise, copy up to _bufsize_ bytes of enhanced metafile header into * Otherwise, copy up to bufsize bytes of enhanced metafile header into
* _buf. * buf.
*/ */
UINT WINAPI GetEnhMetaFileHeader( UINT WINAPI GetEnhMetaFileHeader(
HENHMETAFILE hmf, /* enhanced metafile */ HENHMETAFILE hmf, /* enhanced metafile */
@ -168,13 +168,19 @@ UINT WINAPI GetEnhMetaFileHeader(
) )
{ {
LPENHMETAHEADER emh; LPENHMETAHEADER emh;
UINT size;
if (!buf) return sizeof(ENHMETAHEADER);
emh = EMF_GetEnhMetaHeader(hmf); emh = EMF_GetEnhMetaHeader(hmf);
if(!emh) return FALSE; if(!emh) return FALSE;
memmove(buf, emh, min(sizeof(ENHMETAHEADER), bufsize)); size = emh->nSize;
if (!buf) {
EMF_ReleaseEnhMetaHeader(hmf);
return size;
}
size = min(size, bufsize);
memmove(buf, emh, size);
EMF_ReleaseEnhMetaHeader(hmf); EMF_ReleaseEnhMetaHeader(hmf);
return min(sizeof(ENHMETAHEADER), bufsize); return size;
} }
@ -258,19 +264,6 @@ HENHMETAFILE WINAPI SetEnhMetaFileBits(UINT bufsize, const BYTE *buf)
return EMF_Create_HENHMETAFILE( emh, 0, 0 ); return EMF_Create_HENHMETAFILE( emh, 0, 0 );
} }
INT CALLBACK cbCountSizeOfEnhMetaFile( HDC a,
LPHANDLETABLE b,
LPENHMETARECORD lpEMR,
INT c,
LPVOID lpData )
{
LPUINT uSizeOfRecordData = (LPUINT)lpData;
*uSizeOfRecordData += lpEMR->nSize;
return TRUE;
}
/***************************************************************************** /*****************************************************************************
* GetEnhMetaFileBits (GDI32.175) * GetEnhMetaFileBits (GDI32.175)
* *
@ -281,41 +274,22 @@ UINT WINAPI GetEnhMetaFileBits(
LPBYTE buf LPBYTE buf
) )
{ {
LPENHMETAHEADER lpEnhMetaFile; LPENHMETAHEADER emh = EMF_GetEnhMetaHeader( hmf );
UINT uEnhMetaFileSize = 0; UINT size;
FIXME( "(%04x,%u,%p): untested\n", hmf, bufsize, buf ); if(!emh) return 0;
/* Determine the required buffer size */ size = emh->nBytes;
/* Enumerate all records and count their size */ if( buf == NULL ) {
if( !EnumEnhMetaFile( 0, hmf, cbCountSizeOfEnhMetaFile, &uEnhMetaFileSize, NULL ) ) EMF_ReleaseEnhMetaHeader( hmf );
{ return size;
ERR( "Unable to enumerate enhanced metafile!\n" ); }
return 0;
}
if( buf == NULL ) size = min( size, bufsize );
{ memmove(buf, emh, size);
return uEnhMetaFileSize;
}
/* Copy the lesser of the two byte counts */ EMF_ReleaseEnhMetaHeader( hmf );
uEnhMetaFileSize = min( uEnhMetaFileSize, bufsize ); return size;
/* Copy everything */
lpEnhMetaFile = EMF_GetEnhMetaHeader( hmf );
if( lpEnhMetaFile == NULL )
{
return 0;
}
/* Use memmove just in case they overlap */
memmove(buf, lpEnhMetaFile, bufsize);
EMF_ReleaseEnhMetaHeader( hmf );
return bufsize;
} }
/***************************************************************************** /*****************************************************************************
@ -1229,45 +1203,59 @@ BOOL WINAPI EnumEnhMetaFile(
) )
{ {
BOOL ret = TRUE; BOOL ret = TRUE;
LPENHMETARECORD p = (LPENHMETARECORD) EMF_GetEnhMetaHeader(hmf); LPENHMETAHEADER emh = EMF_GetEnhMetaHeader(hmf);
INT count, i; INT count, i;
HANDLETABLE *ht; HANDLETABLE *ht;
INT savedMode = 0; INT savedMode = 0;
FLOAT xSrcPixSize, ySrcPixSize, xscale, yscale;
XFORM savedXform, xform;
if(!p) return FALSE; if(!emh) {
count = ((LPENHMETAHEADER) p)->nHandles; SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if(!lpRect) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
count = emh->nHandles;
ht = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, ht = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(HANDLETABLE) * count ); sizeof(HANDLETABLE) * count );
ht->objectHandle[0] = hmf; ht->objectHandle[0] = hmf;
if (lpRect) {
LPENHMETAHEADER h = (LPENHMETAHEADER) p; xSrcPixSize = (FLOAT) emh->szlMillimeters.cx / emh->szlDevice.cx;
FLOAT xscale = (h->rclBounds.right - h->rclBounds.left) / ySrcPixSize = (FLOAT) emh->szlMillimeters.cy / emh->szlDevice.cy;
(lpRect->right - lpRect->left); xscale = (FLOAT)(lpRect->right - lpRect->left) * 100.0 /
FLOAT yscale = (h->rclBounds.bottom - h->rclBounds.top) / (emh->rclFrame.right - emh->rclFrame.left) * xSrcPixSize;
(lpRect->bottom - lpRect->top); yscale = (FLOAT)(lpRect->bottom - lpRect->top) * 100.0 /
XFORM xform; (emh->rclFrame.bottom - emh->rclFrame.top) * ySrcPixSize;
xform.eM11 = xscale;
xform.eM12 = 0; xform.eM11 = xscale;
xform.eM21 = 0; xform.eM12 = 0;
xform.eM22 = yscale; xform.eM21 = 0;
xform.eDx = lpRect->left; xform.eM22 = yscale;
xform.eDy = lpRect->top; if(emh->rclFrame.left || emh->rclFrame.top)
FIXME("play into rect doesn't work\n"); FIXME("Can't cope with nonzero rclFrame origin yet\n");
savedMode = SetGraphicsMode(hdc, GM_ADVANCED); /* eDx = lpRect->left - (lpRect width) / (rclFrame width) * rclFrame.left ? */
if (!SetWorldTransform(hdc, &xform)) { xform.eDx = lpRect->left;
WARN("World transform failed!\n"); xform.eDy = lpRect->top;
} savedMode = SetGraphicsMode(hdc, GM_ADVANCED);
GetWorldTransform(hdc, &savedXform);
if (!ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY)) {
ERR("World transform failed!\n");
} }
while (ret) { while (ret) {
ret = (*callback)(hdc, ht, p, count, data); ret = (*callback)(hdc, ht, (LPENHMETARECORD) emh, count, data);
if (p->iType == EMR_EOF) break; if (emh->iType == EMR_EOF) break;
p = (LPENHMETARECORD) ((char *) p + p->nSize); emh = (LPENHMETAHEADER) ((char *) emh + emh->nSize);
} }
for(i = 1; i < count; i++) /* Don't delete element 0 (hmf) */ for(i = 1; i < count; 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); EMF_ReleaseEnhMetaHeader(hmf);
SetWorldTransform(hdc, &savedXform);
if (savedMode) SetGraphicsMode(hdc, savedMode); if (savedMode) SetGraphicsMode(hdc, savedMode);
return ret; return ret;
} }