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"
57 #include "wine/debug.h"
59 WINE_DEFAULT_DEBUG_CHANNEL(metafile
);
70 #define MFHEADERSIZE (sizeof(METAHEADER))
71 #define MFVERSION 0x300
73 /* ### start build ### */
74 extern WORD CALLBACK
MF_CallTo16_word_wllwl(MFENUMPROC16
,WORD
,LONG
,LONG
,WORD
,LONG
);
75 /* ### stop build ### */
77 /******************************************************************
80 * Add a handle to an external handle table and return the index
82 static int MF_AddHandle(HANDLETABLE16
*ht
, WORD htlen
, HGDIOBJ16 hobj
)
86 for (i
= 0; i
< htlen
; i
++)
88 if (*(ht
->objectHandle
+ i
) == 0)
90 *(ht
->objectHandle
+ i
) = hobj
;
98 /******************************************************************
99 * MF_Create_HMETATFILE
101 * Creates a (32 bit) HMETAFILE object from a METAHEADER
103 * HMETAFILEs are GDI objects.
105 HMETAFILE
MF_Create_HMETAFILE(METAHEADER
*mh
)
108 METAFILEOBJ
*metaObj
= GDI_AllocObject( sizeof(METAFILEOBJ
), METAFILE_MAGIC
, &hmf
);
112 GDI_ReleaseObj( hmf
);
117 /******************************************************************
118 * MF_Create_HMETATFILE16
120 * Creates a HMETAFILE16 object from a METAHEADER
122 * HMETAFILE16s are Global memory handles.
124 HMETAFILE16
MF_Create_HMETAFILE16(METAHEADER
*mh
)
127 DWORD size
= mh
->mtSize
* sizeof(WORD
);
129 hmf
= GlobalAlloc16(GMEM_MOVEABLE
, size
);
132 METAHEADER
*mh_dest
= GlobalLock16(hmf
);
133 memcpy(mh_dest
, mh
, size
);
136 HeapFree(GetProcessHeap(), 0, mh
);
140 /******************************************************************
143 * Returns ptr to METAHEADER associated with HMETAFILE
145 static METAHEADER
*MF_GetMetaHeader( HMETAFILE hmf
)
147 METAHEADER
*ret
= NULL
;
148 METAFILEOBJ
* metaObj
= (METAFILEOBJ
*)GDI_GetObjPtr( hmf
, METAFILE_MAGIC
);
152 GDI_ReleaseObj( hmf
);
157 /******************************************************************
160 * Returns ptr to METAHEADER associated with HMETAFILE16
161 * Should be followed by call to MF_ReleaseMetaHeader16
163 static METAHEADER
*MF_GetMetaHeader16( HMETAFILE16 hmf
)
165 return GlobalLock16(hmf
);
168 /******************************************************************
169 * MF_ReleaseMetaHeader16
171 * Releases METAHEADER associated with HMETAFILE16
173 static BOOL16
MF_ReleaseMetaHeader16( HMETAFILE16 hmf
)
175 return GlobalUnlock16( hmf
);
179 /******************************************************************
180 * DeleteMetaFile (GDI.127)
182 BOOL16 WINAPI
DeleteMetaFile16( HMETAFILE16 hmf
)
184 return !GlobalFree16( hmf
);
187 /******************************************************************
188 * DeleteMetaFile (GDI32.@)
190 * Delete a memory-based metafile.
193 BOOL WINAPI
DeleteMetaFile( HMETAFILE hmf
)
195 METAFILEOBJ
* metaObj
= (METAFILEOBJ
*)GDI_GetObjPtr( hmf
, METAFILE_MAGIC
);
196 if (!metaObj
) return FALSE
;
197 HeapFree( GetProcessHeap(), 0, metaObj
->mh
);
198 GDI_FreeObject( hmf
, metaObj
);
202 /******************************************************************
205 * Returns a pointer to a memory based METAHEADER read in from file HFILE
208 static METAHEADER
*MF_ReadMetaFile(HFILE hfile
)
211 DWORD BytesRead
, size
;
213 size
= sizeof(METAHEADER
);
214 mh
= HeapAlloc( GetProcessHeap(), 0, size
);
216 if(ReadFile( hfile
, mh
, size
, &BytesRead
, NULL
) == 0 ||
218 HeapFree( GetProcessHeap(), 0, mh
);
221 size
= mh
->mtSize
* 2;
222 mh
= HeapReAlloc( GetProcessHeap(), 0, mh
, size
);
224 size
-= sizeof(METAHEADER
);
225 if(ReadFile( hfile
, (char *)mh
+ sizeof(METAHEADER
), size
, &BytesRead
,
228 HeapFree( GetProcessHeap(), 0, mh
);
232 if (mh
->mtType
!= METAFILE_MEMORY
) {
233 WARN("Disk metafile had mtType = %04x\n", mh
->mtType
);
234 mh
->mtType
= METAFILE_MEMORY
;
239 /******************************************************************
240 * GetMetaFile (GDI.124)
242 HMETAFILE16 WINAPI
GetMetaFile16( LPCSTR lpFilename
)
247 TRACE("%s\n", lpFilename
);
252 if((hFile
= CreateFileA(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
253 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
256 mh
= MF_ReadMetaFile(hFile
);
259 return MF_Create_HMETAFILE16( mh
);
262 /******************************************************************
263 * GetMetaFileA (GDI32.@)
265 * Read a metafile from a file. Returns handle to a memory-based metafile.
267 HMETAFILE WINAPI
GetMetaFileA( LPCSTR lpFilename
)
272 TRACE("%s\n", lpFilename
);
277 if((hFile
= CreateFileA(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
278 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
281 mh
= MF_ReadMetaFile(hFile
);
284 return MF_Create_HMETAFILE( mh
);
289 /******************************************************************
290 * GetMetaFileW (GDI32.@)
292 HMETAFILE WINAPI
GetMetaFileW( LPCWSTR lpFilename
)
297 TRACE("%s\n", debugstr_w(lpFilename
));
302 if((hFile
= CreateFileW(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
303 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
306 mh
= MF_ReadMetaFile(hFile
);
309 return MF_Create_HMETAFILE( mh
);
313 /******************************************************************
314 * MF_LoadDiskBasedMetaFile
316 * Creates a new memory-based metafile from a disk-based one.
318 static METAHEADER
*MF_LoadDiskBasedMetaFile(METAHEADER
*mh
)
324 if(mh
->mtType
!= METAFILE_DISK
) {
325 ERR("Not a disk based metafile\n");
328 mhd
= (METAHEADERDISK
*)((char *)mh
+ sizeof(METAHEADER
));
330 if((hfile
= CreateFileA(mhd
->filename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
331 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
) {
332 WARN("Can't open file of disk based metafile\n");
335 mh2
= MF_ReadMetaFile(hfile
);
340 /******************************************************************
341 * MF_CreateMetaHeaderDisk
343 * Take a memory based METAHEADER and change it to a disk based METAHEADER
344 * assosiated with filename. Note: Trashes contents of old one.
346 METAHEADER
*MF_CreateMetaHeaderDisk(METAHEADER
*mh
, LPCSTR filename
)
351 mh
= HeapReAlloc( GetProcessHeap(), 0, mh
,
352 sizeof(METAHEADER
) + sizeof(METAHEADERDISK
));
353 mh
->mtType
= METAFILE_DISK
;
354 size
= HeapSize( GetProcessHeap(), 0, mh
);
355 mhd
= (METAHEADERDISK
*)((char *)mh
+ sizeof(METAHEADER
));
356 strcpy(mhd
->filename
, filename
);
360 /******************************************************************
361 * CopyMetaFile (GDI.151)
363 HMETAFILE16 WINAPI
CopyMetaFile16( HMETAFILE16 hSrcMetaFile
, LPCSTR lpFilename
)
365 METAHEADER
*mh
= MF_GetMetaHeader16( hSrcMetaFile
);
366 METAHEADER
*mh2
= NULL
;
369 TRACE("(%08x,%s)\n", hSrcMetaFile
, lpFilename
);
373 if(mh
->mtType
== METAFILE_DISK
)
374 mh2
= MF_LoadDiskBasedMetaFile(mh
);
376 mh2
= HeapAlloc( GetProcessHeap(), 0, mh
->mtSize
* 2 );
377 memcpy( mh2
, mh
, mh
->mtSize
* 2 );
379 MF_ReleaseMetaHeader16( hSrcMetaFile
);
381 if(lpFilename
) { /* disk based metafile */
382 if((hFile
= CreateFileA(lpFilename
, GENERIC_WRITE
, 0, NULL
,
383 CREATE_ALWAYS
, 0, 0)) == INVALID_HANDLE_VALUE
) {
384 HeapFree( GetProcessHeap(), 0, mh2
);
387 WriteFile(hFile
, mh2
, mh2
->mtSize
* 2, NULL
, NULL
);
389 mh2
= MF_CreateMetaHeaderDisk(mh2
, lpFilename
);
392 return MF_Create_HMETAFILE16( mh2
);
396 /******************************************************************
397 * CopyMetaFileA (GDI32.@)
399 * Copies the metafile corresponding to hSrcMetaFile to either
400 * a disk file, if a filename is given, or to a new memory based
401 * metafile, if lpFileName is NULL.
405 * Handle to metafile copy on success, NULL on failure.
409 * Copying to disk returns NULL even if successful.
411 HMETAFILE WINAPI
CopyMetaFileA(
412 HMETAFILE hSrcMetaFile
, /* [in] handle of metafile to copy */
413 LPCSTR lpFilename
/* [in] filename if copying to a file */
415 METAHEADER
*mh
= MF_GetMetaHeader( hSrcMetaFile
);
416 METAHEADER
*mh2
= NULL
;
419 TRACE("(%08x,%s)\n", hSrcMetaFile
, lpFilename
);
423 if(mh
->mtType
== METAFILE_DISK
)
424 mh2
= MF_LoadDiskBasedMetaFile(mh
);
426 mh2
= HeapAlloc( GetProcessHeap(), 0, mh
->mtSize
* 2 );
427 memcpy( mh2
, mh
, mh
->mtSize
* 2 );
430 if(lpFilename
) { /* disk based metafile */
431 if((hFile
= CreateFileA(lpFilename
, GENERIC_WRITE
, 0, NULL
,
432 CREATE_ALWAYS
, 0, 0)) == INVALID_HANDLE_VALUE
) {
433 HeapFree( GetProcessHeap(), 0, mh2
);
436 WriteFile(hFile
, mh2
, mh2
->mtSize
* 2, NULL
, NULL
);
438 mh2
= MF_CreateMetaHeaderDisk(mh2
, lpFilename
);
441 return MF_Create_HMETAFILE( mh2
);
445 /******************************************************************
446 * CopyMetaFileW (GDI32.@)
448 HMETAFILE WINAPI
CopyMetaFileW( HMETAFILE hSrcMetaFile
,
452 DWORD len
= WideCharToMultiByte( CP_ACP
, 0, lpFilename
, -1, NULL
, 0, NULL
, NULL
);
453 LPSTR p
= HeapAlloc( GetProcessHeap(), 0, len
);
457 WideCharToMultiByte( CP_ACP
, 0, lpFilename
, -1, p
, len
, NULL
, NULL
);
458 ret
= CopyMetaFileA( hSrcMetaFile
, p
);
459 HeapFree( GetProcessHeap(), 0, p
);
465 /******************************************************************
466 * IsValidMetaFile (GDI.410)
468 * Attempts to check if a given metafile is correctly formatted.
469 * Currently, the only things verified are several properties of the
473 * TRUE if hmf passes some tests for being a valid metafile, FALSE otherwise.
476 * This is not exactly what windows does, see _Undocumented_Windows_
479 BOOL16 WINAPI
IsValidMetaFile16(HMETAFILE16 hmf
)
482 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
484 if (mh
->mtType
== METAFILE_MEMORY
|| mh
->mtType
== METAFILE_DISK
)
485 if (mh
->mtHeaderSize
== MFHEADERSIZE
/sizeof(INT16
))
486 if (mh
->mtVersion
== MFVERSION
)
488 MF_ReleaseMetaHeader16(hmf
);
490 TRACE("IsValidMetaFile %x => %d\n",hmf
,res
);
495 /*******************************************************************
498 * Helper for PlayMetaFile
500 static BOOL
MF_PlayMetaFile( HDC hdc
, METAHEADER
*mh
)
505 unsigned int offset
= 0;
512 if (!mh
) return FALSE
;
513 if(mh
->mtType
== METAFILE_DISK
) { /* Create a memory-based copy */
514 mh
= MF_LoadDiskBasedMetaFile(mh
);
515 if(!mh
) return FALSE
;
519 /* save the current pen, brush and font */
520 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
521 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
522 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
524 /* create the handle table */
525 ht
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
526 sizeof(HANDLETABLE16
) * mh
->mtNoObjects
);
527 if(!ht
) return FALSE
;
529 /* loop through metafile playing records */
530 offset
= mh
->mtHeaderSize
* 2;
531 while (offset
< mh
->mtSize
* 2)
533 mr
= (METARECORD
*)((char *)mh
+ offset
);
534 TRACE("offset=%04x,size=%08lx\n",
538 "Entry got size 0 at offset %d, total mf length is %ld\n",
539 offset
,mh
->mtSize
*2);
540 break; /* would loop endlessly otherwise */
542 offset
+= mr
->rdSize
* 2;
543 PlayMetaFileRecord16( hdc
, ht
, mr
, mh
->mtNoObjects
);
546 SelectObject(hdc
, hBrush
);
547 SelectObject(hdc
, hPen
);
548 SelectObject(hdc
, hFont
);
550 /* free objects in handle table */
551 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
552 if(*(ht
->objectHandle
+ i
) != 0)
553 DeleteObject(*(ht
->objectHandle
+ i
));
555 /* free handle table */
556 HeapFree( GetProcessHeap(), 0, ht
);
558 HeapFree( GetProcessHeap(), 0, mh
);
562 /******************************************************************
563 * PlayMetaFile (GDI.123)
566 BOOL16 WINAPI
PlayMetaFile16( HDC16 hdc
, HMETAFILE16 hmf
)
569 METAHEADER
*mh
= MF_GetMetaHeader16( hmf
);
570 ret
= MF_PlayMetaFile( hdc
, mh
);
571 MF_ReleaseMetaHeader16( hmf
);
575 /******************************************************************
576 * PlayMetaFile (GDI32.@)
578 * Renders the metafile specified by hmf in the DC specified by
579 * hdc. Returns FALSE on failure, TRUE on success.
581 BOOL WINAPI
PlayMetaFile(
582 HDC hdc
, /* [in] handle of DC to render in */
583 HMETAFILE hmf
/* [in] handle of metafile to render */
586 METAHEADER
*mh
= MF_GetMetaHeader( hmf
);
587 return MF_PlayMetaFile( hdc
, mh
);
591 /******************************************************************
592 * EnumMetaFile (GDI.175)
595 BOOL16 WINAPI
EnumMetaFile16( HDC16 hdc
, HMETAFILE16 hmf
,
596 MFENUMPROC16 lpEnumFunc
, LPARAM lpData
)
598 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
603 unsigned int offset
= 0;
608 BOOL16 result
= TRUE
, loaded
= FALSE
;
610 TRACE("(%04x, %04x, %08lx, %08lx)\n",
611 hdc
, hmf
, (DWORD
)lpEnumFunc
, lpData
);
614 if(!mh
) return FALSE
;
615 if(mh
->mtType
== METAFILE_DISK
) { /* Create a memory-based copy */
616 mh
= MF_LoadDiskBasedMetaFile(mh
);
617 if(!mh
) return FALSE
;
621 /* save the current pen, brush and font */
622 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
623 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
624 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
626 /* create the handle table */
628 hHT
= GlobalAlloc16(GMEM_MOVEABLE
| GMEM_ZEROINIT
,
629 sizeof(HANDLETABLE16
) * mh
->mtNoObjects
);
630 spht
= K32WOWGlobalLock16(hHT
);
633 offset
= mh
->mtHeaderSize
* 2;
635 /* loop through metafile records */
637 while (offset
< (mh
->mtSize
* 2))
639 mr
= (METARECORD
*)((char *)mh
+ offset
);
641 if (!MF_CallTo16_word_wllwl( lpEnumFunc
, hdc
, spht
,
642 MAKESEGPTR( seg
+ (HIWORD(offset
) << __AHSHIFT
), LOWORD(offset
) ),
643 mh
->mtNoObjects
, (LONG
)lpData
))
650 offset
+= (mr
->rdSize
* 2);
653 SelectObject(hdc
, hBrush
);
654 SelectObject(hdc
, hPen
);
655 SelectObject(hdc
, hFont
);
657 ht
= (HANDLETABLE16
*)GlobalLock16(hHT
);
659 /* free objects in handle table */
660 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
661 if(*(ht
->objectHandle
+ i
) != 0)
662 DeleteObject(*(ht
->objectHandle
+ i
));
664 /* free handle table */
667 HeapFree( GetProcessHeap(), 0, mh
);
668 MF_ReleaseMetaHeader16(hmf
);
672 /******************************************************************
673 * EnumMetaFile (GDI32.@)
675 * Loop through the metafile records in hmf, calling the user-specified
676 * function for each one, stopping when the user's function returns FALSE
677 * (which is considered to be failure)
678 * or when no records are left (which is considered to be success).
681 * TRUE on success, FALSE on failure.
684 * Niels de carpentier, april 1996
686 BOOL WINAPI
EnumMetaFile(
689 MFENUMPROC lpEnumFunc
,
692 METAHEADER
*mhTemp
= NULL
, *mh
= MF_GetMetaHeader(hmf
);
697 unsigned int offset
= 0;
702 TRACE("(%08x,%08x,%p,%p)\n", hdc
, hmf
, lpEnumFunc
, (void*)lpData
);
704 if(mh
->mtType
== METAFILE_DISK
)
706 /* Create a memory-based copy */
707 if (!(mhTemp
= MF_LoadDiskBasedMetaFile(mh
))) return FALSE
;
711 /* save the current pen, brush and font */
712 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
713 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
714 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
716 ht
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
717 sizeof(HANDLETABLE
) * mh
->mtNoObjects
);
719 /* loop through metafile records */
720 offset
= mh
->mtHeaderSize
* 2;
722 while (offset
< (mh
->mtSize
* 2))
724 mr
= (METARECORD
*)((char *)mh
+ offset
);
725 TRACE("Calling EnumFunc with record type %x\n",
727 if (!lpEnumFunc( hdc
, ht
, mr
, mh
->mtNoObjects
, (LONG
)lpData
))
733 offset
+= (mr
->rdSize
* 2);
736 /* restore pen, brush and font */
737 SelectObject(hdc
, hBrush
);
738 SelectObject(hdc
, hPen
);
739 SelectObject(hdc
, hFont
);
741 /* free objects in handle table */
742 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
743 if(*(ht
->objectHandle
+ i
) != 0)
744 DeleteObject(*(ht
->objectHandle
+ i
));
746 /* free handle table */
747 HeapFree( GetProcessHeap(), 0, ht
);
748 /* free a copy of metafile */
749 if (mhTemp
) HeapFree( GetProcessHeap(), 0, mhTemp
);
753 static BOOL
MF_Play_MetaCreateRegion( METARECORD
*mr
, HRGN hrgn
);
754 static BOOL
MF_Play_MetaExtTextOut(HDC16 hdc
, METARECORD
*mr
);
755 /******************************************************************
756 * PlayMetaFileRecord (GDI.176)
758 * Render a single metafile record specified by *mr in the DC hdc, while
759 * using the handle table *ht, of length nHandles,
760 * to store metafile objects.
763 * The following metafile records are unimplemented:
765 * DRAWTEXT, ANIMATEPALETTE, SETPALENTRIES,
766 * RESIZEPALETTE, EXTFLOODFILL, RESETDC, STARTDOC, STARTPAGE, ENDPAGE,
767 * ABORTDOC, ENDDOC, CREATEBRUSH, CREATEBITMAPINDIRECT, and CREATEBITMAP.
770 void WINAPI
PlayMetaFileRecord16(
771 HDC16 hdc
, /* [in] DC to render metafile into */
772 HANDLETABLE16
*ht
, /* [in] pointer to handle table for metafile objects */
773 METARECORD
*mr
, /* [in] pointer to metafile record to render */
774 UINT16 nHandles
/* [in] size of handle table */
779 BITMAPINFOHEADER
*infohdr
;
781 TRACE("(%04x %08lx %08lx %04x) function %04x\n",
782 hdc
,(LONG
)ht
, (LONG
)mr
, nHandles
, mr
->rdFunction
);
784 switch (mr
->rdFunction
)
789 case META_DELETEOBJECT
:
790 DeleteObject(*(ht
->objectHandle
+ *(mr
->rdParm
)));
791 *(ht
->objectHandle
+ *(mr
->rdParm
)) = 0;
794 case META_SETBKCOLOR
:
795 SetBkColor16(hdc
, MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
799 SetBkMode16(hdc
, *(mr
->rdParm
));
802 case META_SETMAPMODE
:
803 SetMapMode16(hdc
, *(mr
->rdParm
));
807 SetROP216(hdc
, *(mr
->rdParm
));
811 SetRelAbs16(hdc
, *(mr
->rdParm
));
814 case META_SETPOLYFILLMODE
:
815 SetPolyFillMode16(hdc
, *(mr
->rdParm
));
818 case META_SETSTRETCHBLTMODE
:
819 SetStretchBltMode16(hdc
, *(mr
->rdParm
));
822 case META_SETTEXTCOLOR
:
823 SetTextColor16(hdc
, MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
826 case META_SETWINDOWORG
:
827 SetWindowOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
830 case META_SETWINDOWEXT
:
831 SetWindowExt16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
834 case META_SETVIEWPORTORG
:
835 SetViewportOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
838 case META_SETVIEWPORTEXT
:
839 SetViewportExt16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
842 case META_OFFSETWINDOWORG
:
843 OffsetWindowOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
846 case META_SCALEWINDOWEXT
:
847 ScaleWindowExt16(hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
848 *(mr
->rdParm
+ 1), *(mr
->rdParm
));
851 case META_OFFSETVIEWPORTORG
:
852 OffsetViewportOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
855 case META_SCALEVIEWPORTEXT
:
856 ScaleViewportExt16(hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
857 *(mr
->rdParm
+ 1), *(mr
->rdParm
));
861 LineTo(hdc
, (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
865 MoveTo16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
868 case META_EXCLUDECLIPRECT
:
869 ExcludeClipRect16( hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
870 *(mr
->rdParm
+ 1), *(mr
->rdParm
) );
873 case META_INTERSECTCLIPRECT
:
874 IntersectClipRect16( hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
875 *(mr
->rdParm
+ 1), *(mr
->rdParm
) );
879 Arc(hdc
, (INT16
)*(mr
->rdParm
+ 7), (INT16
)*(mr
->rdParm
+ 6),
880 (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
881 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
882 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
886 Ellipse(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
887 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
891 FloodFill(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
892 MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
896 Pie(hdc
, (INT16
)*(mr
->rdParm
+ 7), (INT16
)*(mr
->rdParm
+ 6),
897 (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
898 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
899 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
903 Rectangle(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
904 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
908 RoundRect(hdc
, (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
909 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
910 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
914 PatBlt16(hdc
, *(mr
->rdParm
+ 5), *(mr
->rdParm
+ 4),
915 *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
916 MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
924 SetPixel(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
925 MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
928 case META_OFFSETCLIPRGN
:
929 OffsetClipRgn16( hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
) );
934 TextOut16(hdc
, *(mr
->rdParm
+ ((s1
+ 1) >> 1) + 2),
935 *(mr
->rdParm
+ ((s1
+ 1) >> 1) + 1),
936 (char *)(mr
->rdParm
+ 1), s1
);
940 Polygon16(hdc
, (LPPOINT16
)(mr
->rdParm
+ 1), *(mr
->rdParm
));
943 case META_POLYPOLYGON
:
944 PolyPolygon16(hdc
, (LPPOINT16
)(mr
->rdParm
+ *(mr
->rdParm
) + 1),
945 (LPINT16
)(mr
->rdParm
+ 1), *(mr
->rdParm
));
949 Polyline16(hdc
, (LPPOINT16
)(mr
->rdParm
+ 1), *(mr
->rdParm
));
953 RestoreDC(hdc
, (INT16
)*(mr
->rdParm
));
956 case META_SELECTOBJECT
:
957 SelectObject(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
961 Chord(hdc
, (INT16
)*(mr
->rdParm
+ 7), (INT16
)*(mr
->rdParm
+ 6),
962 (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
963 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
964 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
967 case META_CREATEPATTERNBRUSH
:
968 switch (*(mr
->rdParm
))
971 infohdr
= (BITMAPINFOHEADER
*)(mr
->rdParm
+ 2);
972 MF_AddHandle(ht
, nHandles
,
973 CreatePatternBrush(CreateBitmap(infohdr
->biWidth
,
978 (sizeof(BITMAPINFOHEADER
) / 2) + 4))));
982 s1
= mr
->rdSize
* 2 - sizeof(METARECORD
) - 2;
983 hndl
= GlobalAlloc16(GMEM_MOVEABLE
, s1
);
984 ptr
= GlobalLock16(hndl
);
985 memcpy(ptr
, mr
->rdParm
+ 2, s1
);
986 GlobalUnlock16(hndl
);
987 MF_AddHandle(ht
, nHandles
,
988 CreateDIBPatternBrush(hndl
, *(mr
->rdParm
+ 1)));
993 ERR("META_CREATEPATTERNBRUSH: Unknown pattern type %d\n",
999 case META_CREATEPENINDIRECT
:
1000 MF_AddHandle(ht
, nHandles
,
1001 CreatePenIndirect16((LOGPEN16
*)(&(mr
->rdParm
))));
1004 case META_CREATEFONTINDIRECT
:
1005 MF_AddHandle(ht
, nHandles
,
1006 CreateFontIndirect16((LOGFONT16
*)(&(mr
->rdParm
))));
1009 case META_CREATEBRUSHINDIRECT
:
1010 MF_AddHandle(ht
, nHandles
,
1011 CreateBrushIndirect16((LOGBRUSH16
*)(&(mr
->rdParm
))));
1014 case META_CREATEPALETTE
:
1015 MF_AddHandle(ht
, nHandles
,
1016 CreatePalette16((LPLOGPALETTE
)mr
->rdParm
));
1019 case META_SETTEXTALIGN
:
1020 SetTextAlign16(hdc
, *(mr
->rdParm
));
1023 case META_SELECTPALETTE
:
1024 GDISelectPalette16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
+1)),
1028 case META_SETMAPPERFLAGS
:
1029 SetMapperFlags16(hdc
, MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1032 case META_REALIZEPALETTE
:
1033 GDIRealizePalette16(hdc
);
1037 FIXME("META_ESCAPE unimplemented.\n");
1040 case META_EXTTEXTOUT
:
1041 MF_Play_MetaExtTextOut( hdc
, mr
);
1044 case META_STRETCHDIB
:
1046 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[11]);
1047 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[2] );
1048 StretchDIBits16(hdc
,mr
->rdParm
[10],mr
->rdParm
[9],mr
->rdParm
[8],
1049 mr
->rdParm
[7],mr
->rdParm
[6],mr
->rdParm
[5],
1050 mr
->rdParm
[4],mr
->rdParm
[3],bits
,info
,
1051 mr
->rdParm
[2],MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1055 case META_DIBSTRETCHBLT
:
1057 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[10]);
1058 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[2] );
1059 StretchDIBits16(hdc
,mr
->rdParm
[9],mr
->rdParm
[8],mr
->rdParm
[7],
1060 mr
->rdParm
[6],mr
->rdParm
[5],mr
->rdParm
[4],
1061 mr
->rdParm
[3],mr
->rdParm
[2],bits
,info
,
1062 DIB_RGB_COLORS
,MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1066 case META_STRETCHBLT
:
1068 HDC16 hdcSrc
=CreateCompatibleDC16(hdc
);
1069 HBITMAP hbitmap
=CreateBitmap(mr
->rdParm
[10], /*Width */
1070 mr
->rdParm
[11], /*Height*/
1071 mr
->rdParm
[13], /*Planes*/
1072 mr
->rdParm
[14], /*BitsPixel*/
1073 (LPSTR
)&mr
->rdParm
[15]); /*bits*/
1074 SelectObject(hdcSrc
,hbitmap
);
1075 StretchBlt16(hdc
,mr
->rdParm
[9],mr
->rdParm
[8],
1076 mr
->rdParm
[7],mr
->rdParm
[6],
1077 hdcSrc
,mr
->rdParm
[5],mr
->rdParm
[4],
1078 mr
->rdParm
[3],mr
->rdParm
[2],
1079 MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1086 HDC16 hdcSrc
=CreateCompatibleDC16(hdc
);
1087 HBITMAP hbitmap
=CreateBitmap(mr
->rdParm
[7]/*Width */,
1088 mr
->rdParm
[8]/*Height*/,
1089 mr
->rdParm
[10]/*Planes*/,
1090 mr
->rdParm
[11]/*BitsPixel*/,
1091 (LPSTR
)&mr
->rdParm
[12]/*bits*/);
1092 SelectObject(hdcSrc
,hbitmap
);
1093 BitBlt(hdc
,(INT16
)mr
->rdParm
[6],(INT16
)mr
->rdParm
[5],
1094 (INT16
)mr
->rdParm
[4],(INT16
)mr
->rdParm
[3],
1095 hdcSrc
, (INT16
)mr
->rdParm
[2],(INT16
)mr
->rdParm
[1],
1096 MAKELONG(0,mr
->rdParm
[0]));
1101 case META_CREATEREGION
:
1103 HRGN hrgn
= CreateRectRgn(0,0,0,0);
1105 MF_Play_MetaCreateRegion(mr
, hrgn
);
1106 MF_AddHandle(ht
, nHandles
, hrgn
);
1110 case META_FILLREGION
:
1111 FillRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
+1)),
1112 *(ht
->objectHandle
+ *(mr
->rdParm
)));
1115 case META_FRAMEREGION
:
1116 FrameRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
+3)),
1117 *(ht
->objectHandle
+ *(mr
->rdParm
+2)),
1118 *(mr
->rdParm
+1), *(mr
->rdParm
));
1121 case META_INVERTREGION
:
1122 InvertRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
1125 case META_PAINTREGION
:
1126 PaintRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
1129 case META_SELECTCLIPREGION
:
1130 SelectClipRgn(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
1133 case META_DIBCREATEPATTERNBRUSH
:
1134 /* *(mr->rdParm) may be BS_PATTERN or BS_DIBPATTERN:
1135 but there's no difference */
1137 TRACE("%d\n",*(mr
->rdParm
));
1138 s1
= mr
->rdSize
* 2 - sizeof(METARECORD
) - 2;
1139 hndl
= GlobalAlloc16(GMEM_MOVEABLE
, s1
);
1140 ptr
= GlobalLock16(hndl
);
1141 memcpy(ptr
, mr
->rdParm
+ 2, s1
);
1142 GlobalUnlock16(hndl
);
1143 MF_AddHandle(ht
, nHandles
,
1144 CreateDIBPatternBrush16(hndl
, *(mr
->rdParm
+ 1)));
1148 case META_DIBBITBLT
:
1149 /* In practice I've found that there are two layouts for
1150 META_DIBBITBLT, one (the first here) is the usual one when a src
1151 dc is actually passed to it, the second occurs when the src dc is
1152 passed in as NULL to the creating BitBlt. As the second case has
1153 no dib, a size check will suffice to distinguish.
1155 Caolan.McNamara@ul.ie */
1157 if (mr
->rdSize
> 12) {
1158 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[8]);
1159 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize(info
, mr
->rdParm
[0]);
1161 StretchDIBits16(hdc
, mr
->rdParm
[7], mr
->rdParm
[6], mr
->rdParm
[5],
1162 mr
->rdParm
[4], mr
->rdParm
[3], mr
->rdParm
[2],
1163 mr
->rdParm
[5], mr
->rdParm
[4], bits
, info
,
1165 MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
1166 } else { /* equivalent to a PatBlt */
1167 PatBlt16(hdc
, mr
->rdParm
[8], mr
->rdParm
[7],
1168 mr
->rdParm
[6], mr
->rdParm
[5],
1169 MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
1173 case META_SETTEXTCHAREXTRA
:
1174 SetTextCharacterExtra16(hdc
, (INT16
)*(mr
->rdParm
));
1177 case META_SETTEXTJUSTIFICATION
:
1178 SetTextJustification(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
1181 case META_EXTFLOODFILL
:
1182 ExtFloodFill(hdc
, (INT16
)*(mr
->rdParm
+ 4), (INT16
)*(mr
->rdParm
+ 3),
1183 MAKELONG(*(mr
->rdParm
+1), *(mr
->rdParm
+ 2)),
1187 case META_SETDIBTODEV
:
1189 BITMAPINFO
*info
= (BITMAPINFO
*) &(mr
->rdParm
[9]);
1190 char *bits
= (char *)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[0] );
1191 SetDIBitsToDevice(hdc
, (INT16
)mr
->rdParm
[8], (INT16
)mr
->rdParm
[7],
1192 (INT16
)mr
->rdParm
[6], (INT16
)mr
->rdParm
[5],
1193 (INT16
)mr
->rdParm
[4], (INT16
)mr
->rdParm
[3],
1194 mr
->rdParm
[2], mr
->rdParm
[1], bits
, info
,
1199 #define META_UNIMP(x) case x: \
1200 FIXME("PlayMetaFileRecord:record type "#x" not implemented.\n"); \
1202 META_UNIMP(META_DRAWTEXT
)
1203 META_UNIMP(META_ANIMATEPALETTE
)
1204 META_UNIMP(META_SETPALENTRIES
)
1205 META_UNIMP(META_RESIZEPALETTE
)
1206 META_UNIMP(META_RESETDC
)
1207 META_UNIMP(META_STARTDOC
)
1208 META_UNIMP(META_STARTPAGE
)
1209 META_UNIMP(META_ENDPAGE
)
1210 META_UNIMP(META_ABORTDOC
)
1211 META_UNIMP(META_ENDDOC
)
1212 META_UNIMP(META_CREATEBRUSH
)
1213 META_UNIMP(META_CREATEBITMAPINDIRECT
)
1214 META_UNIMP(META_CREATEBITMAP
)
1218 WARN("PlayMetaFileRecord: Unknown record type %x\n",
1223 /******************************************************************
1224 * PlayMetaFileRecord (GDI32.@)
1226 BOOL WINAPI
PlayMetaFileRecord( HDC hdc
, HANDLETABLE
*handletable
,
1227 METARECORD
*metarecord
, UINT handles
)
1229 HANDLETABLE16
* ht
= (void *)GlobalAlloc(GPTR
,
1230 handles
*sizeof(HANDLETABLE16
));
1232 TRACE("(%08x,%p,%p,%d)\n", hdc
, handletable
, metarecord
,
1234 for (i
=0; i
<handles
; i
++)
1235 ht
->objectHandle
[i
] = handletable
->objectHandle
[i
];
1236 PlayMetaFileRecord16(hdc
, ht
, metarecord
, handles
);
1237 for (i
=0; i
<handles
; i
++)
1238 handletable
->objectHandle
[i
] = ht
->objectHandle
[i
];
1239 GlobalFree((HGLOBAL
)ht
);
1243 /******************************************************************
1244 * GetMetaFileBits (GDI.159)
1246 * Trade in a metafile object handle for a handle to the metafile memory.
1250 HGLOBAL16 WINAPI
GetMetaFileBits16(
1251 HMETAFILE16 hmf
/* [in] metafile handle */
1254 TRACE("hMem out: %04x\n", hmf
);
1258 /******************************************************************
1259 * SetMetaFileBits (GDI.160)
1261 * Trade in a metafile memory handle for a handle to a metafile object.
1262 * The memory region should hold a proper metafile, otherwise
1263 * problems will occur when it is used. Validity of the memory is not
1264 * checked. The function is essentially just the identity function.
1266 HMETAFILE16 WINAPI
SetMetaFileBits16(
1268 /* [in] handle to a memory region holding a metafile */
1271 TRACE("hmf out: %04x\n", hMem
);
1276 /******************************************************************
1277 * SetMetaFileBitsBetter (GDI.196)
1279 * Trade in a metafile memory handle for a handle to a metafile object,
1280 * making a cursory check (using IsValidMetaFile()) that the memory
1281 * handle points to a valid metafile.
1284 * Handle to a metafile on success, NULL on failure..
1286 HMETAFILE16 WINAPI
SetMetaFileBitsBetter16( HMETAFILE16 hMeta
)
1288 if( IsValidMetaFile16( hMeta
) )
1289 return (HMETAFILE16
)GlobalReAlloc16( hMeta
, 0,
1290 GMEM_SHARE
| GMEM_NODISCARD
| GMEM_MODIFY
);
1291 return (HMETAFILE16
)0;
1294 /******************************************************************
1295 * SetMetaFileBitsEx (GDI32.@)
1297 * Create a metafile from raw data. No checking of the data is performed.
1298 * Use _GetMetaFileBitsEx_ to get raw data from a metafile.
1300 HMETAFILE WINAPI
SetMetaFileBitsEx(
1301 UINT size
, /* [in] size of metafile, in bytes */
1302 const BYTE
*lpData
/* [in] pointer to metafile data */
1305 METAHEADER
*mh
= HeapAlloc( GetProcessHeap(), 0, size
);
1307 memcpy(mh
, lpData
, size
);
1308 return MF_Create_HMETAFILE(mh
);
1311 /*****************************************************************
1312 * GetMetaFileBitsEx (GDI32.@) Get raw metafile data
1314 * Copies the data from metafile _hmf_ into the buffer _buf_.
1315 * If _buf_ is zero, returns size of buffer required. Otherwise,
1316 * returns number of bytes copied.
1318 UINT WINAPI
GetMetaFileBitsEx(
1319 HMETAFILE hmf
, /* [in] metafile */
1320 UINT nSize
, /* [in] size of buf */
1321 LPVOID buf
/* [out] buffer to receive raw metafile data */
1323 METAHEADER
*mh
= MF_GetMetaHeader(hmf
);
1326 TRACE("(%08x,%d,%p)\n", hmf
, nSize
, buf
);
1327 if (!mh
) return 0; /* FIXME: error code */
1328 if(mh
->mtType
== METAFILE_DISK
)
1329 FIXME("Disk-based metafile?\n");
1330 mfSize
= mh
->mtSize
* 2;
1332 TRACE("returning size %d\n", mfSize
);
1335 if(mfSize
> nSize
) mfSize
= nSize
;
1336 memmove(buf
, mh
, mfSize
);
1340 /******************************************************************
1341 * GetWinMetaFileBits [GDI32.@]
1343 UINT WINAPI
GetWinMetaFileBits(HENHMETAFILE hemf
,
1344 UINT cbBuffer
, LPBYTE lpbBuffer
,
1345 INT fnMapMode
, HDC hdcRef
)
1347 FIXME("(%d,%d,%p,%d,%d): stub\n",
1348 hemf
, cbBuffer
, lpbBuffer
, fnMapMode
, hdcRef
);
1352 /******************************************************************
1353 * MF_Play_MetaCreateRegion
1355 * Handles META_CREATEREGION for PlayMetaFileRecord().
1359 * The layout of the record looks something like this:
1364 * 2 Looks like a handle? - not constant
1366 * 4 Total number of bytes
1367 * 5 No. of separate bands = n [see below]
1368 * 6 Largest number of x co-ords in a band
1369 * 7-10 Bounding box x1 y1 x2 y2
1372 * Regions are divided into bands that are uniform in the
1373 * y-direction. Each band consists of pairs of on/off x-coords and is
1375 * m y0 y1 x1 x2 x3 ... xm m
1376 * into successive rdParm[]s.
1378 * This is probably just a dump of the internal RGNOBJ?
1384 static BOOL
MF_Play_MetaCreateRegion( METARECORD
*mr
, HRGN hrgn
)
1389 HRGN hrgn2
= CreateRectRgn( 0, 0, 0, 0 );
1391 for(band
= 0, start
= &(mr
->rdParm
[11]); band
< mr
->rdParm
[5];
1392 band
++, start
= end
+ 1) {
1393 if(*start
/ 2 != (*start
+ 1) / 2) {
1394 WARN("Delimiter not even.\n");
1395 DeleteObject( hrgn2
);
1399 end
= start
+ *start
+ 3;
1400 if(end
> (WORD
*)mr
+ mr
->rdSize
) {
1401 WARN("End points outside record.\n");
1402 DeleteObject( hrgn2
);
1406 if(*start
!= *end
) {
1407 WARN("Mismatched delimiters.\n");
1408 DeleteObject( hrgn2
);
1412 y0
= *(INT16
*)(start
+ 1);
1413 y1
= *(INT16
*)(start
+ 2);
1414 for(pair
= 0; pair
< *start
/ 2; pair
++) {
1415 SetRectRgn( hrgn2
, *(INT16
*)(start
+ 3 + 2*pair
), y0
,
1416 *(INT16
*)(start
+ 4 + 2*pair
), y1
);
1417 CombineRgn(hrgn
, hrgn
, hrgn2
, RGN_OR
);
1420 DeleteObject( hrgn2
);
1425 /******************************************************************
1426 * MF_Play_MetaExtTextOut
1428 * Handles META_EXTTEXTOUT for PlayMetaFileRecord().
1431 static BOOL
MF_Play_MetaExtTextOut(HDC16 hdc
, METARECORD
*mr
)
1438 s1
= mr
->rdParm
[2]; /* String length */
1439 len
= sizeof(METARECORD
) + (((s1
+ 1) >> 1) * 2) + 2 * sizeof(short)
1440 + sizeof(UINT16
) + (mr
->rdParm
[3] ? sizeof(RECT16
) : 0);
1441 /* rec len without dx array */
1443 sot
= (LPSTR
)&mr
->rdParm
[4]; /* start_of_text */
1445 sot
+= sizeof(RECT16
); /* there is a rectangle, so add offset */
1447 if (mr
->rdSize
== len
/ 2)
1448 dxx
= NULL
; /* determine if array present */
1450 if (mr
->rdSize
== (len
+ s1
* sizeof(INT16
)) / 2)
1451 dxx
= (LPINT16
)(sot
+(((s1
+1)>>1)*2));
1453 TRACE("%s len: %ld\n", sot
, mr
->rdSize
);
1455 "Please report: ExtTextOut len=%ld slen=%d rdSize=%ld opt=%04x\n",
1456 len
, s1
, mr
->rdSize
, mr
->rdParm
[3]);
1457 dxx
= NULL
; /* should't happen -- but if, we continue with NULL */
1459 ExtTextOut16( hdc
, mr
->rdParm
[1], /* X position */
1460 mr
->rdParm
[0], /* Y position */
1461 mr
->rdParm
[3], /* options */
1462 mr
->rdParm
[3] ? (LPRECT16
) &mr
->rdParm
[4]:NULL
,
1465 s1
, dxx
); /* length, dx array */
1467 TRACE("%s len: %ld dx0: %d\n", sot
, mr
->rdSize
, dxx
[0]);