4 * Copyright David W. Metcalfe, 1994
5 * Niels de Carpentier, Albrecht Kleine, Huw Davies 1996
11 #include "wine/winbase16.h"
12 #include "metafiledrv.h"
19 /******************************************************************
22 * Add a handle to an external handle table and return the index
25 static int MF_AddHandle(HANDLETABLE16
*ht
, WORD htlen
, HGDIOBJ16 hobj
)
29 for (i
= 0; i
< htlen
; i
++)
31 if (*(ht
->objectHandle
+ i
) == 0)
33 *(ht
->objectHandle
+ i
) = hobj
;
41 /******************************************************************
44 * Note: this function assumes that we never delete objects.
45 * If we do someday, we'll need to maintain a table to re-use deleted
48 static int MF_AddHandleDC( DC
*dc
)
50 METAFILEDRV_PDEVICE
*physDev
= (METAFILEDRV_PDEVICE
*)dc
->physDev
;
51 physDev
->mh
->mtNoObjects
++;
52 return physDev
->nextHandle
++;
56 /******************************************************************
57 * GetMetaFile16 (GDI.124)
59 HMETAFILE16 WINAPI
GetMetaFile16( LPCSTR lpFilename
)
61 return GetMetaFileA( lpFilename
);
65 /******************************************************************
66 * GetMetaFile32A (GDI32.197)
68 * Read a metafile from a file. Returns handle to a disk-based metafile.
70 HMETAFILE WINAPI
GetMetaFileA(
72 /* pointer to string containing filename to read */
80 TRACE(metafile
,"%s\n", lpFilename
);
85 hmf
= GlobalAlloc16(GMEM_MOVEABLE
, MFHEADERSIZE
);
86 mh
= (METAHEADER
*)GlobalLock16(hmf
);
94 if ((hFile
= _lopen(lpFilename
, OF_READ
)) == HFILE_ERROR
)
100 if (_lread(hFile
, (char *)mh
, MFHEADERSIZE
) == HFILE_ERROR
)
107 size
= mh
->mtSize
* 2; /* alloc memory for whole metafile */
109 hmf
= GlobalReAlloc16(hmf
,size
,GMEM_MOVEABLE
);
110 mh
= (METAHEADER
*)GlobalLock16(hmf
);
119 if (_lread(hFile
, (char*)mh
+ mh
->mtHeaderSize
* 2,
120 size
- mh
->mtHeaderSize
* 2) == HFILE_ERROR
)
141 /******************************************************************
142 * GetMetaFile32W (GDI32.199)
144 HMETAFILE WINAPI
GetMetaFileW( LPCWSTR lpFilename
)
146 LPSTR p
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpFilename
);
147 HMETAFILE ret
= GetMetaFileA( p
);
148 HeapFree( GetProcessHeap(), 0, p
);
153 /******************************************************************
154 * CopyMetaFile16 (GDI.151)
157 HMETAFILE16 WINAPI
CopyMetaFile16( HMETAFILE16 hSrcMetaFile
, LPCSTR lpFilename
)
159 return CopyMetaFileA( hSrcMetaFile
, lpFilename
);
163 /******************************************************************
164 * CopyMetaFile32A (GDI32.23)
166 * Copies the metafile corresponding to hSrcMetaFile to either
167 * a disk file, if a filename is given, or to a new memory based
168 * metafile, if lpFileName is NULL.
172 * Handle to metafile copy on success, NULL on failure.
176 * Copying to disk returns NULL even if successful.
178 HMETAFILE WINAPI
CopyMetaFileA(
179 HMETAFILE hSrcMetaFile
, /* handle of metafile to copy */
180 LPCSTR lpFilename
/* filename if copying to a file */
182 HMETAFILE16 handle
= 0;
187 TRACE(metafile
,"(%08x,%s)\n", hSrcMetaFile
, lpFilename
);
189 mh
= (METAHEADER
*)GlobalLock16(hSrcMetaFile
);
194 if (lpFilename
) /* disk based metafile */
197 hFile
= _lcreat(lpFilename
, 0);
199 mh
->mtType
=1; /* disk file version stores 1 here */
200 i
=_lwrite(hFile
, (char *)mh
, mh
->mtSize
* 2) ;
201 mh
->mtType
=j
; /* restore old value [0 or 1] */
205 /* FIXME: return value */
207 else /* memory based metafile */
209 handle
= GlobalAlloc16(GMEM_MOVEABLE
,mh
->mtSize
* 2);
210 mh2
= (METAHEADER
*)GlobalLock16(handle
);
211 memcpy(mh2
,mh
, mh
->mtSize
* 2);
212 GlobalUnlock16(handle
);
215 GlobalUnlock16(hSrcMetaFile
);
220 /******************************************************************
221 * CopyMetaFile32W (GDI32.24)
223 HMETAFILE WINAPI
CopyMetaFileW( HMETAFILE hSrcMetaFile
,
226 LPSTR p
= HEAP_strdupWtoA( GetProcessHeap(), 0, lpFilename
);
227 HMETAFILE ret
= CopyMetaFileA( hSrcMetaFile
, p
);
228 HeapFree( GetProcessHeap(), 0, p
);
233 /******************************************************************
234 * IsValidMetaFile (GDI.410)
236 * Attempts to check if a given metafile is correctly formatted.
237 * Currently, the only things verified are several properties of the
241 * TRUE if hmf passes some tests for being a valid metafile, FALSE otherwise.
244 * This is not exactly what windows does, see _Undocumented_Windows_
248 BOOL16 WINAPI
IsValidMetaFile16(HMETAFILE16 hmf
)
251 METAHEADER
*mh
= (METAHEADER
*)GlobalLock16(hmf
);
253 if (mh
->mtType
== 1 || mh
->mtType
== 0)
254 if (mh
->mtHeaderSize
== MFHEADERSIZE
/sizeof(INT16
))
255 if (mh
->mtVersion
== MFVERSION
)
259 TRACE(metafile
,"IsValidMetaFile %x => %d\n",hmf
,resu
);
264 /******************************************************************
265 * PlayMetaFile16 (GDI.123)
268 BOOL16 WINAPI
PlayMetaFile16( HDC16 hdc
, HMETAFILE16 hmf
)
270 return PlayMetaFile( hdc
, hmf
);
273 /******************************************************************
274 * PlayMetaFile32 (GDI32.265)
276 * Renders the metafile specified by hmf in the DC specified by
277 * hdc. Returns FALSE on failure, TRUE on success.
279 BOOL WINAPI
PlayMetaFile(
280 HDC hdc
, /* handle of DC to render in */
281 HMETAFILE hmf
/* handle of metafile to render */
284 METAHEADER
*mh
= (METAHEADER
*)GlobalLock16(hmf
);
295 TRACE(metafile
,"(%04x %04x)\n",hdc
,hmf
);
296 if (!mh
) return FALSE
;
298 /* save the current pen, brush and font */
299 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
301 hBrush
= dc
->w
.hBrush
;
303 GDI_HEAP_UNLOCK(hdc
);
304 /* create the handle table */
305 hHT
= GlobalAlloc16(GMEM_MOVEABLE
|GMEM_ZEROINIT
,
306 sizeof(HANDLETABLE16
) * mh
->mtNoObjects
);
307 ht
= (HANDLETABLE16
*)GlobalLock16(hHT
);
310 /* loop through metafile playing records */
311 offset
= mh
->mtHeaderSize
* 2;
312 while (offset
< mh
->mtSize
* 2)
314 mr
= (METARECORD
*)((char *)mh
+ offset
);
315 TRACE(metafile
,"offset=%04x,size=%08lx\n",
318 TRACE(metafile
,"Entry got size 0 at offset %d, total mf length is %ld\n",
319 offset
,mh
->mtSize
*2);
320 break; /* would loop endlessly otherwise */
322 offset
+= mr
->rdSize
* 2;
323 PlayMetaFileRecord16( hdc
, ht
, mr
, mh
->mtNoObjects
);
326 SelectObject(hdc
, hBrush
);
327 SelectObject(hdc
, hPen
);
328 SelectObject(hdc
, hFont
);
330 /* free objects in handle table */
331 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
332 if(*(ht
->objectHandle
+ i
) != 0)
333 DeleteObject(*(ht
->objectHandle
+ i
));
335 /* free handle table */
342 /******************************************************************
343 * EnumMetaFile16 (GDI.175)
345 * Loop through the metafile records in hmf, calling the user-specified
346 * function for each one, stopping when the user's function returns FALSE
347 * (which is considered to be failure)
348 * or when no records are left (which is considered to be success).
351 * TRUE on success, FALSE on failure.
354 * Niels de carpentier, april 1996
356 BOOL16 WINAPI
EnumMetaFile16(
359 MFENUMPROC16 lpEnumFunc
,
363 METAHEADER
*mh
= (METAHEADER
*)GlobalLock16(hmf
);
374 BOOL16 result
= TRUE
;
376 TRACE(metafile
,"(%04x, %04x, %08lx, %08lx)\n",
377 hdc
, hmf
, (DWORD
)lpEnumFunc
, lpData
);
379 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
381 hBrush
= dc
->w
.hBrush
;
383 GDI_HEAP_UNLOCK(hdc
);
385 /* create the handle table */
387 hHT
= GlobalAlloc16(GMEM_MOVEABLE
| GMEM_ZEROINIT
,
388 sizeof(HANDLETABLE16
) * mh
->mtNoObjects
);
389 spht
= WIN16_GlobalLock16(hHT
);
391 seg
= GlobalHandleToSel16(hmf
);
392 offset
= mh
->mtHeaderSize
* 2;
394 /* loop through metafile records */
396 while (offset
< (mh
->mtSize
* 2))
398 mr
= (METARECORD
*)((char *)mh
+ offset
);
399 if (!lpEnumFunc( hdc
, (HANDLETABLE16
*)spht
,
400 (METARECORD
*) PTR_SEG_OFF_TO_HUGEPTR(seg
, offset
),
401 mh
->mtNoObjects
, (LONG
)lpData
))
408 offset
+= (mr
->rdSize
* 2);
411 SelectObject(hdc
, hBrush
);
412 SelectObject(hdc
, hPen
);
413 SelectObject(hdc
, hFont
);
415 ht
= (HANDLETABLE16
*)GlobalLock16(hHT
);
417 /* free objects in handle table */
418 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
419 if(*(ht
->objectHandle
+ i
) != 0)
420 DeleteObject(*(ht
->objectHandle
+ i
));
422 /* free handle table */
428 BOOL WINAPI
EnumMetaFile(
431 MFENUMPROC lpEnumFunc
,
434 METAHEADER
*mh
= (METAHEADER
*)GlobalLock16(hmf
);
439 DC
*dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
444 TRACE(metafile
,"(%08x,%08x,%p,%p)\n",
445 hdc
, hmf
, lpEnumFunc
, (void*)lpData
);
448 /* save the current pen, brush and font */
451 hBrush
= dc
->w
.hBrush
;
453 GDI_HEAP_UNLOCK(hdc
);
456 ht
= (HANDLETABLE
*) GlobalAlloc(GPTR
,
457 sizeof(HANDLETABLE
) * mh
->mtNoObjects
);
459 /* loop through metafile records */
460 offset
= mh
->mtHeaderSize
* 2;
462 while (offset
< (mh
->mtSize
* 2))
464 mr
= (METARECORD
*)((char *)mh
+ offset
);
465 if (!lpEnumFunc( hdc
, ht
, mr
, mh
->mtNoObjects
, (LONG
)lpData
))
471 offset
+= (mr
->rdSize
* 2);
474 /* restore pen, brush and font */
475 SelectObject(hdc
, hBrush
);
476 SelectObject(hdc
, hPen
);
477 SelectObject(hdc
, hFont
);
479 /* free objects in handle table */
480 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
481 if(*(ht
->objectHandle
+ i
) != 0)
482 DeleteObject(*(ht
->objectHandle
+ i
));
484 /* free handle table */
485 GlobalFree((HGLOBAL
)ht
);
490 static BOOL
MF_Meta_CreateRegion( METARECORD
*mr
, HRGN hrgn
);
492 /******************************************************************
493 * PlayMetaFileRecord16 (GDI.176)
495 * Render a single metafile record specified by *mr in the DC hdc, while
496 * using the handle table *ht, of length nHandles,
497 * to store metafile objects.
500 * The following metafile records are unimplemented:
502 * FRAMEREGION, DRAWTEXT, SETDIBTODEV, ANIMATEPALETTE, SETPALENTRIES,
503 * RESIZEPALETTE, EXTFLOODFILL, RESETDC, STARTDOC, STARTPAGE, ENDPAGE,
504 * ABORTDOC, ENDDOC, CREATEBRUSH, CREATEBITMAPINDIRECT, and CREATEBITMAP.
507 void WINAPI
PlayMetaFileRecord16(
508 HDC16 hdc
, /* DC to render metafile into */
509 HANDLETABLE16
*ht
, /* pointer to handle table for metafile objects */
510 METARECORD
*mr
, /* pointer to metafile record to render */
511 UINT16 nHandles
/* size of handle table */
516 BITMAPINFOHEADER
*infohdr
;
518 TRACE(metafile
,"(%04x %08lx %08lx %04x) function %04x\n",
519 hdc
,(LONG
)ht
, (LONG
)mr
, nHandles
, mr
->rdFunction
);
521 switch (mr
->rdFunction
)
526 case META_DELETEOBJECT
:
527 DeleteObject(*(ht
->objectHandle
+ *(mr
->rdParm
)));
528 *(ht
->objectHandle
+ *(mr
->rdParm
)) = 0;
531 case META_SETBKCOLOR
:
532 SetBkColor16(hdc
, MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
536 SetBkMode16(hdc
, *(mr
->rdParm
));
539 case META_SETMAPMODE
:
540 SetMapMode16(hdc
, *(mr
->rdParm
));
544 SetROP216(hdc
, *(mr
->rdParm
));
548 SetRelAbs16(hdc
, *(mr
->rdParm
));
551 case META_SETPOLYFILLMODE
:
552 SetPolyFillMode16(hdc
, *(mr
->rdParm
));
555 case META_SETSTRETCHBLTMODE
:
556 SetStretchBltMode16(hdc
, *(mr
->rdParm
));
559 case META_SETTEXTCOLOR
:
560 SetTextColor16(hdc
, MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
563 case META_SETWINDOWORG
:
564 SetWindowOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
567 case META_SETWINDOWEXT
:
568 SetWindowExt16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
571 case META_SETVIEWPORTORG
:
572 SetViewportOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
575 case META_SETVIEWPORTEXT
:
576 SetViewportExt16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
579 case META_OFFSETWINDOWORG
:
580 OffsetWindowOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
583 case META_SCALEWINDOWEXT
:
584 ScaleWindowExt16(hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
585 *(mr
->rdParm
+ 1), *(mr
->rdParm
));
588 case META_OFFSETVIEWPORTORG
:
589 OffsetViewportOrg16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
592 case META_SCALEVIEWPORTEXT
:
593 ScaleViewportExt16(hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
594 *(mr
->rdParm
+ 1), *(mr
->rdParm
));
598 LineTo(hdc
, (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
602 MoveTo16(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
605 case META_EXCLUDECLIPRECT
:
606 ExcludeClipRect16( hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
607 *(mr
->rdParm
+ 1), *(mr
->rdParm
) );
610 case META_INTERSECTCLIPRECT
:
611 IntersectClipRect16( hdc
, *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
612 *(mr
->rdParm
+ 1), *(mr
->rdParm
) );
616 Arc(hdc
, (INT16
)*(mr
->rdParm
+ 7), (INT16
)*(mr
->rdParm
+ 6),
617 (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
618 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
619 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
623 Ellipse(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
624 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
628 FloodFill(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
629 MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
633 Pie(hdc
, (INT16
)*(mr
->rdParm
+ 7), (INT16
)*(mr
->rdParm
+ 6),
634 (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
635 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
636 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
640 Rectangle(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
641 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
645 RoundRect(hdc
, (INT16
)*(mr
->rdParm
+ 5), (INT16
)*(mr
->rdParm
+ 4),
646 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
647 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
651 PatBlt16(hdc
, *(mr
->rdParm
+ 5), *(mr
->rdParm
+ 4),
652 *(mr
->rdParm
+ 3), *(mr
->rdParm
+ 2),
653 MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
661 SetPixel(hdc
, (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
662 MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
665 case META_OFFSETCLIPRGN
:
666 OffsetClipRgn16( hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
) );
671 TextOut16(hdc
, *(mr
->rdParm
+ ((s1
+ 1) >> 1) + 2),
672 *(mr
->rdParm
+ ((s1
+ 1) >> 1) + 1),
673 (char *)(mr
->rdParm
+ 1), s1
);
677 Polygon16(hdc
, (LPPOINT16
)(mr
->rdParm
+ 1), *(mr
->rdParm
));
680 case META_POLYPOLYGON
:
681 PolyPolygon16(hdc
, (LPPOINT16
)(mr
->rdParm
+ *(mr
->rdParm
) + 1),
682 (LPINT16
)(mr
->rdParm
+ 1), *(mr
->rdParm
));
686 Polyline16(hdc
, (LPPOINT16
)(mr
->rdParm
+ 1), *(mr
->rdParm
));
690 RestoreDC(hdc
, (INT16
)*(mr
->rdParm
));
693 case META_SELECTOBJECT
:
694 SelectObject(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
698 Chord(hdc
, (INT16
)*(mr
->rdParm
+ 7), (INT16
)*(mr
->rdParm
+ 6),
699 (INT16
)*(mr
->rdParm
+5), (INT16
)*(mr
->rdParm
+ 4),
700 (INT16
)*(mr
->rdParm
+ 3), (INT16
)*(mr
->rdParm
+ 2),
701 (INT16
)*(mr
->rdParm
+ 1), (INT16
)*(mr
->rdParm
));
704 case META_CREATEPATTERNBRUSH
:
705 switch (*(mr
->rdParm
))
708 infohdr
= (BITMAPINFOHEADER
*)(mr
->rdParm
+ 2);
709 MF_AddHandle(ht
, nHandles
,
710 CreatePatternBrush(CreateBitmap(infohdr
->biWidth
,
715 (sizeof(BITMAPINFOHEADER
) / 2) + 4))));
719 s1
= mr
->rdSize
* 2 - sizeof(METARECORD
) - 2;
720 hndl
= GlobalAlloc16(GMEM_MOVEABLE
, s1
);
721 ptr
= GlobalLock16(hndl
);
722 memcpy(ptr
, mr
->rdParm
+ 2, s1
);
723 GlobalUnlock16(hndl
);
724 MF_AddHandle(ht
, nHandles
,
725 CreateDIBPatternBrush(hndl
, *(mr
->rdParm
+ 1)));
730 case META_CREATEPENINDIRECT
:
731 MF_AddHandle(ht
, nHandles
,
732 CreatePenIndirect16((LOGPEN16
*)(&(mr
->rdParm
))));
735 case META_CREATEFONTINDIRECT
:
736 MF_AddHandle(ht
, nHandles
,
737 CreateFontIndirect16((LOGFONT16
*)(&(mr
->rdParm
))));
740 case META_CREATEBRUSHINDIRECT
:
741 MF_AddHandle(ht
, nHandles
,
742 CreateBrushIndirect16((LOGBRUSH16
*)(&(mr
->rdParm
))));
745 /* W. Magro: Some new metafile operations. Not all debugged. */
746 case META_CREATEPALETTE
:
747 MF_AddHandle(ht
, nHandles
,
748 CreatePalette16((LPLOGPALETTE
)mr
->rdParm
));
751 case META_SETTEXTALIGN
:
752 SetTextAlign16(hdc
, *(mr
->rdParm
));
755 case META_SELECTPALETTE
:
756 SelectPalette16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
+1)),*(mr
->rdParm
));
759 case META_SETMAPPERFLAGS
:
760 SetMapperFlags16(hdc
, *(mr
->rdParm
));
763 case META_REALIZEPALETTE
:
764 RealizePalette16(hdc
);
768 FIXME(metafile
, "META_ESCAPE unimplemented.\n");
771 /* --- Begin of fixed or new metafile operations. July 1996 ----*/
772 case META_EXTTEXTOUT
:
778 s1
= mr
->rdParm
[2]; /* String length */
779 len
= sizeof(METARECORD
) + (((s1
+ 1) >> 1) * 2) + 2 * sizeof(short)
780 + sizeof(UINT16
) + (mr
->rdParm
[3] ? sizeof(RECT16
) : 0); /* rec len without dx array */
782 sot
= (LPSTR
)&mr
->rdParm
[4]; /* start_of_text */
784 sot
+=sizeof(RECT16
); /* there is a rectangle, so add offset */
786 if (mr
->rdSize
== len
/ 2)
787 dxx
= NULL
; /* determine if array present */
789 if (mr
->rdSize
== (len
+ s1
* sizeof(INT16
)) / 2)
790 dxx
= (LPINT16
)(sot
+(((s1
+1)>>1)*2));
793 TRACE(metafile
,"%s len: %ld\n",
796 "Please report: PlayMetaFile/ExtTextOut len=%ld slen=%d rdSize=%ld opt=%04x\n",
797 len
,s1
,mr
->rdSize
,mr
->rdParm
[3]);
798 dxx
= NULL
; /* should't happen -- but if, we continue with NULL [for workaround] */
800 ExtTextOut16( hdc
, mr
->rdParm
[1], /* X position */
801 mr
->rdParm
[0], /* Y position */
802 mr
->rdParm
[3], /* options */
803 mr
->rdParm
[3] ? (LPRECT16
) &mr
->rdParm
[4]:NULL
, /* rectangle */
805 s1
, dxx
); /* length, dx array */
807 TRACE(metafile
,"%s len: %ld dx0: %d\n",
808 sot
,mr
->rdSize
,dxx
[0]);
812 case META_STRETCHDIB
:
814 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[11]);
815 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[2] );
816 StretchDIBits16(hdc
,mr
->rdParm
[10],mr
->rdParm
[9],mr
->rdParm
[8],
817 mr
->rdParm
[7],mr
->rdParm
[6],mr
->rdParm
[5],
818 mr
->rdParm
[4],mr
->rdParm
[3],bits
,info
,
819 mr
->rdParm
[2],MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
823 case META_DIBSTRETCHBLT
:
825 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[10]);
826 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[2] );
827 StretchDIBits16(hdc
,mr
->rdParm
[9],mr
->rdParm
[8],mr
->rdParm
[7],
828 mr
->rdParm
[6],mr
->rdParm
[5],mr
->rdParm
[4],
829 mr
->rdParm
[3],mr
->rdParm
[2],bits
,info
,
830 DIB_RGB_COLORS
,MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
834 case META_STRETCHBLT
:
836 HDC16 hdcSrc
=CreateCompatibleDC16(hdc
);
837 HBITMAP hbitmap
=CreateBitmap(mr
->rdParm
[10], /*Width */
838 mr
->rdParm
[11], /*Height*/
839 mr
->rdParm
[13], /*Planes*/
840 mr
->rdParm
[14], /*BitsPixel*/
841 (LPSTR
)&mr
->rdParm
[15]); /*bits*/
842 SelectObject(hdcSrc
,hbitmap
);
843 StretchBlt16(hdc
,mr
->rdParm
[9],mr
->rdParm
[8],
844 mr
->rdParm
[7],mr
->rdParm
[6],
845 hdcSrc
,mr
->rdParm
[5],mr
->rdParm
[4],
846 mr
->rdParm
[3],mr
->rdParm
[2],
847 MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
852 case META_BITBLT
: /* <-- not yet debugged */
854 HDC16 hdcSrc
=CreateCompatibleDC16(hdc
);
855 HBITMAP hbitmap
=CreateBitmap(mr
->rdParm
[7]/*Width */,
856 mr
->rdParm
[8]/*Height*/,
857 mr
->rdParm
[10]/*Planes*/,
858 mr
->rdParm
[11]/*BitsPixel*/,
859 (LPSTR
)&mr
->rdParm
[12]/*bits*/);
860 SelectObject(hdcSrc
,hbitmap
);
861 BitBlt(hdc
,(INT16
)mr
->rdParm
[6],(INT16
)mr
->rdParm
[5],
862 (INT16
)mr
->rdParm
[4],(INT16
)mr
->rdParm
[3],
863 hdcSrc
, (INT16
)mr
->rdParm
[2],(INT16
)mr
->rdParm
[1],
864 MAKELONG(0,mr
->rdParm
[0]));
869 /* --- Begin of new metafile operations. April, 1997 (ak) ----*/
870 case META_CREATEREGION
:
872 HRGN hrgn
= CreateRectRgn(0,0,0,0);
874 MF_Meta_CreateRegion(mr
, hrgn
);
875 MF_AddHandle(ht
, nHandles
, hrgn
);
879 case META_FILLREGION
:
880 FillRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)),
881 *(ht
->objectHandle
+ *(mr
->rdParm
+1)));
884 case META_INVERTREGION
:
885 InvertRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
888 case META_PAINTREGION
:
889 PaintRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
892 case META_SELECTCLIPREGION
:
893 SelectClipRgn(hdc
, *(ht
->objectHandle
+ *(mr
->rdParm
)));
896 case META_DIBCREATEPATTERNBRUSH
:
897 /* *(mr->rdParm) may be BS_PATTERN or BS_DIBPATTERN: but there's no difference */
898 TRACE(metafile
,"%d\n",*(mr
->rdParm
));
899 s1
= mr
->rdSize
* 2 - sizeof(METARECORD
) - 2;
900 hndl
= GlobalAlloc16(GMEM_MOVEABLE
, s1
);
901 ptr
= GlobalLock16(hndl
);
902 memcpy(ptr
, mr
->rdParm
+ 2, s1
);
903 GlobalUnlock16(hndl
);
904 MF_AddHandle(ht
, nHandles
,CreateDIBPatternBrush16(hndl
, *(mr
->rdParm
+ 1)));
910 /*In practice ive found that theres two layout for META_DIBBITBLT,
911 one (the first here) is the usual one when a src dc is actually passed
912 int, the second occurs when the src dc is passed in as NULL to
914 as the second case has no dib, a size check will suffice to distinguish.
917 Caolan.McNamara@ul.ie
921 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParm
[8]);
922 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParm
[0] );
923 StretchDIBits16(hdc
,mr
->rdParm
[7],mr
->rdParm
[6],mr
->rdParm
[5],
924 mr
->rdParm
[4],mr
->rdParm
[3],mr
->rdParm
[2],
925 mr
->rdParm
[5],mr
->rdParm
[4],bits
,info
,
926 DIB_RGB_COLORS
,MAKELONG(mr
->rdParm
[0],mr
->rdParm
[1]));
928 else /*equivalent to a PatBlt*/
930 PatBlt16(hdc
, mr
->rdParm
[8], mr
->rdParm
[7],
931 mr
->rdParm
[6], mr
->rdParm
[5],
932 MAKELONG(*(mr
->rdParm
), *(mr
->rdParm
+ 1)));
937 case META_SETTEXTCHAREXTRA
:
938 SetTextCharacterExtra16(hdc
, (INT16
)*(mr
->rdParm
));
941 case META_SETTEXTJUSTIFICATION
:
942 SetTextJustification(hdc
, *(mr
->rdParm
+ 1), *(mr
->rdParm
));
945 case META_EXTFLOODFILL
:
946 ExtFloodFill(hdc
, (INT16
)*(mr
->rdParm
+ 4), (INT16
)*(mr
->rdParm
+ 3),
947 MAKELONG(*(mr
->rdParm
+1), *(mr
->rdParm
+ 2)),*(mr
->rdParm
));
950 #define META_UNIMP(x) case x: FIXME(metafile, "PlayMetaFileRecord:record type "#x" not implemented.\n");break;
951 META_UNIMP(META_FRAMEREGION
)
952 META_UNIMP(META_DRAWTEXT
)
953 META_UNIMP(META_SETDIBTODEV
)
954 META_UNIMP(META_ANIMATEPALETTE
)
955 META_UNIMP(META_SETPALENTRIES
)
956 META_UNIMP(META_RESIZEPALETTE
)
957 META_UNIMP(META_RESETDC
)
958 META_UNIMP(META_STARTDOC
)
959 META_UNIMP(META_STARTPAGE
)
960 META_UNIMP(META_ENDPAGE
)
961 META_UNIMP(META_ABORTDOC
)
962 META_UNIMP(META_ENDDOC
)
963 META_UNIMP(META_CREATEBRUSH
)
964 META_UNIMP(META_CREATEBITMAPINDIRECT
)
965 META_UNIMP(META_CREATEBITMAP
)
969 WARN(metafile
, "PlayMetaFileRecord: Unknown record type %x\n",
975 BOOL WINAPI
PlayMetaFileRecord(
977 HANDLETABLE
*handletable
,
978 METARECORD
*metarecord
,
982 HANDLETABLE16
* ht
= (void *)GlobalAlloc(GPTR
,
983 handles
*sizeof(HANDLETABLE16
));
985 TRACE(metafile
, "(%08x,%p,%p,%d)\n", hdc
, handletable
, metarecord
, handles
);
986 for (i
=0; i
<handles
; i
++)
987 ht
->objectHandle
[i
] = handletable
->objectHandle
[i
];
988 PlayMetaFileRecord16(hdc
, ht
, metarecord
, handles
);
989 for (i
=0; i
<handles
; i
++)
990 handletable
->objectHandle
[i
] = ht
->objectHandle
[i
];
991 GlobalFree((HGLOBAL
)ht
);
995 /******************************************************************
996 * GetMetaFileBits (GDI.159)
998 * Trade in a metafile object handle for a handle to the metafile memory.
1002 HGLOBAL16 WINAPI
GetMetaFileBits16(
1003 HMETAFILE16 hmf
/* metafile handle */
1006 TRACE(metafile
,"hMem out: %04x\n", hmf
);
1010 /******************************************************************
1011 * SetMetaFileBits (GDI.160)
1013 * Trade in a metafile memory handle for a handle to a metafile object.
1014 * The memory region should hold a proper metafile, otherwise
1015 * problems will occur when it is used. Validity of the memory is not
1016 * checked. The function is essentially just the identity function.
1018 HMETAFILE16 WINAPI
SetMetaFileBits16(
1020 /* handle to a memory region holding a metafile */
1023 TRACE(metafile
,"hmf out: %04x\n", hMem
);
1028 /******************************************************************
1029 * SetMetaFileBitsBetter (GDI.196)
1031 * Trade in a metafile memory handle for a handle to a metafile object,
1032 * making a cursory check (using IsValidMetaFile()) that the memory
1033 * handle points to a valid metafile.
1036 * Handle to a metafile on success, NULL on failure..
1038 HMETAFILE16 WINAPI
SetMetaFileBitsBetter16( HMETAFILE16 hMeta
)
1040 if( IsValidMetaFile16( hMeta
) )
1041 return (HMETAFILE16
)GlobalReAlloc16( hMeta
, 0,
1042 GMEM_SHARE
| GMEM_NODISCARD
| GMEM_MODIFY
);
1043 return (HMETAFILE16
)0;
1046 /******************************************************************
1047 * SetMetaFileBitsEx (GDI32.323)
1049 * Create a metafile from raw data. No checking of the data is performed.
1050 * Use _GetMetaFileBitsEx_ to get raw data from a metafile.
1052 HMETAFILE WINAPI
SetMetaFileBitsEx(
1053 UINT size
, /* size of metafile, in bytes */
1054 const BYTE
*lpData
/* pointer to metafile data */
1057 HMETAFILE hmf
= GlobalAlloc16(GHND
, size
);
1058 BYTE
*p
= GlobalLock16(hmf
) ;
1059 TRACE(metafile
, "(%d,%p) returning %08x\n", size
, lpData
, hmf
);
1060 if (!hmf
|| !p
) return 0;
1061 memcpy(p
, lpData
, size
);
1062 GlobalUnlock16(hmf
);
1066 /*****************************************************************
1067 * GetMetaFileBitsEx (GDI32.198) Get raw metafile data
1069 * Copies the data from metafile _hmf_ into the buffer _buf_.
1070 * If _buf_ is zero, returns size of buffer required. Otherwise,
1071 * returns number of bytes copied.
1073 UINT WINAPI
GetMetaFileBitsEx(
1074 HMETAFILE hmf
, /* metafile */
1075 UINT nSize
, /* size of buf */
1076 LPVOID buf
/* buffer to receive raw metafile data */
1078 METAHEADER
*h
= GlobalLock16(hmf
);
1081 TRACE(metafile
, "(%08x,%d,%p)\n", hmf
, nSize
, buf
);
1082 if (!h
) return 0; /* FIXME: error code */
1083 mfSize
= h
->mtSize
* 2;
1085 GlobalUnlock16(hmf
);
1086 TRACE(metafile
,"returning size %d\n", mfSize
);
1089 if(mfSize
> nSize
) mfSize
= nSize
;
1090 memmove(buf
, h
, mfSize
);
1091 GlobalUnlock16(hmf
);
1095 /******************************************************************
1096 * GetWinMetaFileBits [GDI32.241]
1098 UINT WINAPI
GetWinMetaFileBits(HENHMETAFILE hemf
,
1099 UINT cbBuffer
, LPBYTE lpbBuffer
,
1100 INT fnMapMode
, HDC hdcRef
)
1102 FIXME(metafile
, "(%d,%d,%p,%d,%d): stub\n",
1103 hemf
, cbBuffer
, lpbBuffer
, fnMapMode
, hdcRef
);
1107 /******************************************************************
1108 * MF_Meta_CreateRegion
1110 * Handles META_CREATEREGION for PlayMetaFileRecord().
1114 * The layout of the record looks something like this:
1119 * 2 Looks like a handle? - not constant
1121 * 4 Total number of bytes
1122 * 5 No. of seperate bands = n [see below]
1123 * 6 Largest number of x co-ords in a band
1124 * 7-10 Bounding box x1 y1 x2 y2
1127 * Regions are divided into bands that are uniform in the
1128 * y-direction. Each band consists of pairs of on/off x-coords and is
1130 * m y0 y1 x1 x2 x3 ... xm m
1131 * into successive rdParm[]s.
1133 * This is probably just a dump of the internal RGNOBJ?
1139 static BOOL
MF_Meta_CreateRegion( METARECORD
*mr
, HRGN hrgn
)
1144 HRGN hrgn2
= CreateRectRgn( 0, 0, 0, 0 );
1146 for(band
= 0, start
= &(mr
->rdParm
[11]); band
< mr
->rdParm
[5];
1147 band
++, start
= end
+ 1) {
1148 if(*start
/ 2 != (*start
+ 1) / 2) {
1149 WARN(metafile
, "Delimiter not even.\n");
1150 DeleteObject( hrgn2
);
1154 end
= start
+ *start
+ 3;
1155 if(end
> (WORD
*)mr
+ mr
->rdSize
) {
1156 WARN(metafile
, "End points outside record.\n");
1157 DeleteObject( hrgn2
);
1161 if(*start
!= *end
) {
1162 WARN(metafile
, "Mismatched delimiters.\n");
1163 DeleteObject( hrgn2
);
1167 y0
= *(INT16
*)(start
+ 1);
1168 y1
= *(INT16
*)(start
+ 2);
1169 for(pair
= 0; pair
< *start
/ 2; pair
++) {
1170 SetRectRgn( hrgn2
, *(INT16
*)(start
+ 3 + 2*pair
), y0
,
1171 *(INT16
*)(start
+ 4 + 2*pair
), y1
);
1172 CombineRgn(hrgn
, hrgn
, hrgn2
, RGN_OR
);
1175 DeleteObject( hrgn2
);
1180 /******************************************************************
1183 * Warning: this function can change the metafile handle.
1186 static BOOL
MF_WriteRecord( DC
*dc
, METARECORD
*mr
, DWORD rlen
)
1190 METAFILEDRV_PDEVICE
*physDev
= (METAFILEDRV_PDEVICE
*)dc
->physDev
;
1192 switch(physDev
->mh
->mtType
)
1194 case METAFILE_MEMORY
:
1195 len
= physDev
->mh
->mtSize
* 2 + rlen
;
1196 mh
= HeapReAlloc( SystemHeap
, 0, physDev
->mh
, len
);
1197 if (!mh
) return FALSE
;
1199 memcpy((WORD
*)physDev
->mh
+ physDev
->mh
->mtSize
, mr
, rlen
);
1202 TRACE(metafile
,"Writing record to disk\n");
1203 if (_lwrite(physDev
->mh
->mtNoParameters
, (char *)mr
, rlen
) == -1)
1207 ERR(metafile
, "Unknown metafile type %d\n", physDev
->mh
->mtType
);
1211 physDev
->mh
->mtSize
+= rlen
/ 2;
1212 physDev
->mh
->mtMaxRecord
= MAX(physDev
->mh
->mtMaxRecord
, rlen
/ 2);
1217 /******************************************************************
1221 BOOL
MF_MetaParam0(DC
*dc
, short func
)
1224 METARECORD
*mr
= (METARECORD
*)&buffer
;
1227 mr
->rdFunction
= func
;
1228 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1232 /******************************************************************
1235 BOOL
MF_MetaParam1(DC
*dc
, short func
, short param1
)
1238 METARECORD
*mr
= (METARECORD
*)&buffer
;
1241 mr
->rdFunction
= func
;
1242 *(mr
->rdParm
) = param1
;
1243 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1247 /******************************************************************
1250 BOOL
MF_MetaParam2(DC
*dc
, short func
, short param1
, short param2
)
1253 METARECORD
*mr
= (METARECORD
*)&buffer
;
1256 mr
->rdFunction
= func
;
1257 *(mr
->rdParm
) = param2
;
1258 *(mr
->rdParm
+ 1) = param1
;
1259 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1263 /******************************************************************
1267 BOOL
MF_MetaParam4(DC
*dc
, short func
, short param1
, short param2
,
1268 short param3
, short param4
)
1271 METARECORD
*mr
= (METARECORD
*)&buffer
;
1274 mr
->rdFunction
= func
;
1275 *(mr
->rdParm
) = param4
;
1276 *(mr
->rdParm
+ 1) = param3
;
1277 *(mr
->rdParm
+ 2) = param2
;
1278 *(mr
->rdParm
+ 3) = param1
;
1279 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1283 /******************************************************************
1287 BOOL
MF_MetaParam6(DC
*dc
, short func
, short param1
, short param2
,
1288 short param3
, short param4
, short param5
, short param6
)
1291 METARECORD
*mr
= (METARECORD
*)&buffer
;
1294 mr
->rdFunction
= func
;
1295 *(mr
->rdParm
) = param6
;
1296 *(mr
->rdParm
+ 1) = param5
;
1297 *(mr
->rdParm
+ 2) = param4
;
1298 *(mr
->rdParm
+ 3) = param3
;
1299 *(mr
->rdParm
+ 4) = param2
;
1300 *(mr
->rdParm
+ 5) = param1
;
1301 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1305 /******************************************************************
1308 BOOL
MF_MetaParam8(DC
*dc
, short func
, short param1
, short param2
,
1309 short param3
, short param4
, short param5
,
1310 short param6
, short param7
, short param8
)
1313 METARECORD
*mr
= (METARECORD
*)&buffer
;
1316 mr
->rdFunction
= func
;
1317 *(mr
->rdParm
) = param8
;
1318 *(mr
->rdParm
+ 1) = param7
;
1319 *(mr
->rdParm
+ 2) = param6
;
1320 *(mr
->rdParm
+ 3) = param5
;
1321 *(mr
->rdParm
+ 4) = param4
;
1322 *(mr
->rdParm
+ 5) = param3
;
1323 *(mr
->rdParm
+ 6) = param2
;
1324 *(mr
->rdParm
+ 7) = param1
;
1325 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1329 /******************************************************************
1330 * MF_CreateBrushIndirect
1333 BOOL
MF_CreateBrushIndirect(DC
*dc
, HBRUSH16 hBrush
, LOGBRUSH16
*logbrush
)
1336 char buffer
[sizeof(METARECORD
) - 2 + sizeof(*logbrush
)];
1337 METARECORD
*mr
= (METARECORD
*)&buffer
;
1339 mr
->rdSize
= (sizeof(METARECORD
) + sizeof(*logbrush
) - 2) / 2;
1340 mr
->rdFunction
= META_CREATEBRUSHINDIRECT
;
1341 memcpy(&(mr
->rdParm
), logbrush
, sizeof(*logbrush
));
1342 if (!(MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2))) return FALSE
;
1344 mr
->rdSize
= sizeof(METARECORD
) / 2;
1345 mr
->rdFunction
= META_SELECTOBJECT
;
1347 if ((index
= MF_AddHandleDC( dc
)) == -1) return FALSE
;
1348 *(mr
->rdParm
) = index
;
1349 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1353 /******************************************************************
1354 * MF_CreatePatternBrush
1357 BOOL
MF_CreatePatternBrush(DC
*dc
, HBRUSH16 hBrush
, LOGBRUSH16
*logbrush
)
1359 DWORD len
, bmSize
, biSize
;
1364 BITMAPINFOHEADER
*infohdr
;
1366 char buffer
[sizeof(METARECORD
)];
1368 switch (logbrush
->lbStyle
)
1371 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr((HGDIOBJ16
)logbrush
->lbHatch
, BITMAP_MAGIC
);
1372 if (!bmp
) return FALSE
;
1373 len
= sizeof(METARECORD
) + sizeof(BITMAPINFOHEADER
) +
1374 (bmp
->bitmap
.bmHeight
* bmp
->bitmap
.bmWidthBytes
) + 6;
1375 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1377 GDI_HEAP_UNLOCK((HGDIOBJ16
)logbrush
->lbHatch
);
1380 mr
= (METARECORD
*)GlobalLock16(hmr
);
1382 mr
->rdFunction
= META_DIBCREATEPATTERNBRUSH
;
1383 mr
->rdSize
= len
/ 2;
1384 *(mr
->rdParm
) = logbrush
->lbStyle
;
1385 *(mr
->rdParm
+ 1) = DIB_RGB_COLORS
;
1386 infohdr
= (BITMAPINFOHEADER
*)(mr
->rdParm
+ 2);
1387 infohdr
->biSize
= sizeof(BITMAPINFOHEADER
);
1388 infohdr
->biWidth
= bmp
->bitmap
.bmWidth
;
1389 infohdr
->biHeight
= bmp
->bitmap
.bmHeight
;
1390 infohdr
->biPlanes
= bmp
->bitmap
.bmPlanes
;
1391 infohdr
->biBitCount
= bmp
->bitmap
.bmBitsPixel
;
1392 memcpy(mr
->rdParm
+ (sizeof(BITMAPINFOHEADER
) / 2) + 4,
1393 PTR_SEG_TO_LIN(bmp
->bitmap
.bmBits
),
1394 bmp
->bitmap
.bmHeight
* bmp
->bitmap
.bmWidthBytes
);
1395 GDI_HEAP_UNLOCK(logbrush
->lbHatch
);
1399 info
= (BITMAPINFO
*)GlobalLock16((HGLOBAL16
)logbrush
->lbHatch
);
1400 if (info
->bmiHeader
.biCompression
)
1401 bmSize
= info
->bmiHeader
.biSizeImage
;
1403 bmSize
= (info
->bmiHeader
.biWidth
* info
->bmiHeader
.biBitCount
1404 + 31) / 32 * 8 * info
->bmiHeader
.biHeight
;
1405 biSize
= DIB_BitmapInfoSize(info
, LOWORD(logbrush
->lbColor
));
1406 len
= sizeof(METARECORD
) + biSize
+ bmSize
+ 2;
1407 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1409 mr
= (METARECORD
*)GlobalLock16(hmr
);
1411 mr
->rdFunction
= META_DIBCREATEPATTERNBRUSH
;
1412 mr
->rdSize
= len
/ 2;
1413 *(mr
->rdParm
) = logbrush
->lbStyle
;
1414 *(mr
->rdParm
+ 1) = LOWORD(logbrush
->lbColor
);
1415 memcpy(mr
->rdParm
+ 2, info
, biSize
+ bmSize
);
1420 if (!(MF_WriteRecord(dc
, mr
, len
)))
1428 mr
= (METARECORD
*)&buffer
;
1429 mr
->rdSize
= sizeof(METARECORD
) / 2;
1430 mr
->rdFunction
= META_SELECTOBJECT
;
1432 if ((index
= MF_AddHandleDC( dc
)) == -1) return FALSE
;
1433 *(mr
->rdParm
) = index
;
1434 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1438 /******************************************************************
1439 * MF_CreatePenIndirect
1442 BOOL
MF_CreatePenIndirect(DC
*dc
, HPEN16 hPen
, LOGPEN16
*logpen
)
1445 char buffer
[sizeof(METARECORD
) - 2 + sizeof(*logpen
)];
1446 METARECORD
*mr
= (METARECORD
*)&buffer
;
1448 mr
->rdSize
= (sizeof(METARECORD
) + sizeof(*logpen
) - 2) / 2;
1449 mr
->rdFunction
= META_CREATEPENINDIRECT
;
1450 memcpy(&(mr
->rdParm
), logpen
, sizeof(*logpen
));
1451 if (!(MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2))) return FALSE
;
1453 mr
->rdSize
= sizeof(METARECORD
) / 2;
1454 mr
->rdFunction
= META_SELECTOBJECT
;
1456 if ((index
= MF_AddHandleDC( dc
)) == -1) return FALSE
;
1457 *(mr
->rdParm
) = index
;
1458 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1462 /******************************************************************
1463 * MF_CreateFontIndirect
1466 BOOL
MF_CreateFontIndirect(DC
*dc
, HFONT16 hFont
, LOGFONT16
*logfont
)
1469 char buffer
[sizeof(METARECORD
) - 2 + sizeof(LOGFONT16
)];
1470 METARECORD
*mr
= (METARECORD
*)&buffer
;
1472 mr
->rdSize
= (sizeof(METARECORD
) + sizeof(LOGFONT16
) - 2) / 2;
1473 mr
->rdFunction
= META_CREATEFONTINDIRECT
;
1474 memcpy(&(mr
->rdParm
), logfont
, sizeof(LOGFONT16
));
1475 if (!(MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2))) return FALSE
;
1477 mr
->rdSize
= sizeof(METARECORD
) / 2;
1478 mr
->rdFunction
= META_SELECTOBJECT
;
1480 if ((index
= MF_AddHandleDC( dc
)) == -1) return FALSE
;
1481 *(mr
->rdParm
) = index
;
1482 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1486 /******************************************************************
1489 BOOL
MF_TextOut(DC
*dc
, short x
, short y
, LPCSTR str
, short count
)
1496 len
= sizeof(METARECORD
) + (((count
+ 1) >> 1) * 2) + 4;
1497 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1499 mr
= (METARECORD
*)GlobalLock16(hmr
);
1502 mr
->rdSize
= len
/ 2;
1503 mr
->rdFunction
= META_TEXTOUT
;
1504 *(mr
->rdParm
) = count
;
1505 memcpy(mr
->rdParm
+ 1, str
, count
);
1506 *(mr
->rdParm
+ ((count
+ 1) >> 1) + 1) = y
;
1507 *(mr
->rdParm
+ ((count
+ 1) >> 1) + 2) = x
;
1508 ret
= MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1513 /******************************************************************
1516 BOOL
MF_ExtTextOut(DC
*dc
, short x
, short y
, UINT16 flags
, const RECT16
*rect
,
1517 LPCSTR str
, short count
, const INT16
*lpDx
)
1524 if((!flags
&& rect
) || (flags
&& !rect
))
1525 WARN(metafile
, "Inconsistent flags and rect\n");
1526 len
= sizeof(METARECORD
) + (((count
+ 1) >> 1) * 2) + 2 * sizeof(short)
1529 len
+= sizeof(RECT16
);
1531 len
+=count
*sizeof(INT16
);
1532 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1534 mr
= (METARECORD
*)GlobalLock16(hmr
);
1537 mr
->rdSize
= len
/ 2;
1538 mr
->rdFunction
= META_EXTTEXTOUT
;
1540 *(mr
->rdParm
+ 1) = x
;
1541 *(mr
->rdParm
+ 2) = count
;
1542 *(mr
->rdParm
+ 3) = flags
;
1543 if (rect
) memcpy(mr
->rdParm
+ 4, rect
, sizeof(RECT16
));
1544 memcpy(mr
->rdParm
+ (rect
? 8 : 4), str
, count
);
1546 memcpy(mr
->rdParm
+ (rect
? 8 : 4) + ((count
+ 1) >> 1),lpDx
,
1547 count
*sizeof(INT16
));
1548 ret
= MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1553 /******************************************************************
1554 * MF_MetaPoly - implements Polygon and Polyline
1556 BOOL
MF_MetaPoly(DC
*dc
, short func
, LPPOINT16 pt
, short count
)
1563 len
= sizeof(METARECORD
) + (count
* 4);
1564 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1566 mr
= (METARECORD
*)GlobalLock16(hmr
);
1569 mr
->rdSize
= len
/ 2;
1570 mr
->rdFunction
= func
;
1571 *(mr
->rdParm
) = count
;
1572 memcpy(mr
->rdParm
+ 1, pt
, count
* 4);
1573 ret
= MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1579 /******************************************************************
1582 BOOL
MF_BitBlt(DC
*dcDest
, short xDest
, short yDest
, short width
,
1583 short height
, DC
*dcSrc
, short xSrc
, short ySrc
, DWORD rop
)
1591 GetObject16(dcSrc
->w
.hBitmap
, sizeof(BITMAP16
), &BM
);
1592 len
= sizeof(METARECORD
) + 12 * sizeof(INT16
) + BM
.bmWidthBytes
* BM
.bmHeight
;
1593 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1595 mr
= (METARECORD
*)GlobalLock16(hmr
);
1596 mr
->rdFunction
= META_BITBLT
;
1597 *(mr
->rdParm
+ 7) = BM
.bmWidth
;
1598 *(mr
->rdParm
+ 8) = BM
.bmHeight
;
1599 *(mr
->rdParm
+ 9) = BM
.bmWidthBytes
;
1600 *(mr
->rdParm
+10) = BM
.bmPlanes
;
1601 *(mr
->rdParm
+11) = BM
.bmBitsPixel
;
1602 TRACE(metafile
,"MF_StretchBlt->len = %ld rop=%lx \n",len
,rop
);
1603 if (GetBitmapBits(dcSrc
->w
.hBitmap
,BM
.bmWidthBytes
* BM
.bmHeight
,
1606 mr
->rdSize
= len
/ sizeof(INT16
);
1607 *(mr
->rdParm
) = HIWORD(rop
);
1608 *(mr
->rdParm
+ 1) = ySrc
;
1609 *(mr
->rdParm
+ 2) = xSrc
;
1610 *(mr
->rdParm
+ 3) = height
;
1611 *(mr
->rdParm
+ 4) = width
;
1612 *(mr
->rdParm
+ 5) = yDest
;
1613 *(mr
->rdParm
+ 6) = xDest
;
1614 ret
= MF_WriteRecord( dcDest
, mr
, mr
->rdSize
* 2);
1623 /**********************************************************************
1625 * this function contains TWO ways for procesing StretchBlt in metafiles,
1626 * decide between rdFunction values META_STRETCHBLT or META_DIBSTRETCHBLT
1627 * via #define STRETCH_VIA_DIB
1629 #define STRETCH_VIA_DIB
1630 #undef STRETCH_VIA_DIB
1631 BOOL
MF_StretchBlt(DC
*dcDest
, short xDest
, short yDest
, short widthDest
,
1632 short heightDest
, DC
*dcSrc
, short xSrc
, short ySrc
,
1633 short widthSrc
, short heightSrc
, DWORD rop
)
1640 #ifdef STRETCH_VIA_DIB
1641 LPBITMAPINFOHEADER lpBMI
;
1644 GetObject16(dcSrc
->w
.hBitmap
, sizeof(BITMAP16
), &BM
);
1645 #ifdef STRETCH_VIA_DIB
1646 nBPP
= BM
.bmPlanes
* BM
.bmBitsPixel
;
1647 len
= sizeof(METARECORD
) + 10 * sizeof(INT16
)
1648 + sizeof(BITMAPINFOHEADER
) + (nBPP
!= 24 ? 1 << nBPP
: 0) * sizeof(RGBQUAD
)
1649 + ((BM
.bmWidth
* nBPP
+ 31) / 32) * 4 * BM
.bmHeight
;
1650 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1652 mr
= (METARECORD
*)GlobalLock16(hmr
);
1653 mr
->rdFunction
= META_DIBSTRETCHBLT
;
1654 lpBMI
=(LPBITMAPINFOHEADER
)(mr
->rdParm
+10);
1655 lpBMI
->biSize
= sizeof(BITMAPINFOHEADER
);
1656 lpBMI
->biWidth
= BM
.bmWidth
;
1657 lpBMI
->biHeight
= BM
.bmHeight
;
1658 lpBMI
->biPlanes
= 1;
1659 lpBMI
->biBitCount
= nBPP
; /* 1,4,8 or 24 */
1660 lpBMI
->biClrUsed
= nBPP
!= 24 ? 1 << nBPP
: 0;
1661 lpBMI
->biSizeImage
= ((lpBMI
->biWidth
* nBPP
+ 31) / 32) * 4 * lpBMI
->biHeight
;
1662 lpBMI
->biCompression
= BI_RGB
;
1663 lpBMI
->biXPelsPerMeter
= MulDiv(GetDeviceCaps(dcSrc
->hSelf
,LOGPIXELSX
),3937,100);
1664 lpBMI
->biYPelsPerMeter
= MulDiv(GetDeviceCaps(dcSrc
->hSelf
,LOGPIXELSY
),3937,100);
1665 lpBMI
->biClrImportant
= 0; /* 1 meter = 39.37 inch */
1667 TRACE(metafile
,"MF_StretchBltViaDIB->len = %ld rop=%lx PixYPM=%ld Caps=%d\n",
1668 len
,rop
,lpBMI
->biYPelsPerMeter
,GetDeviceCaps(hdcSrc
,LOGPIXELSY
));
1669 if (GetDIBits(hdcSrc
,dcSrc
->w
.hBitmap
,0,(UINT
)lpBMI
->biHeight
,
1670 (LPSTR
)lpBMI
+ DIB_BitmapInfoSize( (BITMAPINFO
*)lpBMI
,
1672 (LPBITMAPINFO
)lpBMI
, DIB_RGB_COLORS
))
1674 len
= sizeof(METARECORD
) + 15 * sizeof(INT16
) + BM
.bmWidthBytes
* BM
.bmHeight
;
1675 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1677 mr
= (METARECORD
*)GlobalLock16(hmr
);
1678 mr
->rdFunction
= META_STRETCHBLT
;
1679 *(mr
->rdParm
+10) = BM
.bmWidth
;
1680 *(mr
->rdParm
+11) = BM
.bmHeight
;
1681 *(mr
->rdParm
+12) = BM
.bmWidthBytes
;
1682 *(mr
->rdParm
+13) = BM
.bmPlanes
;
1683 *(mr
->rdParm
+14) = BM
.bmBitsPixel
;
1684 TRACE(metafile
,"MF_StretchBlt->len = %ld rop=%lx \n",len
,rop
);
1685 if (GetBitmapBits( dcSrc
->w
.hBitmap
, BM
.bmWidthBytes
* BM
.bmHeight
,
1689 mr
->rdSize
= len
/ sizeof(INT16
);
1690 *(mr
->rdParm
) = LOWORD(rop
);
1691 *(mr
->rdParm
+ 1) = HIWORD(rop
);
1692 *(mr
->rdParm
+ 2) = heightSrc
;
1693 *(mr
->rdParm
+ 3) = widthSrc
;
1694 *(mr
->rdParm
+ 4) = ySrc
;
1695 *(mr
->rdParm
+ 5) = xSrc
;
1696 *(mr
->rdParm
+ 6) = heightDest
;
1697 *(mr
->rdParm
+ 7) = widthDest
;
1698 *(mr
->rdParm
+ 8) = yDest
;
1699 *(mr
->rdParm
+ 9) = xDest
;
1700 ret
= MF_WriteRecord( dcDest
, mr
, mr
->rdSize
* 2);
1709 /******************************************************************
1712 INT16
MF_CreateRegion(DC
*dc
, HRGN hrgn
)
1717 RECT
*pCurRect
, *pEndRect
;
1718 WORD Bands
= 0, MaxBands
= 0;
1719 WORD
*Param
, *StartBand
;
1722 len
= GetRegionData( hrgn
, 0, NULL
);
1723 if( !(rgndata
= HeapAlloc( SystemHeap
, 0, len
)) ) {
1724 WARN(metafile
, "MF_CreateRegion: can't alloc rgndata buffer\n");
1727 GetRegionData( hrgn
, len
, rgndata
);
1729 /* Overestimate of length:
1730 * Assume every rect is a separate band -> 6 WORDs per rect
1732 len
= sizeof(METARECORD
) + 20 + (rgndata
->rdh
.nCount
* 12);
1733 if( !(mr
= HeapAlloc( SystemHeap
, 0, len
)) ) {
1734 WARN(metafile
, "MF_CreateRegion: can't alloc METARECORD buffer\n");
1735 HeapFree( SystemHeap
, 0, rgndata
);
1741 Param
= mr
->rdParm
+ 11;
1744 pEndRect
= (RECT
*)rgndata
->Buffer
+ rgndata
->rdh
.nCount
;
1745 for(pCurRect
= (RECT
*)rgndata
->Buffer
; pCurRect
< pEndRect
; pCurRect
++)
1747 if( StartBand
&& pCurRect
->top
== *(StartBand
+ 1) )
1749 *Param
++ = pCurRect
->left
;
1750 *Param
++ = pCurRect
->right
;
1756 *StartBand
= Param
- StartBand
- 3;
1757 *Param
++ = *StartBand
;
1758 if(*StartBand
> MaxBands
)
1759 MaxBands
= *StartBand
;
1762 StartBand
= Param
++;
1763 *Param
++ = pCurRect
->top
;
1764 *Param
++ = pCurRect
->bottom
;
1765 *Param
++ = pCurRect
->left
;
1766 *Param
++ = pCurRect
->right
;
1769 len
= Param
- (WORD
*)mr
;
1773 mr
->rdParm
[2] = 0x1234;
1775 mr
->rdParm
[4] = len
* 2;
1776 mr
->rdParm
[5] = Bands
;
1777 mr
->rdParm
[6] = MaxBands
;
1778 mr
->rdParm
[7] = rgndata
->rdh
.rcBound
.left
;
1779 mr
->rdParm
[8] = rgndata
->rdh
.rcBound
.top
;
1780 mr
->rdParm
[9] = rgndata
->rdh
.rcBound
.right
;
1781 mr
->rdParm
[10] = rgndata
->rdh
.rcBound
.bottom
;
1782 mr
->rdFunction
= META_CREATEREGION
;
1783 mr
->rdSize
= len
/ 2;
1784 ret
= MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2 );
1785 HeapFree( SystemHeap
, 0, mr
);
1786 HeapFree( SystemHeap
, 0, rgndata
);
1789 WARN(metafile
, "MF_CreateRegion: MF_WriteRecord failed\n");
1792 return MF_AddHandleDC( dc
);