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:
parent
c43fdb75b3
commit
2cf4ebc1aa
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue