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_LIN_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);
215 char *buffer = (char *)NULL;
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");