Huw Davies : gdi32: Store the original emf as a sequence of MFCOMMENT records.
Alexandre Julliard
julliard at winehq.org
Tue Jun 30 08:33:31 CDT 2009
Module: wine
Branch: master
Commit: 41bbc007a468c3c91baa404e8d838b30868b9ee1
URL: http://source.winehq.org/git/wine.git/?a=commit;h=41bbc007a468c3c91baa404e8d838b30868b9ee1
Author: Huw Davies <huw at codeweavers.com>
Date: Mon Jun 29 16:06:40 2009 +0100
gdi32: Store the original emf as a sequence of MFCOMMENT records.
---
dlls/gdi32/metafile.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 90 insertions(+), 1 deletions(-)
diff --git a/dlls/gdi32/metafile.c b/dlls/gdi32/metafile.c
index 53ceceb..d0c55ce 100644
--- a/dlls/gdi32/metafile.c
+++ b/dlls/gdi32/metafile.c
@@ -1147,6 +1147,81 @@ UINT WINAPI GetMetaFileBitsEx( HMETAFILE hmf, UINT nSize, LPVOID buf )
return mfSize;
}
+#include <pshpack2.h>
+typedef struct
+{
+ DWORD magic; /* WMFC */
+ WORD unk04; /* 1 */
+ WORD unk06; /* 0 */
+ WORD unk08; /* 0 */
+ WORD unk0a; /* 1 */
+ WORD checksum;
+ DWORD unk0e; /* 0 */
+ DWORD num_chunks;
+ DWORD chunk_size;
+ DWORD remaining_size;
+ DWORD emf_size;
+ BYTE *emf_data;
+} mf_comment_chunk;
+#include <poppack.h>
+
+static const DWORD wmfc_magic = 0x43464d57;
+
+/******************************************************************
+ * add_mf_comment
+ *
+ * Helper for GetWinMetaFileBits
+ *
+ * Add the MFCOMMENT record[s] which is essentially a copy
+ * of the original emf.
+ */
+static BOOL add_mf_comment(HDC hdc, HENHMETAFILE emf)
+{
+ DWORD size = GetEnhMetaFileBits(emf, 0, NULL), i;
+ BYTE *bits, *chunk_data;
+ mf_comment_chunk *chunk = NULL;
+ BOOL ret = FALSE;
+ static const DWORD max_chunk_size = 0x2000;
+
+ if(!size) return FALSE;
+ chunk_data = bits = HeapAlloc(GetProcessHeap(), 0, size);
+ if(!bits) return FALSE;
+ if(!GetEnhMetaFileBits(emf, size, bits)) goto end;
+
+ chunk = HeapAlloc(GetProcessHeap(), 0, max_chunk_size + FIELD_OFFSET(mf_comment_chunk, emf_data));
+ if(!chunk) goto end;
+
+ chunk->magic = wmfc_magic;
+ chunk->unk04 = 1;
+ chunk->unk06 = 0;
+ chunk->unk08 = 0;
+ chunk->unk0a = 1;
+ chunk->checksum = 0; /* We fixup the first chunk's checksum before returning from GetWinMetaFileBits */
+ chunk->unk0e = 0;
+ chunk->num_chunks = (size + max_chunk_size - 1) / max_chunk_size;
+ chunk->chunk_size = max_chunk_size;
+ chunk->remaining_size = size;
+ chunk->emf_size = size;
+
+ for(i = 0; i < chunk->num_chunks; i++)
+ {
+ if(i == chunk->num_chunks - 1) /* last chunk */
+ chunk->chunk_size = chunk->remaining_size;
+
+ chunk->remaining_size -= chunk->chunk_size;
+ memcpy(&chunk->emf_data, chunk_data, chunk->chunk_size);
+ chunk_data += chunk->chunk_size;
+
+ if(!Escape(hdc, MFCOMMENT, chunk->chunk_size + FIELD_OFFSET(mf_comment_chunk, emf_data), (char*)chunk, NULL))
+ goto end;
+ }
+ ret = TRUE;
+end:
+ HeapFree(GetProcessHeap(), 0, chunk);
+ HeapFree(GetProcessHeap(), 0, bits);
+ return ret;
+}
+
/******************************************************************
* GetWinMetaFileBits [GDI32.@]
*/
@@ -1156,7 +1231,7 @@ UINT WINAPI GetWinMetaFileBits(HENHMETAFILE hemf,
{
HDC hdcmf;
HMETAFILE hmf;
- UINT ret;
+ UINT ret, full_size;
RECT rc;
GetClipBox(hdcRef, &rc);
@@ -1165,11 +1240,25 @@ UINT WINAPI GetWinMetaFileBits(HENHMETAFILE hemf,
fnMapMode, hdcRef, wine_dbgstr_rect(&rc));
hdcmf = CreateMetaFileW(NULL);
+
+ add_mf_comment(hdcmf, hemf);
+
PlayEnhMetaFile(hdcmf, hemf, &rc);
hmf = CloseMetaFile(hdcmf);
+ full_size = GetMetaFileBitsEx(hmf, 0, NULL);
ret = GetMetaFileBitsEx(hmf, cbBuffer, lpbBuffer);
DeleteMetaFile(hmf);
+ if(ret && ret == full_size && lpbBuffer) /* fixup checksum, but only if retrieving all of the bits */
+ {
+ WORD checksum = 0;
+ METARECORD *comment_rec = (METARECORD*)(lpbBuffer + sizeof(METAHEADER));
+ UINT i;
+
+ for(i = 0; i < full_size / 2; i++)
+ checksum += ((WORD*)lpbBuffer)[i];
+ comment_rec->rdParm[8] = ~checksum + 1;
+ }
return ret;
}
More information about the wine-cvs
mailing list