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"
56 #include "wine/debug.h"
58 WINE_DEFAULT_DEBUG_CHANNEL(metafile
);
75 #define MFHEADERSIZE (sizeof(METAHEADER))
76 #define MFVERSION 0x300
78 /* ### start build ### */
79 extern WORD CALLBACK
MF_CallTo16_word_wllwl(MFENUMPROC16
,WORD
,LONG
,LONG
,WORD
,LONG
);
80 /* ### stop build ### */
82 /******************************************************************
85 * Add a handle to an external handle table and return the index
87 static int MF_AddHandle(HANDLETABLE
*ht
, UINT htlen
, HGDIOBJ hobj
)
91 for (i
= 0; i
< htlen
; i
++)
93 if (*(ht
->objectHandle
+ i
) == 0)
95 *(ht
->objectHandle
+ i
) = hobj
;
103 /******************************************************************
104 * MF_Create_HMETATFILE
106 * Creates a (32 bit) HMETAFILE object from a METAHEADER
108 * HMETAFILEs are GDI objects.
110 HMETAFILE
MF_Create_HMETAFILE(METAHEADER
*mh
)
113 METAFILEOBJ
*metaObj
= GDI_AllocObject( sizeof(METAFILEOBJ
), METAFILE_MAGIC
,
114 (HGDIOBJ
*)&hmf
, NULL
);
118 GDI_ReleaseObj( hmf
);
123 /******************************************************************
124 * MF_Create_HMETATFILE16
126 * Creates a HMETAFILE16 object from a METAHEADER
128 * HMETAFILE16s are Global memory handles.
130 HMETAFILE16
MF_Create_HMETAFILE16(METAHEADER
*mh
)
133 DWORD size
= mh
->mtSize
* sizeof(WORD
);
135 hmf
= GlobalAlloc16(GMEM_MOVEABLE
, size
);
138 METAHEADER
*mh_dest
= GlobalLock16(hmf
);
139 memcpy(mh_dest
, mh
, size
);
142 HeapFree(GetProcessHeap(), 0, mh
);
146 /******************************************************************
149 * Returns ptr to METAHEADER associated with HMETAFILE
151 static METAHEADER
*MF_GetMetaHeader( HMETAFILE hmf
)
153 METAHEADER
*ret
= NULL
;
154 METAFILEOBJ
* metaObj
= (METAFILEOBJ
*)GDI_GetObjPtr( hmf
, METAFILE_MAGIC
);
158 GDI_ReleaseObj( hmf
);
163 /******************************************************************
166 * Returns ptr to METAHEADER associated with HMETAFILE16
167 * Should be followed by call to MF_ReleaseMetaHeader16
169 static METAHEADER
*MF_GetMetaHeader16( HMETAFILE16 hmf
)
171 return GlobalLock16(hmf
);
174 /******************************************************************
175 * MF_ReleaseMetaHeader16
177 * Releases METAHEADER associated with HMETAFILE16
179 static BOOL16
MF_ReleaseMetaHeader16( HMETAFILE16 hmf
)
181 return GlobalUnlock16( hmf
);
185 /******************************************************************
188 * Convert an array of POINT16 to an array of POINT.
189 * Result must be freed by caller.
191 static POINT
*convert_points( UINT count
, POINT16
*pt16
)
194 POINT
*ret
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(*ret
) );
197 for (i
= 0; i
< count
; i
++)
199 ret
[i
].x
= pt16
[i
].x
;
200 ret
[i
].y
= pt16
[i
].y
;
207 /******************************************************************
208 * DeleteMetaFile (GDI.127)
210 BOOL16 WINAPI
DeleteMetaFile16( HMETAFILE16 hmf
)
212 return !GlobalFree16( hmf
);
215 /******************************************************************
216 * DeleteMetaFile (GDI32.@)
218 * Delete a memory-based metafile.
221 BOOL WINAPI
DeleteMetaFile( HMETAFILE hmf
)
223 METAFILEOBJ
* metaObj
= (METAFILEOBJ
*)GDI_GetObjPtr( hmf
, METAFILE_MAGIC
);
224 if (!metaObj
) return FALSE
;
225 HeapFree( GetProcessHeap(), 0, metaObj
->mh
);
226 GDI_FreeObject( hmf
, metaObj
);
230 /******************************************************************
233 * Returns a pointer to a memory based METAHEADER read in from file HFILE
236 static METAHEADER
*MF_ReadMetaFile(HANDLE hfile
)
239 DWORD BytesRead
, size
;
241 size
= sizeof(METAHEADER
);
242 mh
= HeapAlloc( GetProcessHeap(), 0, size
);
244 if(ReadFile( hfile
, mh
, size
, &BytesRead
, NULL
) == 0 ||
246 HeapFree( GetProcessHeap(), 0, mh
);
249 size
= mh
->mtSize
* 2;
250 mh
= HeapReAlloc( GetProcessHeap(), 0, mh
, size
);
252 size
-= sizeof(METAHEADER
);
253 if(ReadFile( hfile
, (char *)mh
+ sizeof(METAHEADER
), size
, &BytesRead
,
256 HeapFree( GetProcessHeap(), 0, mh
);
260 if (mh
->mtType
!= METAFILE_MEMORY
) {
261 WARN("Disk metafile had mtType = %04x\n", mh
->mtType
);
262 mh
->mtType
= METAFILE_MEMORY
;
267 /******************************************************************
268 * GetMetaFile (GDI.124)
270 HMETAFILE16 WINAPI
GetMetaFile16( LPCSTR lpFilename
)
275 TRACE("%s\n", lpFilename
);
280 if((hFile
= CreateFileA(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
281 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
284 mh
= MF_ReadMetaFile(hFile
);
287 return MF_Create_HMETAFILE16( mh
);
290 /******************************************************************
291 * GetMetaFileA (GDI32.@)
293 * Read a metafile from a file. Returns handle to a memory-based metafile.
295 HMETAFILE WINAPI
GetMetaFileA( LPCSTR lpFilename
)
300 TRACE("%s\n", lpFilename
);
305 if((hFile
= CreateFileA(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
306 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
309 mh
= MF_ReadMetaFile(hFile
);
312 return MF_Create_HMETAFILE( mh
);
317 /******************************************************************
318 * GetMetaFileW (GDI32.@)
320 HMETAFILE WINAPI
GetMetaFileW( LPCWSTR lpFilename
)
325 TRACE("%s\n", debugstr_w(lpFilename
));
330 if((hFile
= CreateFileW(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
331 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
334 mh
= MF_ReadMetaFile(hFile
);
337 return MF_Create_HMETAFILE( mh
);
341 /******************************************************************
342 * MF_LoadDiskBasedMetaFile
344 * Creates a new memory-based metafile from a disk-based one.
346 static METAHEADER
*MF_LoadDiskBasedMetaFile(METAHEADER
*mh
)
352 if(mh
->mtType
!= METAFILE_DISK
) {
353 ERR("Not a disk based metafile\n");
356 mhd
= (METAHEADERDISK
*)((char *)mh
+ sizeof(METAHEADER
));
358 if((hfile
= CreateFileA(mhd
->filename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
359 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
) {
360 WARN("Can't open file of disk based metafile\n");
363 mh2
= MF_ReadMetaFile(hfile
);
368 /******************************************************************
369 * MF_CreateMetaHeaderDisk
371 * Take a memory based METAHEADER and change it to a disk based METAHEADER
372 * assosiated with filename. Note: Trashes contents of old one.
374 METAHEADER
*MF_CreateMetaHeaderDisk(METAHEADER
*mh
, LPCSTR filename
)
379 mh
= HeapReAlloc( GetProcessHeap(), 0, mh
,
380 sizeof(METAHEADER
) + sizeof(METAHEADERDISK
));
381 mh
->mtType
= METAFILE_DISK
;
382 size
= HeapSize( GetProcessHeap(), 0, mh
);
383 mhd
= (METAHEADERDISK
*)((char *)mh
+ sizeof(METAHEADER
));
384 strcpy(mhd
->filename
, filename
);
388 /******************************************************************
389 * CopyMetaFile (GDI.151)
391 HMETAFILE16 WINAPI
CopyMetaFile16( HMETAFILE16 hSrcMetaFile
, LPCSTR lpFilename
)
393 METAHEADER
*mh
= MF_GetMetaHeader16( hSrcMetaFile
);
394 METAHEADER
*mh2
= NULL
;
397 TRACE("(%08x,%s)\n", hSrcMetaFile
, lpFilename
);
401 if(mh
->mtType
== METAFILE_DISK
)
402 mh2
= MF_LoadDiskBasedMetaFile(mh
);
404 mh2
= HeapAlloc( GetProcessHeap(), 0, mh
->mtSize
* 2 );
405 memcpy( mh2
, mh
, mh
->mtSize
* 2 );
407 MF_ReleaseMetaHeader16( hSrcMetaFile
);
409 if(lpFilename
) { /* disk based metafile */
410 if((hFile
= CreateFileA(lpFilename
, GENERIC_WRITE
, 0, NULL
,
411 CREATE_ALWAYS
, 0, 0)) == INVALID_HANDLE_VALUE
) {
412 HeapFree( GetProcessHeap(), 0, mh2
);
415 WriteFile(hFile
, mh2
, mh2
->mtSize
* 2, NULL
, NULL
);
417 mh2
= MF_CreateMetaHeaderDisk(mh2
, lpFilename
);
420 return MF_Create_HMETAFILE16( mh2
);
424 /******************************************************************
425 * CopyMetaFileA (GDI32.@)
427 * Copies the metafile corresponding to hSrcMetaFile to either
428 * a disk file, if a filename is given, or to a new memory based
429 * metafile, if lpFileName is NULL.
433 * Handle to metafile copy on success, NULL on failure.
437 * Copying to disk returns NULL even if successful.
439 HMETAFILE WINAPI
CopyMetaFileA(
440 HMETAFILE hSrcMetaFile
, /* [in] handle of metafile to copy */
441 LPCSTR lpFilename
/* [in] filename if copying to a file */
443 METAHEADER
*mh
= MF_GetMetaHeader( hSrcMetaFile
);
444 METAHEADER
*mh2
= NULL
;
447 TRACE("(%p,%s)\n", hSrcMetaFile
, lpFilename
);
451 if(mh
->mtType
== METAFILE_DISK
)
452 mh2
= MF_LoadDiskBasedMetaFile(mh
);
454 mh2
= HeapAlloc( GetProcessHeap(), 0, mh
->mtSize
* 2 );
455 memcpy( mh2
, mh
, mh
->mtSize
* 2 );
458 if(lpFilename
) { /* disk based metafile */
459 if((hFile
= CreateFileA(lpFilename
, GENERIC_WRITE
, 0, NULL
,
460 CREATE_ALWAYS
, 0, 0)) == INVALID_HANDLE_VALUE
) {
461 HeapFree( GetProcessHeap(), 0, mh2
);
464 WriteFile(hFile
, mh2
, mh2
->mtSize
* 2, NULL
, NULL
);
466 mh2
= MF_CreateMetaHeaderDisk(mh2
, lpFilename
);
469 return MF_Create_HMETAFILE( mh2
);
473 /******************************************************************
474 * CopyMetaFileW (GDI32.@)
476 HMETAFILE WINAPI
CopyMetaFileW( HMETAFILE hSrcMetaFile
,
480 DWORD len
= WideCharToMultiByte( CP_ACP
, 0, lpFilename
, -1, NULL
, 0, NULL
, NULL
);
481 LPSTR p
= HeapAlloc( GetProcessHeap(), 0, len
);
485 WideCharToMultiByte( CP_ACP
, 0, lpFilename
, -1, p
, len
, NULL
, NULL
);
486 ret
= CopyMetaFileA( hSrcMetaFile
, p
);
487 HeapFree( GetProcessHeap(), 0, p
);
493 /******************************************************************
494 * IsValidMetaFile (GDI.410)
496 * Attempts to check if a given metafile is correctly formatted.
497 * Currently, the only things verified are several properties of the
501 * TRUE if hmf passes some tests for being a valid metafile, FALSE otherwise.
504 * This is not exactly what windows does, see _Undocumented_Windows_
507 BOOL16 WINAPI
IsValidMetaFile16(HMETAFILE16 hmf
)
510 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
512 if (mh
->mtType
== METAFILE_MEMORY
|| mh
->mtType
== METAFILE_DISK
)
513 if (mh
->mtHeaderSize
== MFHEADERSIZE
/sizeof(INT16
))
514 if (mh
->mtVersion
== MFVERSION
)
516 MF_ReleaseMetaHeader16(hmf
);
518 TRACE("IsValidMetaFile %x => %d\n",hmf
,res
);
523 /*******************************************************************
526 * Helper for PlayMetaFile
528 static BOOL
MF_PlayMetaFile( HDC hdc
, METAHEADER
*mh
)
533 unsigned int offset
= 0;
540 if (!mh
) return FALSE
;
541 if(mh
->mtType
== METAFILE_DISK
) { /* Create a memory-based copy */
542 mh
= MF_LoadDiskBasedMetaFile(mh
);
543 if(!mh
) return FALSE
;
547 /* save the current pen, brush and font */
548 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
549 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
550 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
552 /* create the handle table */
553 ht
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
554 sizeof(HANDLETABLE
) * mh
->mtNoObjects
);
555 if(!ht
) return FALSE
;
557 /* loop through metafile playing records */
558 offset
= mh
->mtHeaderSize
* 2;
559 while (offset
< mh
->mtSize
* 2)
561 mr
= (METARECORD
*)((char *)mh
+ offset
);
562 TRACE("offset=%04x,size=%08lx\n",
566 "Entry got size 0 at offset %d, total mf length is %ld\n",
567 offset
,mh
->mtSize
*2);
568 break; /* would loop endlessly otherwise */
570 offset
+= mr
->rdSize
* 2;
571 PlayMetaFileRecord( hdc
, ht
, mr
, mh
->mtNoObjects
);
574 SelectObject(hdc
, hBrush
);
575 SelectObject(hdc
, hPen
);
576 SelectObject(hdc
, hFont
);
578 /* free objects in handle table */
579 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
580 if(*(ht
->objectHandle
+ i
) != 0)
581 DeleteObject(*(ht
->objectHandle
+ i
));
583 /* free handle table */
584 HeapFree( GetProcessHeap(), 0, ht
);
586 HeapFree( GetProcessHeap(), 0, mh
);
590 /******************************************************************
591 * PlayMetaFile (GDI.123)
594 BOOL16 WINAPI
PlayMetaFile16( HDC16 hdc
, HMETAFILE16 hmf
)
597 METAHEADER
*mh
= MF_GetMetaHeader16( hmf
);
598 ret
= MF_PlayMetaFile( HDC_32(hdc
), mh
);
599 MF_ReleaseMetaHeader16( hmf
);
603 /******************************************************************
604 * PlayMetaFile (GDI32.@)
606 * Renders the metafile specified by hmf in the DC specified by
607 * hdc. Returns FALSE on failure, TRUE on success.
609 BOOL WINAPI
PlayMetaFile(
610 HDC hdc
, /* [in] handle of DC to render in */
611 HMETAFILE hmf
/* [in] handle of metafile to render */
614 METAHEADER
*mh
= MF_GetMetaHeader( hmf
);
615 return MF_PlayMetaFile( hdc
, mh
);
619 /******************************************************************
620 * EnumMetaFile (GDI.175)
623 BOOL16 WINAPI
EnumMetaFile16( HDC16 hdc16
, HMETAFILE16 hmf
,
624 MFENUMPROC16 lpEnumFunc
, LPARAM lpData
)
626 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
629 HDC hdc
= HDC_32(hdc16
);
632 unsigned int offset
= 0;
637 BOOL16 result
= TRUE
, loaded
= FALSE
;
639 TRACE("(%p, %04x, %p, %08lx)\n", hdc
, hmf
, lpEnumFunc
, lpData
);
641 if(!mh
) return FALSE
;
642 if(mh
->mtType
== METAFILE_DISK
) { /* Create a memory-based copy */
643 mh
= MF_LoadDiskBasedMetaFile(mh
);
644 if(!mh
) return FALSE
;
648 /* save the current pen, brush and font */
649 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
650 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
651 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
653 /* create the handle table */
655 hHT
= GlobalAlloc16(GMEM_MOVEABLE
| GMEM_ZEROINIT
,
656 sizeof(HANDLETABLE16
) * mh
->mtNoObjects
);
657 spht
= K32WOWGlobalLock16(hHT
);
660 offset
= mh
->mtHeaderSize
* 2;
662 /* loop through metafile records */
664 while (offset
< (mh
->mtSize
* 2))
666 mr
= (METARECORD
*)((char *)mh
+ offset
);
668 if (!MF_CallTo16_word_wllwl( lpEnumFunc
, hdc16
, spht
,
669 MAKESEGPTR( seg
+ (HIWORD(offset
) << __AHSHIFT
), LOWORD(offset
) ),
670 mh
->mtNoObjects
, (LONG
)lpData
))
677 offset
+= (mr
->rdSize
* 2);
680 SelectObject(hdc
, hBrush
);
681 SelectObject(hdc
, hPen
);
682 SelectObject(hdc
, hFont
);
684 ht
= (HANDLETABLE16
*)GlobalLock16(hHT
);
686 /* free objects in handle table */
687 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
688 if(*(ht
->objectHandle
+ i
) != 0)
689 DeleteObject( (HGDIOBJ
)(ULONG_PTR
)(*(ht
->objectHandle
+ i
) ));
691 /* free handle table */
694 HeapFree( GetProcessHeap(), 0, mh
);
695 MF_ReleaseMetaHeader16(hmf
);
699 /******************************************************************
700 * EnumMetaFile (GDI32.@)
702 * Loop through the metafile records in hmf, calling the user-specified
703 * function for each one, stopping when the user's function returns FALSE
704 * (which is considered to be failure)
705 * or when no records are left (which is considered to be success).
708 * TRUE on success, FALSE on failure.
711 * Niels de carpentier, april 1996
713 BOOL WINAPI
EnumMetaFile(
716 MFENUMPROC lpEnumFunc
,
719 METAHEADER
*mhTemp
= NULL
, *mh
= MF_GetMetaHeader(hmf
);
724 unsigned int offset
= 0;
729 TRACE("(%p,%p,%p,%p)\n", hdc
, hmf
, lpEnumFunc
, (void*)lpData
);
731 if(mh
->mtType
== METAFILE_DISK
)
733 /* Create a memory-based copy */
734 if (!(mhTemp
= MF_LoadDiskBasedMetaFile(mh
))) return FALSE
;
738 /* save the current pen, brush and font */
739 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
740 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
741 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
743 ht
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
744 sizeof(HANDLETABLE
) * mh
->mtNoObjects
);
746 /* loop through metafile records */
747 offset
= mh
->mtHeaderSize
* 2;
749 while (offset
< (mh
->mtSize
* 2))
751 mr
= (METARECORD
*)((char *)mh
+ offset
);
752 if(mr
->rdFunction
== META_EOF
) {
753 TRACE("Got META_EOF so stopping\n");
756 TRACE("Calling EnumFunc with record type %x\n",
758 if (!lpEnumFunc( hdc
, ht
, mr
, mh
->mtNoObjects
, (LONG
)lpData
))
764 offset
+= (mr
->rdSize
* 2);
767 /* restore pen, brush and font */
768 SelectObject(hdc
, hBrush
);
769 SelectObject(hdc
, hPen
);
770 SelectObject(hdc
, hFont
);
772 /* free objects in handle table */
773 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
774 if(*(ht
->objectHandle
+ i
) != 0)
775 DeleteObject(*(ht
->objectHandle
+ i
));
777 /* free handle table */
778 HeapFree( GetProcessHeap(), 0, ht
);
779 /* free a copy of metafile */
780 if (mhTemp
) HeapFree( GetProcessHeap(), 0, mhTemp
);
784 static BOOL
MF_Play_MetaCreateRegion( METARECORD
*mr
, HRGN hrgn
);
785 static BOOL
MF_Play_MetaExtTextOut(HDC hdc
, METARECORD
*mr
);
786 /******************************************************************
787 * PlayMetaFileRecord (GDI32.@)
789 * Render a single metafile record specified by *mr in the DC hdc, while
790 * using the handle table *ht, of length handles,
791 * to store metafile objects.
794 * The following metafile records are unimplemented:
796 * DRAWTEXT, ANIMATEPALETTE, SETPALENTRIES,
797 * RESIZEPALETTE, EXTFLOODFILL, RESETDC, STARTDOC, STARTPAGE, ENDPAGE,
798 * ABORTDOC, ENDDOC, CREATEBRUSH, CREATEBITMAPINDIRECT, and CREATEBITMAP.
800 BOOL WINAPI
PlayMetaFileRecord( HDC hdc
, HANDLETABLE
*ht
, METARECORD
*mr
, UINT handles
)
804 BITMAPINFOHEADER
*infohdr
;
806 TRACE("(%p %p %p %u) function %04x\n", hdc
, ht
, mr
, handles
, mr
->rdFunction
);
808 switch (mr
->rdFunction
)
813 case META_DELETEOBJECT
:
814 DeleteObject(*(ht
->objectHandle
+ mr
->rdParm
[0]));
815 *(ht
->objectHandle
+ mr
->rdParm
[0]) = 0;
818 case META_SETBKCOLOR
:
819 SetBkColor(hdc
, MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
823 SetBkMode(hdc
, mr
->rdParm
[0]);
826 case META_SETMAPMODE
:
827 SetMapMode(hdc
, mr
->rdParm
[0]);
831 SetROP2(hdc
, mr
->rdParm
[0]);
835 SetRelAbs(hdc
, mr
->rdParm
[0]);
838 case META_SETPOLYFILLMODE
:
839 SetPolyFillMode(hdc
, mr
->rdParm
[0]);
842 case META_SETSTRETCHBLTMODE
:
843 SetStretchBltMode(hdc
, mr
->rdParm
[0]);
846 case META_SETTEXTCOLOR
:
847 SetTextColor(hdc
, MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
850 case META_SETWINDOWORG
:
851 SetWindowOrgEx(hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0], NULL
);
854 case META_SETWINDOWEXT
:
855 SetWindowExtEx(hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0], NULL
);
858 case META_SETVIEWPORTORG
:
859 SetViewportOrgEx(hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0], NULL
);
862 case META_SETVIEWPORTEXT
:
863 SetViewportExtEx(hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0], NULL
);
866 case META_OFFSETWINDOWORG
:
867 OffsetWindowOrgEx(hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0], NULL
);
870 case META_SCALEWINDOWEXT
:
871 ScaleWindowExtEx(hdc
, (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
872 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0], NULL
);
875 case META_OFFSETVIEWPORTORG
:
876 OffsetViewportOrgEx(hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0], NULL
);
879 case META_SCALEVIEWPORTEXT
:
880 ScaleViewportExtEx(hdc
, (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
881 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0], NULL
);
885 LineTo(hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0]);
889 MoveToEx(hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0], NULL
);
892 case META_EXCLUDECLIPRECT
:
893 ExcludeClipRect( hdc
, (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
894 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0] );
897 case META_INTERSECTCLIPRECT
:
898 IntersectClipRect( hdc
, (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
899 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0] );
903 Arc(hdc
, (SHORT
)mr
->rdParm
[7], (SHORT
)mr
->rdParm
[6],
904 (SHORT
)mr
->rdParm
[5], (SHORT
)mr
->rdParm
[4],
905 (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
906 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0]);
910 Ellipse(hdc
, (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
911 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0]);
915 FloodFill(hdc
, (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
916 MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
920 Pie(hdc
, (SHORT
)mr
->rdParm
[7], (SHORT
)mr
->rdParm
[6],
921 (SHORT
)mr
->rdParm
[5], (SHORT
)mr
->rdParm
[4],
922 (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
923 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0]);
927 Rectangle(hdc
, (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
928 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0]);
932 RoundRect(hdc
, (SHORT
)mr
->rdParm
[5], (SHORT
)mr
->rdParm
[4],
933 (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
934 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0]);
938 PatBlt(hdc
, (SHORT
)mr
->rdParm
[5], (SHORT
)mr
->rdParm
[4],
939 (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
940 MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
948 SetPixel(hdc
, (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
949 MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
952 case META_OFFSETCLIPRGN
:
953 OffsetClipRgn( hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0] );
958 TextOutA(hdc
, (SHORT
)mr
->rdParm
[((s1
+ 1) >> 1) + 2],
959 (SHORT
)mr
->rdParm
[((s1
+ 1) >> 1) + 1],
960 (char *)(mr
->rdParm
+ 1), s1
);
964 if ((pt
= convert_points( mr
->rdParm
[0], (LPPOINT16
)(mr
->rdParm
+ 1))))
966 Polygon(hdc
, pt
, mr
->rdParm
[0]);
967 HeapFree( GetProcessHeap(), 0, pt
);
971 case META_POLYPOLYGON
:
974 SHORT
*counts
= (SHORT
*)(mr
->rdParm
+ 1);
976 for (i
= total
= 0; i
< mr
->rdParm
[0]; i
++) total
+= counts
[i
];
977 pt
= convert_points( total
, (LPPOINT16
)(counts
+ mr
->rdParm
[0]) );
980 INT
*cnt32
= HeapAlloc( GetProcessHeap(), 0, mr
->rdParm
[0] * sizeof(*cnt32
) );
983 for (i
= 0; i
< mr
->rdParm
[0]; i
++) cnt32
[i
] = counts
[i
];
984 PolyPolygon( hdc
, pt
, cnt32
, mr
->rdParm
[0]);
985 HeapFree( GetProcessHeap(), 0, cnt32
);
988 HeapFree( GetProcessHeap(), 0, pt
);
993 if ((pt
= convert_points( mr
->rdParm
[0], (LPPOINT16
)(mr
->rdParm
+ 1))))
995 Polyline( hdc
, pt
, mr
->rdParm
[0] );
996 HeapFree( GetProcessHeap(), 0, pt
);
1000 case META_RESTOREDC
:
1001 RestoreDC(hdc
, (SHORT
)mr
->rdParm
[0]);
1004 case META_SELECTOBJECT
:
1005 SelectObject(hdc
, *(ht
->objectHandle
+ mr
->rdParm
[0]));
1009 Chord(hdc
, (SHORT
)mr
->rdParm
[7], (SHORT
)mr
->rdParm
[6],
1010 (SHORT
)mr
->rdParm
[5], (SHORT
)mr
->rdParm
[4],
1011 (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
1012 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0]);
1015 case META_CREATEPATTERNBRUSH
:
1016 switch (mr
->rdParm
[0])
1019 infohdr
= (BITMAPINFOHEADER
*)(mr
->rdParm
+ 2);
1020 MF_AddHandle(ht
, handles
,
1021 CreatePatternBrush(CreateBitmap(infohdr
->biWidth
,
1024 infohdr
->biBitCount
,
1025 (LPSTR
)(mr
->rdParm
+
1026 (sizeof(BITMAPINFOHEADER
) / 2) + 4))));
1030 infohdr
= (BITMAPINFOHEADER
*)(mr
->rdParm
+ 2);
1031 MF_AddHandle(ht
, handles
, CreateDIBPatternBrushPt( infohdr
, mr
->rdParm
[1] ));
1035 ERR("META_CREATEPATTERNBRUSH: Unknown pattern type %d\n",
1041 case META_CREATEPENINDIRECT
:
1044 pen
.lopnStyle
= mr
->rdParm
[0];
1045 pen
.lopnWidth
.x
= (SHORT
)mr
->rdParm
[1];
1046 pen
.lopnWidth
.y
= (SHORT
)mr
->rdParm
[2];
1047 pen
.lopnColor
= MAKELONG( mr
->rdParm
[3], mr
->rdParm
[4] );
1048 MF_AddHandle(ht
, handles
, CreatePenIndirect( &pen
));
1052 case META_CREATEFONTINDIRECT
:
1055 font
.lfHeight
= (SHORT
)mr
->rdParm
[0];
1056 font
.lfWidth
= (SHORT
)mr
->rdParm
[1];
1057 font
.lfEscapement
= (SHORT
)mr
->rdParm
[2];
1058 font
.lfOrientation
= (SHORT
)mr
->rdParm
[3];
1059 font
.lfWeight
= (SHORT
)mr
->rdParm
[4];
1060 font
.lfItalic
= LOBYTE(mr
->rdParm
[5]);
1061 font
.lfUnderline
= HIBYTE(mr
->rdParm
[5]);
1062 font
.lfStrikeOut
= LOBYTE(mr
->rdParm
[6]);
1063 font
.lfCharSet
= HIBYTE(mr
->rdParm
[6]);
1064 font
.lfOutPrecision
= LOBYTE(mr
->rdParm
[7]);
1065 font
.lfClipPrecision
= HIBYTE(mr
->rdParm
[7]);
1066 font
.lfQuality
= LOBYTE(mr
->rdParm
[8]);
1067 font
.lfPitchAndFamily
= HIBYTE(mr
->rdParm
[8]);
1068 memcpy( font
.lfFaceName
, mr
->rdParm
+ 9, LF_FACESIZE
);
1069 MF_AddHandle(ht
, handles
, CreateFontIndirectA( &font
));
1073 case META_CREATEBRUSHINDIRECT
:
1076 brush
.lbStyle
= mr
->rdParm
[0];
1077 brush
.lbColor
= MAKELONG( mr
->rdParm
[1], mr
->rdParm
[2] );
1078 brush
.lbHatch
= mr
->rdParm
[3];
1079 MF_AddHandle(ht
, handles
, CreateBrushIndirect( &brush
));
1083 case META_CREATEPALETTE
:
1084 MF_AddHandle(ht
, handles
, CreatePalette((LPLOGPALETTE
)mr
->rdParm
));
1087 case META_SETTEXTALIGN
:
1088 SetTextAlign(hdc
, mr
->rdParm
[0]);
1091 case META_SELECTPALETTE
:
1092 GDISelectPalette(hdc
, *(ht
->objectHandle
+ mr
->rdParm
[1]), mr
->rdParm
[0]);
1095 case META_SETMAPPERFLAGS
:
1096 SetMapperFlags(hdc
, MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1099 case META_REALIZEPALETTE
:
1100 GDIRealizePalette(hdc
);
1104 FIXME("META_ESCAPE unimplemented.\n");
1107 case META_EXTTEXTOUT
:
1108 MF_Play_MetaExtTextOut( hdc
, mr
);
1111 case META_STRETCHDIB
:
1113 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[11]);
1114 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[2] );
1115 StretchDIBits( hdc
, (SHORT
)mr
->rdParm
[10], (SHORT
)mr
->rdParm
[9], (SHORT
)mr
->rdParm
[8],
1116 (SHORT
)mr
->rdParm
[7], (SHORT
)mr
->rdParm
[6], (SHORT
)mr
->rdParm
[5],
1117 (SHORT
)mr
->rdParm
[4], (SHORT
)mr
->rdParm
[3], bits
, info
,
1118 mr
->rdParm
[2],MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1122 case META_DIBSTRETCHBLT
:
1124 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[10]);
1125 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[2] );
1126 StretchDIBits( hdc
, (SHORT
)mr
->rdParm
[9], (SHORT
)mr
->rdParm
[8], (SHORT
)mr
->rdParm
[7],
1127 (SHORT
)mr
->rdParm
[6], (SHORT
)mr
->rdParm
[5], (SHORT
)mr
->rdParm
[4],
1128 (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2], bits
, info
,
1129 DIB_RGB_COLORS
,MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1133 case META_STRETCHBLT
:
1135 HDC hdcSrc
= CreateCompatibleDC(hdc
);
1136 HBITMAP hbitmap
= CreateBitmap(mr
->rdParm
[10], /*Width */
1137 mr
->rdParm
[11], /*Height*/
1138 mr
->rdParm
[13], /*Planes*/
1139 mr
->rdParm
[14], /*BitsPixel*/
1140 (LPSTR
)&mr
->rdParm
[15]); /*bits*/
1141 SelectObject(hdcSrc
,hbitmap
);
1142 StretchBlt(hdc
, (SHORT
)mr
->rdParm
[9], (SHORT
)mr
->rdParm
[8],
1143 (SHORT
)mr
->rdParm
[7], (SHORT
)mr
->rdParm
[6],
1144 hdcSrc
, (SHORT
)mr
->rdParm
[5], (SHORT
)mr
->rdParm
[4],
1145 (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
1146 MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1153 HDC hdcSrc
= CreateCompatibleDC(hdc
);
1154 HBITMAP hbitmap
= CreateBitmap(mr
->rdParm
[7]/*Width */,
1155 mr
->rdParm
[8]/*Height*/,
1156 mr
->rdParm
[10]/*Planes*/,
1157 mr
->rdParm
[11]/*BitsPixel*/,
1158 (LPSTR
)&mr
->rdParm
[12]/*bits*/);
1159 SelectObject(hdcSrc
,hbitmap
);
1160 BitBlt(hdc
,(SHORT
)mr
->rdParm
[6],(SHORT
)mr
->rdParm
[5],
1161 (SHORT
)mr
->rdParm
[4],(SHORT
)mr
->rdParm
[3],
1162 hdcSrc
, (SHORT
)mr
->rdParm
[2],(SHORT
)mr
->rdParm
[1],
1163 MAKELONG(0,mr
->rdParm
[0]));
1168 case META_CREATEREGION
:
1170 HRGN hrgn
= CreateRectRgn(0,0,0,0);
1172 MF_Play_MetaCreateRegion(mr
, hrgn
);
1173 MF_AddHandle(ht
, handles
, hrgn
);
1177 case META_FILLREGION
:
1178 FillRgn(hdc
, *(ht
->objectHandle
+ mr
->rdParm
[1]),
1179 *(ht
->objectHandle
+ mr
->rdParm
[0]));
1182 case META_FRAMEREGION
:
1183 FrameRgn(hdc
, *(ht
->objectHandle
+ mr
->rdParm
[3]),
1184 *(ht
->objectHandle
+ mr
->rdParm
[2]),
1185 (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0]);
1188 case META_INVERTREGION
:
1189 InvertRgn(hdc
, *(ht
->objectHandle
+ mr
->rdParm
[0]));
1192 case META_PAINTREGION
:
1193 PaintRgn(hdc
, *(ht
->objectHandle
+ mr
->rdParm
[0]));
1196 case META_SELECTCLIPREGION
:
1197 SelectClipRgn(hdc
, *(ht
->objectHandle
+ mr
->rdParm
[0]));
1200 case META_DIBCREATEPATTERNBRUSH
:
1201 /* mr->rdParm[0] may be BS_PATTERN or BS_DIBPATTERN:
1202 but there's no difference */
1203 MF_AddHandle(ht
, handles
, CreateDIBPatternBrushPt( mr
->rdParm
+ 2, mr
->rdParm
[1] ));
1206 case META_DIBBITBLT
:
1207 /* In practice I've found that there are two layouts for
1208 META_DIBBITBLT, one (the first here) is the usual one when a src
1209 dc is actually passed to it, the second occurs when the src dc is
1210 passed in as NULL to the creating BitBlt. As the second case has
1211 no dib, a size check will suffice to distinguish.
1213 Caolan.McNamara@ul.ie */
1215 if (mr
->rdSize
> 12) {
1216 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[8]);
1217 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize(info
, mr
->rdParm
[0]);
1219 StretchDIBits(hdc
, (SHORT
)mr
->rdParm
[7], (SHORT
)mr
->rdParm
[6], (SHORT
)mr
->rdParm
[5],
1220 (SHORT
)mr
->rdParm
[4], (SHORT
)mr
->rdParm
[3], (SHORT
)mr
->rdParm
[2],
1221 (SHORT
)mr
->rdParm
[5], (SHORT
)mr
->rdParm
[4], bits
, info
,
1222 DIB_RGB_COLORS
, MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
1224 else /* equivalent to a PatBlt */
1225 PatBlt(hdc
, (SHORT
)mr
->rdParm
[8], (SHORT
)mr
->rdParm
[7],
1226 (SHORT
)mr
->rdParm
[6], (SHORT
)mr
->rdParm
[5],
1227 MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
1230 case META_SETTEXTCHAREXTRA
:
1231 SetTextCharacterExtra(hdc
, (SHORT
)mr
->rdParm
[0]);
1234 case META_SETTEXTJUSTIFICATION
:
1235 SetTextJustification(hdc
, (SHORT
)mr
->rdParm
[1], (SHORT
)mr
->rdParm
[0]);
1238 case META_EXTFLOODFILL
:
1239 ExtFloodFill(hdc
, (SHORT
)mr
->rdParm
[4], (SHORT
)mr
->rdParm
[3],
1240 MAKELONG(mr
->rdParm
[1], mr
->rdParm
[2]),
1244 case META_SETDIBTODEV
:
1246 BITMAPINFO
*info
= (BITMAPINFO
*) &(mr
->rdParm
[9]);
1247 char *bits
= (char *)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[0] );
1248 SetDIBitsToDevice(hdc
, (SHORT
)mr
->rdParm
[8], (SHORT
)mr
->rdParm
[7],
1249 (SHORT
)mr
->rdParm
[6], (SHORT
)mr
->rdParm
[5],
1250 (SHORT
)mr
->rdParm
[4], (SHORT
)mr
->rdParm
[3],
1251 mr
->rdParm
[2], mr
->rdParm
[1], bits
, info
,
1256 #define META_UNIMP(x) case x: \
1257 FIXME("PlayMetaFileRecord:record type "#x" not implemented.\n"); \
1259 META_UNIMP(META_DRAWTEXT
)
1260 META_UNIMP(META_ANIMATEPALETTE
)
1261 META_UNIMP(META_SETPALENTRIES
)
1262 META_UNIMP(META_RESIZEPALETTE
)
1263 META_UNIMP(META_RESETDC
)
1264 META_UNIMP(META_STARTDOC
)
1265 META_UNIMP(META_STARTPAGE
)
1266 META_UNIMP(META_ENDPAGE
)
1267 META_UNIMP(META_ABORTDOC
)
1268 META_UNIMP(META_ENDDOC
)
1269 META_UNIMP(META_CREATEBRUSH
)
1270 META_UNIMP(META_CREATEBITMAPINDIRECT
)
1271 META_UNIMP(META_CREATEBITMAP
)
1275 WARN("PlayMetaFileRecord: Unknown record type %x\n", mr
->rdFunction
);
1281 /******************************************************************
1282 * GetMetaFileBits (GDI.159)
1284 * Trade in a metafile object handle for a handle to the metafile memory.
1288 HGLOBAL16 WINAPI
GetMetaFileBits16(
1289 HMETAFILE16 hmf
/* [in] metafile handle */
1292 TRACE("hMem out: %04x\n", hmf
);
1296 /******************************************************************
1297 * SetMetaFileBits (GDI.160)
1299 * Trade in a metafile memory handle for a handle to a metafile object.
1300 * The memory region should hold a proper metafile, otherwise
1301 * problems will occur when it is used. Validity of the memory is not
1302 * checked. The function is essentially just the identity function.
1304 HMETAFILE16 WINAPI
SetMetaFileBits16(
1306 /* [in] handle to a memory region holding a metafile */
1309 TRACE("hmf out: %04x\n", hMem
);
1314 /******************************************************************
1315 * SetMetaFileBitsBetter (GDI.196)
1317 * Trade in a metafile memory handle for a handle to a metafile object,
1318 * making a cursory check (using IsValidMetaFile()) that the memory
1319 * handle points to a valid metafile.
1322 * Handle to a metafile on success, NULL on failure..
1324 HMETAFILE16 WINAPI
SetMetaFileBitsBetter16( HMETAFILE16 hMeta
)
1326 if( IsValidMetaFile16( hMeta
) )
1327 return (HMETAFILE16
)GlobalReAlloc16( hMeta
, 0,
1328 GMEM_SHARE
| GMEM_NODISCARD
| GMEM_MODIFY
);
1329 return (HMETAFILE16
)0;
1332 /******************************************************************
1333 * SetMetaFileBitsEx (GDI32.@)
1335 * Create a metafile from raw data. No checking of the data is performed.
1336 * Use _GetMetaFileBitsEx_ to get raw data from a metafile.
1338 HMETAFILE WINAPI
SetMetaFileBitsEx(
1339 UINT size
, /* [in] size of metafile, in bytes */
1340 const BYTE
*lpData
/* [in] pointer to metafile data */
1343 METAHEADER
*mh
= HeapAlloc( GetProcessHeap(), 0, size
);
1345 memcpy(mh
, lpData
, size
);
1346 return MF_Create_HMETAFILE(mh
);
1349 /*****************************************************************
1350 * GetMetaFileBitsEx (GDI32.@) Get raw metafile data
1352 * Copies the data from metafile _hmf_ into the buffer _buf_.
1353 * If _buf_ is zero, returns size of buffer required. Otherwise,
1354 * returns number of bytes copied.
1356 UINT WINAPI
GetMetaFileBitsEx(
1357 HMETAFILE hmf
, /* [in] metafile */
1358 UINT nSize
, /* [in] size of buf */
1359 LPVOID buf
/* [out] buffer to receive raw metafile data */
1361 METAHEADER
*mh
= MF_GetMetaHeader(hmf
);
1364 TRACE("(%p,%d,%p)\n", hmf
, nSize
, buf
);
1365 if (!mh
) return 0; /* FIXME: error code */
1366 if(mh
->mtType
== METAFILE_DISK
)
1367 FIXME("Disk-based metafile?\n");
1368 mfSize
= mh
->mtSize
* 2;
1370 TRACE("returning size %d\n", mfSize
);
1373 if(mfSize
> nSize
) mfSize
= nSize
;
1374 memmove(buf
, mh
, mfSize
);
1378 /******************************************************************
1379 * GetWinMetaFileBits [GDI32.@]
1381 UINT WINAPI
GetWinMetaFileBits(HENHMETAFILE hemf
,
1382 UINT cbBuffer
, LPBYTE lpbBuffer
,
1383 INT fnMapMode
, HDC hdcRef
)
1389 FIXME("(%p,%d,%p,%d,%p): stub\n", 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
);