4 * Copyright David W. Metcalfe, 1994
5 * Niels de Carpentier, Albrecht Kleine, Huw Davies 1996
16 #include "metafiledrv.h"
20 /******************************************************************
23 * Add a handle to an external handle table and return the index
26 static int MF_AddHandle(HANDLETABLE16
*ht
, WORD htlen
, HGDIOBJ16 hobj
)
30 for (i
= 0; i
< htlen
; i
++)
32 if (*(ht
->objectHandle
+ i
) == 0)
34 *(ht
->objectHandle
+ i
) = hobj
;
42 /******************************************************************
45 * Note: this function assumes that we never delete objects.
46 * If we do someday, we'll need to maintain a table to re-use deleted
49 static int MF_AddHandleDC( DC
*dc
)
51 METAFILEDRV_PDEVICE
*physDev
= (METAFILEDRV_PDEVICE
*)dc
->physDev
;
52 physDev
->mh
->mtNoObjects
++;
53 return physDev
->nextHandle
++;
57 /******************************************************************
58 * GetMetafile GDI.124 By Kenny MacDonald 30 Nov 94
61 HMETAFILE16
GetMetaFile(LPSTR lpFilename
)
68 dprintf_metafile(stddeb
,"GetMetaFile: %s\n", lpFilename
);
73 hmf
= GlobalAlloc16(GMEM_MOVEABLE
, MFHEADERSIZE
);
74 mh
= (METAHEADER
*)GlobalLock16(hmf
);
81 if ((hFile
= _lopen32(lpFilename
, OF_READ
)) == HFILE_ERROR32
) {
86 if (_lread32(hFile
, (char *)mh
, MFHEADERSIZE
) == HFILE_ERROR32
) {
91 size
= mh
->mtSize
* 2; /* alloc memory for whole metafile */
93 hmf
= GlobalReAlloc16(hmf
,size
,GMEM_MOVEABLE
);
94 mh
= (METAHEADER
*)GlobalLock16(hmf
);
101 if (_lread32(hFile
, (char*)mh
+ mh
->mtHeaderSize
* 2,
102 size
- mh
->mtHeaderSize
* 2) == HFILE_ERROR32
) {
109 if (mh
->mtType
!= 1) {
120 /******************************************************************
121 * CopyMetafile GDI.151 Niels de Carpentier, April 1996
124 HMETAFILE16
CopyMetaFile(HMETAFILE16 hSrcMetaFile
, LPCSTR lpFilename
)
126 HMETAFILE16 handle
= 0;
131 dprintf_metafile(stddeb
,"CopyMetaFile: %s\n", lpFilename
);
133 mh
= (METAHEADER
*)GlobalLock16(hSrcMetaFile
);
138 if (lpFilename
) /* disk based metafile */
141 hFile
= _lcreat32(lpFilename
, 0);
143 mh
->mtType
=1; /* disk file version stores 1 here */
144 i
=_lwrite32(hFile
, (char *)mh
, mh
->mtSize
* 2) ;
145 mh
->mtType
=j
; /* restore old value [0 or 1] */
150 else /* memory based metafile */
152 handle
= GlobalAlloc16(GMEM_MOVEABLE
,mh
->mtSize
* 2);
153 mh2
= (METAHEADER
*)GlobalLock16(handle
);
154 memcpy(mh2
,mh
, mh
->mtSize
* 2);
155 GlobalUnlock16(handle
);
161 /******************************************************************
162 * IsValidMetaFile (GDI.410)
163 * (This is not exactly what windows does, see "Undoc Win")
166 BOOL
IsValidMetaFile(HMETAFILE16 hmf
)
169 METAHEADER
*mh
= (METAHEADER
*)GlobalLock16(hmf
);
171 if (mh
->mtType
== 1 || mh
->mtType
== 0)
172 if (mh
->mtHeaderSize
== MFHEADERSIZE
/sizeof(INT16
))
173 if (mh
->mtVersion
== MFVERSION
)
177 dprintf_metafile(stddeb
,"IsValidMetaFile %x => %d\n",hmf
,resu
);
183 /******************************************************************
184 * CloseMetafile GDI.126
187 HMETAFILE16
CloseMetaFile(HDC16 hdc
)
193 METAFILEDRV_PDEVICE
*physDev
;
195 dprintf_metafile(stddeb
,"CloseMetaFile\n");
197 if (!(dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
))) return 0;
199 physDev
= (METAFILEDRV_PDEVICE
*)dc
->physDev
;
200 mh
= (METAHEADER
*)GlobalLock16( physDev
->hMetafile
);
202 /* Construct the end of metafile record - this is documented
203 * in SDK Knowledgebase Q99334.
206 if (!MF_MetaParam0(dc
, META_EOF
))
212 if (mh
->mtType
== 1) /* disk based metafile */
214 hFile
= mh
->mtNoParameters
;
215 mh
->mtNoParameters
= 0;
216 if (_llseek(hFile
, 0L, 0) == -1)
221 if (_lwrite32(hFile
, (char *)mh
, MFHEADERSIZE
) == -1)
229 hmf
= physDev
->hMetafile
;
230 GlobalUnlock16( hmf
);
231 physDev
->hMetafile
= 0; /* So it won't be deleted */
237 /******************************************************************
238 * DeleteMetafile GDI.127
241 BOOL
DeleteMetaFile(HMETAFILE16 hmf
)
243 METAHEADER
*mh
= (METAHEADER
*)GlobalLock16(hmf
);
253 /******************************************************************
254 * PlayMetafile GDI.123
257 BOOL
PlayMetaFile(HDC16 hdc
, HMETAFILE16 hmf
)
259 METAHEADER
*mh
= (METAHEADER
*)GlobalLock16(hmf
);
270 dprintf_metafile(stddeb
,"PlayMetaFile(%04x %04x)\n",hdc
,hmf
);
272 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
274 hBrush
= dc
->w
.hBrush
;
277 /* create the handle table */
278 hHT
= GlobalAlloc16(GMEM_MOVEABLE
|GMEM_ZEROINIT
,
279 sizeof(HANDLETABLE16
) * mh
->mtNoObjects
);
280 ht
= (HANDLETABLE16
*)GlobalLock16(hHT
);
282 /* loop through metafile playing records */
283 offset
= mh
->mtHeaderSize
* 2;
284 while (offset
< mh
->mtSize
* 2)
286 mr
= (METARECORD
*)((char *)mh
+ offset
);
287 dprintf_metafile(stddeb
,"offset = %04x size = %08lx function = %04x\n",
288 offset
,mr
->rdSize
,mr
->rdFunction
);
289 offset
+= mr
->rdSize
* 2;
290 PlayMetaFileRecord(hdc
, ht
, mr
, mh
->mtNoObjects
);
293 SelectObject32(hdc
, hBrush
);
294 SelectObject32(hdc
, hPen
);
295 SelectObject32(hdc
, hFont
);
297 /* free objects in handle table */
298 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
299 if(*(ht
->objectHandle
+ i
) != 0)
300 DeleteObject32(*(ht
->objectHandle
+ i
));
302 /* free handle table */
309 /******************************************************************
310 * EnumMetafile GDI.175
311 * Niels de carpentier, april 1996
314 BOOL
EnumMetaFile(HDC16 hdc
, HMETAFILE16 hmf
, MFENUMPROC16 lpEnumFunc
,LPARAM lpData
)
316 METAHEADER
*mh
= (METAHEADER
*)GlobalLock16(hmf
);
322 dprintf_metafile(stddeb
,"EnumMetaFile(%04x, %04x, %08lx, %08lx)\n",
323 hdc
, hmf
, (DWORD
)lpEnumFunc
, lpData
);
325 /* create the handle table */
327 hHT
= GlobalAlloc16(GMEM_MOVEABLE
| GMEM_ZEROINIT
,
328 sizeof(HANDLETABLE16
) * mh
->mtNoObjects
);
329 ht
= WIN16_GlobalLock16(hHT
);
331 offset
= mh
->mtHeaderSize
* 2;
333 /* loop through metafile records */
335 spRecord
= WIN16_GlobalLock16(hmf
);
336 while (offset
< (mh
->mtSize
* 2))
338 mr
= (METARECORD
*)((char *)mh
+ offset
);
339 if (!lpEnumFunc( hdc
, (HANDLETABLE16
*)ht
,
340 (METARECORD
*)((UINT32
)spRecord
+ offset
),
341 mh
->mtNoObjects
, (LONG
)lpData
))
344 offset
+= (mr
->rdSize
* 2);
347 /* free handle table */
354 /******************************************************************
355 * PlayMetaFileRecord GDI.176
358 void PlayMetaFileRecord(HDC16 hdc
, HANDLETABLE16
*ht
, METARECORD
*mr
,
364 BITMAPINFOHEADER
*infohdr
;
366 dprintf_metafile(stddeb
,"PlayMetaFileRecord(%04x %08lx %08lx %04x)\n",
367 hdc
,(LONG
)ht
, (LONG
)mr
, nHandles
);
369 switch (mr
->rdFunction
)
374 case META_DELETEOBJECT
:
375 DeleteObject32(*(ht
->objectHandle
+ *(mr
->rdParam
)));
376 *(ht
->objectHandle
+ *(mr
->rdParam
)) = 0;
379 case META_SETBKCOLOR
:
380 SetBkColor(hdc
, MAKELONG(*(mr
->rdParam
), *(mr
->rdParam
+ 1)));
384 SetBkMode16(hdc
, *(mr
->rdParam
));
387 case META_SETMAPMODE
:
388 SetMapMode16(hdc
, *(mr
->rdParam
));
392 SetROP216(hdc
, *(mr
->rdParam
));
396 SetRelAbs16(hdc
, *(mr
->rdParam
));
399 case META_SETPOLYFILLMODE
:
400 SetPolyFillMode16(hdc
, *(mr
->rdParam
));
403 case META_SETSTRETCHBLTMODE
:
404 SetStretchBltMode16(hdc
, *(mr
->rdParam
));
406 case META_SETTEXTCOLOR
:
407 SetTextColor(hdc
, MAKELONG(*(mr
->rdParam
), *(mr
->rdParam
+ 1)));
410 case META_SETWINDOWORG
:
411 SetWindowOrg(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
414 case META_SETWINDOWEXT
:
415 SetWindowExt(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
418 case META_SETVIEWPORTORG
:
419 SetViewportOrg(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
422 case META_SETVIEWPORTEXT
:
423 SetViewportExt(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
426 case META_OFFSETWINDOWORG
:
427 OffsetWindowOrg(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
430 case META_SCALEWINDOWEXT
:
431 ScaleWindowExt(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
432 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
435 case META_OFFSETVIEWPORTORG
:
436 OffsetViewportOrg(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
439 case META_SCALEVIEWPORTEXT
:
440 ScaleViewportExt(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
441 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
445 LineTo32(hdc
, (INT16
)*(mr
->rdParam
+ 1), (INT16
)*(mr
->rdParam
));
449 MoveTo(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
452 case META_EXCLUDECLIPRECT
:
453 ExcludeClipRect16( hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
454 *(mr
->rdParam
+ 1), *(mr
->rdParam
) );
457 case META_INTERSECTCLIPRECT
:
458 IntersectClipRect16( hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
459 *(mr
->rdParam
+ 1), *(mr
->rdParam
) );
463 Arc32(hdc
, (INT16
)*(mr
->rdParam
+ 7), (INT16
)*(mr
->rdParam
+ 6),
464 (INT16
)*(mr
->rdParam
+ 5), (INT16
)*(mr
->rdParam
+ 4),
465 (INT16
)*(mr
->rdParam
+ 3), (INT16
)*(mr
->rdParam
+ 2),
466 (INT16
)*(mr
->rdParam
+ 1), (INT16
)*(mr
->rdParam
));
470 Ellipse32(hdc
, (INT16
)*(mr
->rdParam
+ 3), (INT16
)*(mr
->rdParam
+ 2),
471 (INT16
)*(mr
->rdParam
+ 1), (INT16
)*(mr
->rdParam
));
475 FloodFill32(hdc
, (INT16
)*(mr
->rdParam
+ 3), (INT16
)*(mr
->rdParam
+ 2),
476 MAKELONG(*(mr
->rdParam
), *(mr
->rdParam
+ 1)));
480 Pie32(hdc
, (INT16
)*(mr
->rdParam
+ 7), (INT16
)*(mr
->rdParam
+ 6),
481 (INT16
)*(mr
->rdParam
+ 5), (INT16
)*(mr
->rdParam
+ 4),
482 (INT16
)*(mr
->rdParam
+ 3), (INT16
)*(mr
->rdParam
+ 2),
483 (INT16
)*(mr
->rdParam
+ 1), (INT16
)*(mr
->rdParam
));
487 Rectangle32(hdc
, (INT16
)*(mr
->rdParam
+ 3), (INT16
)*(mr
->rdParam
+ 2),
488 (INT16
)*(mr
->rdParam
+ 1), (INT16
)*(mr
->rdParam
));
492 RoundRect32(hdc
, (INT16
)*(mr
->rdParam
+ 5), (INT16
)*(mr
->rdParam
+ 4),
493 (INT16
)*(mr
->rdParam
+ 3), (INT16
)*(mr
->rdParam
+ 2),
494 (INT16
)*(mr
->rdParam
+ 1), (INT16
)*(mr
->rdParam
));
498 PatBlt16(hdc
, *(mr
->rdParam
+ 5), *(mr
->rdParam
+ 4),
499 *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
500 MAKELONG(*(mr
->rdParam
), *(mr
->rdParam
+ 1)));
508 SetPixel32(hdc
, (INT16
)*(mr
->rdParam
+ 3), (INT16
)*(mr
->rdParam
+ 2),
509 MAKELONG(*(mr
->rdParam
), *(mr
->rdParam
+ 1)));
512 case META_OFFSETCLIPRGN
:
513 OffsetClipRgn16( hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
) );
518 TextOut16(hdc
, *(mr
->rdParam
+ ((s1
+ 1) >> 1) + 2),
519 *(mr
->rdParam
+ ((s1
+ 1) >> 1) + 1),
520 (char *)(mr
->rdParam
+ 1), s1
);
524 Polygon16(hdc
, (LPPOINT16
)(mr
->rdParam
+ 1), *(mr
->rdParam
));
527 case META_POLYPOLYGON
:
528 PolyPolygon16(hdc
, (LPPOINT16
)(mr
->rdParam
+ *(mr
->rdParam
) + 1),
529 (LPINT16
)(mr
->rdParam
+ 1), *(mr
->rdParam
));
533 Polyline16(hdc
, (LPPOINT16
)(mr
->rdParam
+ 1), *(mr
->rdParam
));
537 RestoreDC32(hdc
, (INT16
)*(mr
->rdParam
));
540 case META_SELECTOBJECT
:
541 SelectObject32(hdc
, *(ht
->objectHandle
+ *(mr
->rdParam
)));
545 Chord32(hdc
, (INT16
)*(mr
->rdParam
+ 7), (INT16
)*(mr
->rdParam
+ 6),
546 (INT16
)*(mr
->rdParam
+5), (INT16
)*(mr
->rdParam
+ 4),
547 (INT16
)*(mr
->rdParam
+ 3), (INT16
)*(mr
->rdParam
+ 2),
548 (INT16
)*(mr
->rdParam
+ 1), (INT16
)*(mr
->rdParam
));
551 case META_CREATEPATTERNBRUSH
:
552 switch (*(mr
->rdParam
))
555 infohdr
= (BITMAPINFOHEADER
*)(mr
->rdParam
+ 2);
556 MF_AddHandle(ht
, nHandles
,
557 CreatePatternBrush32(CreateBitmap(infohdr
->biWidth
,
561 (LPSTR
)(mr
->rdParam
+
562 (sizeof(BITMAPINFOHEADER
) / 2) + 4))));
566 s1
= mr
->rdSize
* 2 - sizeof(METARECORD
) - 2;
567 hndl
= GlobalAlloc16(GMEM_MOVEABLE
, s1
);
568 ptr
= GlobalLock16(hndl
);
569 memcpy(ptr
, mr
->rdParam
+ 2, s1
);
570 GlobalUnlock16(hndl
);
571 MF_AddHandle(ht
, nHandles
,
572 CreateDIBPatternBrush32(hndl
, *(mr
->rdParam
+ 1)));
577 case META_CREATEPENINDIRECT
:
578 MF_AddHandle(ht
, nHandles
,
579 CreatePenIndirect16((LOGPEN16
*)(&(mr
->rdParam
))));
582 case META_CREATEFONTINDIRECT
:
583 MF_AddHandle(ht
, nHandles
,
584 CreateFontIndirect16((LOGFONT16
*)(&(mr
->rdParam
))));
587 case META_CREATEBRUSHINDIRECT
:
588 MF_AddHandle(ht
, nHandles
,
589 CreateBrushIndirect16((LOGBRUSH16
*)(&(mr
->rdParam
))));
592 /* W. Magro: Some new metafile operations. Not all debugged. */
593 case META_CREATEPALETTE
:
594 MF_AddHandle(ht
, nHandles
,
595 CreatePalette((LPLOGPALETTE
)mr
->rdParam
));
598 case META_SETTEXTALIGN
:
599 SetTextAlign16(hdc
, *(mr
->rdParam
));
602 case META_SELECTPALETTE
:
603 SelectPalette(hdc
, *(ht
->objectHandle
+ *(mr
->rdParam
+1)),*(mr
->rdParam
));
606 case META_SETMAPPERFLAGS
:
607 SetMapperFlags(hdc
, *(mr
->rdParam
));
610 case META_REALIZEPALETTE
:
615 dprintf_metafile(stddeb
,"PlayMetaFileRecord: META_ESCAPE unimplemented.\n");
618 /* --- Begin of fixed or new metafile operations. July 1996 ----*/
619 case META_EXTTEXTOUT
:
624 s1
= mr
->rdParam
[2]; /* String length */
625 len
= sizeof(METARECORD
) + (((s1
+ 1) >> 1) * 2) + 2 * sizeof(short)
626 + sizeof(UINT16
) + sizeof(RECT16
);
627 if (mr
->rdSize
== len
/ 2)
628 dxx
= NULL
; /* No array present */
629 else if (mr
->rdSize
== (len
+ s1
* sizeof(INT16
)) / 2)
630 dxx
= &mr
->rdParam
[8+(s1
+1)/2]; /* start of array */
633 "PlayMetaFileRecord ExtTextOut mr->rdSize = %08lx, count = %x\n",
637 ExtTextOut16( hdc
, mr
->rdParam
[1], /* X position */
638 mr
->rdParam
[0], /* Y position */
639 mr
->rdParam
[3], /* options */
640 (LPRECT16
) &mr
->rdParam
[4], /* rectangle */
641 (char *)(mr
->rdParam
+ 8), /* string */
642 s1
, dxx
); /* length, dx array */
644 dprintf_metafile(stddeb
,"EXTTEXTOUT len: %ld (%hd %hd) [%s].\n",
645 mr
->rdSize
,dxx
[0],dxx
[1],(char*) &(mr
->rdParam
[8]) );
649 case META_STRETCHDIB
:
651 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParam
[11]);
652 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParam
[2] );
653 StretchDIBits16(hdc
,mr
->rdParam
[10],mr
->rdParam
[9],mr
->rdParam
[8],
654 mr
->rdParam
[7],mr
->rdParam
[6],mr
->rdParam
[5],
655 mr
->rdParam
[4],mr
->rdParam
[3],bits
,info
,
656 mr
->rdParam
[2],MAKELONG(mr
->rdParam
[0],mr
->rdParam
[1]));
660 case META_DIBSTRETCHBLT
:
662 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParam
[10]);
663 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParam
[2] );
664 StretchDIBits16(hdc
,mr
->rdParam
[9],mr
->rdParam
[8],mr
->rdParam
[7],
665 mr
->rdParam
[6],mr
->rdParam
[5],mr
->rdParam
[4],
666 mr
->rdParam
[3],mr
->rdParam
[2],bits
,info
,
667 DIB_RGB_COLORS
,MAKELONG(mr
->rdParam
[0],mr
->rdParam
[1]));
671 case META_STRETCHBLT
:
673 HDC16 hdcSrc
=CreateCompatibleDC16(hdc
);
674 HBITMAP16 hbitmap
=CreateBitmap(mr
->rdParam
[10], /*Width */
675 mr
->rdParam
[11], /*Height*/
676 mr
->rdParam
[13], /*Planes*/
677 mr
->rdParam
[14], /*BitsPixel*/
678 (LPSTR
)&mr
->rdParam
[15]); /*bits*/
679 SelectObject32(hdcSrc
,hbitmap
);
680 StretchBlt16(hdc
,mr
->rdParam
[9],mr
->rdParam
[8],
681 mr
->rdParam
[7],mr
->rdParam
[6],
682 hdcSrc
,mr
->rdParam
[5],mr
->rdParam
[4],
683 mr
->rdParam
[3],mr
->rdParam
[2],
684 MAKELONG(mr
->rdParam
[0],mr
->rdParam
[1]));
689 case META_BITBLT
: /* <-- not yet debugged */
691 HDC16 hdcSrc
=CreateCompatibleDC16(hdc
);
692 HBITMAP16 hbitmap
=CreateBitmap(mr
->rdParam
[7]/*Width */,mr
->rdParam
[8]/*Height*/,
693 mr
->rdParam
[10]/*Planes*/,mr
->rdParam
[11]/*BitsPixel*/,
694 (LPSTR
)&mr
->rdParam
[12]/*bits*/);
695 SelectObject32(hdcSrc
,hbitmap
);
696 BitBlt32(hdc
,(INT16
)mr
->rdParam
[6],(INT16
)mr
->rdParam
[5],
697 (INT16
)mr
->rdParam
[4],(INT16
)mr
->rdParam
[3],
698 hdcSrc
, (INT16
)mr
->rdParam
[2],(INT16
)mr
->rdParam
[1],
699 MAKELONG(0,mr
->rdParam
[0]));
703 #define META_UNIMP(x) case x: fprintf(stderr,"PlayMetaFileRecord:record type "#x" not implemented.\n");break;
704 META_UNIMP(META_SETTEXTCHAREXTRA
)
705 META_UNIMP(META_SETTEXTJUSTIFICATION
)
706 META_UNIMP(META_FILLREGION
)
707 META_UNIMP(META_FRAMEREGION
)
708 META_UNIMP(META_INVERTREGION
)
709 META_UNIMP(META_PAINTREGION
)
710 META_UNIMP(META_SELECTCLIPREGION
)
711 META_UNIMP(META_DRAWTEXT
)
712 META_UNIMP(META_SETDIBTODEV
)
713 META_UNIMP(META_ANIMATEPALETTE
)
714 META_UNIMP(META_SETPALENTRIES
)
715 META_UNIMP(META_RESIZEPALETTE
)
716 META_UNIMP(META_DIBBITBLT
)
717 META_UNIMP(META_DIBCREATEPATTERNBRUSH
)
718 META_UNIMP(META_EXTFLOODFILL
)
719 META_UNIMP(META_RESETDC
)
720 META_UNIMP(META_STARTDOC
)
721 META_UNIMP(META_STARTPAGE
)
722 META_UNIMP(META_ENDPAGE
)
723 META_UNIMP(META_ABORTDOC
)
724 META_UNIMP(META_ENDDOC
)
725 META_UNIMP(META_CREATEBRUSH
)
726 META_UNIMP(META_CREATEBITMAPINDIRECT
)
727 META_UNIMP(META_CREATEBITMAP
)
731 fprintf(stddeb
,"PlayMetaFileRecord: Unknown record type %x\n",
737 /******************************************************************
738 * GetMetaFileBits by William Magro, 19 Sep 1995
740 * Trade in a meta file object handle for a handle to the meta file memory
743 HGLOBAL16
GetMetaFileBits(HMETAFILE16 hmf
)
745 dprintf_metafile(stddeb
,"GetMetaFileBits: hMem out: %04x\n", hmf
);
750 /******************************************************************
751 * SetMetaFileBits by William Magro, 19 Sep 1995
753 * Trade in a meta file memory handle for a handle to a meta file object
756 HMETAFILE16
SetMetaFileBits( HGLOBAL16 hMem
)
758 dprintf_metafile(stddeb
,"SetMetaFileBits: hmf out: %04x\n", hMem
);
763 /******************************************************************
766 * Warning: this function can change the metafile handle.
769 static BOOL32
MF_WriteRecord( DC
*dc
, METARECORD
*mr
, WORD rlen
)
773 METAFILEDRV_PDEVICE
*physDev
= (METAFILEDRV_PDEVICE
*)dc
->physDev
;
775 switch(physDev
->mh
->mtType
)
777 case METAFILE_MEMORY
:
778 len
= physDev
->mh
->mtSize
* 2 + rlen
;
779 mh
= HeapReAlloc( SystemHeap
, 0, physDev
->mh
, len
);
780 if (!mh
) return FALSE
;
782 memcpy((WORD
*)physDev
->mh
+ physDev
->mh
->mtSize
, mr
, rlen
);
785 dprintf_metafile(stddeb
,"Writing record to disk\n");
786 if (_lwrite32(physDev
->mh
->mtNoParameters
, (char *)mr
, rlen
) == -1)
790 fprintf( stderr
, "Unknown metafile type %d\n", physDev
->mh
->mtType
);
794 physDev
->mh
->mtSize
+= rlen
/ 2;
795 physDev
->mh
->mtMaxRecord
= MAX(physDev
->mh
->mtMaxRecord
, rlen
/ 2);
800 /******************************************************************
804 BOOL32
MF_MetaParam0(DC
*dc
, short func
)
807 METARECORD
*mr
= (METARECORD
*)&buffer
;
810 mr
->rdFunction
= func
;
811 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
815 /******************************************************************
818 BOOL32
MF_MetaParam1(DC
*dc
, short func
, short param1
)
821 METARECORD
*mr
= (METARECORD
*)&buffer
;
824 mr
->rdFunction
= func
;
825 *(mr
->rdParam
) = param1
;
826 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
830 /******************************************************************
833 BOOL32
MF_MetaParam2(DC
*dc
, short func
, short param1
, short param2
)
836 METARECORD
*mr
= (METARECORD
*)&buffer
;
839 mr
->rdFunction
= func
;
840 *(mr
->rdParam
) = param2
;
841 *(mr
->rdParam
+ 1) = param1
;
842 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
846 /******************************************************************
850 BOOL32
MF_MetaParam4(DC
*dc
, short func
, short param1
, short param2
,
851 short param3
, short param4
)
854 METARECORD
*mr
= (METARECORD
*)&buffer
;
857 mr
->rdFunction
= func
;
858 *(mr
->rdParam
) = param4
;
859 *(mr
->rdParam
+ 1) = param3
;
860 *(mr
->rdParam
+ 2) = param2
;
861 *(mr
->rdParam
+ 3) = param1
;
862 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
866 /******************************************************************
870 BOOL32
MF_MetaParam6(DC
*dc
, short func
, short param1
, short param2
,
871 short param3
, short param4
, short param5
, short param6
)
874 METARECORD
*mr
= (METARECORD
*)&buffer
;
877 mr
->rdFunction
= func
;
878 *(mr
->rdParam
) = param6
;
879 *(mr
->rdParam
+ 1) = param5
;
880 *(mr
->rdParam
+ 2) = param4
;
881 *(mr
->rdParam
+ 3) = param3
;
882 *(mr
->rdParam
+ 4) = param2
;
883 *(mr
->rdParam
+ 5) = param1
;
884 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
888 /******************************************************************
891 BOOL32
MF_MetaParam8(DC
*dc
, short func
, short param1
, short param2
,
892 short param3
, short param4
, short param5
,
893 short param6
, short param7
, short param8
)
896 METARECORD
*mr
= (METARECORD
*)&buffer
;
899 mr
->rdFunction
= func
;
900 *(mr
->rdParam
) = param8
;
901 *(mr
->rdParam
+ 1) = param7
;
902 *(mr
->rdParam
+ 2) = param6
;
903 *(mr
->rdParam
+ 3) = param5
;
904 *(mr
->rdParam
+ 4) = param4
;
905 *(mr
->rdParam
+ 5) = param3
;
906 *(mr
->rdParam
+ 6) = param2
;
907 *(mr
->rdParam
+ 7) = param1
;
908 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
912 /******************************************************************
913 * MF_CreateBrushIndirect
916 BOOL32
MF_CreateBrushIndirect(DC
*dc
, HBRUSH16 hBrush
, LOGBRUSH16
*logbrush
)
919 char buffer
[sizeof(METARECORD
) - 2 + sizeof(*logbrush
)];
920 METARECORD
*mr
= (METARECORD
*)&buffer
;
922 mr
->rdSize
= (sizeof(METARECORD
) + sizeof(*logbrush
) - 2) / 2;
923 mr
->rdFunction
= META_CREATEBRUSHINDIRECT
;
924 memcpy(&(mr
->rdParam
), logbrush
, sizeof(*logbrush
));
925 if (!(MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2))) return FALSE
;
927 mr
->rdSize
= sizeof(METARECORD
) / 2;
928 mr
->rdFunction
= META_SELECTOBJECT
;
930 if ((index
= MF_AddHandleDC( dc
)) == -1) return FALSE
;
931 *(mr
->rdParam
) = index
;
932 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
936 /******************************************************************
937 * MF_CreatePatternBrush
940 BOOL32
MF_CreatePatternBrush(DC
*dc
, HBRUSH16 hBrush
, LOGBRUSH16
*logbrush
)
942 DWORD len
, bmSize
, biSize
;
947 BITMAPINFOHEADER
*infohdr
;
949 char buffer
[sizeof(METARECORD
)];
951 switch (logbrush
->lbStyle
)
954 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr((HGDIOBJ16
)logbrush
->lbHatch
, BITMAP_MAGIC
);
955 if (!bmp
) return FALSE
;
956 len
= sizeof(METARECORD
) + sizeof(BITMAPINFOHEADER
) +
957 (bmp
->bitmap
.bmHeight
* bmp
->bitmap
.bmWidthBytes
) + 6;
958 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
960 mr
= (METARECORD
*)GlobalLock16(hmr
);
962 mr
->rdFunction
= META_DIBCREATEPATTERNBRUSH
;
963 mr
->rdSize
= len
/ 2;
964 *(mr
->rdParam
) = logbrush
->lbStyle
;
965 *(mr
->rdParam
+ 1) = DIB_RGB_COLORS
;
966 infohdr
= (BITMAPINFOHEADER
*)(mr
->rdParam
+ 2);
967 infohdr
->biSize
= sizeof(BITMAPINFOHEADER
);
968 infohdr
->biWidth
= bmp
->bitmap
.bmWidth
;
969 infohdr
->biHeight
= bmp
->bitmap
.bmHeight
;
970 infohdr
->biPlanes
= bmp
->bitmap
.bmPlanes
;
971 infohdr
->biBitCount
= bmp
->bitmap
.bmBitsPixel
;
972 memcpy(mr
->rdParam
+ (sizeof(BITMAPINFOHEADER
) / 2) + 4,
973 PTR_SEG_TO_LIN(bmp
->bitmap
.bmBits
),
974 bmp
->bitmap
.bmHeight
* bmp
->bitmap
.bmWidthBytes
);
978 info
= (BITMAPINFO
*)GlobalLock16((HGLOBAL16
)logbrush
->lbHatch
);
979 if (info
->bmiHeader
.biCompression
)
980 bmSize
= info
->bmiHeader
.biSizeImage
;
982 bmSize
= (info
->bmiHeader
.biWidth
* info
->bmiHeader
.biBitCount
983 + 31) / 32 * 8 * info
->bmiHeader
.biHeight
;
984 biSize
= DIB_BitmapInfoSize(info
, LOWORD(logbrush
->lbColor
));
985 len
= sizeof(METARECORD
) + biSize
+ bmSize
+ 2;
986 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
988 mr
= (METARECORD
*)GlobalLock16(hmr
);
990 mr
->rdFunction
= META_DIBCREATEPATTERNBRUSH
;
991 mr
->rdSize
= len
/ 2;
992 *(mr
->rdParam
) = logbrush
->lbStyle
;
993 *(mr
->rdParam
+ 1) = LOWORD(logbrush
->lbColor
);
994 memcpy(mr
->rdParam
+ 2, info
, biSize
+ bmSize
);
999 if (!(MF_WriteRecord(dc
, mr
, len
)))
1007 mr
= (METARECORD
*)&buffer
;
1008 mr
->rdSize
= sizeof(METARECORD
) / 2;
1009 mr
->rdFunction
= META_SELECTOBJECT
;
1011 if ((index
= MF_AddHandleDC( dc
)) == -1) return FALSE
;
1012 *(mr
->rdParam
) = index
;
1013 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1017 /******************************************************************
1018 * MF_CreatePenIndirect
1021 BOOL32
MF_CreatePenIndirect(DC
*dc
, HPEN16 hPen
, LOGPEN16
*logpen
)
1024 char buffer
[sizeof(METARECORD
) - 2 + sizeof(*logpen
)];
1025 METARECORD
*mr
= (METARECORD
*)&buffer
;
1027 mr
->rdSize
= (sizeof(METARECORD
) + sizeof(*logpen
) - 2) / 2;
1028 mr
->rdFunction
= META_CREATEPENINDIRECT
;
1029 memcpy(&(mr
->rdParam
), logpen
, sizeof(*logpen
));
1030 if (!(MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2))) return FALSE
;
1032 mr
->rdSize
= sizeof(METARECORD
) / 2;
1033 mr
->rdFunction
= META_SELECTOBJECT
;
1035 if ((index
= MF_AddHandleDC( dc
)) == -1) return FALSE
;
1036 *(mr
->rdParam
) = index
;
1037 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1041 /******************************************************************
1042 * MF_CreateFontIndirect
1045 BOOL32
MF_CreateFontIndirect(DC
*dc
, HFONT16 hFont
, LOGFONT16
*logfont
)
1048 char buffer
[sizeof(METARECORD
) - 2 + sizeof(LOGFONT16
)];
1049 METARECORD
*mr
= (METARECORD
*)&buffer
;
1051 mr
->rdSize
= (sizeof(METARECORD
) + sizeof(LOGFONT16
) - 2) / 2;
1052 mr
->rdFunction
= META_CREATEFONTINDIRECT
;
1053 memcpy(&(mr
->rdParam
), logfont
, sizeof(LOGFONT16
));
1054 if (!(MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2))) return FALSE
;
1056 mr
->rdSize
= sizeof(METARECORD
) / 2;
1057 mr
->rdFunction
= META_SELECTOBJECT
;
1059 if ((index
= MF_AddHandleDC( dc
)) == -1) return FALSE
;
1060 *(mr
->rdParam
) = index
;
1061 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1065 /******************************************************************
1068 BOOL32
MF_TextOut(DC
*dc
, short x
, short y
, LPCSTR str
, short count
)
1075 len
= sizeof(METARECORD
) + (((count
+ 1) >> 1) * 2) + 4;
1076 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1078 mr
= (METARECORD
*)GlobalLock16(hmr
);
1081 mr
->rdSize
= len
/ 2;
1082 mr
->rdFunction
= META_TEXTOUT
;
1083 *(mr
->rdParam
) = count
;
1084 memcpy(mr
->rdParam
+ 1, str
, count
);
1085 *(mr
->rdParam
+ ((count
+ 1) >> 1) + 1) = y
;
1086 *(mr
->rdParam
+ ((count
+ 1) >> 1) + 2) = x
;
1087 ret
= MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1092 /******************************************************************
1095 BOOL32
MF_ExtTextOut(DC
*dc
, short x
, short y
, UINT16 flags
, const RECT16
*rect
,
1096 LPCSTR str
, short count
, const INT16
*lpDx
)
1103 len
= sizeof(METARECORD
) + (((count
+ 1) >> 1) * 2) + 2 * sizeof(short)
1104 + sizeof(UINT16
) + sizeof(RECT16
);
1106 len
+=count
*sizeof(INT16
);
1107 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1109 mr
= (METARECORD
*)GlobalLock16(hmr
);
1112 mr
->rdSize
= len
/ 2;
1113 mr
->rdFunction
= META_EXTTEXTOUT
;
1115 *(mr
->rdParam
+ 1) = x
;
1116 *(mr
->rdParam
+ 2) = count
;
1117 *(mr
->rdParam
+ 3) = flags
;
1118 if (rect
) memcpy(mr
->rdParam
+ 4, rect
, sizeof(RECT16
));
1119 memcpy(mr
->rdParam
+ 8, str
, count
);
1121 memcpy(mr
->rdParam
+ 8+ ((count
+ 1) >> 1),lpDx
,count
*sizeof(INT16
));
1122 ret
= MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1127 /******************************************************************
1128 * MF_MetaPoly - implements Polygon and Polyline
1130 BOOL32
MF_MetaPoly(DC
*dc
, short func
, LPPOINT16 pt
, short count
)
1137 len
= sizeof(METARECORD
) + (count
* 4);
1138 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1140 mr
= (METARECORD
*)GlobalLock16(hmr
);
1143 mr
->rdSize
= len
/ 2;
1144 mr
->rdFunction
= func
;
1145 *(mr
->rdParam
) = count
;
1146 memcpy(mr
->rdParam
+ 1, pt
, count
* 4);
1147 ret
= MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1153 /******************************************************************
1156 BOOL32
MF_BitBlt(DC
*dcDest
, short xDest
, short yDest
, short width
,
1157 short height
, DC
*dcSrc
, short xSrc
, short ySrc
, DWORD rop
)
1165 GetObject16(dcSrc
->w
.hBitmap
, sizeof(BITMAP16
), &BM
);
1166 len
= sizeof(METARECORD
) + 12 * sizeof(INT16
) + BM
.bmWidthBytes
* BM
.bmHeight
;
1167 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1169 mr
= (METARECORD
*)GlobalLock16(hmr
);
1170 mr
->rdFunction
= META_BITBLT
;
1171 *(mr
->rdParam
+ 7) = BM
.bmWidth
;
1172 *(mr
->rdParam
+ 8) = BM
.bmHeight
;
1173 *(mr
->rdParam
+ 9) = BM
.bmWidthBytes
;
1174 *(mr
->rdParam
+10) = BM
.bmPlanes
;
1175 *(mr
->rdParam
+11) = BM
.bmBitsPixel
;
1176 dprintf_metafile(stddeb
,"MF_StretchBlt->len = %ld rop=%lx \n",len
,rop
);
1177 if (GetBitmapBits(dcSrc
->w
.hBitmap
,BM
.bmWidthBytes
* BM
.bmHeight
,mr
->rdParam
+12))
1179 mr
->rdSize
= len
/ sizeof(INT16
);
1180 *(mr
->rdParam
) = HIWORD(rop
);
1181 *(mr
->rdParam
+ 1) = ySrc
;
1182 *(mr
->rdParam
+ 2) = xSrc
;
1183 *(mr
->rdParam
+ 3) = height
;
1184 *(mr
->rdParam
+ 4) = width
;
1185 *(mr
->rdParam
+ 5) = yDest
;
1186 *(mr
->rdParam
+ 6) = xDest
;
1187 ret
= MF_WriteRecord( dcDest
, mr
, mr
->rdSize
* 2);
1196 /**********************************************************************
1198 * this function contains TWO ways for procesing StretchBlt in metafiles,
1199 * decide between rdFunction values META_STRETCHBLT or META_DIBSTRETCHBLT
1200 * via #define STRETCH_VIA_DIB
1202 #define STRETCH_VIA_DIB
1203 #undef STRETCH_VIA_DIB
1204 BOOL32
MF_StretchBlt(DC
*dcDest
, short xDest
, short yDest
, short widthDest
,
1205 short heightDest
, DC
*dcSrc
, short xSrc
, short ySrc
,
1206 short widthSrc
, short heightSrc
, DWORD rop
)
1213 #ifdef STRETCH_VIA_DIB
1214 LPBITMAPINFOHEADER lpBMI
;
1217 GetObject16(dcSrc
->w
.hBitmap
, sizeof(BITMAP16
), &BM
);
1218 #ifdef STRETCH_VIA_DIB
1219 nBPP
= BM
.bmPlanes
* BM
.bmBitsPixel
;
1220 len
= sizeof(METARECORD
) + 10 * sizeof(INT16
)
1221 + sizeof(BITMAPINFOHEADER
) + (nBPP
!= 24 ? 1 << nBPP
: 0) * sizeof(RGBQUAD
)
1222 + ((BM
.bmWidth
* nBPP
+ 31) / 32) * 4 * BM
.bmHeight
;
1223 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1225 mr
= (METARECORD
*)GlobalLock16(hmr
);
1226 mr
->rdFunction
= META_DIBSTRETCHBLT
;
1227 lpBMI
=(LPBITMAPINFOHEADER
)(mr
->rdParam
+10);
1228 lpBMI
->biSize
= sizeof(BITMAPINFOHEADER
);
1229 lpBMI
->biWidth
= BM
.bmWidth
;
1230 lpBMI
->biHeight
= BM
.bmHeight
;
1231 lpBMI
->biPlanes
= 1;
1232 lpBMI
->biBitCount
= nBPP
; /* 1,4,8 or 24 */
1233 lpBMI
->biClrUsed
= nBPP
!= 24 ? 1 << nBPP
: 0;
1234 lpBMI
->biSizeImage
= ((lpBMI
->biWidth
* nBPP
+ 31) / 32) * 4 * lpBMI
->biHeight
;
1235 lpBMI
->biCompression
= BI_RGB
;
1236 lpBMI
->biXPelsPerMeter
= MulDiv32(GetDeviceCaps(dcSrc
->hSelf
,LOGPIXELSX
),3937,100);
1237 lpBMI
->biYPelsPerMeter
= MulDiv32(GetDeviceCaps(dcSrc
->hSelf
,LOGPIXELSY
),3937,100);
1238 lpBMI
->biClrImportant
= 0; /* 1 meter = 39.37 inch */
1240 dprintf_metafile(stddeb
,"MF_StretchBltViaDIB->len = %ld rop=%lx PixYPM=%ld Caps=%d\n",
1241 len
,rop
,lpBMI
->biYPelsPerMeter
,GetDeviceCaps(hdcSrc
,LOGPIXELSY
));
1242 if (GetDIBits(hdcSrc
,dcSrc
->w
.hBitmap
,0,(UINT
)lpBMI
->biHeight
,
1243 (LPSTR
)lpBMI
+ DIB_BitmapInfoSize( (BITMAPINFO
*)lpBMI
,
1245 (LPBITMAPINFO
)lpBMI
, DIB_RGB_COLORS
))
1247 len
= sizeof(METARECORD
) + 15 * sizeof(INT16
) + BM
.bmWidthBytes
* BM
.bmHeight
;
1248 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1250 mr
= (METARECORD
*)GlobalLock16(hmr
);
1251 mr
->rdFunction
= META_STRETCHBLT
;
1252 *(mr
->rdParam
+10) = BM
.bmWidth
;
1253 *(mr
->rdParam
+11) = BM
.bmHeight
;
1254 *(mr
->rdParam
+12) = BM
.bmWidthBytes
;
1255 *(mr
->rdParam
+13) = BM
.bmPlanes
;
1256 *(mr
->rdParam
+14) = BM
.bmBitsPixel
;
1257 dprintf_metafile(stddeb
,"MF_StretchBlt->len = %ld rop=%lx \n",len
,rop
);
1258 if (GetBitmapBits(dcSrc
->w
.hBitmap
,BM
.bmWidthBytes
* BM
.bmHeight
,mr
->rdParam
+15))
1261 mr
->rdSize
= len
/ sizeof(INT16
);
1262 *(mr
->rdParam
) = LOWORD(rop
);
1263 *(mr
->rdParam
+ 1) = HIWORD(rop
);
1264 *(mr
->rdParam
+ 2) = heightSrc
;
1265 *(mr
->rdParam
+ 3) = widthSrc
;
1266 *(mr
->rdParam
+ 4) = ySrc
;
1267 *(mr
->rdParam
+ 5) = xSrc
;
1268 *(mr
->rdParam
+ 6) = heightDest
;
1269 *(mr
->rdParam
+ 7) = widthDest
;
1270 *(mr
->rdParam
+ 8) = yDest
;
1271 *(mr
->rdParam
+ 9) = xDest
;
1272 ret
= MF_WriteRecord( dcDest
, mr
, mr
->rdSize
* 2);