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"
44 #include "debugtools.h"
46 DEFAULT_DEBUG_CHANNEL(metafile
);
57 #define MFHEADERSIZE (sizeof(METAHEADER))
58 #define MFVERSION 0x300
60 /* ### start build ### */
61 extern WORD CALLBACK
MF_CallTo16_word_wllwl(MFENUMPROC16
,WORD
,LONG
,LONG
,WORD
,LONG
);
62 /* ### stop build ### */
64 /******************************************************************
67 * Add a handle to an external handle table and return the index
69 static int MF_AddHandle(HANDLETABLE16
*ht
, WORD htlen
, HGDIOBJ16 hobj
)
73 for (i
= 0; i
< htlen
; i
++)
75 if (*(ht
->objectHandle
+ i
) == 0)
77 *(ht
->objectHandle
+ i
) = hobj
;
85 /******************************************************************
86 * MF_Create_HMETATFILE
88 * Creates a (32 bit) HMETAFILE object from a METAHEADER
90 * HMETAFILEs are GDI objects.
92 HMETAFILE
MF_Create_HMETAFILE(METAHEADER
*mh
)
95 METAFILEOBJ
*metaObj
= GDI_AllocObject( sizeof(METAFILEOBJ
), METAFILE_MAGIC
, &hmf
);
99 GDI_ReleaseObj( hmf
);
104 /******************************************************************
105 * MF_Create_HMETATFILE16
107 * Creates a HMETAFILE16 object from a METAHEADER
109 * HMETAFILE16s are Global memory handles.
111 HMETAFILE16
MF_Create_HMETAFILE16(METAHEADER
*mh
)
114 DWORD size
= mh
->mtSize
* sizeof(WORD
);
116 hmf
= GlobalAlloc16(GMEM_MOVEABLE
, size
);
119 METAHEADER
*mh_dest
= GlobalLock16(hmf
);
120 memcpy(mh_dest
, mh
, size
);
123 HeapFree(GetProcessHeap(), 0, mh
);
127 /******************************************************************
130 * Returns ptr to METAHEADER associated with HMETAFILE
132 static METAHEADER
*MF_GetMetaHeader( HMETAFILE hmf
)
134 METAHEADER
*ret
= NULL
;
135 METAFILEOBJ
* metaObj
= (METAFILEOBJ
*)GDI_GetObjPtr( hmf
, METAFILE_MAGIC
);
139 GDI_ReleaseObj( hmf
);
144 /******************************************************************
147 * Returns ptr to METAHEADER associated with HMETAFILE16
148 * Should be followed by call to MF_ReleaseMetaHeader16
150 static METAHEADER
*MF_GetMetaHeader16( HMETAFILE16 hmf
)
152 return GlobalLock16(hmf
);
155 /******************************************************************
156 * MF_ReleaseMetaHeader16
158 * Releases METAHEADER associated with HMETAFILE16
160 static BOOL16
MF_ReleaseMetaHeader16( HMETAFILE16 hmf
)
162 return GlobalUnlock16( hmf
);
166 /******************************************************************
167 * DeleteMetaFile (GDI.127)
169 BOOL16 WINAPI
DeleteMetaFile16( HMETAFILE16 hmf
)
171 return !GlobalFree16( hmf
);
174 /******************************************************************
175 * DeleteMetaFile (GDI32.@)
177 * Delete a memory-based metafile.
180 BOOL WINAPI
DeleteMetaFile( HMETAFILE hmf
)
182 METAFILEOBJ
* metaObj
= (METAFILEOBJ
*)GDI_GetObjPtr( hmf
, METAFILE_MAGIC
);
183 if (!metaObj
) return FALSE
;
184 HeapFree( GetProcessHeap(), 0, metaObj
->mh
);
185 GDI_FreeObject( hmf
, metaObj
);
189 /******************************************************************
192 * Returns a pointer to a memory based METAHEADER read in from file HFILE
195 static METAHEADER
*MF_ReadMetaFile(HFILE hfile
)
198 DWORD BytesRead
, size
;
200 size
= sizeof(METAHEADER
);
201 mh
= HeapAlloc( GetProcessHeap(), 0, size
);
203 if(ReadFile( hfile
, mh
, size
, &BytesRead
, NULL
) == 0 ||
205 HeapFree( GetProcessHeap(), 0, mh
);
208 size
= mh
->mtSize
* 2;
209 mh
= HeapReAlloc( GetProcessHeap(), 0, mh
, size
);
211 size
-= sizeof(METAHEADER
);
212 if(ReadFile( hfile
, (char *)mh
+ sizeof(METAHEADER
), size
, &BytesRead
,
215 HeapFree( GetProcessHeap(), 0, mh
);
219 if (mh
->mtType
!= METAFILE_MEMORY
) {
220 WARN("Disk metafile had mtType = %04x\n", mh
->mtType
);
221 mh
->mtType
= METAFILE_MEMORY
;
226 /******************************************************************
227 * GetMetaFile (GDI.124)
229 HMETAFILE16 WINAPI
GetMetaFile16( LPCSTR lpFilename
)
234 TRACE("%s\n", lpFilename
);
239 if((hFile
= CreateFileA(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
240 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
243 mh
= MF_ReadMetaFile(hFile
);
246 return MF_Create_HMETAFILE16( mh
);
249 /******************************************************************
250 * GetMetaFileA (GDI32.@)
252 * Read a metafile from a file. Returns handle to a memory-based metafile.
254 HMETAFILE WINAPI
GetMetaFileA( LPCSTR lpFilename
)
259 TRACE("%s\n", lpFilename
);
264 if((hFile
= CreateFileA(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
265 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
268 mh
= MF_ReadMetaFile(hFile
);
271 return MF_Create_HMETAFILE( mh
);
276 /******************************************************************
277 * GetMetaFileW (GDI32.@)
279 HMETAFILE WINAPI
GetMetaFileW( LPCWSTR lpFilename
)
284 TRACE("%s\n", debugstr_w(lpFilename
));
289 if((hFile
= CreateFileW(lpFilename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
290 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
)
293 mh
= MF_ReadMetaFile(hFile
);
296 return MF_Create_HMETAFILE( mh
);
300 /******************************************************************
301 * MF_LoadDiskBasedMetaFile
303 * Creates a new memory-based metafile from a disk-based one.
305 static METAHEADER
*MF_LoadDiskBasedMetaFile(METAHEADER
*mh
)
311 if(mh
->mtType
!= METAFILE_DISK
) {
312 ERR("Not a disk based metafile\n");
315 mhd
= (METAHEADERDISK
*)((char *)mh
+ sizeof(METAHEADER
));
317 if((hfile
= CreateFileA(mhd
->filename
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
318 OPEN_EXISTING
, 0, 0)) == INVALID_HANDLE_VALUE
) {
319 WARN("Can't open file of disk based metafile\n");
322 mh2
= MF_ReadMetaFile(hfile
);
327 /******************************************************************
328 * MF_CreateMetaHeaderDisk
330 * Take a memory based METAHEADER and change it to a disk based METAHEADER
331 * assosiated with filename. Note: Trashes contents of old one.
333 METAHEADER
*MF_CreateMetaHeaderDisk(METAHEADER
*mh
, LPCSTR filename
)
338 mh
= HeapReAlloc( GetProcessHeap(), 0, mh
,
339 sizeof(METAHEADER
) + sizeof(METAHEADERDISK
));
340 mh
->mtType
= METAFILE_DISK
;
341 size
= HeapSize( GetProcessHeap(), 0, mh
);
342 mhd
= (METAHEADERDISK
*)((char *)mh
+ sizeof(METAHEADER
));
343 strcpy(mhd
->filename
, filename
);
347 /******************************************************************
348 * CopyMetaFile (GDI.151)
350 HMETAFILE16 WINAPI
CopyMetaFile16( HMETAFILE16 hSrcMetaFile
, LPCSTR lpFilename
)
352 METAHEADER
*mh
= MF_GetMetaHeader16( hSrcMetaFile
);
353 METAHEADER
*mh2
= NULL
;
356 TRACE("(%08x,%s)\n", hSrcMetaFile
, lpFilename
);
360 if(mh
->mtType
== METAFILE_DISK
)
361 mh2
= MF_LoadDiskBasedMetaFile(mh
);
363 mh2
= HeapAlloc( GetProcessHeap(), 0, mh
->mtSize
* 2 );
364 memcpy( mh2
, mh
, mh
->mtSize
* 2 );
366 MF_ReleaseMetaHeader16( hSrcMetaFile
);
368 if(lpFilename
) { /* disk based metafile */
369 if((hFile
= CreateFileA(lpFilename
, GENERIC_WRITE
, 0, NULL
,
370 CREATE_ALWAYS
, 0, 0)) == INVALID_HANDLE_VALUE
) {
371 HeapFree( GetProcessHeap(), 0, mh2
);
374 WriteFile(hFile
, mh2
, mh2
->mtSize
* 2, NULL
, NULL
);
376 mh2
= MF_CreateMetaHeaderDisk(mh2
, lpFilename
);
379 return MF_Create_HMETAFILE16( mh2
);
383 /******************************************************************
384 * CopyMetaFileA (GDI32.@)
386 * Copies the metafile corresponding to hSrcMetaFile to either
387 * a disk file, if a filename is given, or to a new memory based
388 * metafile, if lpFileName is NULL.
392 * Handle to metafile copy on success, NULL on failure.
396 * Copying to disk returns NULL even if successful.
398 HMETAFILE WINAPI
CopyMetaFileA(
399 HMETAFILE hSrcMetaFile
, /* [in] handle of metafile to copy */
400 LPCSTR lpFilename
/* [in] filename if copying to a file */
402 METAHEADER
*mh
= MF_GetMetaHeader( hSrcMetaFile
);
403 METAHEADER
*mh2
= NULL
;
406 TRACE("(%08x,%s)\n", hSrcMetaFile
, lpFilename
);
410 if(mh
->mtType
== METAFILE_DISK
)
411 mh2
= MF_LoadDiskBasedMetaFile(mh
);
413 mh2
= HeapAlloc( GetProcessHeap(), 0, mh
->mtSize
* 2 );
414 memcpy( mh2
, mh
, mh
->mtSize
* 2 );
417 if(lpFilename
) { /* disk based metafile */
418 if((hFile
= CreateFileA(lpFilename
, GENERIC_WRITE
, 0, NULL
,
419 CREATE_ALWAYS
, 0, 0)) == INVALID_HANDLE_VALUE
) {
420 HeapFree( GetProcessHeap(), 0, mh2
);
423 WriteFile(hFile
, mh2
, mh2
->mtSize
* 2, NULL
, NULL
);
425 mh2
= MF_CreateMetaHeaderDisk(mh2
, lpFilename
);
428 return MF_Create_HMETAFILE( mh2
);
432 /******************************************************************
433 * CopyMetaFileW (GDI32.@)
435 HMETAFILE WINAPI
CopyMetaFileW( HMETAFILE hSrcMetaFile
,
439 DWORD len
= WideCharToMultiByte( CP_ACP
, 0, lpFilename
, -1, NULL
, 0, NULL
, NULL
);
440 LPSTR p
= HeapAlloc( GetProcessHeap(), 0, len
);
444 WideCharToMultiByte( CP_ACP
, 0, lpFilename
, -1, p
, len
, NULL
, NULL
);
445 ret
= CopyMetaFileA( hSrcMetaFile
, p
);
446 HeapFree( GetProcessHeap(), 0, p
);
452 /******************************************************************
453 * IsValidMetaFile (GDI.410)
455 * Attempts to check if a given metafile is correctly formatted.
456 * Currently, the only things verified are several properties of the
460 * TRUE if hmf passes some tests for being a valid metafile, FALSE otherwise.
463 * This is not exactly what windows does, see _Undocumented_Windows_
466 BOOL16 WINAPI
IsValidMetaFile16(HMETAFILE16 hmf
)
469 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
471 if (mh
->mtType
== METAFILE_MEMORY
|| mh
->mtType
== METAFILE_DISK
)
472 if (mh
->mtHeaderSize
== MFHEADERSIZE
/sizeof(INT16
))
473 if (mh
->mtVersion
== MFVERSION
)
475 MF_ReleaseMetaHeader16(hmf
);
477 TRACE("IsValidMetaFile %x => %d\n",hmf
,res
);
482 /*******************************************************************
485 * Helper for PlayMetaFile
487 static BOOL
MF_PlayMetaFile( HDC hdc
, METAHEADER
*mh
)
492 unsigned int offset
= 0;
499 if (!mh
) return FALSE
;
500 if(mh
->mtType
== METAFILE_DISK
) { /* Create a memory-based copy */
501 mh
= MF_LoadDiskBasedMetaFile(mh
);
502 if(!mh
) return FALSE
;
506 /* save the current pen, brush and font */
507 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
508 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
509 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
511 /* create the handle table */
512 ht
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
513 sizeof(HANDLETABLE16
) * mh
->mtNoObjects
);
514 if(!ht
) return FALSE
;
516 /* loop through metafile playing records */
517 offset
= mh
->mtHeaderSize
* 2;
518 while (offset
< mh
->mtSize
* 2)
520 mr
= (METARECORD
*)((char *)mh
+ offset
);
521 TRACE("offset=%04x,size=%08lx\n",
525 "Entry got size 0 at offset %d, total mf length is %ld\n",
526 offset
,mh
->mtSize
*2);
527 break; /* would loop endlessly otherwise */
529 offset
+= mr
->rdSize
* 2;
530 PlayMetaFileRecord16( hdc
, ht
, mr
, mh
->mtNoObjects
);
533 SelectObject(hdc
, hBrush
);
534 SelectObject(hdc
, hPen
);
535 SelectObject(hdc
, hFont
);
537 /* free objects in handle table */
538 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
539 if(*(ht
->objectHandle
+ i
) != 0)
540 DeleteObject(*(ht
->objectHandle
+ i
));
542 /* free handle table */
543 HeapFree( GetProcessHeap(), 0, ht
);
545 HeapFree( GetProcessHeap(), 0, mh
);
549 /******************************************************************
550 * PlayMetaFile (GDI.123)
553 BOOL16 WINAPI
PlayMetaFile16( HDC16 hdc
, HMETAFILE16 hmf
)
556 METAHEADER
*mh
= MF_GetMetaHeader16( hmf
);
557 ret
= MF_PlayMetaFile( hdc
, mh
);
558 MF_ReleaseMetaHeader16( hmf
);
562 /******************************************************************
563 * PlayMetaFile (GDI32.@)
565 * Renders the metafile specified by hmf in the DC specified by
566 * hdc. Returns FALSE on failure, TRUE on success.
568 BOOL WINAPI
PlayMetaFile(
569 HDC hdc
, /* [in] handle of DC to render in */
570 HMETAFILE hmf
/* [in] handle of metafile to render */
573 METAHEADER
*mh
= MF_GetMetaHeader( hmf
);
574 return MF_PlayMetaFile( hdc
, mh
);
578 /******************************************************************
579 * EnumMetaFile (GDI.175)
582 BOOL16 WINAPI
EnumMetaFile16( HDC16 hdc
, HMETAFILE16 hmf
,
583 MFENUMPROC16 lpEnumFunc
, LPARAM lpData
)
585 METAHEADER
*mh
= MF_GetMetaHeader16(hmf
);
590 unsigned int offset
= 0;
595 BOOL16 result
= TRUE
, loaded
= FALSE
;
597 TRACE("(%04x, %04x, %08lx, %08lx)\n",
598 hdc
, hmf
, (DWORD
)lpEnumFunc
, lpData
);
601 if(!mh
) return FALSE
;
602 if(mh
->mtType
== METAFILE_DISK
) { /* Create a memory-based copy */
603 mh
= MF_LoadDiskBasedMetaFile(mh
);
604 if(!mh
) return FALSE
;
608 /* save the current pen, brush and font */
609 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
610 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
611 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
613 /* create the handle table */
615 hHT
= GlobalAlloc16(GMEM_MOVEABLE
| GMEM_ZEROINIT
,
616 sizeof(HANDLETABLE16
) * mh
->mtNoObjects
);
617 spht
= K32WOWGlobalLock16(hHT
);
620 offset
= mh
->mtHeaderSize
* 2;
622 /* loop through metafile records */
624 while (offset
< (mh
->mtSize
* 2))
626 mr
= (METARECORD
*)((char *)mh
+ offset
);
628 if (!MF_CallTo16_word_wllwl( lpEnumFunc
, hdc
, spht
,
629 MAKESEGPTR( seg
+ (HIWORD(offset
) << __AHSHIFT
), LOWORD(offset
) ),
630 mh
->mtNoObjects
, (LONG
)lpData
))
637 offset
+= (mr
->rdSize
* 2);
640 SelectObject(hdc
, hBrush
);
641 SelectObject(hdc
, hPen
);
642 SelectObject(hdc
, hFont
);
644 ht
= (HANDLETABLE16
*)GlobalLock16(hHT
);
646 /* free objects in handle table */
647 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
648 if(*(ht
->objectHandle
+ i
) != 0)
649 DeleteObject(*(ht
->objectHandle
+ i
));
651 /* free handle table */
654 HeapFree( GetProcessHeap(), 0, mh
);
655 MF_ReleaseMetaHeader16(hmf
);
659 /******************************************************************
660 * EnumMetaFile (GDI32.@)
662 * Loop through the metafile records in hmf, calling the user-specified
663 * function for each one, stopping when the user's function returns FALSE
664 * (which is considered to be failure)
665 * or when no records are left (which is considered to be success).
668 * TRUE on success, FALSE on failure.
671 * Niels de carpentier, april 1996
673 BOOL WINAPI
EnumMetaFile(
676 MFENUMPROC lpEnumFunc
,
679 METAHEADER
*mhTemp
= NULL
, *mh
= MF_GetMetaHeader(hmf
);
684 unsigned int offset
= 0;
689 TRACE("(%08x,%08x,%p,%p)\n", hdc
, hmf
, lpEnumFunc
, (void*)lpData
);
691 if(mh
->mtType
== METAFILE_DISK
)
693 /* Create a memory-based copy */
694 if (!(mhTemp
= MF_LoadDiskBasedMetaFile(mh
))) return FALSE
;
698 /* save the current pen, brush and font */
699 hPen
= GetCurrentObject(hdc
, OBJ_PEN
);
700 hBrush
= GetCurrentObject(hdc
, OBJ_BRUSH
);
701 hFont
= GetCurrentObject(hdc
, OBJ_FONT
);
703 ht
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
704 sizeof(HANDLETABLE
) * mh
->mtNoObjects
);
706 /* loop through metafile records */
707 offset
= mh
->mtHeaderSize
* 2;
709 while (offset
< (mh
->mtSize
* 2))
711 mr
= (METARECORD
*)((char *)mh
+ offset
);
712 TRACE("Calling EnumFunc with record type %x\n",
714 if (!lpEnumFunc( hdc
, ht
, mr
, mh
->mtNoObjects
, (LONG
)lpData
))
720 offset
+= (mr
->rdSize
* 2);
723 /* restore pen, brush and font */
724 SelectObject(hdc
, hBrush
);
725 SelectObject(hdc
, hPen
);
726 SelectObject(hdc
, hFont
);
728 /* free objects in handle table */
729 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
730 if(*(ht
->objectHandle
+ i
) != 0)
731 DeleteObject(*(ht
->objectHandle
+ i
));
733 /* free handle table */
734 HeapFree( GetProcessHeap(), 0, ht
);
735 /* free a copy of metafile */
736 if (mhTemp
) HeapFree( GetProcessHeap(), 0, mhTemp
);
740 static BOOL
MF_Play_MetaCreateRegion( METARECORD
*mr
, HRGN hrgn
);
741 static BOOL
MF_Play_MetaExtTextOut(HDC16 hdc
, METARECORD
*mr
);
742 /******************************************************************
743 * PlayMetaFileRecord (GDI.176)
745 * Render a single metafile record specified by *mr in the DC hdc, while
746 * using the handle table *ht, of length nHandles,
747 * to store metafile objects.
750 * The following metafile records are unimplemented:
752 * DRAWTEXT, ANIMATEPALETTE, SETPALENTRIES,
753 * RESIZEPALETTE, EXTFLOODFILL, RESETDC, STARTDOC, STARTPAGE, ENDPAGE,
754 * ABORTDOC, ENDDOC, CREATEBRUSH, CREATEBITMAPINDIRECT, and CREATEBITMAP.
757 void WINAPI
PlayMetaFileRecord16(
758 HDC16 hdc
, /* [in] DC to render metafile into */
759 HANDLETABLE16
*ht
, /* [in] pointer to handle table for metafile objects */
760 METARECORD
*mr
, /* [in] pointer to metafile record to render */
761 UINT16 nHandles
/* [in] size of handle table */
766 BITMAPINFOHEADER
*infohdr
;
768 TRACE("(%04x %08lx %08lx %04x) function %04x\n",
769 hdc
,(LONG
)ht
, (LONG
)mr
, nHandles
, mr
->rdFunction
);
771 switch (mr
->rdFunction
)
776 case META_DELETEOBJECT
:
777 DeleteObject(*(ht
->objectHandle
+ *(mr
->rdParm
)));
778 *(ht
->objectHandle
+ *(mr
->rdParm
)) = 0;
781 case META_SETBKCOLOR
:
782 SetBkColor16(hdc
, MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
786 SetBkMode16(hdc
, *(mr
->rdParm
));
789 case META_SETMAPMODE
:
790 SetMapMode16(hdc
, *(mr
->rdParm
));
794 SetROP216(hdc
, *(mr
->rdParm
));
798 SetRelAbs16(hdc
, *(mr
->rdParm
));
801 case META_SETPOLYFILLMODE
:
802 SetPolyFillMode16(hdc
, *(mr
->rdParm
));
805 case META_SETSTRETCHBLTMODE
:
806 SetStretchBltMode16(hdc
, *(mr
->rdParm
));
809 case META_SETTEXTCOLOR
:
810 SetTextColor16(hdc
, MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
813 case META_SETWINDOWORG
:
814 SetWindowOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
817 case META_SETWINDOWEXT
:
818 SetWindowExt16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
821 case META_SETVIEWPORTORG
:
822 SetViewportOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
825 case META_SETVIEWPORTEXT
:
826 SetViewportExt16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
829 case META_OFFSETWINDOWORG
:
830 OffsetWindowOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
833 case META_SCALEWINDOWEXT
:
834 ScaleWindowExt16(hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
835 *(mr
->rdParm
+ 1), *(mr
->rdParm
));
838 case META_OFFSETVIEWPORTORG
:
839 OffsetViewportOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
842 case META_SCALEVIEWPORTEXT
:
843 ScaleViewportExt16(hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
844 *(mr
->rdParm
+ 1), *(mr
->rdParm
));
848 LineTo(hdc
, (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
852 MoveTo16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
855 case META_EXCLUDECLIPRECT
:
856 ExcludeClipRect16( hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
857 *(mr
->rdParm
+ 1), *(mr
->rdParm
) );
860 case META_INTERSECTCLIPRECT
:
861 IntersectClipRect16( hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
862 *(mr
->rdParm
+ 1), *(mr
->rdParm
) );
866 Arc(hdc
, (INT16
)*(mr
->rdParm
+ 7), (INT16
)*(mr
->rdParm
+ 6),
867 (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
868 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
869 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
873 Ellipse(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
874 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
878 FloodFill(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
879 MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
883 Pie(hdc
, (INT16
)*(mr
->rdParm
+ 7), (INT16
)*(mr
->rdParm
+ 6),
884 (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
885 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
886 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
890 Rectangle(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
891 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
895 RoundRect(hdc
, (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
896 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
897 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
901 PatBlt16(hdc
, *(mr
->rdParm
+ 5), *(mr
->rdParm
+ 4),
902 *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
903 MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
911 SetPixel(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
912 MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
915 case META_OFFSETCLIPRGN
:
916 OffsetClipRgn16( hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
) );
921 TextOut16(hdc
, *(mr
->rdParm
+ ((s1
+ 1) >> 1) + 2),
922 *(mr
->rdParm
+ ((s1
+ 1) >> 1) + 1),
923 (char *)(mr
->rdParm
+ 1), s1
);
927 Polygon16(hdc
, (LPPOINT16
)(mr
->rdParm
+ 1), *(mr
->rdParm
));
930 case META_POLYPOLYGON
:
931 PolyPolygon16(hdc
, (LPPOINT16
)(mr
->rdParm
+ *(mr
->rdParm
) + 1),
932 (LPINT16
)(mr
->rdParm
+ 1), *(mr
->rdParm
));
936 Polyline16(hdc
, (LPPOINT16
)(mr
->rdParm
+ 1), *(mr
->rdParm
));
940 RestoreDC(hdc
, (INT16
)*(mr
->rdParm
));
943 case META_SELECTOBJECT
:
944 SelectObject(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
948 Chord(hdc
, (INT16
)*(mr
->rdParm
+ 7), (INT16
)*(mr
->rdParm
+ 6),
949 (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
950 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
951 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
954 case META_CREATEPATTERNBRUSH
:
955 switch (*(mr
->rdParm
))
958 infohdr
= (BITMAPINFOHEADER
*)(mr
->rdParm
+ 2);
959 MF_AddHandle(ht
, nHandles
,
960 CreatePatternBrush(CreateBitmap(infohdr
->biWidth
,
965 (sizeof(BITMAPINFOHEADER
) / 2) + 4))));
969 s1
= mr
->rdSize
* 2 - sizeof(METARECORD
) - 2;
970 hndl
= GlobalAlloc16(GMEM_MOVEABLE
, s1
);
971 ptr
= GlobalLock16(hndl
);
972 memcpy(ptr
, mr
->rdParm
+ 2, s1
);
973 GlobalUnlock16(hndl
);
974 MF_AddHandle(ht
, nHandles
,
975 CreateDIBPatternBrush(hndl
, *(mr
->rdParm
+ 1)));
980 ERR("META_CREATEPATTERNBRUSH: Unknown pattern type %d\n",
986 case META_CREATEPENINDIRECT
:
987 MF_AddHandle(ht
, nHandles
,
988 CreatePenIndirect16((LOGPEN16
*)(&(mr
->rdParm
))));
991 case META_CREATEFONTINDIRECT
:
992 MF_AddHandle(ht
, nHandles
,
993 CreateFontIndirect16((LOGFONT16
*)(&(mr
->rdParm
))));
996 case META_CREATEBRUSHINDIRECT
:
997 MF_AddHandle(ht
, nHandles
,
998 CreateBrushIndirect16((LOGBRUSH16
*)(&(mr
->rdParm
))));
1001 case META_CREATEPALETTE
:
1002 MF_AddHandle(ht
, nHandles
,
1003 CreatePalette16((LPLOGPALETTE
)mr
->rdParm
));
1006 case META_SETTEXTALIGN
:
1007 SetTextAlign16(hdc
, *(mr
->rdParm
));
1010 case META_SELECTPALETTE
:
1011 GDISelectPalette16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
+1)),
1015 case META_SETMAPPERFLAGS
:
1016 SetMapperFlags16(hdc
, MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1019 case META_REALIZEPALETTE
:
1020 GDIRealizePalette16(hdc
);
1024 FIXME("META_ESCAPE unimplemented.\n");
1027 case META_EXTTEXTOUT
:
1028 MF_Play_MetaExtTextOut( hdc
, mr
);
1031 case META_STRETCHDIB
:
1033 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[11]);
1034 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[2] );
1035 StretchDIBits16(hdc
,mr
->rdParm
[10],mr
->rdParm
[9],mr
->rdParm
[8],
1036 mr
->rdParm
[7],mr
->rdParm
[6],mr
->rdParm
[5],
1037 mr
->rdParm
[4],mr
->rdParm
[3],bits
,info
,
1038 mr
->rdParm
[2],MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1042 case META_DIBSTRETCHBLT
:
1044 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[10]);
1045 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[2] );
1046 StretchDIBits16(hdc
,mr
->rdParm
[9],mr
->rdParm
[8],mr
->rdParm
[7],
1047 mr
->rdParm
[6],mr
->rdParm
[5],mr
->rdParm
[4],
1048 mr
->rdParm
[3],mr
->rdParm
[2],bits
,info
,
1049 DIB_RGB_COLORS
,MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1053 case META_STRETCHBLT
:
1055 HDC16 hdcSrc
=CreateCompatibleDC16(hdc
);
1056 HBITMAP hbitmap
=CreateBitmap(mr
->rdParm
[10], /*Width */
1057 mr
->rdParm
[11], /*Height*/
1058 mr
->rdParm
[13], /*Planes*/
1059 mr
->rdParm
[14], /*BitsPixel*/
1060 (LPSTR
)&mr
->rdParm
[15]); /*bits*/
1061 SelectObject(hdcSrc
,hbitmap
);
1062 StretchBlt16(hdc
,mr
->rdParm
[9],mr
->rdParm
[8],
1063 mr
->rdParm
[7],mr
->rdParm
[6],
1064 hdcSrc
,mr
->rdParm
[5],mr
->rdParm
[4],
1065 mr
->rdParm
[3],mr
->rdParm
[2],
1066 MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
1073 HDC16 hdcSrc
=CreateCompatibleDC16(hdc
);
1074 HBITMAP hbitmap
=CreateBitmap(mr
->rdParm
[7]/*Width */,
1075 mr
->rdParm
[8]/*Height*/,
1076 mr
->rdParm
[10]/*Planes*/,
1077 mr
->rdParm
[11]/*BitsPixel*/,
1078 (LPSTR
)&mr
->rdParm
[12]/*bits*/);
1079 SelectObject(hdcSrc
,hbitmap
);
1080 BitBlt(hdc
,(INT16
)mr
->rdParm
[6],(INT16
)mr
->rdParm
[5],
1081 (INT16
)mr
->rdParm
[4],(INT16
)mr
->rdParm
[3],
1082 hdcSrc
, (INT16
)mr
->rdParm
[2],(INT16
)mr
->rdParm
[1],
1083 MAKELONG(0,mr
->rdParm
[0]));
1088 case META_CREATEREGION
:
1090 HRGN hrgn
= CreateRectRgn(0,0,0,0);
1092 MF_Play_MetaCreateRegion(mr
, hrgn
);
1093 MF_AddHandle(ht
, nHandles
, hrgn
);
1097 case META_FILLREGION
:
1098 FillRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
+1)),
1099 *(ht
->objectHandle
+ *(mr
->rdParm
)));
1102 case META_FRAMEREGION
:
1103 FrameRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
+3)),
1104 *(ht
->objectHandle
+ *(mr
->rdParm
+2)),
1105 *(mr
->rdParm
+1), *(mr
->rdParm
));
1108 case META_INVERTREGION
:
1109 InvertRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
1112 case META_PAINTREGION
:
1113 PaintRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
1116 case META_SELECTCLIPREGION
:
1117 SelectClipRgn(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
1120 case META_DIBCREATEPATTERNBRUSH
:
1121 /* *(mr->rdParm) may be BS_PATTERN or BS_DIBPATTERN:
1122 but there's no difference */
1124 TRACE("%d\n",*(mr
->rdParm
));
1125 s1
= mr
->rdSize
* 2 - sizeof(METARECORD
) - 2;
1126 hndl
= GlobalAlloc16(GMEM_MOVEABLE
, s1
);
1127 ptr
= GlobalLock16(hndl
);
1128 memcpy(ptr
, mr
->rdParm
+ 2, s1
);
1129 GlobalUnlock16(hndl
);
1130 MF_AddHandle(ht
, nHandles
,
1131 CreateDIBPatternBrush16(hndl
, *(mr
->rdParm
+ 1)));
1135 case META_DIBBITBLT
:
1136 /* In practice I've found that there are two layouts for
1137 META_DIBBITBLT, one (the first here) is the usual one when a src
1138 dc is actually passed to it, the second occurs when the src dc is
1139 passed in as NULL to the creating BitBlt. As the second case has
1140 no dib, a size check will suffice to distinguish.
1142 Caolan.McNamara@ul.ie */
1144 if (mr
->rdSize
> 12) {
1145 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[8]);
1146 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize(info
, mr
->rdParm
[0]);
1148 StretchDIBits16(hdc
, mr
->rdParm
[7], mr
->rdParm
[6], mr
->rdParm
[5],
1149 mr
->rdParm
[4], mr
->rdParm
[3], mr
->rdParm
[2],
1150 mr
->rdParm
[5], mr
->rdParm
[4], bits
, info
,
1152 MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
1153 } else { /* equivalent to a PatBlt */
1154 PatBlt16(hdc
, mr
->rdParm
[8], mr
->rdParm
[7],
1155 mr
->rdParm
[6], mr
->rdParm
[5],
1156 MAKELONG(mr
->rdParm
[0], mr
->rdParm
[1]));
1160 case META_SETTEXTCHAREXTRA
:
1161 SetTextCharacterExtra16(hdc
, (INT16
)*(mr
->rdParm
));
1164 case META_SETTEXTJUSTIFICATION
:
1165 SetTextJustification(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
1168 case META_EXTFLOODFILL
:
1169 ExtFloodFill(hdc
, (INT16
)*(mr
->rdParm
+ 4), (INT16
)*(mr
->rdParm
+ 3),
1170 MAKELONG(*(mr
->rdParm
+1), *(mr
->rdParm
+ 2)),
1174 case META_SETDIBTODEV
:
1176 BITMAPINFO
*info
= (BITMAPINFO
*) &(mr
->rdParm
[9]);
1177 char *bits
= (char *)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[0] );
1178 SetDIBitsToDevice(hdc
, (INT16
)mr
->rdParm
[8], (INT16
)mr
->rdParm
[7],
1179 (INT16
)mr
->rdParm
[6], (INT16
)mr
->rdParm
[5],
1180 (INT16
)mr
->rdParm
[4], (INT16
)mr
->rdParm
[3],
1181 mr
->rdParm
[2], mr
->rdParm
[1], bits
, info
,
1186 #define META_UNIMP(x) case x: \
1187 FIXME("PlayMetaFileRecord:record type "#x" not implemented.\n"); \
1189 META_UNIMP(META_DRAWTEXT
)
1190 META_UNIMP(META_ANIMATEPALETTE
)
1191 META_UNIMP(META_SETPALENTRIES
)
1192 META_UNIMP(META_RESIZEPALETTE
)
1193 META_UNIMP(META_RESETDC
)
1194 META_UNIMP(META_STARTDOC
)
1195 META_UNIMP(META_STARTPAGE
)
1196 META_UNIMP(META_ENDPAGE
)
1197 META_UNIMP(META_ABORTDOC
)
1198 META_UNIMP(META_ENDDOC
)
1199 META_UNIMP(META_CREATEBRUSH
)
1200 META_UNIMP(META_CREATEBITMAPINDIRECT
)
1201 META_UNIMP(META_CREATEBITMAP
)
1205 WARN("PlayMetaFileRecord: Unknown record type %x\n",
1210 /******************************************************************
1211 * PlayMetaFileRecord (GDI32.@)
1213 BOOL WINAPI
PlayMetaFileRecord( HDC hdc
, HANDLETABLE
*handletable
,
1214 METARECORD
*metarecord
, UINT handles
)
1216 HANDLETABLE16
* ht
= (void *)GlobalAlloc(GPTR
,
1217 handles
*sizeof(HANDLETABLE16
));
1219 TRACE("(%08x,%p,%p,%d)\n", hdc
, handletable
, metarecord
,
1221 for (i
=0; i
<handles
; i
++)
1222 ht
->objectHandle
[i
] = handletable
->objectHandle
[i
];
1223 PlayMetaFileRecord16(hdc
, ht
, metarecord
, handles
);
1224 for (i
=0; i
<handles
; i
++)
1225 handletable
->objectHandle
[i
] = ht
->objectHandle
[i
];
1226 GlobalFree((HGLOBAL
)ht
);
1230 /******************************************************************
1231 * GetMetaFileBits (GDI.159)
1233 * Trade in a metafile object handle for a handle to the metafile memory.
1237 HGLOBAL16 WINAPI
GetMetaFileBits16(
1238 HMETAFILE16 hmf
/* [in] metafile handle */
1241 TRACE("hMem out: %04x\n", hmf
);
1245 /******************************************************************
1246 * SetMetaFileBits (GDI.160)
1248 * Trade in a metafile memory handle for a handle to a metafile object.
1249 * The memory region should hold a proper metafile, otherwise
1250 * problems will occur when it is used. Validity of the memory is not
1251 * checked. The function is essentially just the identity function.
1253 HMETAFILE16 WINAPI
SetMetaFileBits16(
1255 /* [in] handle to a memory region holding a metafile */
1258 TRACE("hmf out: %04x\n", hMem
);
1263 /******************************************************************
1264 * SetMetaFileBitsBetter (GDI.196)
1266 * Trade in a metafile memory handle for a handle to a metafile object,
1267 * making a cursory check (using IsValidMetaFile()) that the memory
1268 * handle points to a valid metafile.
1271 * Handle to a metafile on success, NULL on failure..
1273 HMETAFILE16 WINAPI
SetMetaFileBitsBetter16( HMETAFILE16 hMeta
)
1275 if( IsValidMetaFile16( hMeta
) )
1276 return (HMETAFILE16
)GlobalReAlloc16( hMeta
, 0,
1277 GMEM_SHARE
| GMEM_NODISCARD
| GMEM_MODIFY
);
1278 return (HMETAFILE16
)0;
1281 /******************************************************************
1282 * SetMetaFileBitsEx (GDI32.@)
1284 * Create a metafile from raw data. No checking of the data is performed.
1285 * Use _GetMetaFileBitsEx_ to get raw data from a metafile.
1287 HMETAFILE WINAPI
SetMetaFileBitsEx(
1288 UINT size
, /* [in] size of metafile, in bytes */
1289 const BYTE
*lpData
/* [in] pointer to metafile data */
1292 METAHEADER
*mh
= HeapAlloc( GetProcessHeap(), 0, size
);
1294 memcpy(mh
, lpData
, size
);
1295 return MF_Create_HMETAFILE(mh
);
1298 /*****************************************************************
1299 * GetMetaFileBitsEx (GDI32.@) Get raw metafile data
1301 * Copies the data from metafile _hmf_ into the buffer _buf_.
1302 * If _buf_ is zero, returns size of buffer required. Otherwise,
1303 * returns number of bytes copied.
1305 UINT WINAPI
GetMetaFileBitsEx(
1306 HMETAFILE hmf
, /* [in] metafile */
1307 UINT nSize
, /* [in] size of buf */
1308 LPVOID buf
/* [out] buffer to receive raw metafile data */
1310 METAHEADER
*mh
= MF_GetMetaHeader(hmf
);
1313 TRACE("(%08x,%d,%p)\n", hmf
, nSize
, buf
);
1314 if (!mh
) return 0; /* FIXME: error code */
1315 if(mh
->mtType
== METAFILE_DISK
)
1316 FIXME("Disk-based metafile?\n");
1317 mfSize
= mh
->mtSize
* 2;
1319 TRACE("returning size %d\n", mfSize
);
1322 if(mfSize
> nSize
) mfSize
= nSize
;
1323 memmove(buf
, mh
, mfSize
);
1327 /******************************************************************
1328 * GetWinMetaFileBits [GDI32.@]
1330 UINT WINAPI
GetWinMetaFileBits(HENHMETAFILE hemf
,
1331 UINT cbBuffer
, LPBYTE lpbBuffer
,
1332 INT fnMapMode
, HDC hdcRef
)
1334 FIXME("(%d,%d,%p,%d,%d): stub\n",
1335 hemf
, cbBuffer
, lpbBuffer
, fnMapMode
, hdcRef
);
1339 /******************************************************************
1340 * MF_Play_MetaCreateRegion
1342 * Handles META_CREATEREGION for PlayMetaFileRecord().
1346 * The layout of the record looks something like this:
1351 * 2 Looks like a handle? - not constant
1353 * 4 Total number of bytes
1354 * 5 No. of separate bands = n [see below]
1355 * 6 Largest number of x co-ords in a band
1356 * 7-10 Bounding box x1 y1 x2 y2
1359 * Regions are divided into bands that are uniform in the
1360 * y-direction. Each band consists of pairs of on/off x-coords and is
1362 * m y0 y1 x1 x2 x3 ... xm m
1363 * into successive rdParm[]s.
1365 * This is probably just a dump of the internal RGNOBJ?
1371 static BOOL
MF_Play_MetaCreateRegion( METARECORD
*mr
, HRGN hrgn
)
1376 HRGN hrgn2
= CreateRectRgn( 0, 0, 0, 0 );
1378 for(band
= 0, start
= &(mr
->rdParm
[11]); band
< mr
->rdParm
[5];
1379 band
++, start
= end
+ 1) {
1380 if(*start
/ 2 != (*start
+ 1) / 2) {
1381 WARN("Delimiter not even.\n");
1382 DeleteObject( hrgn2
);
1386 end
= start
+ *start
+ 3;
1387 if(end
> (WORD
*)mr
+ mr
->rdSize
) {
1388 WARN("End points outside record.\n");
1389 DeleteObject( hrgn2
);
1393 if(*start
!= *end
) {
1394 WARN("Mismatched delimiters.\n");
1395 DeleteObject( hrgn2
);
1399 y0
= *(INT16
*)(start
+ 1);
1400 y1
= *(INT16
*)(start
+ 2);
1401 for(pair
= 0; pair
< *start
/ 2; pair
++) {
1402 SetRectRgn( hrgn2
, *(INT16
*)(start
+ 3 + 2*pair
), y0
,
1403 *(INT16
*)(start
+ 4 + 2*pair
), y1
);
1404 CombineRgn(hrgn
, hrgn
, hrgn2
, RGN_OR
);
1407 DeleteObject( hrgn2
);
1412 /******************************************************************
1413 * MF_Play_MetaExtTextOut
1415 * Handles META_EXTTEXTOUT for PlayMetaFileRecord().
1418 static BOOL
MF_Play_MetaExtTextOut(HDC16 hdc
, METARECORD
*mr
)
1425 s1
= mr
->rdParm
[2]; /* String length */
1426 len
= sizeof(METARECORD
) + (((s1
+ 1) >> 1) * 2) + 2 * sizeof(short)
1427 + sizeof(UINT16
) + (mr
->rdParm
[3] ? sizeof(RECT16
) : 0);
1428 /* rec len without dx array */
1430 sot
= (LPSTR
)&mr
->rdParm
[4]; /* start_of_text */
1432 sot
+= sizeof(RECT16
); /* there is a rectangle, so add offset */
1434 if (mr
->rdSize
== len
/ 2)
1435 dxx
= NULL
; /* determine if array present */
1437 if (mr
->rdSize
== (len
+ s1
* sizeof(INT16
)) / 2)
1438 dxx
= (LPINT16
)(sot
+(((s1
+1)>>1)*2));
1440 TRACE("%s len: %ld\n", sot
, mr
->rdSize
);
1442 "Please report: ExtTextOut len=%ld slen=%d rdSize=%ld opt=%04x\n",
1443 len
, s1
, mr
->rdSize
, mr
->rdParm
[3]);
1444 dxx
= NULL
; /* should't happen -- but if, we continue with NULL */
1446 ExtTextOut16( hdc
, mr
->rdParm
[1], /* X position */
1447 mr
->rdParm
[0], /* Y position */
1448 mr
->rdParm
[3], /* options */
1449 mr
->rdParm
[3] ? (LPRECT16
) &mr
->rdParm
[4]:NULL
,
1452 s1
, dxx
); /* length, dx array */
1454 TRACE("%s len: %ld dx0: %d\n", sot
, mr
->rdSize
, dxx
[0]);