4 * Copyright David W. Metcalfe, 1994
5 * Niels de Carpentier, Albrecht Kleine, Huw Davies 1996
10 * These functions are primarily involved with metafile playback or anything
11 * that touches a HMETAFILE.
12 * For recording of metafiles look in graphics/metafiledrv/
14 * Note that (32 bit) HMETAFILEs are GDI objects, while HMETAFILE16s are
15 * global memory handles so these cannot be interchanged.
17 * Memory-based metafiles are just stored as a continuous block of memory with
18 * a METAHEADER at the head with METARECORDs appended to it. mtType is
19 * METAFILE_MEMORY (1). Note this is indentical to the disk image of a
20 * disk-based metafile - even mtType is METAFILE_MEMORY.
21 * 16bit HMETAFILE16s are global handles to this block
22 * 32bit HMETAFILEs are GDI handles METAFILEOBJs, which contains a ptr to
24 * Disk-based metafiles are rather different. HMETAFILE16s point to a
25 * METAHEADER which has mtType equal to METAFILE_DISK (2). Following the 9
26 * WORDs of the METAHEADER there are a further 3 WORDs of 0, 1 of 0x117, 1
27 * more 0, then 2 which may be a time stamp of the file and then the path of
28 * the file (METAHEADERDISK). I've copied this for 16bit compatibility.
38 #include "wine/winbase16.h"
39 #include "wine/wingdi16.h"
45 #include "debugtools.h"
47 DEFAULT_DEBUG_CHANNEL(metafile
);
58 #define MFHEADERSIZE (sizeof(METAHEADER))
59 #define MFVERSION 0x300
61 /******************************************************************
64 * Add a handle to an external handle table and return the index
66 static int MF_AddHandle(HANDLETABLE16
*ht
, WORD htlen
, HGDIOBJ16 hobj
)
70 for (i
= 0; i
< htlen
; i
++)
72 if (*(ht
->objectHandle
+ i
) == 0)
74 *(ht
->objectHandle
+ i
) = hobj
;
82 /******************************************************************
83 * MF_Create_HMETATFILE
85 * Creates a (32 bit) HMETAFILE object from a METAHEADER
87 * HMETAFILEs are GDI objects.
89 HMETAFILE
MF_Create_HMETAFILE(METAHEADER
*mh
)
92 METAFILEOBJ
*metaObj
= GDI_AllocObject( sizeof(METAFILEOBJ
), METAFILE_MAGIC
, &hmf
);
96 GDI_ReleaseObj( hmf
);
101 /******************************************************************
102 * MF_Create_HMETATFILE16
104 * Creates a HMETAFILE16 object from a METAHEADER
106 * HMETAFILE16s are Global memory handles.
108 HMETAFILE16
MF_Create_HMETAFILE16(METAHEADER
*mh
)
111 DWORD size
= mh
->mtSize
* sizeof(WORD
);
113 hmf
= GlobalAlloc16(GMEM_MOVEABLE
, size
);
116 METAHEADER
*mh_dest
= GlobalLock16(hmf
);
117 memcpy(mh_dest
, mh
, size
);
120 HeapFree(GetProcessHeap(), 0, mh
);
124 /******************************************************************
127 * Returns ptr to METAHEADER associated with HMETAFILE
128 * Should be followed by call to MF_ReleaseMetaHeader
130 static METAHEADER
*MF_GetMetaHeader( HMETAFILE hmf
)
132 METAFILEOBJ
* metaObj
= (METAFILEOBJ
*)GDI_GetObjPtr( hmf
, METAFILE_MAGIC
);
133 return metaObj
? metaObj
->mh
: 0;
136 /******************************************************************
139 * Returns ptr to METAHEADER associated with HMETAFILE16
140 * Should be followed by call to MF_ReleaseMetaHeader16
142 static METAHEADER
*MF_GetMetaHeader16( HMETAFILE16 hmf
)
144 return GlobalLock16(hmf
);
147 /******************************************************************
148 * MF_ReleaseMetaHeader
150 * Releases METAHEADER associated with HMETAFILE
152 static void MF_ReleaseMetaHeader( HMETAFILE hmf
)
154 GDI_ReleaseObj( hmf
);
157 /******************************************************************
158 * MF_ReleaseMetaHeader16
160 * Releases METAHEADER associated with HMETAFILE16
162 static BOOL16
MF_ReleaseMetaHeader16( HMETAFILE16 hmf
)
164 return GlobalUnlock16( hmf
);
168 /******************************************************************
169 * DeleteMetaFile (GDI.127)
171 BOOL16 WINAPI
DeleteMetaFile16( HMETAFILE16 hmf
)
173 return !GlobalFree16( hmf
);
176 /******************************************************************
177 * DeleteMetaFile (GDI32.@)
179 * Delete a memory-based metafile.
182 BOOL WINAPI
DeleteMetaFile( HMETAFILE hmf
)
184 METAFILEOBJ
* metaObj
= (METAFILEOBJ
*)GDI_GetObjPtr( hmf
, METAFILE_MAGIC
);
185 if (!metaObj
) return FALSE
;
186 HeapFree( GetProcessHeap(), 0, metaObj
->mh
);
187 GDI_FreeObject( hmf
, metaObj
);
191 /******************************************************************
194 * Returns a pointer to a memory based METAHEADER read in from file HFILE
197 static METAHEADER
*MF_ReadMetaFile(HFILE hfile
)
200 DWORD BytesRead
, size
;
202 size
= sizeof(METAHEADER
);
203 mh
= HeapAlloc( GetProcessHeap(), 0, size
);
205 if(ReadFile( hfile
, mh
, size
, &BytesRead
, NULL
) == 0 ||
207 HeapFree( GetProcessHeap(), 0, mh
);
210 size
= mh
->mtSize
* 2;
211 mh
= HeapReAlloc( GetProcessHeap(), 0, mh
, size
);
213 size
-= sizeof(METAHEADER
);
214 if(ReadFile( hfile
, (char *)mh
+ sizeof(METAHEADER
), size
, &BytesRead
,
217 HeapFree( GetProcessHeap(), 0, mh
);
221 if (mh
->mtType
!= METAFILE_MEMORY
) {
222 WARN("Disk metafile had mtType = %04x\n", mh
->mtType
);
223 mh
->mtType
= METAFILE_MEMORY
;
228 /******************************************************************
229 * GetMetaFile (GDI.124)
231 HMETAFILE16 WINAPI
GetMetaFile16( LPCSTR lpFilename
)
236 TRACE("%s\n", lpFilename
);
241 if((hFile
= CreateFileA(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
242 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
245 mh
= MF_ReadMetaFile(hFile
);
248 return MF_Create_HMETAFILE16( mh
);
251 /******************************************************************
252 * GetMetaFileA (GDI32.@)
254 * Read a metafile from a file. Returns handle to a memory-based metafile.
256 HMETAFILE WINAPI
GetMetaFileA( LPCSTR lpFilename
)
261 TRACE("%s\n", lpFilename
);
266 if((hFile
= CreateFileA(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
267 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
270 mh
= MF_ReadMetaFile(hFile
);
273 return MF_Create_HMETAFILE( mh
);
278 /******************************************************************
279 * GetMetaFileW (GDI32.@)
281 HMETAFILE WINAPI
GetMetaFileW( LPCWSTR lpFilename
)
286 TRACE("%s\n", debugstr_w(lpFilename
));
291 if((hFile
= CreateFileW(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
292 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
295 mh
= MF_ReadMetaFile(hFile
);
298 return MF_Create_HMETAFILE( mh
);
302 /******************************************************************
303 * MF_LoadDiskBasedMetaFile
305 * Creates a new memory-based metafile from a disk-based one.
307 static METAHEADER
*MF_LoadDiskBasedMetaFile(METAHEADER
*mh
)
313 if(mh
->mtType
!= METAFILE_DISK
) {
314 ERR("Not a disk based metafile\n");
317 mhd
= (METAHEADERDISK
*)((char *)mh
+ sizeof(METAHEADER
));
319 if((hfile
= CreateFileA(mhd
->filename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
320 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
) {
321 WARN("Can't open file of disk based metafile\n");
324 mh2
= MF_ReadMetaFile(hfile
);
329 /******************************************************************
330 * MF_CreateMetaHeaderDisk
332 * Take a memory based METAHEADER and change it to a disk based METAHEADER
333 * assosiated with filename. Note: Trashes contents of old one.
335 METAHEADER
*MF_CreateMetaHeaderDisk(METAHEADER
*mh
, LPCSTR filename
)
340 mh
= HeapReAlloc( GetProcessHeap(), 0, mh
,
341 sizeof(METAHEADER
) + sizeof(METAHEADERDISK
));
342 mh
->mtType
= METAFILE_DISK
;
343 size
= HeapSize( GetProcessHeap(), 0, mh
);
344 mhd
= (METAHEADERDISK
*)((char *)mh
+ sizeof(METAHEADER
));
345 strcpy(mhd
->filename
, filename
);
349 /******************************************************************
350 * CopyMetaFile (GDI.151)
352 HMETAFILE16 WINAPI
CopyMetaFile16( HMETAFILE16 hSrcMetaFile
, LPCSTR lpFilename
)
354 METAHEADER
*mh
= MF_GetMetaHeader16( hSrcMetaFile
);
355 METAHEADER
*mh2
= NULL
;
358 TRACE("(%08x,%s)\n", hSrcMetaFile
, lpFilename
);
362 if(mh
->mtType
== METAFILE_DISK
)
363 mh2
= MF_LoadDiskBasedMetaFile(mh
);
365 mh2
= HeapAlloc( GetProcessHeap(), 0, mh
->mtSize
* 2 );
366 memcpy( mh2
, mh
, mh
->mtSize
* 2 );
368 MF_ReleaseMetaHeader16( hSrcMetaFile
);
370 if(lpFilename
) { /* disk based metafile */
371 if((hFile
= CreateFileA(lpFilename
, GENERIC_WRITE
, 0, NULL
,
372 CREATE_ALWAYS
, 0, 0)) == INVALID_HANDLE_VALUE
) {
373 HeapFree( GetProcessHeap(), 0, mh2
);
376 WriteFile(hFile
, mh2
, mh2
->mtSize
* 2, NULL
, NULL
);
378 mh2
= MF_CreateMetaHeaderDisk(mh2
, lpFilename
);
381 return MF_Create_HMETAFILE16( mh2
);
385 /******************************************************************
386 * CopyMetaFileA (GDI32.@)
388 * Copies the metafile corresponding to hSrcMetaFile to either
389 * a disk file, if a filename is given, or to a new memory based
390 * metafile, if lpFileName is NULL.
394 * Handle to metafile copy on success, NULL on failure.
398 * Copying to disk returns NULL even if successful.
400 HMETAFILE WINAPI
CopyMetaFileA(
401 HMETAFILE hSrcMetaFile
, /* [in] handle of metafile to copy */
402 LPCSTR lpFilename
/* [in] filename if copying to a file */
404 METAHEADER
*mh
= MF_GetMetaHeader( hSrcMetaFile
);
405 METAHEADER
*mh2
= NULL
;
408 TRACE("(%08x,%s)\n", hSrcMetaFile
, lpFilename
);
412 if(mh
->mtType
== METAFILE_DISK
)
413 mh2
= MF_LoadDiskBasedMetaFile(mh
);
415 mh2
= HeapAlloc( GetProcessHeap(), 0, mh
->mtSize
* 2 );
416 memcpy( mh2
, mh
, mh
->mtSize
* 2 );
418 MF_ReleaseMetaHeader( hSrcMetaFile
);
420 if(lpFilename
) { /* disk based metafile */
421 if((hFile
= CreateFileA(lpFilename
, GENERIC_WRITE
, 0, NULL
,
422 CREATE_ALWAYS
, 0, 0)) == INVALID_HANDLE_VALUE
) {
423 HeapFree( GetProcessHeap(), 0, mh2
);
426 WriteFile(hFile
, mh2
, mh2
->mtSize
* 2, NULL
, NULL
);
428 mh2
= MF_CreateMetaHeaderDisk(mh2
, lpFilename
);
431 return MF_Create_HMETAFILE( mh2
);
435 /******************************************************************
436 * CopyMetaFileW (GDI32.@)
438 HMETAFILE WINAPI
CopyMetaFileW( HMETAFILE hSrcMetaFile
,
441 LPSTR p
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpFilename
);
442 HMETAFILE ret
= CopyMetaFileA( hSrcMetaFile
, p
);
443 HeapFree( GetProcessHeap(), 0, p
);
448 /******************************************************************
449 * IsValidMetaFile (GDI.410)
451 * Attempts to check if a given metafile is correctly formatted.
452 * Currently, the only things verified are several properties of the
456 * TRUE if hmf passes some tests for being a valid metafile, FALSE otherwise.
459 * This is not exactly what windows does, see _Undocumented_Windows_
462 BOOL16 WINAPI
IsValidMetaFile16(HMETAFILE16 hmf
)
465 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
467 if (mh
->mtType
== METAFILE_MEMORY
|| mh
->mtType
== METAFILE_DISK
)
468 if (mh
->mtHeaderSize
== MFHEADERSIZE
/sizeof(INT16
))
469 if (mh
->mtVersion
== MFVERSION
)
471 MF_ReleaseMetaHeader16(hmf
);
473 TRACE("IsValidMetaFile %x => %d\n",hmf
,res
);
478 /*******************************************************************
481 * Helper for PlayMetaFile
483 static BOOL
MF_PlayMetaFile( HDC hdc
, METAHEADER
*mh
)
488 unsigned int offset
= 0;
495 if (!mh
) return FALSE
;
496 if(mh
->mtType
== METAFILE_DISK
) { /* Create a memory-based copy */
497 mh
= MF_LoadDiskBasedMetaFile(mh
);
498 if(!mh
) return FALSE
;
502 /* save the current pen, brush and font */
503 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
504 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
505 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
507 /* create the handle table */
508 ht
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
509 sizeof(HANDLETABLE16
) * mh
->mtNoObjects
);
510 if(!ht
) return FALSE
;
512 /* loop through metafile playing records */
513 offset
= mh
->mtHeaderSize
* 2;
514 while (offset
< mh
->mtSize
* 2)
516 mr
= (METARECORD
*)((char *)mh
+ offset
);
517 TRACE("offset=%04x,size=%08lx\n",
521 "Entry got size 0 at offset %d, total mf length is %ld\n",
522 offset
,mh
->mtSize
*2);
523 break; /* would loop endlessly otherwise */
525 offset
+= mr
->rdSize
* 2;
526 PlayMetaFileRecord16( hdc
, ht
, mr
, mh
->mtNoObjects
);
529 SelectObject(hdc
, hBrush
);
530 SelectObject(hdc
, hPen
);
531 SelectObject(hdc
, hFont
);
533 /* free objects in handle table */
534 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
535 if(*(ht
->objectHandle
+ i
) != 0)
536 DeleteObject(*(ht
->objectHandle
+ i
));
538 /* free handle table */
539 HeapFree( GetProcessHeap(), 0, ht
);
541 HeapFree( GetProcessHeap(), 0, mh
);
545 /******************************************************************
546 * PlayMetaFile (GDI.123)
549 BOOL16 WINAPI
PlayMetaFile16( HDC16 hdc
, HMETAFILE16 hmf
)
552 METAHEADER
*mh
= MF_GetMetaHeader16( hmf
);
553 ret
= MF_PlayMetaFile( hdc
, mh
);
554 MF_ReleaseMetaHeader16( hmf
);
558 /******************************************************************
559 * PlayMetaFile (GDI32.@)
561 * Renders the metafile specified by hmf in the DC specified by
562 * hdc. Returns FALSE on failure, TRUE on success.
564 BOOL WINAPI
PlayMetaFile(
565 HDC hdc
, /* [in] handle of DC to render in */
566 HMETAFILE hmf
/* [in] handle of metafile to render */
570 METAHEADER
*mh
= MF_GetMetaHeader( hmf
);
571 ret
= MF_PlayMetaFile( hdc
, mh
);
572 MF_ReleaseMetaHeader( hmf
);
577 /******************************************************************
578 * EnumMetaFile16 (GDI.175)
581 BOOL16 WINAPI
EnumMetaFile16( HDC16 hdc
, HMETAFILE16 hmf
,
582 MFENUMPROC16 lpEnumFunc
, LPARAM lpData
)
584 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
589 unsigned int offset
= 0;
594 BOOL16 result
= TRUE
, loaded
= FALSE
;
596 TRACE("(%04x, %04x, %08lx, %08lx)\n",
597 hdc
, hmf
, (DWORD
)lpEnumFunc
, lpData
);
600 if(!mh
) return FALSE
;
601 if(mh
->mtType
== METAFILE_DISK
) { /* Create a memory-based copy */
602 mh
= MF_LoadDiskBasedMetaFile(mh
);
603 if(!mh
) return FALSE
;
607 /* save the current pen, brush and font */
608 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
609 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
610 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
612 /* create the handle table */
614 hHT
= GlobalAlloc16(GMEM_MOVEABLE
| GMEM_ZEROINIT
,
615 sizeof(HANDLETABLE16
) * mh
->mtNoObjects
);
616 spht
= K32WOWGlobalLock16(hHT
);
619 offset
= mh
->mtHeaderSize
* 2;
621 /* loop through metafile records */
623 while (offset
< (mh
->mtSize
* 2))
625 mr
= (METARECORD
*)((char *)mh
+ offset
);
626 if (!lpEnumFunc( hdc
, (HANDLETABLE16
*)spht
,
627 (METARECORD
*)MAKESEGPTR( seg
+ (HIWORD(offset
) << __AHSHIFT
), LOWORD(offset
) ),
628 mh
->mtNoObjects
, (LONG
)lpData
))
635 offset
+= (mr
->rdSize
* 2);
638 SelectObject(hdc
, hBrush
);
639 SelectObject(hdc
, hPen
);
640 SelectObject(hdc
, hFont
);
642 ht
= (HANDLETABLE16
*)GlobalLock16(hHT
);
644 /* free objects in handle table */
645 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
646 if(*(ht
->objectHandle
+ i
) != 0)
647 DeleteObject(*(ht
->objectHandle
+ i
));
649 /* free handle table */
652 HeapFree( GetProcessHeap(), 0, mh
);
653 MF_ReleaseMetaHeader16(hmf
);
657 /******************************************************************
658 * EnumMetaFile (GDI32.@)
660 * Loop through the metafile records in hmf, calling the user-specified
661 * function for each one, stopping when the user's function returns FALSE
662 * (which is considered to be failure)
663 * or when no records are left (which is considered to be success).
666 * TRUE on success, FALSE on failure.
669 * Niels de carpentier, april 1996
671 BOOL WINAPI
EnumMetaFile(
674 MFENUMPROC lpEnumFunc
,
677 METAHEADER
*mhTemp
= NULL
, *mh
= MF_GetMetaHeader(hmf
);
682 unsigned int offset
= 0;
687 TRACE("(%08x,%08x,%p,%p)\n",
688 hdc
, hmf
, lpEnumFunc
, (void*)lpData
);
690 if(mh
->mtType
== METAFILE_DISK
) { /* Create a memory-based copy */
691 mhTemp
= MF_LoadDiskBasedMetaFile(mh
);
694 MF_ReleaseMetaHeader(hmf
);
701 /* We need to copy this thing instead of use it directly because we
702 * have to close the hmf handle for the purpose of avoiding deadlock.
704 mhTemp
= HeapAlloc( GetProcessHeap(), 0, mh
->mtHeaderSize
+ mh
->mtSize
*2 );
707 MF_ReleaseMetaHeader(hmf
);
710 memcpy( mhTemp
, mh
, mh
->mtHeaderSize
+ mh
->mtSize
*2 );
713 MF_ReleaseMetaHeader(hmf
);
714 hmf
= 0; /* just in case */
716 /* save the current pen, brush and font */
717 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
718 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
719 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
721 ht
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
722 sizeof(HANDLETABLE
) * mh
->mtNoObjects
);
724 /* loop through metafile records */
725 offset
= mh
->mtHeaderSize
* 2;
727 while (offset
< (mh
->mtSize
* 2))
729 mr
= (METARECORD
*)((char *)mh
+ offset
);
730 TRACE("Calling EnumFunc with record type %x\n",
732 if (!lpEnumFunc( hdc
, ht
, mr
, mh
->mtNoObjects
, (LONG
)lpData
))
738 offset
+= (mr
->rdSize
* 2);
741 /* restore pen, brush and font */
742 SelectObject(hdc
, hBrush
);
743 SelectObject(hdc
, hPen
);
744 SelectObject(hdc
, hFont
);
746 /* free objects in handle table */
747 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
748 if(*(ht
->objectHandle
+ i
) != 0)
749 DeleteObject(*(ht
->objectHandle
+ i
));
751 /* free handle table */
752 HeapFree( GetProcessHeap(), 0, ht
);
753 /* free a copy of metafile */
754 HeapFree( GetProcessHeap(), 0, mh
);
758 static BOOL
MF_Play_MetaCreateRegion( METARECORD
*mr
, HRGN hrgn
);
759 static BOOL
MF_Play_MetaExtTextOut(HDC16 hdc
, METARECORD
*mr
);
760 /******************************************************************
761 * PlayMetaFileRecord (GDI.176)
763 * Render a single metafile record specified by *mr in the DC hdc, while
764 * using the handle table *ht, of length nHandles,
765 * to store metafile objects.
768 * The following metafile records are unimplemented:
770 * DRAWTEXT, ANIMATEPALETTE, SETPALENTRIES,
771 * RESIZEPALETTE, EXTFLOODFILL, RESETDC, STARTDOC, STARTPAGE, ENDPAGE,
772 * ABORTDOC, ENDDOC, CREATEBRUSH, CREATEBITMAPINDIRECT, and CREATEBITMAP.
775 void WINAPI
PlayMetaFileRecord16(
776 HDC16 hdc
, /* [in] DC to render metafile into */
777 HANDLETABLE16
*ht
, /* [in] pointer to handle table for metafile objects */
778 METARECORD
*mr
, /* [in] pointer to metafile record to render */
779 UINT16 nHandles
/* [in] size of handle table */
784 BITMAPINFOHEADER
*infohdr
;
786 TRACE("(%04x %08lx %08lx %04x) function %04x\n",
787 hdc
,(LONG
)ht
, (LONG
)mr
, nHandles
, mr
->rdFunction
);
789 switch (mr
->rdFunction
)
794 case META_DELETEOBJECT
:
795 DeleteObject(*(ht
->objectHandle
+ *(mr
->rdParm
)));
796 *(ht
->objectHandle
+ *(mr
->rdParm
)) = 0;
799 case META_SETBKCOLOR
:
800 SetBkColor16(hdc
, MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
804 SetBkMode16(hdc
, *(mr
->rdParm
));
807 case META_SETMAPMODE
:
808 SetMapMode16(hdc
, *(mr
->rdParm
));
812 SetROP216(hdc
, *(mr
->rdParm
));
816 SetRelAbs16(hdc
, *(mr
->rdParm
));
819 case META_SETPOLYFILLMODE
:
820 SetPolyFillMode16(hdc
, *(mr
->rdParm
));
823 case META_SETSTRETCHBLTMODE
:
824 SetStretchBltMode16(hdc
, *(mr
->rdParm
));
827 case META_SETTEXTCOLOR
:
828 SetTextColor16(hdc
, MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
831 case META_SETWINDOWORG
:
832 SetWindowOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
835 case META_SETWINDOWEXT
:
836 SetWindowExt16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
839 case META_SETVIEWPORTORG
:
840 SetViewportOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
843 case META_SETVIEWPORTEXT
:
844 SetViewportExt16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
847 case META_OFFSETWINDOWORG
:
848 OffsetWindowOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
851 case META_SCALEWINDOWEXT
:
852 ScaleWindowExt16(hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
853 *(mr
->rdParm
+ 1), *(mr
->rdParm
));
856 case META_OFFSETVIEWPORTORG
:
857 OffsetViewportOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
860 case META_SCALEVIEWPORTEXT
:
861 ScaleViewportExt16(hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
862 *(mr
->rdParm
+ 1), *(mr
->rdParm
));
866 LineTo(hdc
, (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
870 MoveTo16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
873 case META_EXCLUDECLIPRECT
:
874 ExcludeClipRect16( hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
875 *(mr
->rdParm
+ 1), *(mr
->rdParm
) );
878 case META_INTERSECTCLIPRECT
:
879 IntersectClipRect16( hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
880 *(mr
->rdParm
+ 1), *(mr
->rdParm
) );
884 Arc(hdc
, (INT16
)*(mr
->rdParm
+ 7), (INT16
)*(mr
->rdParm
+ 6),
885 (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
886 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
887 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
891 Ellipse(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
892 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
896 FloodFill(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
897 MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
901 Pie(hdc
, (INT16
)*(mr
->rdParm
+ 7), (INT16
)*(mr
->rdParm
+ 6),
902 (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
903 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
904 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
908 Rectangle(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
909 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
913 RoundRect(hdc
, (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
914 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
915 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
919 PatBlt16(hdc
, *(mr
->rdParm
+ 5), *(mr
->rdParm
+ 4),
920 *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
921 MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
929 SetPixel(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
930 MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
933 case META_OFFSETCLIPRGN
:
934 OffsetClipRgn16( hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
) );
939 TextOut16(hdc
, *(mr
->rdParm
+ ((s1
+ 1) >> 1) + 2),
940 *(mr
->rdParm
+ ((s1
+ 1) >> 1) + 1),
941 (char *)(mr
->rdParm
+ 1), s1
);
945 Polygon16(hdc
, (LPPOINT16
)(mr
->rdParm
+ 1), *(mr
->rdParm
));
948 case META_POLYPOLYGON
:
949 PolyPolygon16(hdc
, (LPPOINT16
)(mr
->rdParm
+ *(mr
->rdParm
) + 1),
950 (LPINT16
)(mr
->rdParm
+ 1), *(mr
->rdParm
));
954 Polyline16(hdc
, (LPPOINT16
)(mr
->rdParm
+ 1), *(mr
->rdParm
));
958 RestoreDC(hdc
, (INT16
)*(mr
->rdParm
));
961 case META_SELECTOBJECT
:
962 SelectObject(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
966 Chord(hdc
, (INT16
)*(mr
->rdParm
+ 7), (INT16
)*(mr
->rdParm
+ 6),
967 (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
968 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
969 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
972 case META_CREATEPATTERNBRUSH
:
973 switch (*(mr
->rdParm
))
976 infohdr
= (BITMAPINFOHEADER
*)(mr
->rdParm
+ 2);
977 MF_AddHandle(ht
, nHandles
,
978 CreatePatternBrush(CreateBitmap(infohdr
->biWidth
,
983 (sizeof(BITMAPINFOHEADER
) / 2) + 4))));
987 s1
= mr
->rdSize
* 2 - sizeof(METARECORD
) - 2;
988 hndl
= GlobalAlloc16(GMEM_MOVEABLE
, s1
);
989 ptr
= GlobalLock16(hndl
);
990 memcpy(ptr
, mr
->rdParm
+ 2, s1
);
991 GlobalUnlock16(hndl
);
992 MF_AddHandle(ht
, nHandles
,
993 CreateDIBPatternBrush(hndl
, *(mr
->rdParm
+ 1)));
998 ERR("META_CREATEPATTERNBRUSH: Unknown pattern type %d\n",
1004 case META_CREATEPENINDIRECT
:
1005 MF_AddHandle(ht
, nHandles
,
1006 CreatePenIndirect16((LOGPEN16
*)(&(mr
->rdParm
))));
1009 case META_CREATEFONTINDIRECT
:
1010 MF_AddHandle(ht
, nHandles
,
1011 CreateFontIndirect16((LOGFONT16
*)(&(mr
->rdParm
))));
1014 case META_CREATEBRUSHINDIRECT
:
1015 MF_AddHandle(ht
, nHandles
,
1016 CreateBrushIndirect16((LOGBRUSH16
*)(&(mr
->rdParm
))));
1019 case META_CREATEPALETTE
:
1020 MF_AddHandle(ht
, nHandles
,
1021 CreatePalette16((LPLOGPALETTE
)mr
->rdParm
));
1024 case META_SETTEXTALIGN
:
1025 SetTextAlign16(hdc
, *(mr
->rdParm
));
1028 case META_SELECTPALETTE
:
1029 GDISelectPalette16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
+1)),
1033 case META_SETMAPPERFLAGS
:
1034 SetMapperFlags16(hdc
, MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1037 case META_REALIZEPALETTE
:
1038 GDIRealizePalette16(hdc
);
1042 FIXME("META_ESCAPE unimplemented.\n");
1045 case META_EXTTEXTOUT
:
1046 MF_Play_MetaExtTextOut( hdc
, mr
);
1049 case META_STRETCHDIB
:
1051 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[11]);
1052 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[2] );
1053 StretchDIBits16(hdc
,mr
->rdParm
[10],mr
->rdParm
[9],mr
->rdParm
[8],
1054 mr
->rdParm
[7],mr
->rdParm
[6],mr
->rdParm
[5],
1055 mr
->rdParm
[4],mr
->rdParm
[3],bits
,info
,
1056 mr
->rdParm
[2],MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1060 case META_DIBSTRETCHBLT
:
1062 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[10]);
1063 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[2] );
1064 StretchDIBits16(hdc
,mr
->rdParm
[9],mr
->rdParm
[8],mr
->rdParm
[7],
1065 mr
->rdParm
[6],mr
->rdParm
[5],mr
->rdParm
[4],
1066 mr
->rdParm
[3],mr
->rdParm
[2],bits
,info
,
1067 DIB_RGB_COLORS
,MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1071 case META_STRETCHBLT
:
1073 HDC16 hdcSrc
=CreateCompatibleDC16(hdc
);
1074 HBITMAP hbitmap
=CreateBitmap(mr
->rdParm
[10], /*Width */
1075 mr
->rdParm
[11], /*Height*/
1076 mr
->rdParm
[13], /*Planes*/
1077 mr
->rdParm
[14], /*BitsPixel*/
1078 (LPSTR
)&mr
->rdParm
[15]); /*bits*/
1079 SelectObject(hdcSrc
,hbitmap
);
1080 StretchBlt16(hdc
,mr
->rdParm
[9],mr
->rdParm
[8],
1081 mr
->rdParm
[7],mr
->rdParm
[6],
1082 hdcSrc
,mr
->rdParm
[5],mr
->rdParm
[4],
1083 mr
->rdParm
[3],mr
->rdParm
[2],
1084 MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1091 HDC16 hdcSrc
=CreateCompatibleDC16(hdc
);
1092 HBITMAP hbitmap
=CreateBitmap(mr
->rdParm
[7]/*Width */,
1093 mr
->rdParm
[8]/*Height*/,
1094 mr
->rdParm
[10]/*Planes*/,
1095 mr
->rdParm
[11]/*BitsPixel*/,
1096 (LPSTR
)&mr
->rdParm
[12]/*bits*/);
1097 SelectObject(hdcSrc
,hbitmap
);
1098 BitBlt(hdc
,(INT16
)mr
->rdParm
[6],(INT16
)mr
->rdParm
[5],
1099 (INT16
)mr
->rdParm
[4],(INT16
)mr
->rdParm
[3],
1100 hdcSrc
, (INT16
)mr
->rdParm
[2],(INT16
)mr
->rdParm
[1],
1101 MAKELONG(0,mr
->rdParm
[0]));
1106 case META_CREATEREGION
:
1108 HRGN hrgn
= CreateRectRgn(0,0,0,0);
1110 MF_Play_MetaCreateRegion(mr
, hrgn
);
1111 MF_AddHandle(ht
, nHandles
, hrgn
);
1115 case META_FILLREGION
:
1116 FillRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
+1)),
1117 *(ht
->objectHandle
+ *(mr
->rdParm
)));
1120 case META_FRAMEREGION
:
1121 FrameRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
+3)),
1122 *(ht
->objectHandle
+ *(mr
->rdParm
+2)),
1123 *(mr
->rdParm
+1), *(mr
->rdParm
));
1126 case META_INVERTREGION
:
1127 InvertRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
1130 case META_PAINTREGION
:
1131 PaintRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
1134 case META_SELECTCLIPREGION
:
1135 SelectClipRgn(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
1138 case META_DIBCREATEPATTERNBRUSH
:
1139 /* *(mr->rdParm) may be BS_PATTERN or BS_DIBPATTERN:
1140 but there's no difference */
1142 TRACE("%d\n",*(mr
->rdParm
));
1143 s1
= mr
->rdSize
* 2 - sizeof(METARECORD
) - 2;
1144 hndl
= GlobalAlloc16(GMEM_MOVEABLE
, s1
);
1145 ptr
= GlobalLock16(hndl
);
1146 memcpy(ptr
, mr
->rdParm
+ 2, s1
);
1147 GlobalUnlock16(hndl
);
1148 MF_AddHandle(ht
, nHandles
,
1149 CreateDIBPatternBrush16(hndl
, *(mr
->rdParm
+ 1)));
1153 case META_DIBBITBLT
:
1154 /* In practice I've found that there are two layouts for
1155 META_DIBBITBLT, one (the first here) is the usual one when a src
1156 dc is actually passed to it, the second occurs when the src dc is
1157 passed in as NULL to the creating BitBlt. As the second case has
1158 no dib, a size check will suffice to distinguish.
1160 Caolan.McNamara@ul.ie */
1162 if (mr
->rdSize
> 12) {
1163 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[8]);
1164 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize(info
, mr
->rdParm
[0]);
1166 StretchDIBits16(hdc
, mr
->rdParm
[7], mr
->rdParm
[6], mr
->rdParm
[5],
1167 mr
->rdParm
[4], mr
->rdParm
[3], mr
->rdParm
[2],
1168 mr
->rdParm
[5], mr
->rdParm
[4], bits
, info
,
1170 MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
1171 } else { /* equivalent to a PatBlt */
1172 PatBlt16(hdc
, mr
->rdParm
[8], mr
->rdParm
[7],
1173 mr
->rdParm
[6], mr
->rdParm
[5],
1174 MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
1178 case META_SETTEXTCHAREXTRA
:
1179 SetTextCharacterExtra16(hdc
, (INT16
)*(mr
->rdParm
));
1182 case META_SETTEXTJUSTIFICATION
:
1183 SetTextJustification(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
1186 case META_EXTFLOODFILL
:
1187 ExtFloodFill(hdc
, (INT16
)*(mr
->rdParm
+ 4), (INT16
)*(mr
->rdParm
+ 3),
1188 MAKELONG(*(mr
->rdParm
+1), *(mr
->rdParm
+ 2)),
1192 case META_SETDIBTODEV
:
1194 BITMAPINFO
*info
= (BITMAPINFO
*) &(mr
->rdParm
[9]);
1195 char *bits
= (char *)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[0] );
1196 SetDIBitsToDevice(hdc
, (INT16
)mr
->rdParm
[8], (INT16
)mr
->rdParm
[7],
1197 (INT16
)mr
->rdParm
[6], (INT16
)mr
->rdParm
[5],
1198 (INT16
)mr
->rdParm
[4], (INT16
)mr
->rdParm
[3],
1199 mr
->rdParm
[2], mr
->rdParm
[1], bits
, info
,
1204 #define META_UNIMP(x) case x: \
1205 FIXME("PlayMetaFileRecord:record type "#x" not implemented.\n"); \
1207 META_UNIMP(META_DRAWTEXT
)
1208 META_UNIMP(META_ANIMATEPALETTE
)
1209 META_UNIMP(META_SETPALENTRIES
)
1210 META_UNIMP(META_RESIZEPALETTE
)
1211 META_UNIMP(META_RESETDC
)
1212 META_UNIMP(META_STARTDOC
)
1213 META_UNIMP(META_STARTPAGE
)
1214 META_UNIMP(META_ENDPAGE
)
1215 META_UNIMP(META_ABORTDOC
)
1216 META_UNIMP(META_ENDDOC
)
1217 META_UNIMP(META_CREATEBRUSH
)
1218 META_UNIMP(META_CREATEBITMAPINDIRECT
)
1219 META_UNIMP(META_CREATEBITMAP
)
1223 WARN("PlayMetaFileRecord: Unknown record type %x\n",
1228 /******************************************************************
1229 * PlayMetaFileRecord (GDI32.@)
1231 BOOL WINAPI
PlayMetaFileRecord( HDC hdc
, HANDLETABLE
*handletable
,
1232 METARECORD
*metarecord
, UINT handles
)
1234 HANDLETABLE16
* ht
= (void *)GlobalAlloc(GPTR
,
1235 handles
*sizeof(HANDLETABLE16
));
1237 TRACE("(%08x,%p,%p,%d)\n", hdc
, handletable
, metarecord
,
1239 for (i
=0; i
<handles
; i
++)
1240 ht
->objectHandle
[i
] = handletable
->objectHandle
[i
];
1241 PlayMetaFileRecord16(hdc
, ht
, metarecord
, handles
);
1242 for (i
=0; i
<handles
; i
++)
1243 handletable
->objectHandle
[i
] = ht
->objectHandle
[i
];
1244 GlobalFree((HGLOBAL
)ht
);
1248 /******************************************************************
1249 * GetMetaFileBits (GDI.159)
1251 * Trade in a metafile object handle for a handle to the metafile memory.
1255 HGLOBAL16 WINAPI
GetMetaFileBits16(
1256 HMETAFILE16 hmf
/* [in] metafile handle */
1259 TRACE("hMem out: %04x\n", hmf
);
1263 /******************************************************************
1264 * SetMetaFileBits (GDI.160)
1266 * Trade in a metafile memory handle for a handle to a metafile object.
1267 * The memory region should hold a proper metafile, otherwise
1268 * problems will occur when it is used. Validity of the memory is not
1269 * checked. The function is essentially just the identity function.
1271 HMETAFILE16 WINAPI
SetMetaFileBits16(
1273 /* [in] handle to a memory region holding a metafile */
1276 TRACE("hmf out: %04x\n", hMem
);
1281 /******************************************************************
1282 * SetMetaFileBitsBetter (GDI.196)
1284 * Trade in a metafile memory handle for a handle to a metafile object,
1285 * making a cursory check (using IsValidMetaFile()) that the memory
1286 * handle points to a valid metafile.
1289 * Handle to a metafile on success, NULL on failure..
1291 HMETAFILE16 WINAPI
SetMetaFileBitsBetter16( HMETAFILE16 hMeta
)
1293 if( IsValidMetaFile16( hMeta
) )
1294 return (HMETAFILE16
)GlobalReAlloc16( hMeta
, 0,
1295 GMEM_SHARE
| GMEM_NODISCARD
| GMEM_MODIFY
);
1296 return (HMETAFILE16
)0;
1299 /******************************************************************
1300 * SetMetaFileBitsEx (GDI32.@)
1302 * Create a metafile from raw data. No checking of the data is performed.
1303 * Use _GetMetaFileBitsEx_ to get raw data from a metafile.
1305 HMETAFILE WINAPI
SetMetaFileBitsEx(
1306 UINT size
, /* [in] size of metafile, in bytes */
1307 const BYTE
*lpData
/* [in] pointer to metafile data */
1310 METAHEADER
*mh
= HeapAlloc( GetProcessHeap(), 0, size
);
1312 memcpy(mh
, lpData
, size
);
1313 return MF_Create_HMETAFILE(mh
);
1316 /*****************************************************************
1317 * GetMetaFileBitsEx (GDI32.@) Get raw metafile data
1319 * Copies the data from metafile _hmf_ into the buffer _buf_.
1320 * If _buf_ is zero, returns size of buffer required. Otherwise,
1321 * returns number of bytes copied.
1323 UINT WINAPI
GetMetaFileBitsEx(
1324 HMETAFILE hmf
, /* [in] metafile */
1325 UINT nSize
, /* [in] size of buf */
1326 LPVOID buf
/* [out] buffer to receive raw metafile data */
1328 METAHEADER
*mh
= MF_GetMetaHeader(hmf
);
1331 TRACE("(%08x,%d,%p)\n", hmf
, nSize
, buf
);
1332 if (!mh
) return 0; /* FIXME: error code */
1333 if(mh
->mtType
== METAFILE_DISK
)
1334 FIXME("Disk-based metafile?\n");
1335 mfSize
= mh
->mtSize
* 2;
1337 MF_ReleaseMetaHeader(hmf
);
1338 TRACE("returning size %d\n", mfSize
);
1341 if(mfSize
> nSize
) mfSize
= nSize
;
1342 memmove(buf
, mh
, mfSize
);
1343 MF_ReleaseMetaHeader(hmf
);
1347 /******************************************************************
1348 * GetWinMetaFileBits [GDI32.@]
1350 UINT WINAPI
GetWinMetaFileBits(HENHMETAFILE hemf
,
1351 UINT cbBuffer
, LPBYTE lpbBuffer
,
1352 INT fnMapMode
, HDC hdcRef
)
1354 FIXME("(%d,%d,%p,%d,%d): stub\n",
1355 hemf
, cbBuffer
, lpbBuffer
, fnMapMode
, hdcRef
);
1359 /******************************************************************
1360 * MF_Play_MetaCreateRegion
1362 * Handles META_CREATEREGION for PlayMetaFileRecord().
1366 * The layout of the record looks something like this:
1371 * 2 Looks like a handle? - not constant
1373 * 4 Total number of bytes
1374 * 5 No. of separate bands = n [see below]
1375 * 6 Largest number of x co-ords in a band
1376 * 7-10 Bounding box x1 y1 x2 y2
1379 * Regions are divided into bands that are uniform in the
1380 * y-direction. Each band consists of pairs of on/off x-coords and is
1382 * m y0 y1 x1 x2 x3 ... xm m
1383 * into successive rdParm[]s.
1385 * This is probably just a dump of the internal RGNOBJ?
1391 static BOOL
MF_Play_MetaCreateRegion( METARECORD
*mr
, HRGN hrgn
)
1396 HRGN hrgn2
= CreateRectRgn( 0, 0, 0, 0 );
1398 for(band
= 0, start
= &(mr
->rdParm
[11]); band
< mr
->rdParm
[5];
1399 band
++, start
= end
+ 1) {
1400 if(*start
/ 2 != (*start
+ 1) / 2) {
1401 WARN("Delimiter not even.\n");
1402 DeleteObject( hrgn2
);
1406 end
= start
+ *start
+ 3;
1407 if(end
> (WORD
*)mr
+ mr
->rdSize
) {
1408 WARN("End points outside record.\n");
1409 DeleteObject( hrgn2
);
1413 if(*start
!= *end
) {
1414 WARN("Mismatched delimiters.\n");
1415 DeleteObject( hrgn2
);
1419 y0
= *(INT16
*)(start
+ 1);
1420 y1
= *(INT16
*)(start
+ 2);
1421 for(pair
= 0; pair
< *start
/ 2; pair
++) {
1422 SetRectRgn( hrgn2
, *(INT16
*)(start
+ 3 + 2*pair
), y0
,
1423 *(INT16
*)(start
+ 4 + 2*pair
), y1
);
1424 CombineRgn(hrgn
, hrgn
, hrgn2
, RGN_OR
);
1427 DeleteObject( hrgn2
);
1432 /******************************************************************
1433 * MF_Play_MetaExtTextOut
1435 * Handles META_EXTTEXTOUT for PlayMetaFileRecord().
1438 static BOOL
MF_Play_MetaExtTextOut(HDC16 hdc
, METARECORD
*mr
)
1445 s1
= mr
->rdParm
[2]; /* String length */
1446 len
= sizeof(METARECORD
) + (((s1
+ 1) >> 1) * 2) + 2 * sizeof(short)
1447 + sizeof(UINT16
) + (mr
->rdParm
[3] ? sizeof(RECT16
) : 0);
1448 /* rec len without dx array */
1450 sot
= (LPSTR
)&mr
->rdParm
[4]; /* start_of_text */
1452 sot
+= sizeof(RECT16
); /* there is a rectangle, so add offset */
1454 if (mr
->rdSize
== len
/ 2)
1455 dxx
= NULL
; /* determine if array present */
1457 if (mr
->rdSize
== (len
+ s1
* sizeof(INT16
)) / 2)
1458 dxx
= (LPINT16
)(sot
+(((s1
+1)>>1)*2));
1460 TRACE("%s len: %ld\n", sot
, mr
->rdSize
);
1462 "Please report: ExtTextOut len=%ld slen=%d rdSize=%ld opt=%04x\n",
1463 len
, s1
, mr
->rdSize
, mr
->rdParm
[3]);
1464 dxx
= NULL
; /* should't happen -- but if, we continue with NULL */
1466 ExtTextOut16( hdc
, mr
->rdParm
[1], /* X position */
1467 mr
->rdParm
[0], /* Y position */
1468 mr
->rdParm
[3], /* options */
1469 mr
->rdParm
[3] ? (LPRECT16
) &mr
->rdParm
[4]:NULL
,
1472 s1
, dxx
); /* length, dx array */
1474 TRACE("%s len: %ld dx0: %d\n", sot
, mr
->rdSize
, dxx
[0]);