4 * Copyright David W. Metcalfe, 1994
6 static char Copyright[] = "Copyright David W. Metcalfe, 1994";
14 /* #define DEBUG_METAFILE */
17 #define HTINCR 10 /* handle table allocation size increment */
19 static HANDLE hHT
; /* handle of the handle table */
20 static int HTLen
; /* allocated length of handle table */
22 /******************************************************************
23 * GetMetafile GDI.124 By Kenny MacDonald 30 Nov 94
25 HMETAFILE
GetMetaFile(LPSTR lpFilename
)
31 dprintf_metafile(stddeb
,"GetMetaFile: %s\n", lpFilename
);
36 hmf
= GlobalAlloc(GMEM_MOVEABLE
, sizeof(METAFILE
));
37 mf
= (METAFILE
*)GlobalLock(hmf
);
43 mf
->hMetaHdr
= GlobalAlloc(GMEM_MOVEABLE
, MFHEADERSIZE
);
44 mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
46 GlobalFree(mf
->hMetaHdr
);
50 strcpy(mf
->Filename
, lpFilename
);
51 mf
->wMagic
= METAFILE_MAGIC
;
52 if ((mf
->hFile
= _lopen(lpFilename
, OF_READ
)) == HFILE_ERROR
) {
56 if (_lread(mf
->hFile
, (char *)mh
, MFHEADERSIZE
) == HFILE_ERROR
) {
57 GlobalFree(mf
->hMetaHdr
);
64 GlobalUnlock(mf
->hMetaHdr
);
72 /******************************************************************
73 * CreateMetafile GDI.125
75 HANDLE
CreateMetaFile(LPSTR lpFilename
)
83 dprintf_metafile(stddeb
,"CreateMetaFile: %s\n", lpFilename
);
85 handle
= GDI_AllocObject(sizeof(DC
), METAFILE_DC_MAGIC
);
86 if (!handle
) return 0;
87 dc
= (DC
*)GDI_HEAP_ADDR(handle
);
89 if (!(dc
->w
.hMetaFile
= GlobalAlloc(GMEM_MOVEABLE
, sizeof(METAFILE
))))
91 mf
= (METAFILE
*)GlobalLock(dc
->w
.hMetaFile
);
92 if (!(mf
->hMetaHdr
= GlobalAlloc(GMEM_MOVEABLE
, sizeof(METAHEADER
))))
94 GlobalFree(dc
->w
.hMetaFile
);
97 mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
99 mf
->wMagic
= METAFILE_MAGIC
;
100 mh
->mtHeaderSize
= MFHEADERSIZE
/ 2;
101 mh
->mtVersion
= MFVERSION
;
102 mh
->mtSize
= MFHEADERSIZE
/ 2;
105 mh
->mtNoParameters
= 0;
107 if (lpFilename
) /* disk based metafile */
110 strcpy(mf
->Filename
, lpFilename
);
111 mf
->hFile
= _lcreat(lpFilename
, 0);
112 if (_lwrite(mf
->hFile
, (char *)mh
, MFHEADERSIZE
) == -1)
114 GlobalFree(mf
->hMetaHdr
);
115 GlobalFree(dc
->w
.hMetaFile
);
119 else /* memory based metafile */
122 /* create the handle table */
124 hHT
= GlobalAlloc(GMEM_MOVEABLE
| GMEM_ZEROINIT
,
125 sizeof(HANDLETABLE
) * HTLen
);
126 ht
= (HANDLETABLE
*)GlobalLock(hHT
);
128 GlobalUnlock(mf
->hMetaHdr
);
129 GlobalUnlock(dc
->w
.hMetaFile
);
134 /******************************************************************
135 * CloseMetafile GDI.126
137 HMETAFILE
CloseMetaFile(HDC hdc
)
143 /* METARECORD *mr = (METARECORD *)&buffer;*/
145 dprintf_metafile(stddeb
,"CloseMetaFile\n");
147 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
149 mf
= (METAFILE
*)GlobalLock(dc
->w
.hMetaFile
);
150 mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
152 /* Construct the end of metafile record - this is documented
153 * in SDK Knowledgebase Q99334.
155 if (!MF_MetaParam0(dc
, META_EOF
))
157 GlobalFree(mf
->hMetaHdr
);
158 GlobalFree(dc
->w
.hMetaFile
);
162 if (mh
->mtType
== 1) /* disk based metafile */
164 if (_llseek(mf
->hFile
, 0L, 0) == -1)
166 GlobalFree(mf
->hMetaHdr
);
167 GlobalFree(dc
->w
.hMetaFile
);
170 if (_lwrite(mf
->hFile
, (char *)mh
, MFHEADERSIZE
) == -1)
172 GlobalFree(mf
->hMetaHdr
);
173 GlobalFree(dc
->w
.hMetaFile
);
179 /* delete the handle table */
182 GlobalUnlock(mf
->hMetaHdr
);
183 hmf
= dc
->w
.hMetaFile
;
190 /******************************************************************
191 * DeleteMetafile GDI.127
193 BOOL
DeleteMetaFile(HMETAFILE hmf
)
195 METAFILE
*mf
= (METAFILE
*)GlobalLock(hmf
);
197 if (mf
->wMagic
!= METAFILE_MAGIC
)
200 GlobalFree(mf
->hMetaHdr
);
206 /******************************************************************
207 * PlayMetafile GDI.123
209 BOOL
PlayMetaFile(HDC hdc
, HMETAFILE hmf
)
211 METAFILE
*mf
= (METAFILE
*)GlobalLock(hmf
);
217 if (mf
->wMagic
!= METAFILE_MAGIC
)
220 mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
221 if (mh
->mtType
== 1) /* disk based metafile */
223 mf
->hFile
= _lopen(mf
->Filename
, OF_READ
);
224 mf
->hBuffer
= GlobalAlloc(GMEM_MOVEABLE
, mh
->mtMaxRecord
* 2);
225 buffer
= (char *)GlobalLock(mf
->hBuffer
);
226 _llseek(mf
->hFile
, mh
->mtHeaderSize
* 2, 0);
227 mf
->MetaOffset
= mh
->mtHeaderSize
* 2;
229 else if (mh
->mtType
== 0) /* memory based metafile */
230 mf
->MetaOffset
= mh
->mtHeaderSize
* 2;
231 else /* not a valid metafile type */
234 /* create the handle table */
235 hHT
= GlobalAlloc(GMEM_MOVEABLE
, sizeof(HANDLETABLE
) * mh
->mtNoObjects
);
236 ht
= (HANDLETABLE
*)GlobalLock(hHT
);
238 /* loop through metafile playing records */
239 while (mf
->MetaOffset
< mh
->mtSize
* 2)
241 if (mh
->mtType
== 1) /* disk based metafile */
243 _lread(mf
->hFile
, buffer
, sizeof(METARECORD
));
244 mr
= (METARECORD
*)buffer
;
245 _lread(mf
->hFile
, (char *)(mr
->rdParam
+ 1), (mr
->rdSize
* 2) -
247 mf
->MetaOffset
+= mr
->rdSize
* 2;
249 else /* memory based metafile */
251 mr
= (METARECORD
*)((char *)mh
+ mf
->MetaOffset
);
252 mf
->MetaOffset
+= mr
->rdSize
* 2;
254 PlayMetaFileRecord(hdc
, ht
, mr
, mh
->mtNoObjects
);
257 /* close disk based metafile and free buffer */
260 GlobalFree(mf
->hBuffer
);
264 /* free handle table */
271 /******************************************************************
272 * PlayMetaFileRecord GDI.176
274 void PlayMetaFileRecord(HDC hdc
, HANDLETABLE
*ht
, METARECORD
*mr
,
280 BITMAPINFOHEADER
*infohdr
;
282 switch (mr
->rdFunction
)
287 case META_DELETEOBJECT
:
288 DeleteObject(*(ht
->objectHandle
+ *(mr
->rdParam
)));
291 case META_SETBKCOLOR
:
292 SetBkColor(hdc
, *(mr
->rdParam
));
296 SetBkMode(hdc
, *(mr
->rdParam
));
299 case META_SETMAPMODE
:
300 SetMapMode(hdc
, *(mr
->rdParam
));
304 SetROP2(hdc
, *(mr
->rdParam
));
308 SetRelAbs(hdc
, *(mr
->rdParam
));
311 case META_SETPOLYFILLMODE
:
312 SetPolyFillMode(hdc
, *(mr
->rdParam
));
315 case META_SETSTRETCHBLTMODE
:
316 SetStretchBltMode(hdc
, *(mr
->rdParam
));
319 case META_SETTEXTCOLOR
:
320 SetTextColor(hdc
, MAKELONG(*(mr
->rdParam
), *(mr
->rdParam
+ 1)));
323 case META_SETWINDOWORG
:
324 SetWindowOrg(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
327 case META_SETWINDOWEXT
:
328 SetWindowExt(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
331 case META_SETVIEWPORTORG
:
332 SetViewportOrg(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
335 case META_SETVIEWPORTEXT
:
336 SetViewportExt(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
339 case META_OFFSETWINDOWORG
:
340 OffsetWindowOrg(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
343 case META_SCALEWINDOWEXT
:
344 ScaleWindowExt(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
345 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
348 case META_OFFSETVIEWPORTORG
:
349 OffsetViewportOrg(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
352 case META_SCALEVIEWPORTEXT
:
353 ScaleViewportExt(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
354 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
358 LineTo(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
362 MoveTo(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
365 case META_EXCLUDECLIPRECT
:
366 ExcludeClipRect(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
367 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
370 case META_INTERSECTCLIPRECT
:
371 IntersectClipRect(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
372 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
376 Arc(hdc
, *(mr
->rdParam
+ 7), *(mr
->rdParam
+ 6), *(mr
->rdParam
+ 5),
377 *(mr
->rdParam
+ 4), *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
378 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
382 Ellipse(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
383 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
387 FloodFill(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
388 MAKELONG(*(mr
->rdParam
+ 1), *(mr
->rdParam
)));
392 Pie(hdc
, *(mr
->rdParam
+ 7), *(mr
->rdParam
+ 6), *(mr
->rdParam
+ 5),
393 *(mr
->rdParam
+ 4), *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
394 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
398 Ellipse(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
399 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
403 RoundRect(hdc
, *(mr
->rdParam
+ 5), *(mr
->rdParam
+ 4),
404 *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
405 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
409 PatBlt(hdc
, *(mr
->rdParam
+ 5), *(mr
->rdParam
+ 4),
410 *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
411 MAKELONG(*(mr
->rdParam
), *(mr
->rdParam
+ 1)));
419 SetPixel(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
420 MAKELONG(*(mr
->rdParam
+ 1), *(mr
->rdParam
)));
423 case META_OFFSETCLIPRGN
:
424 OffsetClipRgn(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
429 TextOut(hdc
, *(mr
->rdParam
+ ((s1
+ 1) >> 1) + 2),
430 *(mr
->rdParam
+ ((s1
+ 1) >> 1) + 1),
431 (char *)(mr
->rdParam
+ 1), s1
);
435 Polygon(hdc
, (LPPOINT
)(mr
->rdParam
+ 1), *(mr
->rdParam
));
438 case META_POLYPOLYGON
:
439 PolyPolygon(hdc
, (LPPOINT
)(mr
->rdParam
+ *(mr
->rdParam
) + 1),
440 (mr
->rdParam
+ 1), *(mr
->rdParam
));
444 Polyline(hdc
, (LPPOINT
)(mr
->rdParam
+ 1), *(mr
->rdParam
));
448 RestoreDC(hdc
, *(mr
->rdParam
));
451 case META_SELECTOBJECT
:
452 SelectObject(hdc
, *(ht
->objectHandle
+ *(mr
->rdParam
)));
456 Chord(hdc
, *(mr
->rdParam
+ 7), *(mr
->rdParam
+ 6), *(mr
->rdParam
+ 5),
457 *(mr
->rdParam
+ 4), *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
458 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
461 case META_CREATEPATTERNBRUSH
:
462 switch (*(mr
->rdParam
))
465 infohdr
= (BITMAPINFOHEADER
*)(mr
->rdParam
+ 2);
466 MF_AddHandle(ht
, nHandles
,
467 CreatePatternBrush(CreateBitmap(infohdr
->biWidth
,
471 (LPSTR
)(mr
->rdParam
+
472 (sizeof(BITMAPINFOHEADER
) / 2) + 4))));
476 s1
= mr
->rdSize
* 2 - sizeof(METARECORD
) - 2;
477 hndl
= GlobalAlloc(GMEM_MOVEABLE
, s1
);
478 ptr
= GlobalLock(hndl
);
479 memcpy(ptr
, mr
->rdParam
+ 2, s1
);
481 MF_AddHandle(ht
, nHandles
,
482 CreateDIBPatternBrush(hndl
, *(mr
->rdParam
+ 1)));
487 case META_CREATEPENINDIRECT
:
488 MF_AddHandle(ht
, nHandles
,
489 CreatePenIndirect((LOGPEN
*)(&(mr
->rdParam
))));
492 case META_CREATEFONTINDIRECT
:
493 MF_AddHandle(ht
, nHandles
,
494 CreateFontIndirect((LOGFONT
*)(&(mr
->rdParam
))));
497 case META_CREATEBRUSHINDIRECT
:
498 MF_AddHandle(ht
, nHandles
,
499 CreateBrushIndirect((LOGBRUSH
*)(&(mr
->rdParam
))));
503 fprintf(stderr
,"PlayMetaFileRecord: Unknown record type %x\n",
509 /******************************************************************
512 BOOL
MF_WriteRecord(HMETAFILE hmf
, METARECORD
*mr
, WORD rlen
)
515 METAFILE
*mf
= (METAFILE
*)GlobalLock(hmf
);
516 METAHEADER
*mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
518 if (mh
->mtType
== 0) /* memory based metafile */
520 len
= mh
->mtSize
* 2 + rlen
;
521 GlobalUnlock(mf
->hMetaHdr
);
522 mf
->hMetaHdr
= GlobalReAlloc(mf
->hMetaHdr
, len
, GMEM_MOVEABLE
);
523 mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
524 memcpy(mh
+ mh
->mtSize
* 2, mr
, rlen
);
526 else if (mh
->mtType
== 1) /* disk based metafile */
528 if (_lwrite(mf
->hFile
, (char *)mr
, rlen
) == -1)
530 GlobalUnlock(mf
->hMetaHdr
);
536 GlobalUnlock(mf
->hMetaHdr
);
540 mh
->mtSize
+= rlen
/ 2;
541 mh
->mtMaxRecord
= max(mh
->mtMaxRecord
, rlen
/ 2);
542 GlobalUnlock(mf
->hMetaHdr
);
547 /******************************************************************
550 * Add a handle to an external handle table and return the index
552 int MF_AddHandle(HANDLETABLE
*ht
, WORD htlen
, HANDLE hobj
)
556 for (i
= 0; i
< htlen
; i
++)
558 if (*(ht
->objectHandle
+ i
) == 0)
560 *(ht
->objectHandle
+ i
) = hobj
;
568 /******************************************************************
569 * MF_AddHandleInternal
571 * Add a handle to the internal handle table and return the index
573 int MF_AddHandleInternal(HANDLE hobj
)
576 HANDLETABLE
*ht
= (HANDLETABLE
*)GlobalLock(hHT
);
578 for (i
= 0; i
< HTLen
; i
++)
580 if (*(ht
->objectHandle
+ i
) == 0)
582 *(ht
->objectHandle
+ i
) = hobj
;
588 if (!(hHT
= GlobalReAlloc(hHT
, HTINCR
, GMEM_MOVEABLE
| GMEM_ZEROINIT
)))
591 ht
= (HANDLETABLE
*)GlobalLock(hHT
);
592 *(ht
->objectHandle
+ i
) = hobj
;
598 /******************************************************************
601 BOOL
MF_MetaParam0(DC
*dc
, short func
)
604 METARECORD
*mr
= (METARECORD
*)&buffer
;
607 mr
->rdFunction
= func
;
608 return MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
612 /******************************************************************
615 BOOL
MF_MetaParam1(DC
*dc
, short func
, short param1
)
618 METARECORD
*mr
= (METARECORD
*)&buffer
;
621 mr
->rdFunction
= func
;
622 *(mr
->rdParam
) = param1
;
623 return MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
627 /******************************************************************
630 BOOL
MF_MetaParam2(DC
*dc
, short func
, short param1
, short param2
)
633 METARECORD
*mr
= (METARECORD
*)&buffer
;
636 mr
->rdFunction
= func
;
637 *(mr
->rdParam
) = param2
;
638 *(mr
->rdParam
+ 1) = param1
;
639 return MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
643 /******************************************************************
646 BOOL
MF_MetaParam4(DC
*dc
, short func
, short param1
, short param2
,
647 short param3
, short param4
)
650 METARECORD
*mr
= (METARECORD
*)&buffer
;
653 mr
->rdFunction
= func
;
654 *(mr
->rdParam
) = param4
;
655 *(mr
->rdParam
+ 1) = param3
;
656 *(mr
->rdParam
+ 2) = param2
;
657 *(mr
->rdParam
+ 3) = param1
;
658 return MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
662 /******************************************************************
665 BOOL
MF_MetaParam6(DC
*dc
, short func
, short param1
, short param2
,
666 short param3
, short param4
, short param5
, short param6
)
669 METARECORD
*mr
= (METARECORD
*)&buffer
;
672 mr
->rdFunction
= func
;
673 *(mr
->rdParam
) = param6
;
674 *(mr
->rdParam
+ 1) = param5
;
675 *(mr
->rdParam
+ 2) = param4
;
676 *(mr
->rdParam
+ 3) = param3
;
677 *(mr
->rdParam
+ 4) = param2
;
678 *(mr
->rdParam
+ 5) = param1
;
679 return MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
683 /******************************************************************
686 BOOL
MF_MetaParam8(DC
*dc
, short func
, short param1
, short param2
,
687 short param3
, short param4
, short param5
,
688 short param6
, short param7
, short param8
)
691 METARECORD
*mr
= (METARECORD
*)&buffer
;
694 mr
->rdFunction
= func
;
695 *(mr
->rdParam
) = param8
;
696 *(mr
->rdParam
+ 1) = param7
;
697 *(mr
->rdParam
+ 2) = param6
;
698 *(mr
->rdParam
+ 3) = param5
;
699 *(mr
->rdParam
+ 4) = param4
;
700 *(mr
->rdParam
+ 5) = param3
;
701 *(mr
->rdParam
+ 6) = param2
;
702 *(mr
->rdParam
+ 7) = param1
;
703 return MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
707 /******************************************************************
708 * MF_CreateBrushIndirect
710 BOOL
MF_CreateBrushIndirect(DC
*dc
, HBRUSH hBrush
, LOGBRUSH
*logbrush
)
714 char buffer
[sizeof(METARECORD
) - 2 + sizeof(LOGBRUSH
)];
715 METARECORD
*mr
= (METARECORD
*)&buffer
;
719 mr
->rdSize
= (sizeof(METARECORD
) + sizeof(LOGBRUSH
) - 2) / 2;
720 mr
->rdFunction
= META_CREATEBRUSHINDIRECT
;
721 memcpy(&(mr
->rdParam
), logbrush
, sizeof(LOGBRUSH
));
722 if (!MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2))
725 mr
->rdSize
= sizeof(METARECORD
) / 2;
726 mr
->rdFunction
= META_SELECTOBJECT
;
727 if ((index
= MF_AddHandleInternal(hBrush
)) == -1)
730 mf
= (METAFILE
*)GlobalLock(dc
->w
.hMetaFile
);
731 mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
732 *(mr
->rdParam
) = index
;
733 if (index
>= mh
->mtNoObjects
)
735 rc
= MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
736 GlobalUnlock(mf
->hMetaHdr
);
737 GlobalUnlock(dc
->w
.hMetaFile
);
742 /******************************************************************
743 * MF_CreatePatternBrush
745 BOOL
MF_CreatePatternBrush(DC
*dc
, HBRUSH hBrush
, LOGBRUSH
*logbrush
)
747 DWORD len
, bmSize
, biSize
;
752 BITMAPINFOHEADER
*infohdr
;
755 char buffer
[sizeof(METARECORD
)];
759 switch (logbrush
->lbStyle
)
762 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr(logbrush
->lbHatch
, BITMAP_MAGIC
);
763 if (!bmp
) return FALSE
;
764 len
= sizeof(METARECORD
) + sizeof(BITMAPINFOHEADER
) +
765 (bmp
->bitmap
.bmHeight
* bmp
->bitmap
.bmWidthBytes
) + 6;
766 if (!(hmr
= GlobalAlloc(GMEM_MOVEABLE
, len
)))
768 mr
= (METARECORD
*)GlobalLock(hmr
);
770 mr
->rdFunction
= META_DIBCREATEPATTERNBRUSH
;
771 mr
->rdSize
= len
/ 2;
772 *(mr
->rdParam
) = logbrush
->lbStyle
;
773 *(mr
->rdParam
+ 1) = DIB_RGB_COLORS
;
774 infohdr
= (BITMAPINFOHEADER
*)(mr
->rdParam
+ 2);
775 infohdr
->biSize
= sizeof(BITMAPINFOHEADER
);
776 infohdr
->biWidth
= bmp
->bitmap
.bmWidth
;
777 infohdr
->biHeight
= bmp
->bitmap
.bmHeight
;
778 infohdr
->biPlanes
= bmp
->bitmap
.bmPlanes
;
779 infohdr
->biBitCount
= bmp
->bitmap
.bmBitsPixel
;
780 memcpy(mr
->rdParam
+ (sizeof(BITMAPINFOHEADER
) / 2) + 4,
782 bmp
->bitmap
.bmHeight
* bmp
->bitmap
.bmWidthBytes
);
786 info
= (BITMAPINFO
*)GlobalLock(logbrush
->lbHatch
);
787 bmSize
= info
->bmiHeader
.biSizeImage
;
789 bmSize
= (info
->bmiHeader
.biWidth
* info
->bmiHeader
.biBitCount
790 + 31) / 32 * 8 * info
->bmiHeader
.biHeight
;
791 biSize
= DIB_BitmapInfoSize(info
, LOWORD(logbrush
->lbColor
));
792 len
= sizeof(METARECORD
) + biSize
+ bmSize
+ 2;
793 if (!(hmr
= GlobalAlloc(GMEM_MOVEABLE
, len
)))
795 mr
= (METARECORD
*)GlobalLock(hmr
);
797 mr
->rdFunction
= META_DIBCREATEPATTERNBRUSH
;
798 mr
->rdSize
= len
/ 2;
799 *(mr
->rdParam
) = logbrush
->lbStyle
;
800 *(mr
->rdParam
+ 1) = LOWORD(logbrush
->lbColor
);
801 memcpy(mr
->rdParam
+ 2, info
, biSize
+ bmSize
);
806 if (!MF_WriteRecord(dc
->w
.hMetaFile
, mr
, len
))
813 mr
= (METARECORD
*)&buffer
;
814 mr
->rdSize
= sizeof(METARECORD
) / 2;
815 mr
->rdFunction
= META_SELECTOBJECT
;
816 if ((index
= MF_AddHandleInternal(hBrush
)) == -1)
819 mf
= (METAFILE
*)GlobalLock(dc
->w
.hMetaFile
);
820 mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
821 *(mr
->rdParam
) = index
;
822 if (index
>= mh
->mtNoObjects
)
824 rc
= MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
825 GlobalUnlock(mf
->hMetaHdr
);
826 GlobalUnlock(dc
->w
.hMetaFile
);
831 /******************************************************************
832 * MF_CreatePenIndirect
834 BOOL
MF_CreatePenIndirect(DC
*dc
, HPEN hPen
, LOGPEN
*logpen
)
838 char buffer
[sizeof(METARECORD
) - 2 + sizeof(LOGPEN
)];
839 METARECORD
*mr
= (METARECORD
*)&buffer
;
843 mr
->rdSize
= (sizeof(METARECORD
) + sizeof(LOGPEN
) - 2) / 2;
844 mr
->rdFunction
= META_CREATEPENINDIRECT
;
845 memcpy(&(mr
->rdParam
), logpen
, sizeof(LOGPEN
));
846 if (!MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2))
849 mr
->rdSize
= sizeof(METARECORD
) / 2;
850 mr
->rdFunction
= META_SELECTOBJECT
;
851 if ((index
= MF_AddHandleInternal(hPen
)) == -1)
854 mf
= (METAFILE
*)GlobalLock(dc
->w
.hMetaFile
);
855 mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
856 *(mr
->rdParam
) = index
;
857 if (index
>= mh
->mtNoObjects
)
859 rc
= MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
860 GlobalUnlock(mf
->hMetaHdr
);
861 GlobalUnlock(dc
->w
.hMetaFile
);
866 /******************************************************************
867 * MF_CreateFontIndirect
869 BOOL
MF_CreateFontIndirect(DC
*dc
, HFONT hFont
, LOGFONT
*logfont
)
873 char buffer
[sizeof(METARECORD
) - 2 + sizeof(LOGFONT
)];
874 METARECORD
*mr
= (METARECORD
*)&buffer
;
878 mr
->rdSize
= (sizeof(METARECORD
) + sizeof(LOGFONT
) - 2) / 2;
879 mr
->rdFunction
= META_CREATEFONTINDIRECT
;
880 memcpy(&(mr
->rdParam
), logfont
, sizeof(LOGFONT
));
881 if (!MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2))
884 mr
->rdSize
= sizeof(METARECORD
) / 2;
885 mr
->rdFunction
= META_SELECTOBJECT
;
886 if ((index
= MF_AddHandleInternal(hFont
)) == -1)
889 mf
= (METAFILE
*)GlobalLock(dc
->w
.hMetaFile
);
890 mh
= (METAHEADER
*)GlobalLock(mf
->hMetaHdr
);
891 *(mr
->rdParam
) = index
;
892 if (index
>= mh
->mtNoObjects
)
894 rc
= MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
895 GlobalUnlock(mf
->hMetaHdr
);
896 GlobalUnlock(dc
->w
.hMetaFile
);
901 /******************************************************************
904 BOOL
MF_TextOut(DC
*dc
, short x
, short y
, LPSTR str
, short count
)
911 len
= sizeof(METARECORD
) + (((count
+ 1) >> 1) * 2) + 4;
912 if (!(hmr
= GlobalAlloc(GMEM_MOVEABLE
, len
)))
914 mr
= (METARECORD
*)GlobalLock(hmr
);
917 mr
->rdSize
= len
/ 2;
918 mr
->rdFunction
= META_TEXTOUT
;
919 *(mr
->rdParam
) = count
;
920 memcpy(mr
->rdParam
+ 1, str
, count
);
921 *(mr
->rdParam
+ ((count
+ 1) >> 1) + 1) = y
;
922 *(mr
->rdParam
+ ((count
+ 1) >> 1) + 2) = x
;
923 rc
= MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
929 /******************************************************************
930 * MF_MetaPoly - implements Polygon and Polyline
932 BOOL
MF_MetaPoly(DC
*dc
, short func
, LPPOINT pt
, short count
)
939 len
= sizeof(METARECORD
) + (count
* 4);
940 if (!(hmr
= GlobalAlloc(GMEM_MOVEABLE
, len
)))
942 mr
= (METARECORD
*)GlobalLock(hmr
);
945 mr
->rdSize
= len
/ 2;
946 mr
->rdFunction
= func
;
947 *(mr
->rdParam
) = count
;
948 memcpy(mr
->rdParam
+ 1, pt
, count
* 4);
949 rc
= MF_WriteRecord(dc
->w
.hMetaFile
, mr
, mr
->rdSize
* 2);
955 /******************************************************************
958 BOOL
MF_BitBlt(DC
*dcDest
, short xDest
, short yDest
, short width
,
959 short height
, HDC hdcSrc
, short xSrc
, short ySrc
, DWORD rop
)
961 fprintf(stdnimp
,"MF_BitBlt: not implemented yet\n");
966 /******************************************************************
969 BOOL
MF_StretchBlt(DC
*dcDest
, short xDest
, short yDest
, short widthDest
,
970 short heightDest
, HDC hdcSrc
, short xSrc
, short ySrc
,
971 short widthSrc
, short heightSrc
, DWORD rop
)
973 fprintf(stdnimp
,"MF_StretchBlt: not implemented yet\n");