4 * Copyright David W. Metcalfe, 1994
5 * Niels de Carpentier, Albrecht Kleine, Huw Davies 1996
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * These functions are primarily involved with metafile playback or anything
24 * that touches a HMETAFILE.
25 * For recording of metafiles look in graphics/metafiledrv/
27 * Note that (32 bit) HMETAFILEs are GDI objects, while HMETAFILE16s are
28 * global memory handles so these cannot be interchanged.
30 * Memory-based metafiles are just stored as a continuous block of memory with
31 * a METAHEADER at the head with METARECORDs appended to it. mtType is
32 * METAFILE_MEMORY (1). Note this is indentical to the disk image of a
33 * disk-based metafile - even mtType is METAFILE_MEMORY.
34 * 16bit HMETAFILE16s are global handles to this block
35 * 32bit HMETAFILEs are GDI handles METAFILEOBJs, which contains a ptr to
37 * Disk-based metafiles are rather different. HMETAFILE16s point to a
38 * METAHEADER which has mtType equal to METAFILE_DISK (2). Following the 9
39 * WORDs of the METAHEADER there are a further 3 WORDs of 0, 1 of 0x117, 1
40 * more 0, then 2 which may be a time stamp of the file and then the path of
41 * the file (METAHEADERDISK). I've copied this for 16bit compatibility.
51 #include "wine/winbase16.h"
52 #include "wine/wingdi16.h"
55 #include "wine/debug.h"
57 WINE_DEFAULT_DEBUG_CHANNEL(metafile
);
74 #define MFHEADERSIZE (sizeof(METAHEADER))
75 #define MFVERSION 0x300
77 /* ### start build ### */
78 extern WORD CALLBACK
MF_CallTo16_word_wllwl(MFENUMPROC16
,WORD
,LONG
,LONG
,WORD
,LONG
);
79 /* ### stop build ### */
81 /******************************************************************
84 * Add a handle to an external handle table and return the index
86 static int MF_AddHandle(HANDLETABLE16
*ht
, WORD htlen
, HGDIOBJ16 hobj
)
90 for (i
= 0; i
< htlen
; i
++)
92 if (*(ht
->objectHandle
+ i
) == 0)
94 *(ht
->objectHandle
+ i
) = hobj
;
102 /******************************************************************
103 * MF_Create_HMETATFILE
105 * Creates a (32 bit) HMETAFILE object from a METAHEADER
107 * HMETAFILEs are GDI objects.
109 HMETAFILE
MF_Create_HMETAFILE(METAHEADER
*mh
)
112 METAFILEOBJ
*metaObj
= GDI_AllocObject( sizeof(METAFILEOBJ
), METAFILE_MAGIC
, &hmf
, NULL
);
116 GDI_ReleaseObj( hmf
);
121 /******************************************************************
122 * MF_Create_HMETATFILE16
124 * Creates a HMETAFILE16 object from a METAHEADER
126 * HMETAFILE16s are Global memory handles.
128 HMETAFILE16
MF_Create_HMETAFILE16(METAHEADER
*mh
)
131 DWORD size
= mh
->mtSize
* sizeof(WORD
);
133 hmf
= GlobalAlloc16(GMEM_MOVEABLE
, size
);
136 METAHEADER
*mh_dest
= GlobalLock16(hmf
);
137 memcpy(mh_dest
, mh
, size
);
140 HeapFree(GetProcessHeap(), 0, mh
);
144 /******************************************************************
147 * Returns ptr to METAHEADER associated with HMETAFILE
149 static METAHEADER
*MF_GetMetaHeader( HMETAFILE hmf
)
151 METAHEADER
*ret
= NULL
;
152 METAFILEOBJ
* metaObj
= (METAFILEOBJ
*)GDI_GetObjPtr( hmf
, METAFILE_MAGIC
);
156 GDI_ReleaseObj( hmf
);
161 /******************************************************************
164 * Returns ptr to METAHEADER associated with HMETAFILE16
165 * Should be followed by call to MF_ReleaseMetaHeader16
167 static METAHEADER
*MF_GetMetaHeader16( HMETAFILE16 hmf
)
169 return GlobalLock16(hmf
);
172 /******************************************************************
173 * MF_ReleaseMetaHeader16
175 * Releases METAHEADER associated with HMETAFILE16
177 static BOOL16
MF_ReleaseMetaHeader16( HMETAFILE16 hmf
)
179 return GlobalUnlock16( hmf
);
183 /******************************************************************
184 * DeleteMetaFile (GDI.127)
186 BOOL16 WINAPI
DeleteMetaFile16( HMETAFILE16 hmf
)
188 return !GlobalFree16( hmf
);
191 /******************************************************************
192 * DeleteMetaFile (GDI32.@)
194 * Delete a memory-based metafile.
197 BOOL WINAPI
DeleteMetaFile( HMETAFILE hmf
)
199 METAFILEOBJ
* metaObj
= (METAFILEOBJ
*)GDI_GetObjPtr( hmf
, METAFILE_MAGIC
);
200 if (!metaObj
) return FALSE
;
201 HeapFree( GetProcessHeap(), 0, metaObj
->mh
);
202 GDI_FreeObject( hmf
, metaObj
);
206 /******************************************************************
209 * Returns a pointer to a memory based METAHEADER read in from file HFILE
212 static METAHEADER
*MF_ReadMetaFile(HANDLE hfile
)
215 DWORD BytesRead
, size
;
217 size
= sizeof(METAHEADER
);
218 mh
= HeapAlloc( GetProcessHeap(), 0, size
);
220 if(ReadFile( hfile
, mh
, size
, &BytesRead
, NULL
) == 0 ||
222 HeapFree( GetProcessHeap(), 0, mh
);
225 size
= mh
->mtSize
* 2;
226 mh
= HeapReAlloc( GetProcessHeap(), 0, mh
, size
);
228 size
-= sizeof(METAHEADER
);
229 if(ReadFile( hfile
, (char *)mh
+ sizeof(METAHEADER
), size
, &BytesRead
,
232 HeapFree( GetProcessHeap(), 0, mh
);
236 if (mh
->mtType
!= METAFILE_MEMORY
) {
237 WARN("Disk metafile had mtType = %04x\n", mh
->mtType
);
238 mh
->mtType
= METAFILE_MEMORY
;
243 /******************************************************************
244 * GetMetaFile (GDI.124)
246 HMETAFILE16 WINAPI
GetMetaFile16( LPCSTR lpFilename
)
251 TRACE("%s\n", lpFilename
);
256 if((hFile
= CreateFileA(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
257 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
260 mh
= MF_ReadMetaFile(hFile
);
263 return MF_Create_HMETAFILE16( mh
);
266 /******************************************************************
267 * GetMetaFileA (GDI32.@)
269 * Read a metafile from a file. Returns handle to a memory-based metafile.
271 HMETAFILE WINAPI
GetMetaFileA( LPCSTR lpFilename
)
276 TRACE("%s\n", lpFilename
);
281 if((hFile
= CreateFileA(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
282 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
285 mh
= MF_ReadMetaFile(hFile
);
288 return MF_Create_HMETAFILE( mh
);
293 /******************************************************************
294 * GetMetaFileW (GDI32.@)
296 HMETAFILE WINAPI
GetMetaFileW( LPCWSTR lpFilename
)
301 TRACE("%s\n", debugstr_w(lpFilename
));
306 if((hFile
= CreateFileW(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
307 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
310 mh
= MF_ReadMetaFile(hFile
);
313 return MF_Create_HMETAFILE( mh
);
317 /******************************************************************
318 * MF_LoadDiskBasedMetaFile
320 * Creates a new memory-based metafile from a disk-based one.
322 static METAHEADER
*MF_LoadDiskBasedMetaFile(METAHEADER
*mh
)
328 if(mh
->mtType
!= METAFILE_DISK
) {
329 ERR("Not a disk based metafile\n");
332 mhd
= (METAHEADERDISK
*)((char *)mh
+ sizeof(METAHEADER
));
334 if((hfile
= CreateFileA(mhd
->filename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
335 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
) {
336 WARN("Can't open file of disk based metafile\n");
339 mh2
= MF_ReadMetaFile(hfile
);
344 /******************************************************************
345 * MF_CreateMetaHeaderDisk
347 * Take a memory based METAHEADER and change it to a disk based METAHEADER
348 * assosiated with filename. Note: Trashes contents of old one.
350 METAHEADER
*MF_CreateMetaHeaderDisk(METAHEADER
*mh
, LPCSTR filename
)
355 mh
= HeapReAlloc( GetProcessHeap(), 0, mh
,
356 sizeof(METAHEADER
) + sizeof(METAHEADERDISK
));
357 mh
->mtType
= METAFILE_DISK
;
358 size
= HeapSize( GetProcessHeap(), 0, mh
);
359 mhd
= (METAHEADERDISK
*)((char *)mh
+ sizeof(METAHEADER
));
360 strcpy(mhd
->filename
, filename
);
364 /******************************************************************
365 * CopyMetaFile (GDI.151)
367 HMETAFILE16 WINAPI
CopyMetaFile16( HMETAFILE16 hSrcMetaFile
, LPCSTR lpFilename
)
369 METAHEADER
*mh
= MF_GetMetaHeader16( hSrcMetaFile
);
370 METAHEADER
*mh2
= NULL
;
373 TRACE("(%08x,%s)\n", hSrcMetaFile
, lpFilename
);
377 if(mh
->mtType
== METAFILE_DISK
)
378 mh2
= MF_LoadDiskBasedMetaFile(mh
);
380 mh2
= HeapAlloc( GetProcessHeap(), 0, mh
->mtSize
* 2 );
381 memcpy( mh2
, mh
, mh
->mtSize
* 2 );
383 MF_ReleaseMetaHeader16( hSrcMetaFile
);
385 if(lpFilename
) { /* disk based metafile */
386 if((hFile
= CreateFileA(lpFilename
, GENERIC_WRITE
, 0, NULL
,
387 CREATE_ALWAYS
, 0, 0)) == INVALID_HANDLE_VALUE
) {
388 HeapFree( GetProcessHeap(), 0, mh2
);
391 WriteFile(hFile
, mh2
, mh2
->mtSize
* 2, NULL
, NULL
);
393 mh2
= MF_CreateMetaHeaderDisk(mh2
, lpFilename
);
396 return MF_Create_HMETAFILE16( mh2
);
400 /******************************************************************
401 * CopyMetaFileA (GDI32.@)
403 * Copies the metafile corresponding to hSrcMetaFile to either
404 * a disk file, if a filename is given, or to a new memory based
405 * metafile, if lpFileName is NULL.
409 * Handle to metafile copy on success, NULL on failure.
413 * Copying to disk returns NULL even if successful.
415 HMETAFILE WINAPI
CopyMetaFileA(
416 HMETAFILE hSrcMetaFile
, /* [in] handle of metafile to copy */
417 LPCSTR lpFilename
/* [in] filename if copying to a file */
419 METAHEADER
*mh
= MF_GetMetaHeader( hSrcMetaFile
);
420 METAHEADER
*mh2
= NULL
;
423 TRACE("(%08x,%s)\n", hSrcMetaFile
, lpFilename
);
427 if(mh
->mtType
== METAFILE_DISK
)
428 mh2
= MF_LoadDiskBasedMetaFile(mh
);
430 mh2
= HeapAlloc( GetProcessHeap(), 0, mh
->mtSize
* 2 );
431 memcpy( mh2
, mh
, mh
->mtSize
* 2 );
434 if(lpFilename
) { /* disk based metafile */
435 if((hFile
= CreateFileA(lpFilename
, GENERIC_WRITE
, 0, NULL
,
436 CREATE_ALWAYS
, 0, 0)) == INVALID_HANDLE_VALUE
) {
437 HeapFree( GetProcessHeap(), 0, mh2
);
440 WriteFile(hFile
, mh2
, mh2
->mtSize
* 2, NULL
, NULL
);
442 mh2
= MF_CreateMetaHeaderDisk(mh2
, lpFilename
);
445 return MF_Create_HMETAFILE( mh2
);
449 /******************************************************************
450 * CopyMetaFileW (GDI32.@)
452 HMETAFILE WINAPI
CopyMetaFileW( HMETAFILE hSrcMetaFile
,
456 DWORD len
= WideCharToMultiByte( CP_ACP
, 0, lpFilename
, -1, NULL
, 0, NULL
, NULL
);
457 LPSTR p
= HeapAlloc( GetProcessHeap(), 0, len
);
461 WideCharToMultiByte( CP_ACP
, 0, lpFilename
, -1, p
, len
, NULL
, NULL
);
462 ret
= CopyMetaFileA( hSrcMetaFile
, p
);
463 HeapFree( GetProcessHeap(), 0, p
);
469 /******************************************************************
470 * IsValidMetaFile (GDI.410)
472 * Attempts to check if a given metafile is correctly formatted.
473 * Currently, the only things verified are several properties of the
477 * TRUE if hmf passes some tests for being a valid metafile, FALSE otherwise.
480 * This is not exactly what windows does, see _Undocumented_Windows_
483 BOOL16 WINAPI
IsValidMetaFile16(HMETAFILE16 hmf
)
486 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
488 if (mh
->mtType
== METAFILE_MEMORY
|| mh
->mtType
== METAFILE_DISK
)
489 if (mh
->mtHeaderSize
== MFHEADERSIZE
/sizeof(INT16
))
490 if (mh
->mtVersion
== MFVERSION
)
492 MF_ReleaseMetaHeader16(hmf
);
494 TRACE("IsValidMetaFile %x => %d\n",hmf
,res
);
499 /*******************************************************************
502 * Helper for PlayMetaFile
504 static BOOL
MF_PlayMetaFile( HDC hdc
, METAHEADER
*mh
)
509 unsigned int offset
= 0;
516 if (!mh
) return FALSE
;
517 if(mh
->mtType
== METAFILE_DISK
) { /* Create a memory-based copy */
518 mh
= MF_LoadDiskBasedMetaFile(mh
);
519 if(!mh
) return FALSE
;
523 /* save the current pen, brush and font */
524 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
525 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
526 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
528 /* create the handle table */
529 ht
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
530 sizeof(HANDLETABLE16
) * mh
->mtNoObjects
);
531 if(!ht
) return FALSE
;
533 /* loop through metafile playing records */
534 offset
= mh
->mtHeaderSize
* 2;
535 while (offset
< mh
->mtSize
* 2)
537 mr
= (METARECORD
*)((char *)mh
+ offset
);
538 TRACE("offset=%04x,size=%08lx\n",
542 "Entry got size 0 at offset %d, total mf length is %ld\n",
543 offset
,mh
->mtSize
*2);
544 break; /* would loop endlessly otherwise */
546 offset
+= mr
->rdSize
* 2;
547 PlayMetaFileRecord16( hdc
, ht
, mr
, mh
->mtNoObjects
);
550 SelectObject(hdc
, hBrush
);
551 SelectObject(hdc
, hPen
);
552 SelectObject(hdc
, hFont
);
554 /* free objects in handle table */
555 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
556 if(*(ht
->objectHandle
+ i
) != 0)
557 DeleteObject(*(ht
->objectHandle
+ i
));
559 /* free handle table */
560 HeapFree( GetProcessHeap(), 0, ht
);
562 HeapFree( GetProcessHeap(), 0, mh
);
566 /******************************************************************
567 * PlayMetaFile (GDI.123)
570 BOOL16 WINAPI
PlayMetaFile16( HDC16 hdc
, HMETAFILE16 hmf
)
573 METAHEADER
*mh
= MF_GetMetaHeader16( hmf
);
574 ret
= MF_PlayMetaFile( hdc
, mh
);
575 MF_ReleaseMetaHeader16( hmf
);
579 /******************************************************************
580 * PlayMetaFile (GDI32.@)
582 * Renders the metafile specified by hmf in the DC specified by
583 * hdc. Returns FALSE on failure, TRUE on success.
585 BOOL WINAPI
PlayMetaFile(
586 HDC hdc
, /* [in] handle of DC to render in */
587 HMETAFILE hmf
/* [in] handle of metafile to render */
590 METAHEADER
*mh
= MF_GetMetaHeader( hmf
);
591 return MF_PlayMetaFile( hdc
, mh
);
595 /******************************************************************
596 * EnumMetaFile (GDI.175)
599 BOOL16 WINAPI
EnumMetaFile16( HDC16 hdc
, HMETAFILE16 hmf
,
600 MFENUMPROC16 lpEnumFunc
, LPARAM lpData
)
602 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
607 unsigned int offset
= 0;
612 BOOL16 result
= TRUE
, loaded
= FALSE
;
614 TRACE("(%04x, %04x, %08lx, %08lx)\n",
615 hdc
, hmf
, (DWORD
)lpEnumFunc
, lpData
);
618 if(!mh
) return FALSE
;
619 if(mh
->mtType
== METAFILE_DISK
) { /* Create a memory-based copy */
620 mh
= MF_LoadDiskBasedMetaFile(mh
);
621 if(!mh
) return FALSE
;
625 /* save the current pen, brush and font */
626 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
627 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
628 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
630 /* create the handle table */
632 hHT
= GlobalAlloc16(GMEM_MOVEABLE
| GMEM_ZEROINIT
,
633 sizeof(HANDLETABLE16
) * mh
->mtNoObjects
);
634 spht
= K32WOWGlobalLock16(hHT
);
637 offset
= mh
->mtHeaderSize
* 2;
639 /* loop through metafile records */
641 while (offset
< (mh
->mtSize
* 2))
643 mr
= (METARECORD
*)((char *)mh
+ offset
);
645 if (!MF_CallTo16_word_wllwl( lpEnumFunc
, hdc
, spht
,
646 MAKESEGPTR( seg
+ (HIWORD(offset
) << __AHSHIFT
), LOWORD(offset
) ),
647 mh
->mtNoObjects
, (LONG
)lpData
))
654 offset
+= (mr
->rdSize
* 2);
657 SelectObject(hdc
, hBrush
);
658 SelectObject(hdc
, hPen
);
659 SelectObject(hdc
, hFont
);
661 ht
= (HANDLETABLE16
*)GlobalLock16(hHT
);
663 /* free objects in handle table */
664 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
665 if(*(ht
->objectHandle
+ i
) != 0)
666 DeleteObject(*(ht
->objectHandle
+ i
));
668 /* free handle table */
671 HeapFree( GetProcessHeap(), 0, mh
);
672 MF_ReleaseMetaHeader16(hmf
);
676 /******************************************************************
677 * EnumMetaFile (GDI32.@)
679 * Loop through the metafile records in hmf, calling the user-specified
680 * function for each one, stopping when the user's function returns FALSE
681 * (which is considered to be failure)
682 * or when no records are left (which is considered to be success).
685 * TRUE on success, FALSE on failure.
688 * Niels de carpentier, april 1996
690 BOOL WINAPI
EnumMetaFile(
693 MFENUMPROC lpEnumFunc
,
696 METAHEADER
*mhTemp
= NULL
, *mh
= MF_GetMetaHeader(hmf
);
701 unsigned int offset
= 0;
706 TRACE("(%08x,%08x,%p,%p)\n", hdc
, hmf
, lpEnumFunc
, (void*)lpData
);
708 if(mh
->mtType
== METAFILE_DISK
)
710 /* Create a memory-based copy */
711 if (!(mhTemp
= MF_LoadDiskBasedMetaFile(mh
))) return FALSE
;
715 /* save the current pen, brush and font */
716 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
717 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
718 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
720 ht
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
721 sizeof(HANDLETABLE
) * mh
->mtNoObjects
);
723 /* loop through metafile records */
724 offset
= mh
->mtHeaderSize
* 2;
726 while (offset
< (mh
->mtSize
* 2))
728 mr
= (METARECORD
*)((char *)mh
+ offset
);
729 if(mr
->rdFunction
== META_EOF
) {
730 TRACE("Got META_EOF so stopping\n");
733 TRACE("Calling EnumFunc with record type %x\n",
735 if (!lpEnumFunc( hdc
, ht
, mr
, mh
->mtNoObjects
, (LONG
)lpData
))
741 offset
+= (mr
->rdSize
* 2);
744 /* restore pen, brush and font */
745 SelectObject(hdc
, hBrush
);
746 SelectObject(hdc
, hPen
);
747 SelectObject(hdc
, hFont
);
749 /* free objects in handle table */
750 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
751 if(*(ht
->objectHandle
+ i
) != 0)
752 DeleteObject(*(ht
->objectHandle
+ i
));
754 /* free handle table */
755 HeapFree( GetProcessHeap(), 0, ht
);
756 /* free a copy of metafile */
757 if (mhTemp
) HeapFree( GetProcessHeap(), 0, mhTemp
);
761 static BOOL
MF_Play_MetaCreateRegion( METARECORD
*mr
, HRGN hrgn
);
762 static BOOL
MF_Play_MetaExtTextOut(HDC16 hdc
, METARECORD
*mr
);
763 /******************************************************************
764 * PlayMetaFileRecord (GDI.176)
766 * Render a single metafile record specified by *mr in the DC hdc, while
767 * using the handle table *ht, of length nHandles,
768 * to store metafile objects.
771 * The following metafile records are unimplemented:
773 * DRAWTEXT, ANIMATEPALETTE, SETPALENTRIES,
774 * RESIZEPALETTE, EXTFLOODFILL, RESETDC, STARTDOC, STARTPAGE, ENDPAGE,
775 * ABORTDOC, ENDDOC, CREATEBRUSH, CREATEBITMAPINDIRECT, and CREATEBITMAP.
778 void WINAPI
PlayMetaFileRecord16(
779 HDC16 hdc
, /* [in] DC to render metafile into */
780 HANDLETABLE16
*ht
, /* [in] pointer to handle table for metafile objects */
781 METARECORD
*mr
, /* [in] pointer to metafile record to render */
782 UINT16 nHandles
/* [in] size of handle table */
787 BITMAPINFOHEADER
*infohdr
;
789 TRACE("(%04x %08lx %08lx %04x) function %04x\n",
790 hdc
,(LONG
)ht
, (LONG
)mr
, nHandles
, mr
->rdFunction
);
792 switch (mr
->rdFunction
)
797 case META_DELETEOBJECT
:
798 DeleteObject(*(ht
->objectHandle
+ *(mr
->rdParm
)));
799 *(ht
->objectHandle
+ *(mr
->rdParm
)) = 0;
802 case META_SETBKCOLOR
:
803 SetBkColor16(hdc
, MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
807 SetBkMode16(hdc
, *(mr
->rdParm
));
810 case META_SETMAPMODE
:
811 SetMapMode16(hdc
, *(mr
->rdParm
));
815 SetROP216(hdc
, *(mr
->rdParm
));
819 SetRelAbs16(hdc
, *(mr
->rdParm
));
822 case META_SETPOLYFILLMODE
:
823 SetPolyFillMode16(hdc
, *(mr
->rdParm
));
826 case META_SETSTRETCHBLTMODE
:
827 SetStretchBltMode16(hdc
, *(mr
->rdParm
));
830 case META_SETTEXTCOLOR
:
831 SetTextColor16(hdc
, MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
834 case META_SETWINDOWORG
:
835 SetWindowOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
838 case META_SETWINDOWEXT
:
839 SetWindowExt16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
842 case META_SETVIEWPORTORG
:
843 SetViewportOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
846 case META_SETVIEWPORTEXT
:
847 SetViewportExt16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
850 case META_OFFSETWINDOWORG
:
851 OffsetWindowOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
854 case META_SCALEWINDOWEXT
:
855 ScaleWindowExt16(hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
856 *(mr
->rdParm
+ 1), *(mr
->rdParm
));
859 case META_OFFSETVIEWPORTORG
:
860 OffsetViewportOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
863 case META_SCALEVIEWPORTEXT
:
864 ScaleViewportExt16(hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
865 *(mr
->rdParm
+ 1), *(mr
->rdParm
));
869 LineTo(hdc
, (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
873 MoveTo16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
876 case META_EXCLUDECLIPRECT
:
877 ExcludeClipRect16( hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
878 *(mr
->rdParm
+ 1), *(mr
->rdParm
) );
881 case META_INTERSECTCLIPRECT
:
882 IntersectClipRect16( hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
883 *(mr
->rdParm
+ 1), *(mr
->rdParm
) );
887 Arc(hdc
, (INT16
)*(mr
->rdParm
+ 7), (INT16
)*(mr
->rdParm
+ 6),
888 (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
889 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
890 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
894 Ellipse(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
895 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
899 FloodFill(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
900 MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
904 Pie(hdc
, (INT16
)*(mr
->rdParm
+ 7), (INT16
)*(mr
->rdParm
+ 6),
905 (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
906 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
907 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
911 Rectangle(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
912 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
916 RoundRect(hdc
, (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
917 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
918 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
922 PatBlt16(hdc
, *(mr
->rdParm
+ 5), *(mr
->rdParm
+ 4),
923 *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
924 MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
932 SetPixel(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
933 MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
936 case META_OFFSETCLIPRGN
:
937 OffsetClipRgn16( hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
) );
942 TextOut16(hdc
, *(mr
->rdParm
+ ((s1
+ 1) >> 1) + 2),
943 *(mr
->rdParm
+ ((s1
+ 1) >> 1) + 1),
944 (char *)(mr
->rdParm
+ 1), s1
);
948 Polygon16(hdc
, (LPPOINT16
)(mr
->rdParm
+ 1), *(mr
->rdParm
));
951 case META_POLYPOLYGON
:
952 PolyPolygon16(hdc
, (LPPOINT16
)(mr
->rdParm
+ *(mr
->rdParm
) + 1),
953 (LPINT16
)(mr
->rdParm
+ 1), *(mr
->rdParm
));
957 Polyline16(hdc
, (LPPOINT16
)(mr
->rdParm
+ 1), *(mr
->rdParm
));
961 RestoreDC(hdc
, (INT16
)*(mr
->rdParm
));
964 case META_SELECTOBJECT
:
965 SelectObject(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
969 Chord(hdc
, (INT16
)*(mr
->rdParm
+ 7), (INT16
)*(mr
->rdParm
+ 6),
970 (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
971 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
972 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
975 case META_CREATEPATTERNBRUSH
:
976 switch (*(mr
->rdParm
))
979 infohdr
= (BITMAPINFOHEADER
*)(mr
->rdParm
+ 2);
980 MF_AddHandle(ht
, nHandles
,
981 CreatePatternBrush(CreateBitmap(infohdr
->biWidth
,
986 (sizeof(BITMAPINFOHEADER
) / 2) + 4))));
990 s1
= mr
->rdSize
* 2 - sizeof(METARECORD
) - 2;
991 hndl
= GlobalAlloc16(GMEM_MOVEABLE
, s1
);
992 ptr
= GlobalLock16(hndl
);
993 memcpy(ptr
, mr
->rdParm
+ 2, s1
);
994 GlobalUnlock16(hndl
);
995 MF_AddHandle(ht
, nHandles
,
996 CreateDIBPatternBrush(hndl
, *(mr
->rdParm
+ 1)));
1001 ERR("META_CREATEPATTERNBRUSH: Unknown pattern type %d\n",
1007 case META_CREATEPENINDIRECT
:
1008 MF_AddHandle(ht
, nHandles
,
1009 CreatePenIndirect16((LOGPEN16
*)(&(mr
->rdParm
))));
1012 case META_CREATEFONTINDIRECT
:
1013 MF_AddHandle(ht
, nHandles
,
1014 CreateFontIndirect16((LOGFONT16
*)(&(mr
->rdParm
))));
1017 case META_CREATEBRUSHINDIRECT
:
1018 MF_AddHandle(ht
, nHandles
,
1019 CreateBrushIndirect16((LOGBRUSH16
*)(&(mr
->rdParm
))));
1022 case META_CREATEPALETTE
:
1023 MF_AddHandle(ht
, nHandles
,
1024 CreatePalette16((LPLOGPALETTE
)mr
->rdParm
));
1027 case META_SETTEXTALIGN
:
1028 SetTextAlign16(hdc
, *(mr
->rdParm
));
1031 case META_SELECTPALETTE
:
1032 GDISelectPalette16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
+1)),
1036 case META_SETMAPPERFLAGS
:
1037 SetMapperFlags16(hdc
, MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1040 case META_REALIZEPALETTE
:
1041 GDIRealizePalette16(hdc
);
1045 FIXME("META_ESCAPE unimplemented.\n");
1048 case META_EXTTEXTOUT
:
1049 MF_Play_MetaExtTextOut( hdc
, mr
);
1052 case META_STRETCHDIB
:
1054 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[11]);
1055 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[2] );
1056 StretchDIBits16(hdc
,mr
->rdParm
[10],mr
->rdParm
[9],mr
->rdParm
[8],
1057 mr
->rdParm
[7],mr
->rdParm
[6],mr
->rdParm
[5],
1058 mr
->rdParm
[4],mr
->rdParm
[3],bits
,info
,
1059 mr
->rdParm
[2],MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1063 case META_DIBSTRETCHBLT
:
1065 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[10]);
1066 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[2] );
1067 StretchDIBits16(hdc
,mr
->rdParm
[9],mr
->rdParm
[8],mr
->rdParm
[7],
1068 mr
->rdParm
[6],mr
->rdParm
[5],mr
->rdParm
[4],
1069 mr
->rdParm
[3],mr
->rdParm
[2],bits
,info
,
1070 DIB_RGB_COLORS
,MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1074 case META_STRETCHBLT
:
1076 HDC16 hdcSrc
=CreateCompatibleDC16(hdc
);
1077 HBITMAP hbitmap
=CreateBitmap(mr
->rdParm
[10], /*Width */
1078 mr
->rdParm
[11], /*Height*/
1079 mr
->rdParm
[13], /*Planes*/
1080 mr
->rdParm
[14], /*BitsPixel*/
1081 (LPSTR
)&mr
->rdParm
[15]); /*bits*/
1082 SelectObject(hdcSrc
,hbitmap
);
1083 StretchBlt16(hdc
,mr
->rdParm
[9],mr
->rdParm
[8],
1084 mr
->rdParm
[7],mr
->rdParm
[6],
1085 hdcSrc
,mr
->rdParm
[5],mr
->rdParm
[4],
1086 mr
->rdParm
[3],mr
->rdParm
[2],
1087 MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1094 HDC16 hdcSrc
=CreateCompatibleDC16(hdc
);
1095 HBITMAP hbitmap
=CreateBitmap(mr
->rdParm
[7]/*Width */,
1096 mr
->rdParm
[8]/*Height*/,
1097 mr
->rdParm
[10]/*Planes*/,
1098 mr
->rdParm
[11]/*BitsPixel*/,
1099 (LPSTR
)&mr
->rdParm
[12]/*bits*/);
1100 SelectObject(hdcSrc
,hbitmap
);
1101 BitBlt(hdc
,(INT16
)mr
->rdParm
[6],(INT16
)mr
->rdParm
[5],
1102 (INT16
)mr
->rdParm
[4],(INT16
)mr
->rdParm
[3],
1103 hdcSrc
, (INT16
)mr
->rdParm
[2],(INT16
)mr
->rdParm
[1],
1104 MAKELONG(0,mr
->rdParm
[0]));
1109 case META_CREATEREGION
:
1111 HRGN hrgn
= CreateRectRgn(0,0,0,0);
1113 MF_Play_MetaCreateRegion(mr
, hrgn
);
1114 MF_AddHandle(ht
, nHandles
, hrgn
);
1118 case META_FILLREGION
:
1119 FillRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
+1)),
1120 *(ht
->objectHandle
+ *(mr
->rdParm
)));
1123 case META_FRAMEREGION
:
1124 FrameRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
+3)),
1125 *(ht
->objectHandle
+ *(mr
->rdParm
+2)),
1126 *(mr
->rdParm
+1), *(mr
->rdParm
));
1129 case META_INVERTREGION
:
1130 InvertRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
1133 case META_PAINTREGION
:
1134 PaintRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
1137 case META_SELECTCLIPREGION
:
1138 SelectClipRgn(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
1141 case META_DIBCREATEPATTERNBRUSH
:
1142 /* *(mr->rdParm) may be BS_PATTERN or BS_DIBPATTERN:
1143 but there's no difference */
1145 TRACE("%d\n",*(mr
->rdParm
));
1146 s1
= mr
->rdSize
* 2 - sizeof(METARECORD
) - 2;
1147 hndl
= GlobalAlloc16(GMEM_MOVEABLE
, s1
);
1148 ptr
= GlobalLock16(hndl
);
1149 memcpy(ptr
, mr
->rdParm
+ 2, s1
);
1150 GlobalUnlock16(hndl
);
1151 MF_AddHandle(ht
, nHandles
,
1152 CreateDIBPatternBrush16(hndl
, *(mr
->rdParm
+ 1)));
1156 case META_DIBBITBLT
:
1157 /* In practice I've found that there are two layouts for
1158 META_DIBBITBLT, one (the first here) is the usual one when a src
1159 dc is actually passed to it, the second occurs when the src dc is
1160 passed in as NULL to the creating BitBlt. As the second case has
1161 no dib, a size check will suffice to distinguish.
1163 Caolan.McNamara@ul.ie */
1165 if (mr
->rdSize
> 12) {
1166 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[8]);
1167 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize(info
, mr
->rdParm
[0]);
1169 StretchDIBits16(hdc
, mr
->rdParm
[7], mr
->rdParm
[6], mr
->rdParm
[5],
1170 mr
->rdParm
[4], mr
->rdParm
[3], mr
->rdParm
[2],
1171 mr
->rdParm
[5], mr
->rdParm
[4], bits
, info
,
1173 MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
1174 } else { /* equivalent to a PatBlt */
1175 PatBlt16(hdc
, mr
->rdParm
[8], mr
->rdParm
[7],
1176 mr
->rdParm
[6], mr
->rdParm
[5],
1177 MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
1181 case META_SETTEXTCHAREXTRA
:
1182 SetTextCharacterExtra16(hdc
, (INT16
)*(mr
->rdParm
));
1185 case META_SETTEXTJUSTIFICATION
:
1186 SetTextJustification(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
1189 case META_EXTFLOODFILL
:
1190 ExtFloodFill(hdc
, (INT16
)*(mr
->rdParm
+ 4), (INT16
)*(mr
->rdParm
+ 3),
1191 MAKELONG(*(mr
->rdParm
+1), *(mr
->rdParm
+ 2)),
1195 case META_SETDIBTODEV
:
1197 BITMAPINFO
*info
= (BITMAPINFO
*) &(mr
->rdParm
[9]);
1198 char *bits
= (char *)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[0] );
1199 SetDIBitsToDevice(hdc
, (INT16
)mr
->rdParm
[8], (INT16
)mr
->rdParm
[7],
1200 (INT16
)mr
->rdParm
[6], (INT16
)mr
->rdParm
[5],
1201 (INT16
)mr
->rdParm
[4], (INT16
)mr
->rdParm
[3],
1202 mr
->rdParm
[2], mr
->rdParm
[1], bits
, info
,
1207 #define META_UNIMP(x) case x: \
1208 FIXME("PlayMetaFileRecord:record type "#x" not implemented.\n"); \
1210 META_UNIMP(META_DRAWTEXT
)
1211 META_UNIMP(META_ANIMATEPALETTE
)
1212 META_UNIMP(META_SETPALENTRIES
)
1213 META_UNIMP(META_RESIZEPALETTE
)
1214 META_UNIMP(META_RESETDC
)
1215 META_UNIMP(META_STARTDOC
)
1216 META_UNIMP(META_STARTPAGE
)
1217 META_UNIMP(META_ENDPAGE
)
1218 META_UNIMP(META_ABORTDOC
)
1219 META_UNIMP(META_ENDDOC
)
1220 META_UNIMP(META_CREATEBRUSH
)
1221 META_UNIMP(META_CREATEBITMAPINDIRECT
)
1222 META_UNIMP(META_CREATEBITMAP
)
1226 WARN("PlayMetaFileRecord: Unknown record type %x\n",
1231 /******************************************************************
1232 * PlayMetaFileRecord (GDI32.@)
1234 BOOL WINAPI
PlayMetaFileRecord( HDC hdc
, HANDLETABLE
*handletable
,
1235 METARECORD
*metarecord
, UINT handles
)
1237 HANDLETABLE16
* ht
= (void *)GlobalAlloc(GPTR
,
1238 handles
*sizeof(HANDLETABLE16
));
1240 TRACE("(%08x,%p,%p,%d)\n", hdc
, handletable
, metarecord
,
1242 for (i
=0; i
<handles
; i
++)
1243 ht
->objectHandle
[i
] = handletable
->objectHandle
[i
];
1244 PlayMetaFileRecord16(hdc
, ht
, metarecord
, handles
);
1245 for (i
=0; i
<handles
; i
++)
1246 handletable
->objectHandle
[i
] = ht
->objectHandle
[i
];
1247 GlobalFree((HGLOBAL
)ht
);
1251 /******************************************************************
1252 * GetMetaFileBits (GDI.159)
1254 * Trade in a metafile object handle for a handle to the metafile memory.
1258 HGLOBAL16 WINAPI
GetMetaFileBits16(
1259 HMETAFILE16 hmf
/* [in] metafile handle */
1262 TRACE("hMem out: %04x\n", hmf
);
1266 /******************************************************************
1267 * SetMetaFileBits (GDI.160)
1269 * Trade in a metafile memory handle for a handle to a metafile object.
1270 * The memory region should hold a proper metafile, otherwise
1271 * problems will occur when it is used. Validity of the memory is not
1272 * checked. The function is essentially just the identity function.
1274 HMETAFILE16 WINAPI
SetMetaFileBits16(
1276 /* [in] handle to a memory region holding a metafile */
1279 TRACE("hmf out: %04x\n", hMem
);
1284 /******************************************************************
1285 * SetMetaFileBitsBetter (GDI.196)
1287 * Trade in a metafile memory handle for a handle to a metafile object,
1288 * making a cursory check (using IsValidMetaFile()) that the memory
1289 * handle points to a valid metafile.
1292 * Handle to a metafile on success, NULL on failure..
1294 HMETAFILE16 WINAPI
SetMetaFileBitsBetter16( HMETAFILE16 hMeta
)
1296 if( IsValidMetaFile16( hMeta
) )
1297 return (HMETAFILE16
)GlobalReAlloc16( hMeta
, 0,
1298 GMEM_SHARE
| GMEM_NODISCARD
| GMEM_MODIFY
);
1299 return (HMETAFILE16
)0;
1302 /******************************************************************
1303 * SetMetaFileBitsEx (GDI32.@)
1305 * Create a metafile from raw data. No checking of the data is performed.
1306 * Use _GetMetaFileBitsEx_ to get raw data from a metafile.
1308 HMETAFILE WINAPI
SetMetaFileBitsEx(
1309 UINT size
, /* [in] size of metafile, in bytes */
1310 const BYTE
*lpData
/* [in] pointer to metafile data */
1313 METAHEADER
*mh
= HeapAlloc( GetProcessHeap(), 0, size
);
1315 memcpy(mh
, lpData
, size
);
1316 return MF_Create_HMETAFILE(mh
);
1319 /*****************************************************************
1320 * GetMetaFileBitsEx (GDI32.@) Get raw metafile data
1322 * Copies the data from metafile _hmf_ into the buffer _buf_.
1323 * If _buf_ is zero, returns size of buffer required. Otherwise,
1324 * returns number of bytes copied.
1326 UINT WINAPI
GetMetaFileBitsEx(
1327 HMETAFILE hmf
, /* [in] metafile */
1328 UINT nSize
, /* [in] size of buf */
1329 LPVOID buf
/* [out] buffer to receive raw metafile data */
1331 METAHEADER
*mh
= MF_GetMetaHeader(hmf
);
1334 TRACE("(%08x,%d,%p)\n", hmf
, nSize
, buf
);
1335 if (!mh
) return 0; /* FIXME: error code */
1336 if(mh
->mtType
== METAFILE_DISK
)
1337 FIXME("Disk-based metafile?\n");
1338 mfSize
= mh
->mtSize
* 2;
1340 TRACE("returning size %d\n", mfSize
);
1343 if(mfSize
> nSize
) mfSize
= nSize
;
1344 memmove(buf
, mh
, mfSize
);
1348 /******************************************************************
1349 * GetWinMetaFileBits [GDI32.@]
1351 UINT WINAPI
GetWinMetaFileBits(HENHMETAFILE hemf
,
1352 UINT cbBuffer
, LPBYTE lpbBuffer
,
1353 INT fnMapMode
, HDC hdcRef
)
1359 FIXME("(%d,%d,%p,%d,%d): stub\n",
1360 hemf
, cbBuffer
, lpbBuffer
, fnMapMode
, hdcRef
);
1361 hdcmf
= CreateMetaFileA(NULL
);
1362 /* PlayEnhMetaFile(hdcmf, hemf, lpRect); where does the bounding rect come from? */
1363 hmf
= CloseMetaFile(hdcmf
);
1364 ret
= GetMetaFileBitsEx(hmf
, cbBuffer
, lpbBuffer
);
1365 DeleteMetaFile(hmf
);
1369 /******************************************************************
1370 * MF_Play_MetaCreateRegion
1372 * Handles META_CREATEREGION for PlayMetaFileRecord().
1376 * The layout of the record looks something like this:
1381 * 2 Looks like a handle? - not constant
1383 * 4 Total number of bytes
1384 * 5 No. of separate bands = n [see below]
1385 * 6 Largest number of x co-ords in a band
1386 * 7-10 Bounding box x1 y1 x2 y2
1389 * Regions are divided into bands that are uniform in the
1390 * y-direction. Each band consists of pairs of on/off x-coords and is
1392 * m y0 y1 x1 x2 x3 ... xm m
1393 * into successive rdParm[]s.
1395 * This is probably just a dump of the internal RGNOBJ?
1401 static BOOL
MF_Play_MetaCreateRegion( METARECORD
*mr
, HRGN hrgn
)
1406 HRGN hrgn2
= CreateRectRgn( 0, 0, 0, 0 );
1408 for(band
= 0, start
= &(mr
->rdParm
[11]); band
< mr
->rdParm
[5];
1409 band
++, start
= end
+ 1) {
1410 if(*start
/ 2 != (*start
+ 1) / 2) {
1411 WARN("Delimiter not even.\n");
1412 DeleteObject( hrgn2
);
1416 end
= start
+ *start
+ 3;
1417 if(end
> (WORD
*)mr
+ mr
->rdSize
) {
1418 WARN("End points outside record.\n");
1419 DeleteObject( hrgn2
);
1423 if(*start
!= *end
) {
1424 WARN("Mismatched delimiters.\n");
1425 DeleteObject( hrgn2
);
1429 y0
= *(INT16
*)(start
+ 1);
1430 y1
= *(INT16
*)(start
+ 2);
1431 for(pair
= 0; pair
< *start
/ 2; pair
++) {
1432 SetRectRgn( hrgn2
, *(INT16
*)(start
+ 3 + 2*pair
), y0
,
1433 *(INT16
*)(start
+ 4 + 2*pair
), y1
);
1434 CombineRgn(hrgn
, hrgn
, hrgn2
, RGN_OR
);
1437 DeleteObject( hrgn2
);
1442 /******************************************************************
1443 * MF_Play_MetaExtTextOut
1445 * Handles META_EXTTEXTOUT for PlayMetaFileRecord().
1448 static BOOL
MF_Play_MetaExtTextOut(HDC16 hdc
, METARECORD
*mr
)
1454 BOOL isrect
= mr
->rdParm
[3] & (ETO_OPAQUE
| ETO_CLIPPED
);
1456 s1
= mr
->rdParm
[2]; /* String length */
1457 len
= sizeof(METARECORD
) + (((s1
+ 1) >> 1) * 2) + 2 * sizeof(short)
1458 + sizeof(UINT16
) + (isrect
? sizeof(RECT16
) : 0);
1459 /* rec len without dx array */
1461 sot
= (LPSTR
)&mr
->rdParm
[4]; /* start_of_text */
1463 sot
+= sizeof(RECT16
); /* there is a rectangle, so add offset */
1465 if (mr
->rdSize
== len
/ 2)
1466 dxx
= NULL
; /* determine if array present */
1468 if (mr
->rdSize
== (len
+ s1
* sizeof(INT16
)) / 2)
1469 dxx
= (LPINT16
)(sot
+(((s1
+1)>>1)*2));
1471 TRACE("%s len: %ld\n", sot
, mr
->rdSize
);
1473 "Please report: ExtTextOut len=%ld slen=%d rdSize=%ld opt=%04x\n",
1474 len
, s1
, mr
->rdSize
, mr
->rdParm
[3]);
1475 dxx
= NULL
; /* should't happen -- but if, we continue with NULL */
1477 ExtTextOut16( hdc
, mr
->rdParm
[1], /* X position */
1478 mr
->rdParm
[0], /* Y position */
1479 mr
->rdParm
[3], /* options */
1480 mr
->rdParm
[3] ? (LPRECT16
) &mr
->rdParm
[4]:NULL
,
1483 s1
, dxx
); /* length, dx array */
1485 TRACE("%s len: %ld dx0: %d\n", sot
, mr
->rdSize
, dxx
[0]);