4 * Copyright David W. Metcalfe, 1994
5 * Niels de Carpentier, Albrecht Kleine, Huw Davies 1996
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * These functions are primarily involved with metafile playback or anything
24 * that touches a HMETAFILE.
25 * For recording of metafiles look in graphics/metafiledrv/
27 * Note that (32 bit) HMETAFILEs are GDI objects, while HMETAFILE16s are
28 * global memory handles so these cannot be interchanged.
30 * Memory-based metafiles are just stored as a continuous block of memory with
31 * a METAHEADER at the head with METARECORDs appended to it. mtType is
32 * METAFILE_MEMORY (1). Note this is indentical to the disk image of a
33 * disk-based metafile - even mtType is METAFILE_MEMORY.
34 * 16bit HMETAFILE16s are global handles to this block
35 * 32bit HMETAFILEs are GDI handles METAFILEOBJs, which contains a ptr to
37 * Disk-based metafiles are rather different. HMETAFILE16s point to a
38 * METAHEADER which has mtType equal to METAFILE_DISK (2). Following the 9
39 * WORDs of the METAHEADER there are a further 3 WORDs of 0, 1 of 0x117, 1
40 * more 0, then 2 which may be a time stamp of the file and then the path of
41 * the file (METAHEADERDISK). I've copied this for 16bit compatibility.
51 #include "wine/winbase16.h"
52 #include "wine/wingdi16.h"
55 #include "wine/debug.h"
57 WINE_DEFAULT_DEBUG_CHANNEL(metafile
);
74 #define MFHEADERSIZE (sizeof(METAHEADER))
75 #define MFVERSION 0x300
77 /* ### start build ### */
78 extern WORD CALLBACK
MF_CallTo16_word_wllwl(MFENUMPROC16
,WORD
,LONG
,LONG
,WORD
,LONG
);
79 /* ### stop build ### */
81 /******************************************************************
84 * Add a handle to an external handle table and return the index
86 static int MF_AddHandle(HANDLETABLE
*ht
, UINT htlen
, HGDIOBJ hobj
)
90 for (i
= 0; i
< htlen
; i
++)
92 if (*(ht
->objectHandle
+ i
) == 0)
94 *(ht
->objectHandle
+ i
) = hobj
;
102 /******************************************************************
103 * MF_Create_HMETATFILE
105 * Creates a (32 bit) HMETAFILE object from a METAHEADER
107 * HMETAFILEs are GDI objects.
109 HMETAFILE
MF_Create_HMETAFILE(METAHEADER
*mh
)
112 METAFILEOBJ
*metaObj
= GDI_AllocObject( sizeof(METAFILEOBJ
), METAFILE_MAGIC
, &hmf
, NULL
);
116 GDI_ReleaseObj( hmf
);
121 /******************************************************************
122 * MF_Create_HMETATFILE16
124 * Creates a HMETAFILE16 object from a METAHEADER
126 * HMETAFILE16s are Global memory handles.
128 HMETAFILE16
MF_Create_HMETAFILE16(METAHEADER
*mh
)
131 DWORD size
= mh
->mtSize
* sizeof(WORD
);
133 hmf
= GlobalAlloc16(GMEM_MOVEABLE
, size
);
136 METAHEADER
*mh_dest
= GlobalLock16(hmf
);
137 memcpy(mh_dest
, mh
, size
);
140 HeapFree(GetProcessHeap(), 0, mh
);
144 /******************************************************************
147 * Returns ptr to METAHEADER associated with HMETAFILE
149 static METAHEADER
*MF_GetMetaHeader( HMETAFILE hmf
)
151 METAHEADER
*ret
= NULL
;
152 METAFILEOBJ
* metaObj
= (METAFILEOBJ
*)GDI_GetObjPtr( hmf
, METAFILE_MAGIC
);
156 GDI_ReleaseObj( hmf
);
161 /******************************************************************
164 * Returns ptr to METAHEADER associated with HMETAFILE16
165 * Should be followed by call to MF_ReleaseMetaHeader16
167 static METAHEADER
*MF_GetMetaHeader16( HMETAFILE16 hmf
)
169 return GlobalLock16(hmf
);
172 /******************************************************************
173 * MF_ReleaseMetaHeader16
175 * Releases METAHEADER associated with HMETAFILE16
177 static BOOL16
MF_ReleaseMetaHeader16( HMETAFILE16 hmf
)
179 return GlobalUnlock16( hmf
);
183 /******************************************************************
186 * Convert an array of POINT16 to an array of POINT.
187 * Result must be freed by caller.
189 static POINT
*convert_points( UINT count
, POINT16
*pt16
)
192 POINT
*ret
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(*ret
) );
195 for (i
= 0; i
< count
; i
++)
197 ret
[i
].x
= pt16
[i
].x
;
198 ret
[i
].y
= pt16
[i
].y
;
205 /******************************************************************
206 * DeleteMetaFile (GDI.127)
208 BOOL16 WINAPI
DeleteMetaFile16( HMETAFILE16 hmf
)
210 return !GlobalFree16( hmf
);
213 /******************************************************************
214 * DeleteMetaFile (GDI32.@)
216 * Delete a memory-based metafile.
219 BOOL WINAPI
DeleteMetaFile( HMETAFILE hmf
)
221 METAFILEOBJ
* metaObj
= (METAFILEOBJ
*)GDI_GetObjPtr( hmf
, METAFILE_MAGIC
);
222 if (!metaObj
) return FALSE
;
223 HeapFree( GetProcessHeap(), 0, metaObj
->mh
);
224 GDI_FreeObject( hmf
, metaObj
);
228 /******************************************************************
231 * Returns a pointer to a memory based METAHEADER read in from file HFILE
234 static METAHEADER
*MF_ReadMetaFile(HANDLE hfile
)
237 DWORD BytesRead
, size
;
239 size
= sizeof(METAHEADER
);
240 mh
= HeapAlloc( GetProcessHeap(), 0, size
);
242 if(ReadFile( hfile
, mh
, size
, &BytesRead
, NULL
) == 0 ||
244 HeapFree( GetProcessHeap(), 0, mh
);
247 size
= mh
->mtSize
* 2;
248 mh
= HeapReAlloc( GetProcessHeap(), 0, mh
, size
);
250 size
-= sizeof(METAHEADER
);
251 if(ReadFile( hfile
, (char *)mh
+ sizeof(METAHEADER
), size
, &BytesRead
,
254 HeapFree( GetProcessHeap(), 0, mh
);
258 if (mh
->mtType
!= METAFILE_MEMORY
) {
259 WARN("Disk metafile had mtType = %04x\n", mh
->mtType
);
260 mh
->mtType
= METAFILE_MEMORY
;
265 /******************************************************************
266 * GetMetaFile (GDI.124)
268 HMETAFILE16 WINAPI
GetMetaFile16( LPCSTR lpFilename
)
273 TRACE("%s\n", lpFilename
);
278 if((hFile
= CreateFileA(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
279 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
282 mh
= MF_ReadMetaFile(hFile
);
285 return MF_Create_HMETAFILE16( mh
);
288 /******************************************************************
289 * GetMetaFileA (GDI32.@)
291 * Read a metafile from a file. Returns handle to a memory-based metafile.
293 HMETAFILE WINAPI
GetMetaFileA( LPCSTR lpFilename
)
298 TRACE("%s\n", lpFilename
);
303 if((hFile
= CreateFileA(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
304 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
307 mh
= MF_ReadMetaFile(hFile
);
310 return MF_Create_HMETAFILE( mh
);
315 /******************************************************************
316 * GetMetaFileW (GDI32.@)
318 HMETAFILE WINAPI
GetMetaFileW( LPCWSTR lpFilename
)
323 TRACE("%s\n", debugstr_w(lpFilename
));
328 if((hFile
= CreateFileW(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
329 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
332 mh
= MF_ReadMetaFile(hFile
);
335 return MF_Create_HMETAFILE( mh
);
339 /******************************************************************
340 * MF_LoadDiskBasedMetaFile
342 * Creates a new memory-based metafile from a disk-based one.
344 static METAHEADER
*MF_LoadDiskBasedMetaFile(METAHEADER
*mh
)
350 if(mh
->mtType
!= METAFILE_DISK
) {
351 ERR("Not a disk based metafile\n");
354 mhd
= (METAHEADERDISK
*)((char *)mh
+ sizeof(METAHEADER
));
356 if((hfile
= CreateFileA(mhd
->filename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
357 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
) {
358 WARN("Can't open file of disk based metafile\n");
361 mh2
= MF_ReadMetaFile(hfile
);
366 /******************************************************************
367 * MF_CreateMetaHeaderDisk
369 * Take a memory based METAHEADER and change it to a disk based METAHEADER
370 * assosiated with filename. Note: Trashes contents of old one.
372 METAHEADER
*MF_CreateMetaHeaderDisk(METAHEADER
*mh
, LPCSTR filename
)
377 mh
= HeapReAlloc( GetProcessHeap(), 0, mh
,
378 sizeof(METAHEADER
) + sizeof(METAHEADERDISK
));
379 mh
->mtType
= METAFILE_DISK
;
380 size
= HeapSize( GetProcessHeap(), 0, mh
);
381 mhd
= (METAHEADERDISK
*)((char *)mh
+ sizeof(METAHEADER
));
382 strcpy(mhd
->filename
, filename
);
386 /******************************************************************
387 * CopyMetaFile (GDI.151)
389 HMETAFILE16 WINAPI
CopyMetaFile16( HMETAFILE16 hSrcMetaFile
, LPCSTR lpFilename
)
391 METAHEADER
*mh
= MF_GetMetaHeader16( hSrcMetaFile
);
392 METAHEADER
*mh2
= NULL
;
395 TRACE("(%08x,%s)\n", hSrcMetaFile
, lpFilename
);
399 if(mh
->mtType
== METAFILE_DISK
)
400 mh2
= MF_LoadDiskBasedMetaFile(mh
);
402 mh2
= HeapAlloc( GetProcessHeap(), 0, mh
->mtSize
* 2 );
403 memcpy( mh2
, mh
, mh
->mtSize
* 2 );
405 MF_ReleaseMetaHeader16( hSrcMetaFile
);
407 if(lpFilename
) { /* disk based metafile */
408 if((hFile
= CreateFileA(lpFilename
, GENERIC_WRITE
, 0, NULL
,
409 CREATE_ALWAYS
, 0, 0)) == INVALID_HANDLE_VALUE
) {
410 HeapFree( GetProcessHeap(), 0, mh2
);
413 WriteFile(hFile
, mh2
, mh2
->mtSize
* 2, NULL
, NULL
);
415 mh2
= MF_CreateMetaHeaderDisk(mh2
, lpFilename
);
418 return MF_Create_HMETAFILE16( mh2
);
422 /******************************************************************
423 * CopyMetaFileA (GDI32.@)
425 * Copies the metafile corresponding to hSrcMetaFile to either
426 * a disk file, if a filename is given, or to a new memory based
427 * metafile, if lpFileName is NULL.
431 * Handle to metafile copy on success, NULL on failure.
435 * Copying to disk returns NULL even if successful.
437 HMETAFILE WINAPI
CopyMetaFileA(
438 HMETAFILE hSrcMetaFile
, /* [in] handle of metafile to copy */
439 LPCSTR lpFilename
/* [in] filename if copying to a file */
441 METAHEADER
*mh
= MF_GetMetaHeader( hSrcMetaFile
);
442 METAHEADER
*mh2
= NULL
;
445 TRACE("(%08x,%s)\n", hSrcMetaFile
, lpFilename
);
449 if(mh
->mtType
== METAFILE_DISK
)
450 mh2
= MF_LoadDiskBasedMetaFile(mh
);
452 mh2
= HeapAlloc( GetProcessHeap(), 0, mh
->mtSize
* 2 );
453 memcpy( mh2
, mh
, mh
->mtSize
* 2 );
456 if(lpFilename
) { /* disk based metafile */
457 if((hFile
= CreateFileA(lpFilename
, GENERIC_WRITE
, 0, NULL
,
458 CREATE_ALWAYS
, 0, 0)) == INVALID_HANDLE_VALUE
) {
459 HeapFree( GetProcessHeap(), 0, mh2
);
462 WriteFile(hFile
, mh2
, mh2
->mtSize
* 2, NULL
, NULL
);
464 mh2
= MF_CreateMetaHeaderDisk(mh2
, lpFilename
);
467 return MF_Create_HMETAFILE( mh2
);
471 /******************************************************************
472 * CopyMetaFileW (GDI32.@)
474 HMETAFILE WINAPI
CopyMetaFileW( HMETAFILE hSrcMetaFile
,
478 DWORD len
= WideCharToMultiByte( CP_ACP
, 0, lpFilename
, -1, NULL
, 0, NULL
, NULL
);
479 LPSTR p
= HeapAlloc( GetProcessHeap(), 0, len
);
483 WideCharToMultiByte( CP_ACP
, 0, lpFilename
, -1, p
, len
, NULL
, NULL
);
484 ret
= CopyMetaFileA( hSrcMetaFile
, p
);
485 HeapFree( GetProcessHeap(), 0, p
);
491 /******************************************************************
492 * IsValidMetaFile (GDI.410)
494 * Attempts to check if a given metafile is correctly formatted.
495 * Currently, the only things verified are several properties of the
499 * TRUE if hmf passes some tests for being a valid metafile, FALSE otherwise.
502 * This is not exactly what windows does, see _Undocumented_Windows_
505 BOOL16 WINAPI
IsValidMetaFile16(HMETAFILE16 hmf
)
508 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
510 if (mh
->mtType
== METAFILE_MEMORY
|| mh
->mtType
== METAFILE_DISK
)
511 if (mh
->mtHeaderSize
== MFHEADERSIZE
/sizeof(INT16
))
512 if (mh
->mtVersion
== MFVERSION
)
514 MF_ReleaseMetaHeader16(hmf
);
516 TRACE("IsValidMetaFile %x => %d\n",hmf
,res
);
521 /*******************************************************************
524 * Helper for PlayMetaFile
526 static BOOL
MF_PlayMetaFile( HDC hdc
, METAHEADER
*mh
)
531 unsigned int offset
= 0;
538 if (!mh
) return FALSE
;
539 if(mh
->mtType
== METAFILE_DISK
) { /* Create a memory-based copy */
540 mh
= MF_LoadDiskBasedMetaFile(mh
);
541 if(!mh
) return FALSE
;
545 /* save the current pen, brush and font */
546 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
547 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
548 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
550 /* create the handle table */
551 ht
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
552 sizeof(HANDLETABLE
) * mh
->mtNoObjects
);
553 if(!ht
) return FALSE
;
555 /* loop through metafile playing records */
556 offset
= mh
->mtHeaderSize
* 2;
557 while (offset
< mh
->mtSize
* 2)
559 mr
= (METARECORD
*)((char *)mh
+ offset
);
560 TRACE("offset=%04x,size=%08lx\n",
564 "Entry got size 0 at offset %d, total mf length is %ld\n",
565 offset
,mh
->mtSize
*2);
566 break; /* would loop endlessly otherwise */
568 offset
+= mr
->rdSize
* 2;
569 PlayMetaFileRecord( hdc
, ht
, mr
, mh
->mtNoObjects
);
572 SelectObject(hdc
, hBrush
);
573 SelectObject(hdc
, hPen
);
574 SelectObject(hdc
, hFont
);
576 /* free objects in handle table */
577 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
578 if(*(ht
->objectHandle
+ i
) != 0)
579 DeleteObject(*(ht
->objectHandle
+ i
));
581 /* free handle table */
582 HeapFree( GetProcessHeap(), 0, ht
);
584 HeapFree( GetProcessHeap(), 0, mh
);
588 /******************************************************************
589 * PlayMetaFile (GDI.123)
592 BOOL16 WINAPI
PlayMetaFile16( HDC16 hdc
, HMETAFILE16 hmf
)
595 METAHEADER
*mh
= MF_GetMetaHeader16( hmf
);
596 ret
= MF_PlayMetaFile( hdc
, mh
);
597 MF_ReleaseMetaHeader16( hmf
);
601 /******************************************************************
602 * PlayMetaFile (GDI32.@)
604 * Renders the metafile specified by hmf in the DC specified by
605 * hdc. Returns FALSE on failure, TRUE on success.
607 BOOL WINAPI
PlayMetaFile(
608 HDC hdc
, /* [in] handle of DC to render in */
609 HMETAFILE hmf
/* [in] handle of metafile to render */
612 METAHEADER
*mh
= MF_GetMetaHeader( hmf
);
613 return MF_PlayMetaFile( hdc
, mh
);
617 /******************************************************************
618 * EnumMetaFile (GDI.175)
621 BOOL16 WINAPI
EnumMetaFile16( HDC16 hdc
, HMETAFILE16 hmf
,
622 MFENUMPROC16 lpEnumFunc
, LPARAM lpData
)
624 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
629 unsigned int offset
= 0;
634 BOOL16 result
= TRUE
, loaded
= FALSE
;
636 TRACE("(%04x, %04x, %08lx, %08lx)\n",
637 hdc
, hmf
, (DWORD
)lpEnumFunc
, lpData
);
640 if(!mh
) return FALSE
;
641 if(mh
->mtType
== METAFILE_DISK
) { /* Create a memory-based copy */
642 mh
= MF_LoadDiskBasedMetaFile(mh
);
643 if(!mh
) return FALSE
;
647 /* save the current pen, brush and font */
648 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
649 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
650 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
652 /* create the handle table */
654 hHT
= GlobalAlloc16(GMEM_MOVEABLE
| GMEM_ZEROINIT
,
655 sizeof(HANDLETABLE16
) * mh
->mtNoObjects
);
656 spht
= K32WOWGlobalLock16(hHT
);
659 offset
= mh
->mtHeaderSize
* 2;
661 /* loop through metafile records */
663 while (offset
< (mh
->mtSize
* 2))
665 mr
= (METARECORD
*)((char *)mh
+ offset
);
667 if (!MF_CallTo16_word_wllwl( lpEnumFunc
, hdc
, spht
,
668 MAKESEGPTR( seg
+ (HIWORD(offset
) << __AHSHIFT
), LOWORD(offset
) ),
669 mh
->mtNoObjects
, (LONG
)lpData
))
676 offset
+= (mr
->rdSize
* 2);
679 SelectObject(hdc
, hBrush
);
680 SelectObject(hdc
, hPen
);
681 SelectObject(hdc
, hFont
);
683 ht
= (HANDLETABLE16
*)GlobalLock16(hHT
);
685 /* free objects in handle table */
686 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
687 if(*(ht
->objectHandle
+ i
) != 0)
688 DeleteObject(*(ht
->objectHandle
+ i
));
690 /* free handle table */
693 HeapFree( GetProcessHeap(), 0, mh
);
694 MF_ReleaseMetaHeader16(hmf
);
698 /******************************************************************
699 * EnumMetaFile (GDI32.@)
701 * Loop through the metafile records in hmf, calling the user-specified
702 * function for each one, stopping when the user's function returns FALSE
703 * (which is considered to be failure)
704 * or when no records are left (which is considered to be success).
707 * TRUE on success, FALSE on failure.
710 * Niels de carpentier, april 1996
712 BOOL WINAPI
EnumMetaFile(
715 MFENUMPROC lpEnumFunc
,
718 METAHEADER
*mhTemp
= NULL
, *mh
= MF_GetMetaHeader(hmf
);
723 unsigned int offset
= 0;
728 TRACE("(%08x,%08x,%p,%p)\n", hdc
, hmf
, lpEnumFunc
, (void*)lpData
);
730 if(mh
->mtType
== METAFILE_DISK
)
732 /* Create a memory-based copy */
733 if (!(mhTemp
= MF_LoadDiskBasedMetaFile(mh
))) return FALSE
;
737 /* save the current pen, brush and font */
738 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
739 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
740 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
742 ht
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
743 sizeof(HANDLETABLE
) * mh
->mtNoObjects
);
745 /* loop through metafile records */
746 offset
= mh
->mtHeaderSize
* 2;
748 while (offset
< (mh
->mtSize
* 2))
750 mr
= (METARECORD
*)((char *)mh
+ offset
);
751 if(mr
->rdFunction
== META_EOF
) {
752 TRACE("Got META_EOF so stopping\n");
755 TRACE("Calling EnumFunc with record type %x\n",
757 if (!lpEnumFunc( hdc
, ht
, mr
, mh
->mtNoObjects
, (LONG
)lpData
))
763 offset
+= (mr
->rdSize
* 2);
766 /* restore pen, brush and font */
767 SelectObject(hdc
, hBrush
);
768 SelectObject(hdc
, hPen
);
769 SelectObject(hdc
, hFont
);
771 /* free objects in handle table */
772 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
773 if(*(ht
->objectHandle
+ i
) != 0)
774 DeleteObject(*(ht
->objectHandle
+ i
));
776 /* free handle table */
777 HeapFree( GetProcessHeap(), 0, ht
);
778 /* free a copy of metafile */
779 if (mhTemp
) HeapFree( GetProcessHeap(), 0, mhTemp
);
783 static BOOL
MF_Play_MetaCreateRegion( METARECORD
*mr
, HRGN hrgn
);
784 static BOOL
MF_Play_MetaExtTextOut(HDC hdc
, METARECORD
*mr
);
785 /******************************************************************
786 * PlayMetaFileRecord (GDI32.@)
788 * Render a single metafile record specified by *mr in the DC hdc, while
789 * using the handle table *ht, of length handles,
790 * to store metafile objects.
793 * The following metafile records are unimplemented:
795 * DRAWTEXT, ANIMATEPALETTE, SETPALENTRIES,
796 * RESIZEPALETTE, EXTFLOODFILL, RESETDC, STARTDOC, STARTPAGE, ENDPAGE,
797 * ABORTDOC, ENDDOC, CREATEBRUSH, CREATEBITMAPINDIRECT, and CREATEBITMAP.
799 BOOL WINAPI
PlayMetaFileRecord( HDC hdc
, HANDLETABLE
*ht
, METARECORD
*mr
, UINT handles
)
803 BITMAPINFOHEADER
*infohdr
;
805 TRACE("(%04x %p %p %u) function %04x\n", hdc
, ht
, mr
, handles
, mr
->rdFunction
);
807 switch (mr
->rdFunction
)
812 case META_DELETEOBJECT
:
813 DeleteObject(*(ht
->objectHandle
+ mr
->rdParm
[0]));
814 *(ht
->objectHandle
+ mr
->rdParm
[0]) = 0;
817 case META_SETBKCOLOR
:
818 SetBkColor(hdc
, MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
822 SetBkMode(hdc
, mr
->rdParm
[0]);
825 case META_SETMAPMODE
:
826 SetMapMode(hdc
, mr
->rdParm
[0]);
830 SetROP2(hdc
, mr
->rdParm
[0]);
834 SetRelAbs(hdc
, mr
->rdParm
[0]);
837 case META_SETPOLYFILLMODE
:
838 SetPolyFillMode(hdc
, mr
->rdParm
[0]);
841 case META_SETSTRETCHBLTMODE
:
842 SetStretchBltMode(hdc
, mr
->rdParm
[0]);
845 case META_SETTEXTCOLOR
:
846 SetTextColor(hdc
, MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
849 case META_SETWINDOWORG
:
850 SetWindowOrgEx(hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0], NULL
);
853 case META_SETWINDOWEXT
:
854 SetWindowExtEx(hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0], NULL
);
857 case META_SETVIEWPORTORG
:
858 SetViewportOrgEx(hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0], NULL
);
861 case META_SETVIEWPORTEXT
:
862 SetViewportExtEx(hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0], NULL
);
865 case META_OFFSETWINDOWORG
:
866 OffsetWindowOrgEx(hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0], NULL
);
869 case META_SCALEWINDOWEXT
:
870 ScaleWindowExtEx(hdc
, (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
871 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0], NULL
);
874 case META_OFFSETVIEWPORTORG
:
875 OffsetViewportOrgEx(hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0], NULL
);
878 case META_SCALEVIEWPORTEXT
:
879 ScaleViewportExtEx(hdc
, (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
880 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0], NULL
);
884 LineTo(hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0]);
888 MoveToEx(hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0], NULL
);
891 case META_EXCLUDECLIPRECT
:
892 ExcludeClipRect( hdc
, (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
893 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0] );
896 case META_INTERSECTCLIPRECT
:
897 IntersectClipRect( hdc
, (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
898 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0] );
902 Arc(hdc
, (SHORT
)mr
->rdParm
[7], (SHORT
)mr
->rdParm
[6],
903 (SHORT
)mr
->rdParm
[5], (SHORT
)mr
->rdParm
[4],
904 (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
905 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0]);
909 Ellipse(hdc
, (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
910 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0]);
914 FloodFill(hdc
, (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
915 MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
919 Pie(hdc
, (SHORT
)mr
->rdParm
[7], (SHORT
)mr
->rdParm
[6],
920 (SHORT
)mr
->rdParm
[5], (SHORT
)mr
->rdParm
[4],
921 (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
922 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0]);
926 Rectangle(hdc
, (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
927 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0]);
931 RoundRect(hdc
, (SHORT
)mr
->rdParm
[5], (SHORT
)mr
->rdParm
[4],
932 (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
933 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0]);
937 PatBlt(hdc
, (SHORT
)mr
->rdParm
[5], (SHORT
)mr
->rdParm
[4],
938 (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
939 MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
947 SetPixel(hdc
, (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
948 MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
951 case META_OFFSETCLIPRGN
:
952 OffsetClipRgn( hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0] );
957 TextOutA(hdc
, (SHORT
)mr
->rdParm
[((s1
+ 1) >> 1) + 2],
958 (SHORT
)mr
->rdParm
[((s1
+ 1) >> 1) + 1],
959 (char *)(mr
->rdParm
+ 1), s1
);
963 if ((pt
= convert_points( mr
->rdParm
[0], (LPPOINT16
)(mr
->rdParm
+ 1))))
965 Polygon(hdc
, pt
, mr
->rdParm
[0]);
966 HeapFree( GetProcessHeap(), 0, pt
);
970 case META_POLYPOLYGON
:
973 SHORT
*counts
= (SHORT
*)(mr
->rdParm
+ 1);
975 for (i
= total
= 0; i
< mr
->rdParm
[0]; i
++) total
+= counts
[i
];
976 pt
= convert_points( total
, (LPPOINT16
)(counts
+ mr
->rdParm
[0]) );
979 INT
*cnt32
= HeapAlloc( GetProcessHeap(), 0, mr
->rdParm
[0] * sizeof(*cnt32
) );
982 for (i
= 0; i
< mr
->rdParm
[0]; i
++) cnt32
[i
] = counts
[i
];
983 PolyPolygon( hdc
, pt
, cnt32
, mr
->rdParm
[0]);
984 HeapFree( GetProcessHeap(), 0, cnt32
);
987 HeapFree( GetProcessHeap(), 0, pt
);
992 if ((pt
= convert_points( mr
->rdParm
[0], (LPPOINT16
)(mr
->rdParm
+ 1))))
994 Polyline( hdc
, pt
, mr
->rdParm
[0] );
995 HeapFree( GetProcessHeap(), 0, pt
);
1000 RestoreDC(hdc
, (SHORT
)mr
->rdParm
[0]);
1003 case META_SELECTOBJECT
:
1004 SelectObject(hdc
, *(ht
->objectHandle
+ mr
->rdParm
[0]));
1008 Chord(hdc
, (SHORT
)mr
->rdParm
[7], (SHORT
)mr
->rdParm
[6],
1009 (SHORT
)mr
->rdParm
[5], (SHORT
)mr
->rdParm
[4],
1010 (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
1011 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0]);
1014 case META_CREATEPATTERNBRUSH
:
1015 switch (mr
->rdParm
[0])
1018 infohdr
= (BITMAPINFOHEADER
*)(mr
->rdParm
+ 2);
1019 MF_AddHandle(ht
, handles
,
1020 CreatePatternBrush(CreateBitmap(infohdr
->biWidth
,
1023 infohdr
->biBitCount
,
1024 (LPSTR
)(mr
->rdParm
+
1025 (sizeof(BITMAPINFOHEADER
) / 2) + 4))));
1029 infohdr
= (BITMAPINFOHEADER
*)(mr
->rdParm
+ 2);
1030 MF_AddHandle(ht
, handles
, CreateDIBPatternBrushPt( infohdr
, mr
->rdParm
[1] ));
1034 ERR("META_CREATEPATTERNBRUSH: Unknown pattern type %d\n",
1040 case META_CREATEPENINDIRECT
:
1043 pen
.lopnStyle
= mr
->rdParm
[0];
1044 pen
.lopnWidth
.x
= (SHORT
)mr
->rdParm
[1];
1045 pen
.lopnWidth
.y
= (SHORT
)mr
->rdParm
[2];
1046 pen
.lopnColor
= MAKELONG( mr
->rdParm
[3], mr
->rdParm
[4] );
1047 MF_AddHandle(ht
, handles
, CreatePenIndirect( &pen
));
1051 case META_CREATEFONTINDIRECT
:
1054 font
.lfHeight
= (SHORT
)mr
->rdParm
[0];
1055 font
.lfWidth
= (SHORT
)mr
->rdParm
[1];
1056 font
.lfEscapement
= (SHORT
)mr
->rdParm
[2];
1057 font
.lfOrientation
= (SHORT
)mr
->rdParm
[3];
1058 font
.lfWeight
= (SHORT
)mr
->rdParm
[4];
1059 font
.lfItalic
= LOBYTE(mr
->rdParm
[5]);
1060 font
.lfUnderline
= HIBYTE(mr
->rdParm
[5]);
1061 font
.lfStrikeOut
= LOBYTE(mr
->rdParm
[6]);
1062 font
.lfCharSet
= HIBYTE(mr
->rdParm
[6]);
1063 font
.lfOutPrecision
= LOBYTE(mr
->rdParm
[7]);
1064 font
.lfClipPrecision
= HIBYTE(mr
->rdParm
[7]);
1065 font
.lfQuality
= LOBYTE(mr
->rdParm
[8]);
1066 font
.lfPitchAndFamily
= HIBYTE(mr
->rdParm
[8]);
1067 memcpy( font
.lfFaceName
, mr
->rdParm
+ 9, LF_FACESIZE
);
1068 MF_AddHandle(ht
, handles
, CreateFontIndirectA( &font
));
1072 case META_CREATEBRUSHINDIRECT
:
1075 brush
.lbStyle
= mr
->rdParm
[0];
1076 brush
.lbColor
= MAKELONG( mr
->rdParm
[1], mr
->rdParm
[2] );
1077 brush
.lbHatch
= mr
->rdParm
[3];
1078 MF_AddHandle(ht
, handles
, CreateBrushIndirect( &brush
));
1082 case META_CREATEPALETTE
:
1083 MF_AddHandle(ht
, handles
, CreatePalette((LPLOGPALETTE
)mr
->rdParm
));
1086 case META_SETTEXTALIGN
:
1087 SetTextAlign(hdc
, mr
->rdParm
[0]);
1090 case META_SELECTPALETTE
:
1091 GDISelectPalette(hdc
, *(ht
->objectHandle
+ mr
->rdParm
[1]), mr
->rdParm
[0]);
1094 case META_SETMAPPERFLAGS
:
1095 SetMapperFlags(hdc
, MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1098 case META_REALIZEPALETTE
:
1099 GDIRealizePalette(hdc
);
1103 FIXME("META_ESCAPE unimplemented.\n");
1106 case META_EXTTEXTOUT
:
1107 MF_Play_MetaExtTextOut( hdc
, mr
);
1110 case META_STRETCHDIB
:
1112 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[11]);
1113 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[2] );
1114 StretchDIBits( hdc
, (SHORT
)mr
->rdParm
[10], (SHORT
)mr
->rdParm
[9], (SHORT
)mr
->rdParm
[8],
1115 (SHORT
)mr
->rdParm
[7], (SHORT
)mr
->rdParm
[6], (SHORT
)mr
->rdParm
[5],
1116 (SHORT
)mr
->rdParm
[4], (SHORT
)mr
->rdParm
[3], bits
, info
,
1117 mr
->rdParm
[2],MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1121 case META_DIBSTRETCHBLT
:
1123 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[10]);
1124 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[2] );
1125 StretchDIBits( hdc
, (SHORT
)mr
->rdParm
[9], (SHORT
)mr
->rdParm
[8], (SHORT
)mr
->rdParm
[7],
1126 (SHORT
)mr
->rdParm
[6], (SHORT
)mr
->rdParm
[5], (SHORT
)mr
->rdParm
[4],
1127 (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2], bits
, info
,
1128 DIB_RGB_COLORS
,MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1132 case META_STRETCHBLT
:
1134 HDC hdcSrc
= CreateCompatibleDC(hdc
);
1135 HBITMAP hbitmap
= CreateBitmap(mr
->rdParm
[10], /*Width */
1136 mr
->rdParm
[11], /*Height*/
1137 mr
->rdParm
[13], /*Planes*/
1138 mr
->rdParm
[14], /*BitsPixel*/
1139 (LPSTR
)&mr
->rdParm
[15]); /*bits*/
1140 SelectObject(hdcSrc
,hbitmap
);
1141 StretchBlt(hdc
, (SHORT
)mr
->rdParm
[9], (SHORT
)mr
->rdParm
[8],
1142 (SHORT
)mr
->rdParm
[7], (SHORT
)mr
->rdParm
[6],
1143 hdcSrc
, (SHORT
)mr
->rdParm
[5], (SHORT
)mr
->rdParm
[4],
1144 (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
1145 MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1152 HDC hdcSrc
= CreateCompatibleDC(hdc
);
1153 HBITMAP hbitmap
= CreateBitmap(mr
->rdParm
[7]/*Width */,
1154 mr
->rdParm
[8]/*Height*/,
1155 mr
->rdParm
[10]/*Planes*/,
1156 mr
->rdParm
[11]/*BitsPixel*/,
1157 (LPSTR
)&mr
->rdParm
[12]/*bits*/);
1158 SelectObject(hdcSrc
,hbitmap
);
1159 BitBlt(hdc
,(SHORT
)mr
->rdParm
[6],(SHORT
)mr
->rdParm
[5],
1160 (SHORT
)mr
->rdParm
[4],(SHORT
)mr
->rdParm
[3],
1161 hdcSrc
, (SHORT
)mr
->rdParm
[2],(SHORT
)mr
->rdParm
[1],
1162 MAKELONG(0,mr
->rdParm
[0]));
1167 case META_CREATEREGION
:
1169 HRGN hrgn
= CreateRectRgn(0,0,0,0);
1171 MF_Play_MetaCreateRegion(mr
, hrgn
);
1172 MF_AddHandle(ht
, handles
, hrgn
);
1176 case META_FILLREGION
:
1177 FillRgn(hdc
, *(ht
->objectHandle
+ mr
->rdParm
[1]),
1178 *(ht
->objectHandle
+ mr
->rdParm
[0]));
1181 case META_FRAMEREGION
:
1182 FrameRgn(hdc
, *(ht
->objectHandle
+ mr
->rdParm
[3]),
1183 *(ht
->objectHandle
+ mr
->rdParm
[2]),
1184 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0]);
1187 case META_INVERTREGION
:
1188 InvertRgn(hdc
, *(ht
->objectHandle
+ mr
->rdParm
[0]));
1191 case META_PAINTREGION
:
1192 PaintRgn(hdc
, *(ht
->objectHandle
+ mr
->rdParm
[0]));
1195 case META_SELECTCLIPREGION
:
1196 SelectClipRgn(hdc
, *(ht
->objectHandle
+ mr
->rdParm
[0]));
1199 case META_DIBCREATEPATTERNBRUSH
:
1200 /* mr->rdParm[0] may be BS_PATTERN or BS_DIBPATTERN:
1201 but there's no difference */
1202 MF_AddHandle(ht
, handles
, CreateDIBPatternBrushPt( mr
->rdParm
+ 2, mr
->rdParm
[1] ));
1205 case META_DIBBITBLT
:
1206 /* In practice I've found that there are two layouts for
1207 META_DIBBITBLT, one (the first here) is the usual one when a src
1208 dc is actually passed to it, the second occurs when the src dc is
1209 passed in as NULL to the creating BitBlt. As the second case has
1210 no dib, a size check will suffice to distinguish.
1212 Caolan.McNamara@ul.ie */
1214 if (mr
->rdSize
> 12) {
1215 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[8]);
1216 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize(info
, mr
->rdParm
[0]);
1218 StretchDIBits(hdc
, (SHORT
)mr
->rdParm
[7], (SHORT
)mr
->rdParm
[6], (SHORT
)mr
->rdParm
[5],
1219 (SHORT
)mr
->rdParm
[4], (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
1220 (SHORT
)mr
->rdParm
[5], (SHORT
)mr
->rdParm
[4], bits
, info
,
1221 DIB_RGB_COLORS
, MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
1223 else /* equivalent to a PatBlt */
1224 PatBlt(hdc
, (SHORT
)mr
->rdParm
[8], (SHORT
)mr
->rdParm
[7],
1225 (SHORT
)mr
->rdParm
[6], (SHORT
)mr
->rdParm
[5],
1226 MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
1229 case META_SETTEXTCHAREXTRA
:
1230 SetTextCharacterExtra(hdc
, (SHORT
)mr
->rdParm
[0]);
1233 case META_SETTEXTJUSTIFICATION
:
1234 SetTextJustification(hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0]);
1237 case META_EXTFLOODFILL
:
1238 ExtFloodFill(hdc
, (SHORT
)mr
->rdParm
[4], (SHORT
)mr
->rdParm
[3],
1239 MAKELONG(mr
->rdParm
[1], mr
->rdParm
[2]),
1243 case META_SETDIBTODEV
:
1245 BITMAPINFO
*info
= (BITMAPINFO
*) &(mr
->rdParm
[9]);
1246 char *bits
= (char *)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[0] );
1247 SetDIBitsToDevice(hdc
, (SHORT
)mr
->rdParm
[8], (SHORT
)mr
->rdParm
[7],
1248 (SHORT
)mr
->rdParm
[6], (SHORT
)mr
->rdParm
[5],
1249 (SHORT
)mr
->rdParm
[4], (SHORT
)mr
->rdParm
[3],
1250 mr
->rdParm
[2], mr
->rdParm
[1], bits
, info
,
1255 #define META_UNIMP(x) case x: \
1256 FIXME("PlayMetaFileRecord:record type "#x" not implemented.\n"); \
1258 META_UNIMP(META_DRAWTEXT
)
1259 META_UNIMP(META_ANIMATEPALETTE
)
1260 META_UNIMP(META_SETPALENTRIES
)
1261 META_UNIMP(META_RESIZEPALETTE
)
1262 META_UNIMP(META_RESETDC
)
1263 META_UNIMP(META_STARTDOC
)
1264 META_UNIMP(META_STARTPAGE
)
1265 META_UNIMP(META_ENDPAGE
)
1266 META_UNIMP(META_ABORTDOC
)
1267 META_UNIMP(META_ENDDOC
)
1268 META_UNIMP(META_CREATEBRUSH
)
1269 META_UNIMP(META_CREATEBITMAPINDIRECT
)
1270 META_UNIMP(META_CREATEBITMAP
)
1274 WARN("PlayMetaFileRecord: Unknown record type %x\n", mr
->rdFunction
);
1280 /******************************************************************
1281 * GetMetaFileBits (GDI.159)
1283 * Trade in a metafile object handle for a handle to the metafile memory.
1287 HGLOBAL16 WINAPI
GetMetaFileBits16(
1288 HMETAFILE16 hmf
/* [in] metafile handle */
1291 TRACE("hMem out: %04x\n", hmf
);
1295 /******************************************************************
1296 * SetMetaFileBits (GDI.160)
1298 * Trade in a metafile memory handle for a handle to a metafile object.
1299 * The memory region should hold a proper metafile, otherwise
1300 * problems will occur when it is used. Validity of the memory is not
1301 * checked. The function is essentially just the identity function.
1303 HMETAFILE16 WINAPI
SetMetaFileBits16(
1305 /* [in] handle to a memory region holding a metafile */
1308 TRACE("hmf out: %04x\n", hMem
);
1313 /******************************************************************
1314 * SetMetaFileBitsBetter (GDI.196)
1316 * Trade in a metafile memory handle for a handle to a metafile object,
1317 * making a cursory check (using IsValidMetaFile()) that the memory
1318 * handle points to a valid metafile.
1321 * Handle to a metafile on success, NULL on failure..
1323 HMETAFILE16 WINAPI
SetMetaFileBitsBetter16( HMETAFILE16 hMeta
)
1325 if( IsValidMetaFile16( hMeta
) )
1326 return (HMETAFILE16
)GlobalReAlloc16( hMeta
, 0,
1327 GMEM_SHARE
| GMEM_NODISCARD
| GMEM_MODIFY
);
1328 return (HMETAFILE16
)0;
1331 /******************************************************************
1332 * SetMetaFileBitsEx (GDI32.@)
1334 * Create a metafile from raw data. No checking of the data is performed.
1335 * Use _GetMetaFileBitsEx_ to get raw data from a metafile.
1337 HMETAFILE WINAPI
SetMetaFileBitsEx(
1338 UINT size
, /* [in] size of metafile, in bytes */
1339 const BYTE
*lpData
/* [in] pointer to metafile data */
1342 METAHEADER
*mh
= HeapAlloc( GetProcessHeap(), 0, size
);
1344 memcpy(mh
, lpData
, size
);
1345 return MF_Create_HMETAFILE(mh
);
1348 /*****************************************************************
1349 * GetMetaFileBitsEx (GDI32.@) Get raw metafile data
1351 * Copies the data from metafile _hmf_ into the buffer _buf_.
1352 * If _buf_ is zero, returns size of buffer required. Otherwise,
1353 * returns number of bytes copied.
1355 UINT WINAPI
GetMetaFileBitsEx(
1356 HMETAFILE hmf
, /* [in] metafile */
1357 UINT nSize
, /* [in] size of buf */
1358 LPVOID buf
/* [out] buffer to receive raw metafile data */
1360 METAHEADER
*mh
= MF_GetMetaHeader(hmf
);
1363 TRACE("(%08x,%d,%p)\n", hmf
, nSize
, buf
);
1364 if (!mh
) return 0; /* FIXME: error code */
1365 if(mh
->mtType
== METAFILE_DISK
)
1366 FIXME("Disk-based metafile?\n");
1367 mfSize
= mh
->mtSize
* 2;
1369 TRACE("returning size %d\n", mfSize
);
1372 if(mfSize
> nSize
) mfSize
= nSize
;
1373 memmove(buf
, mh
, mfSize
);
1377 /******************************************************************
1378 * GetWinMetaFileBits [GDI32.@]
1380 UINT WINAPI
GetWinMetaFileBits(HENHMETAFILE hemf
,
1381 UINT cbBuffer
, LPBYTE lpbBuffer
,
1382 INT fnMapMode
, HDC hdcRef
)
1388 FIXME("(%d,%d,%p,%d,%d): stub\n",
1389 hemf
, cbBuffer
, lpbBuffer
, fnMapMode
, hdcRef
);
1390 hdcmf
= CreateMetaFileA(NULL
);
1391 /* PlayEnhMetaFile(hdcmf, hemf, lpRect); where does the bounding rect come from? */
1392 hmf
= CloseMetaFile(hdcmf
);
1393 ret
= GetMetaFileBitsEx(hmf
, cbBuffer
, lpbBuffer
);
1394 DeleteMetaFile(hmf
);
1398 /******************************************************************
1399 * MF_Play_MetaCreateRegion
1401 * Handles META_CREATEREGION for PlayMetaFileRecord().
1405 * The layout of the record looks something like this:
1410 * 2 Looks like a handle? - not constant
1412 * 4 Total number of bytes
1413 * 5 No. of separate bands = n [see below]
1414 * 6 Largest number of x co-ords in a band
1415 * 7-10 Bounding box x1 y1 x2 y2
1418 * Regions are divided into bands that are uniform in the
1419 * y-direction. Each band consists of pairs of on/off x-coords and is
1421 * m y0 y1 x1 x2 x3 ... xm m
1422 * into successive rdParm[]s.
1424 * This is probably just a dump of the internal RGNOBJ?
1430 static BOOL
MF_Play_MetaCreateRegion( METARECORD
*mr
, HRGN hrgn
)
1435 HRGN hrgn2
= CreateRectRgn( 0, 0, 0, 0 );
1437 for(band
= 0, start
= &(mr
->rdParm
[11]); band
< mr
->rdParm
[5];
1438 band
++, start
= end
+ 1) {
1439 if(*start
/ 2 != (*start
+ 1) / 2) {
1440 WARN("Delimiter not even.\n");
1441 DeleteObject( hrgn2
);
1445 end
= start
+ *start
+ 3;
1446 if(end
> (WORD
*)mr
+ mr
->rdSize
) {
1447 WARN("End points outside record.\n");
1448 DeleteObject( hrgn2
);
1452 if(*start
!= *end
) {
1453 WARN("Mismatched delimiters.\n");
1454 DeleteObject( hrgn2
);
1458 y0
= *(INT16
*)(start
+ 1);
1459 y1
= *(INT16
*)(start
+ 2);
1460 for(pair
= 0; pair
< *start
/ 2; pair
++) {
1461 SetRectRgn( hrgn2
, *(INT16
*)(start
+ 3 + 2*pair
), y0
,
1462 *(INT16
*)(start
+ 4 + 2*pair
), y1
);
1463 CombineRgn(hrgn
, hrgn
, hrgn2
, RGN_OR
);
1466 DeleteObject( hrgn2
);
1471 /******************************************************************
1472 * MF_Play_MetaExtTextOut
1474 * Handles META_EXTTEXTOUT for PlayMetaFileRecord().
1477 static BOOL
MF_Play_MetaExtTextOut(HDC hdc
, METARECORD
*mr
)
1486 BOOL isrect
= mr
->rdParm
[3] & (ETO_OPAQUE
| ETO_CLIPPED
);
1488 s1
= mr
->rdParm
[2]; /* String length */
1489 len
= sizeof(METARECORD
) + (((s1
+ 1) >> 1) * 2) + 2 * sizeof(short)
1490 + sizeof(UINT16
) + (isrect
? sizeof(RECT16
) : 0);
1491 /* rec len without dx array */
1493 sot
= (LPSTR
)&mr
->rdParm
[4]; /* start_of_text */
1496 rect
.left
= (SHORT
)mr
->rdParm
[4];
1497 rect
.top
= (SHORT
)mr
->rdParm
[5];
1498 rect
.right
= (SHORT
)mr
->rdParm
[6];
1499 rect
.bottom
= (SHORT
)mr
->rdParm
[7];
1500 sot
+= sizeof(RECT16
); /* there is a rectangle, so add offset */
1503 if (mr
->rdSize
== len
/ 2)
1504 dxx
= NULL
; /* determine if array present */
1506 if (mr
->rdSize
== (len
+ s1
* sizeof(INT16
)) / 2)
1508 dxx
= (LPINT16
)(sot
+(((s1
+1)>>1)*2));
1509 dx
= HeapAlloc( GetProcessHeap(), 0, s1
*sizeof(INT
));
1510 if (dx
) for (i
= 0; i
< s1
; i
++) dx
[i
] = (SHORT
)dxx
[i
];
1513 TRACE("%s len: %ld\n", sot
, mr
->rdSize
);
1515 "Please report: ExtTextOut len=%ld slen=%d rdSize=%ld opt=%04x\n",
1516 len
, s1
, mr
->rdSize
, mr
->rdParm
[3]);
1517 dxx
= NULL
; /* should't happen -- but if, we continue with NULL */
1520 (SHORT
)mr
->rdParm
[1], /* X position */
1521 (SHORT
)mr
->rdParm
[0], /* Y position */
1522 mr
->rdParm
[3], /* options */
1523 &rect
, /* rectangle */
1525 s1
, dx
); /* length, dx array */
1528 TRACE("%s len: %ld dx0: %d\n", sot
, mr
->rdSize
, dx
[0]);
1529 HeapFree( GetProcessHeap(), 0, dx
);