4 * Copyright David W. Metcalfe, 1994
7 static char Copyright
[] = "Copyright David W. Metcalfe, 1994";
12 #include "prototypes.h"
14 #define DEBUG_METAFILE
16 #define HTINCR 10 /* handle table allocation size increment */
18 static HANDLE hHT
; /* handle of the handle table */
19 static int HTLen
; /* allocated length of handle table */
21 /******************************************************************
22 * CreateMetafile GDI.125
24 HANDLE
CreateMetaFile(LPSTR lpFilename
)
33 printf("CreateMetaFile: %s\n", lpFilename
);
36 handle
= GDI_AllocObject(sizeof(DC
), METAFILE_DC_MAGIC
);
37 if (!handle
) return 0;
38 dc
= (DC
*)GDI_HEAP_ADDR(handle
);
40 if (!(dc
->w
.hMetaFile
= GlobalAlloc(GMEM_MOVEABLE
, sizeof(METAFILE
))))
42 mf
= (METAFILE
*)GlobalLock(dc
->w
.hMetaFile
);
43 if (!(mf
->hMetaHdr
= GlobalAlloc(GMEM_MOVEABLE
, sizeof(METAHEADER
))))
45 GlobalFree(dc
->w
.hMetaFile
);
48 mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
50 mf
->wMagic
= METAFILE_MAGIC
;
51 mh
->mtHeaderSize
= MFHEADERSIZE
/ 2;
52 mh
->mtVersion
= MFVERSION
;
53 mh
->mtSize
= MFHEADERSIZE
/ 2;
56 mh
->mtNoParameters
= 0;
58 if (lpFilename
) /* disk based metafile */
61 strcpy(mf
->Filename
, lpFilename
);
62 mf
->hFile
= _lcreat(lpFilename
, 0);
63 if (_lwrite(mf
->hFile
, (char *)mh
, MFHEADERSIZE
) == -1)
65 GlobalFree(mf
->hMetaHdr
);
66 GlobalFree(dc
->w
.hMetaFile
);
70 else /* memory based metafile */
73 /* create the handle table */
75 hHT
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_ZEROINIT
,
76 sizeof(HANDLETABLE
) * HTLen
);
77 ht
= (HANDLETABLE
*)GlobalLock(hHT
);
79 GlobalUnlock(mf
->hMetaHdr
);
80 GlobalUnlock(dc
->w
.hMetaFile
);
85 /******************************************************************
86 * CloseMetafile GDI.126
88 HMETAFILE
CloseMetaFile(HDC hdc
)
95 METARECORD
*mr
= (METARECORD
*)&buffer
;
98 printf("CloseMetaFile\n");
101 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
103 mf
= (METAFILE
*)GlobalLock(dc
->w
.hMetaFile
);
104 mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
106 /* Construct the end of metafile record - this is documented
107 * in SDK Knowledgebase Q99334.
109 if (!MF_MetaParam0(dc
, META_EOF
))
111 GlobalFree(mf
->hMetaHdr
);
112 GlobalFree(dc
->w
.hMetaFile
);
116 if (mh
->mtType
== 1) /* disk based metafile */
118 if (_llseek(mf
->hFile
, 0L, 0) == -1)
120 GlobalFree(mf
->hMetaHdr
);
121 GlobalFree(dc
->w
.hMetaFile
);
124 if (_lwrite(mf
->hFile
, (char *)mh
, MFHEADERSIZE
) == -1)
126 GlobalFree(mf
->hMetaHdr
);
127 GlobalFree(dc
->w
.hMetaFile
);
133 /* delete the handle table */
136 GlobalUnlock(mf
->hMetaHdr
);
137 hmf
= dc
->w
.hMetaFile
;
144 /******************************************************************
145 * DeleteMetafile GDI.127
147 BOOL
DeleteMetaFile(HMETAFILE hmf
)
149 METAFILE
*mf
= (METAFILE
*)GlobalLock(hmf
);
151 if (mf
->wMagic
!= METAFILE_MAGIC
)
154 GlobalFree(mf
->hMetaHdr
);
160 /******************************************************************
161 * PlayMetafile GDI.123
163 BOOL
PlayMetaFile(HDC hdc
, HMETAFILE hmf
)
165 METAFILE
*mf
= (METAFILE
*)GlobalLock(hmf
);
171 if (mf
->wMagic
!= METAFILE_MAGIC
)
174 mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
175 if (mh
->mtType
== 1) /* disk based metafile */
177 mf
->hFile
= _lopen(mf
->Filename
, OF_READ
);
178 mf
->hBuffer
= GlobalAlloc(GMEM_MOVEABLE
, mh
->mtMaxRecord
* 2);
179 buffer
= (char *)GlobalLock(mf
->hBuffer
);
180 _llseek(mf
->hFile
, mh
->mtHeaderSize
* 2, 0);
181 mf
->MetaOffset
= mh
->mtHeaderSize
* 2;
183 else if (mh
->mtType
== 0) /* memory based metafile */
184 mf
->MetaOffset
= mh
->mtHeaderSize
* 2;
185 else /* not a valid metafile type */
188 /* create the handle table */
189 hHT
= GlobalAlloc(GMEM_MOVEABLE
, sizeof(HANDLETABLE
) * mh
->mtNoObjects
);
190 ht
= (HANDLETABLE
*)GlobalLock(hHT
);
192 /* loop through metafile playing records */
193 while (mf
->MetaOffset
< mh
->mtSize
* 2)
195 if (mh
->mtType
== 1) /* disk based metafile */
197 _lread(mf
->hFile
, buffer
, sizeof(METARECORD
));
198 mr
= (METARECORD
*)&buffer
;
199 _lread(mf
->hFile
, (char *)(mr
->rdParam
+ 1), (mr
->rdSize
* 2) -
201 mf
->MetaOffset
+= mr
->rdSize
* 2;
203 else /* memory based metafile */
205 mr
= (METARECORD
*)((char *)mh
+ mf
->MetaOffset
);
206 mf
->MetaOffset
+= mr
->rdSize
* 2;
208 PlayMetaFileRecord(hdc
, ht
, mr
, mh
->mtNoObjects
);
211 /* close disk based metafile and free buffer */
214 GlobalFree(mf
->hBuffer
);
218 /* free handle table */
225 /******************************************************************
226 * PlayMetaFileRecord GDI.176
228 void PlayMetaFileRecord(HDC hdc
, HANDLETABLE
*ht
, METARECORD
*mr
,
234 BITMAPINFOHEADER
*infohdr
;
236 switch (mr
->rdFunction
)
238 case META_SETBKCOLOR
:
239 SetBkColor(hdc
, *(mr
->rdParam
));
243 SetBkMode(hdc
, *(mr
->rdParam
));
246 case META_SETMAPMODE
:
247 SetMapMode(hdc
, *(mr
->rdParam
));
251 SetROP2(hdc
, *(mr
->rdParam
));
255 SetRelAbs(hdc
, *(mr
->rdParam
));
258 case META_SETPOLYFILLMODE
:
259 SetPolyFillMode(hdc
, *(mr
->rdParam
));
262 case META_SETSTRETCHBLTMODE
:
263 SetStretchBltMode(hdc
, *(mr
->rdParam
));
266 case META_SETTEXTCOLOR
:
267 SetTextColor(hdc
, MAKELONG(*(mr
->rdParam
), *(mr
->rdParam
+ 1)));
270 case META_SETWINDOWORG
:
271 SetWindowOrg(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
274 case META_SETWINDOWEXT
:
275 SetWindowExt(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
278 case META_SETVIEWPORTORG
:
279 SetViewportOrg(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
282 case META_SETVIEWPORTEXT
:
283 SetViewportExt(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
286 case META_OFFSETWINDOWORG
:
287 OffsetWindowOrg(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
290 case META_SCALEWINDOWEXT
:
291 ScaleWindowExt(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
292 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
295 case META_OFFSETVIEWPORTORG
:
296 OffsetViewportOrg(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
299 case META_SCALEVIEWPORTEXT
:
300 ScaleViewportExt(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
301 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
305 LineTo(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
309 MoveTo(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
312 case META_EXCLUDECLIPRECT
:
313 ExcludeClipRect(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
314 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
317 case META_INTERSECTCLIPRECT
:
318 IntersectClipRect(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
319 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
323 Arc(hdc
, *(mr
->rdParam
+ 7), *(mr
->rdParam
+ 6), *(mr
->rdParam
+ 5),
324 *(mr
->rdParam
+ 4), *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
325 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
329 Ellipse(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
330 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
334 FloodFill(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
335 MAKELONG(*(mr
->rdParam
+ 1), *(mr
->rdParam
)));
339 Pie(hdc
, *(mr
->rdParam
+ 7), *(mr
->rdParam
+ 6), *(mr
->rdParam
+ 5),
340 *(mr
->rdParam
+ 4), *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
341 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
345 Ellipse(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
346 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
350 RoundRect(hdc
, *(mr
->rdParam
+ 5), *(mr
->rdParam
+ 4),
351 *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
352 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
356 PatBlt(hdc
, *(mr
->rdParam
+ 5), *(mr
->rdParam
+ 4),
357 *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
358 MAKELONG(*(mr
->rdParam
), *(mr
->rdParam
+ 1)));
366 SetPixel(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
367 MAKELONG(*(mr
->rdParam
+ 1), *(mr
->rdParam
)));
370 case META_OFFSETCLIPRGN
:
371 OffsetClipRgn(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
376 TextOut(hdc
, *(mr
->rdParam
+ ((s1
+ 1) >> 1) + 2),
377 *(mr
->rdParam
+ ((s1
+ 1) >> 1) + 1),
378 (char *)(mr
->rdParam
+ 1), s1
);
382 Polygon(hdc
, (LPPOINT
)(mr
->rdParam
+ 1), *(mr
->rdParam
));
386 Polyline(hdc
, (LPPOINT
)(mr
->rdParam
+ 1), *(mr
->rdParam
));
390 RestoreDC(hdc
, *(mr
->rdParam
));
393 case META_SELECTOBJECT
:
394 SelectObject(hdc
, *(ht
->objectHandle
+ *(mr
->rdParam
)));
398 Chord(hdc
, *(mr
->rdParam
+ 7), *(mr
->rdParam
+ 6), *(mr
->rdParam
+ 5),
399 *(mr
->rdParam
+ 4), *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
400 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
403 case META_CREATEPATTERNBRUSH
:
404 switch (*(mr
->rdParam
))
407 infohdr
= (BITMAPINFOHEADER
*)(mr
->rdParam
+ 2);
408 MF_AddHandle(ht
, nHandles
,
409 CreatePatternBrush(CreateBitmap(infohdr
->biWidth
,
413 (LPSTR
)(mr
->rdParam
+
414 (sizeof(BITMAPINFOHEADER
) / 2) + 4))));
418 s1
= mr
->rdSize
* 2 - sizeof(METARECORD
) - 2;
419 hndl
= GlobalAlloc(GMEM_MOVEABLE
, s1
);
420 ptr
= GlobalLock(hndl
);
421 memcpy(ptr
, mr
->rdParam
+ 2, s1
);
423 MF_AddHandle(ht
, nHandles
,
424 CreateDIBPatternBrush(hndl
, *(mr
->rdParam
+ 1)));
429 case META_CREATEPENINDIRECT
:
430 MF_AddHandle(ht
, nHandles
,
431 CreatePenIndirect((LOGPEN
*)(&(mr
->rdParam
))));
434 case META_CREATEFONTINDIRECT
:
435 MF_AddHandle(ht
, nHandles
,
436 CreateFontIndirect((LOGFONT
*)(&(mr
->rdParam
))));
439 case META_CREATEBRUSHINDIRECT
:
440 MF_AddHandle(ht
, nHandles
,
441 CreateBrushIndirect((LOGBRUSH
*)(&(mr
->rdParam
))));
445 printf("PlayMetaFileRecord: Unknown record type %x\n",
451 /******************************************************************
454 BOOL
MF_WriteRecord(HMETAFILE hmf
, METARECORD
*mr
, WORD rlen
)
457 METAFILE
*mf
= (METAFILE
*)GlobalLock(hmf
);
458 METAHEADER
*mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
460 if (mh
->mtType
== 0) /* memory based metafile */
462 len
= mh
->mtSize
* 2 + rlen
;
463 GlobalUnlock(mf
->hMetaHdr
);
464 mf
->hMetaHdr
= GlobalReAlloc(mf
->hMetaHdr
, len
, GMEM_MOVEABLE
);
465 mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
466 memcpy(mh
+ mh
->mtSize
* 2, mr
, rlen
);
468 else if (mh
->mtType
== 1) /* disk based metafile */
470 if (_lwrite(mf
->hFile
, (char *)mr
, rlen
) == -1)
472 GlobalUnlock(mf
->hMetaHdr
);
478 GlobalUnlock(mf
->hMetaHdr
);
482 mh
->mtSize
+= rlen
/ 2;
483 mh
->mtMaxRecord
= max(mh
->mtMaxRecord
, rlen
/ 2);
484 GlobalUnlock(mf
->hMetaHdr
);
489 /******************************************************************
492 * Add a handle to an external handle table and return the index
494 int MF_AddHandle(HANDLETABLE
*ht
, WORD htlen
, HANDLE hobj
)
498 for (i
= 0; i
< htlen
; i
++)
500 if (*(ht
->objectHandle
+ i
) == 0)
502 *(ht
->objectHandle
+ i
) = hobj
;
510 /******************************************************************
511 * MF_AddHandleInternal
513 * Add a handle to the internal handle table and return the index
515 int MF_AddHandleInternal(HANDLE hobj
)
518 HANDLETABLE
*ht
= (HANDLETABLE
*)GlobalLock(hHT
);
520 for (i
= 0; i
< HTLen
; i
++)
522 if (*(ht
->objectHandle
+ i
) == 0)
524 *(ht
->objectHandle
+ i
) = hobj
;
530 if (!(hHT
= GlobalReAlloc(hHT
, HTINCR
, GMEM_MOVEABLE
| GMEM_ZEROINIT
)))
533 ht
= (HANDLETABLE
*)GlobalLock(hHT
);
534 *(ht
->objectHandle
+ i
) = hobj
;
540 /******************************************************************
543 BOOL
MF_MetaParam0(DC
*dc
, short func
)
546 METARECORD
*mr
= (METARECORD
*)&buffer
;
549 mr
->rdFunction
= func
;
550 return MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
554 /******************************************************************
557 BOOL
MF_MetaParam1(DC
*dc
, short func
, short param1
)
560 METARECORD
*mr
= (METARECORD
*)&buffer
;
563 mr
->rdFunction
= func
;
564 *(mr
->rdParam
) = param1
;
565 return MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
569 /******************************************************************
572 BOOL
MF_MetaParam2(DC
*dc
, short func
, short param1
, short param2
)
575 METARECORD
*mr
= (METARECORD
*)&buffer
;
578 mr
->rdFunction
= func
;
579 *(mr
->rdParam
) = param2
;
580 *(mr
->rdParam
+ 1) = param1
;
581 return MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
585 /******************************************************************
588 BOOL
MF_MetaParam4(DC
*dc
, short func
, short param1
, short param2
,
589 short param3
, short param4
)
592 METARECORD
*mr
= (METARECORD
*)&buffer
;
595 mr
->rdFunction
= func
;
596 *(mr
->rdParam
) = param4
;
597 *(mr
->rdParam
+ 1) = param3
;
598 *(mr
->rdParam
+ 2) = param2
;
599 *(mr
->rdParam
+ 3) = param1
;
600 return MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
604 /******************************************************************
607 BOOL
MF_MetaParam6(DC
*dc
, short func
, short param1
, short param2
,
608 short param3
, short param4
, short param5
, short param6
)
611 METARECORD
*mr
= (METARECORD
*)&buffer
;
614 mr
->rdFunction
= func
;
615 *(mr
->rdParam
) = param6
;
616 *(mr
->rdParam
+ 1) = param5
;
617 *(mr
->rdParam
+ 2) = param4
;
618 *(mr
->rdParam
+ 3) = param3
;
619 *(mr
->rdParam
+ 4) = param2
;
620 *(mr
->rdParam
+ 5) = param1
;
621 return MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
625 /******************************************************************
628 BOOL
MF_MetaParam8(DC
*dc
, short func
, short param1
, short param2
,
629 short param3
, short param4
, short param5
,
630 short param6
, short param7
, short param8
)
633 METARECORD
*mr
= (METARECORD
*)&buffer
;
636 mr
->rdFunction
= func
;
637 *(mr
->rdParam
) = param8
;
638 *(mr
->rdParam
+ 1) = param7
;
639 *(mr
->rdParam
+ 2) = param6
;
640 *(mr
->rdParam
+ 3) = param5
;
641 *(mr
->rdParam
+ 4) = param4
;
642 *(mr
->rdParam
+ 5) = param3
;
643 *(mr
->rdParam
+ 6) = param2
;
644 *(mr
->rdParam
+ 7) = param1
;
645 return MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
649 /******************************************************************
650 * MF_CreateBrushIndirect
652 BOOL
MF_CreateBrushIndirect(DC
*dc
, HBRUSH hBrush
, LOGBRUSH
*logbrush
)
656 char buffer
[sizeof(METARECORD
) - 2 + sizeof(LOGBRUSH
)];
657 METARECORD
*mr
= (METARECORD
*)&buffer
;
661 mr
->rdSize
= (sizeof(METARECORD
) + sizeof(LOGBRUSH
) - 2) / 2;
662 mr
->rdFunction
= META_CREATEBRUSHINDIRECT
;
663 memcpy(&(mr
->rdParam
), logbrush
, sizeof(LOGBRUSH
));
664 if (!MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2))
667 mr
->rdSize
= sizeof(METARECORD
) / 2;
668 mr
->rdFunction
= META_SELECTOBJECT
;
669 if ((index
= MF_AddHandleInternal(hBrush
)) == -1)
672 mf
= (METAFILE
*)GlobalLock(dc
->w
.hMetaFile
);
673 mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
674 *(mr
->rdParam
) = index
;
675 if (index
>= mh
->mtNoObjects
)
677 rc
= MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
678 GlobalUnlock(mf
->hMetaHdr
);
679 GlobalUnlock(dc
->w
.hMetaFile
);
684 /******************************************************************
685 * MF_CreatePatternBrush
687 BOOL
MF_CreatePatternBrush(DC
*dc
, HBRUSH hBrush
, LOGBRUSH
*logbrush
)
689 DWORD len
, bmSize
, biSize
;
694 BITMAPINFOHEADER
*infohdr
;
697 char buffer
[sizeof(METARECORD
)];
701 switch (logbrush
->lbStyle
)
704 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr(logbrush
->lbHatch
, BITMAP_MAGIC
);
705 if (!bmp
) return FALSE
;
706 len
= sizeof(METARECORD
) + sizeof(BITMAPINFOHEADER
) +
707 (bmp
->bitmap
.bmHeight
* bmp
->bitmap
.bmWidthBytes
) + 6;
708 if (!(hmr
= GlobalAlloc(GMEM_MOVEABLE
, len
)))
710 mr
= (METARECORD
*)GlobalLock(hmr
);
712 mr
->rdFunction
= META_DIBCREATEPATTERNBRUSH
;
713 mr
->rdSize
= len
/ 2;
714 *(mr
->rdParam
) = logbrush
->lbStyle
;
715 *(mr
->rdParam
+ 1) = DIB_RGB_COLORS
;
716 infohdr
= (BITMAPINFOHEADER
*)(mr
->rdParam
+ 2);
717 infohdr
->biSize
= sizeof(BITMAPINFOHEADER
);
718 infohdr
->biWidth
= bmp
->bitmap
.bmWidth
;
719 infohdr
->biHeight
= bmp
->bitmap
.bmHeight
;
720 infohdr
->biPlanes
= bmp
->bitmap
.bmPlanes
;
721 infohdr
->biBitCount
= bmp
->bitmap
.bmBitsPixel
;
722 memcpy(mr
->rdParam
+ (sizeof(BITMAPINFOHEADER
) / 2) + 4,
724 bmp
->bitmap
.bmHeight
* bmp
->bitmap
.bmWidthBytes
);
728 info
= (BITMAPINFO
*)GlobalLock(logbrush
->lbHatch
);
729 bmSize
= info
->bmiHeader
.biSizeImage
;
731 bmSize
= (info
->bmiHeader
.biWidth
* info
->bmiHeader
.biBitCount
732 + 31) / 32 * 8 * info
->bmiHeader
.biHeight
;
733 biSize
= DIB_BitmapInfoSize(info
, LOWORD(logbrush
->lbColor
));
734 len
= sizeof(METARECORD
) + biSize
+ bmSize
+ 2;
735 if (!(hmr
= GlobalAlloc(GMEM_MOVEABLE
, len
)))
737 mr
= (METARECORD
*)GlobalLock(hmr
);
739 mr
->rdFunction
= META_DIBCREATEPATTERNBRUSH
;
740 mr
->rdSize
= len
/ 2;
741 *(mr
->rdParam
) = logbrush
->lbStyle
;
742 *(mr
->rdParam
+ 1) = LOWORD(logbrush
->lbColor
);
743 memcpy(mr
->rdParam
+ 2, info
, biSize
+ bmSize
);
746 if (!MF_WriteRecord(dc
->w
.hMetaFile
, mr
, len
))
753 mr
= (METARECORD
*)&buffer
;
754 mr
->rdSize
= sizeof(METARECORD
) / 2;
755 mr
->rdFunction
= META_SELECTOBJECT
;
756 if ((index
= MF_AddHandleInternal(hBrush
)) == -1)
759 mf
= (METAFILE
*)GlobalLock(dc
->w
.hMetaFile
);
760 mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
761 *(mr
->rdParam
) = index
;
762 if (index
>= mh
->mtNoObjects
)
764 rc
= MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
765 GlobalUnlock(mf
->hMetaHdr
);
766 GlobalUnlock(dc
->w
.hMetaFile
);
771 /******************************************************************
772 * MF_CreatePenIndirect
774 BOOL
MF_CreatePenIndirect(DC
*dc
, HPEN hPen
, LOGPEN
*logpen
)
778 char buffer
[sizeof(METARECORD
) - 2 + sizeof(LOGPEN
)];
779 METARECORD
*mr
= (METARECORD
*)&buffer
;
783 mr
->rdSize
= (sizeof(METARECORD
) + sizeof(LOGPEN
) - 2) / 2;
784 mr
->rdFunction
= META_CREATEPENINDIRECT
;
785 memcpy(&(mr
->rdParam
), logpen
, sizeof(LOGPEN
));
786 if (!MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2))
789 mr
->rdSize
= sizeof(METARECORD
) / 2;
790 mr
->rdFunction
= META_SELECTOBJECT
;
791 if ((index
= MF_AddHandleInternal(hPen
)) == -1)
794 mf
= (METAFILE
*)GlobalLock(dc
->w
.hMetaFile
);
795 mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
796 *(mr
->rdParam
) = index
;
797 if (index
>= mh
->mtNoObjects
)
799 rc
= MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
800 GlobalUnlock(mf
->hMetaHdr
);
801 GlobalUnlock(dc
->w
.hMetaFile
);
806 /******************************************************************
807 * MF_CreateFontIndirect
809 BOOL
MF_CreateFontIndirect(DC
*dc
, HFONT hFont
, LOGFONT
*logfont
)
813 char buffer
[sizeof(METARECORD
) - 2 + sizeof(LOGFONT
)];
814 METARECORD
*mr
= (METARECORD
*)&buffer
;
818 mr
->rdSize
= (sizeof(METARECORD
) + sizeof(LOGFONT
) - 2) / 2;
819 mr
->rdFunction
= META_CREATEFONTINDIRECT
;
820 memcpy(&(mr
->rdParam
), logfont
, sizeof(LOGFONT
));
821 if (!MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2))
824 mr
->rdSize
= sizeof(METARECORD
) / 2;
825 mr
->rdFunction
= META_SELECTOBJECT
;
826 if ((index
= MF_AddHandleInternal(hFont
)) == -1)
829 mf
= (METAFILE
*)GlobalLock(dc
->w
.hMetaFile
);
830 mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
831 *(mr
->rdParam
) = index
;
832 if (index
>= mh
->mtNoObjects
)
834 rc
= MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
835 GlobalUnlock(mf
->hMetaHdr
);
836 GlobalUnlock(dc
->w
.hMetaFile
);
841 /******************************************************************
844 BOOL
MF_TextOut(DC
*dc
, short x
, short y
, LPSTR str
, short count
)
851 len
= sizeof(METARECORD
) + (((count
+ 1) >> 1) * 2) + 4;
852 if (!(hmr
= GlobalAlloc(GMEM_MOVEABLE
, len
)))
854 mr
= (METARECORD
*)GlobalLock(hmr
);
857 mr
->rdSize
= len
/ 2;
858 mr
->rdFunction
= META_TEXTOUT
;
859 *(mr
->rdParam
) = count
;
860 memcpy(mr
->rdParam
+ 1, str
, count
);
861 *(mr
->rdParam
+ ((count
+ 1) >> 1) + 1) = y
;
862 *(mr
->rdParam
+ ((count
+ 1) >> 1) + 2) = x
;
863 rc
= MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
869 /******************************************************************
870 * MF_MetaPoly - implements Polygon and Polyline
872 BOOL
MF_MetaPoly(DC
*dc
, short func
, LPPOINT pt
, short count
)
879 len
= sizeof(METARECORD
) + (count
* 4);
880 if (!(hmr
= GlobalAlloc(GMEM_MOVEABLE
, len
)))
882 mr
= (METARECORD
*)GlobalLock(hmr
);
885 mr
->rdSize
= len
/ 2;
886 mr
->rdFunction
= func
;
887 *(mr
->rdParam
) = count
;
888 memcpy(mr
->rdParam
+ 1, pt
, count
* 4);
889 rc
= MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
895 /******************************************************************
898 BOOL
MF_BitBlt(DC
*dcDest
, short xDest
, short yDest
, short width
,
899 short height
, HDC hdcSrc
, short xSrc
, short ySrc
, DWORD rop
)
901 printf("MF_BitBlt: not implemented yet\n");
905 /******************************************************************
908 BOOL
MF_StretchBlt(DC
*dcDest
, short xDest
, short yDest
, short widthDest
,
909 short heightDest
, HDC hdcSrc
, short xSrc
, short ySrc
,
910 short widthSrc
, short heightSrc
, DWORD rop
)
912 printf("MF_StretchBlt: not implemented yet\n");