Release 960805
[wine/multimedia.git] / objects / metafile.c
blob3c2ad1ab95af295f60dd76da6ab6fa55c41216c3
1 /*
2 * Metafile functions
4 * Copyright David W. Metcalfe, 1994
5 * Niels de Carpentier, Albrecht Kleine 1996
7 */
9 #include <string.h>
10 #include <fcntl.h>
11 #include "gdi.h"
12 #include "bitmap.h"
13 #include "file.h"
14 #include "metafile.h"
15 #include "stackframe.h"
16 #include "stddebug.h"
17 #include "debug.h"
19 #define HTINCR 10 /* handle table allocation size increment */
21 static HANDLE hHT; /* handle of the handle table */
22 static int HTLen; /* allocated length of handle table */
24 /******************************************************************
25 * GetMetafile GDI.124 By Kenny MacDonald 30 Nov 94
28 HMETAFILE GetMetaFile(LPSTR lpFilename)
30 HMETAFILE hmf;
31 METAHEADER *mh;
32 HFILE hFile;
33 DWORD size;
35 dprintf_metafile(stddeb,"GetMetaFile: %s\n", lpFilename);
37 if (!lpFilename)
38 return 0;
40 hmf = GlobalAlloc16(GMEM_MOVEABLE, MFHEADERSIZE);
41 mh = (METAHEADER *)GlobalLock16(hmf);
43 if (!mh) {
44 GlobalFree16(hmf);
45 return 0;
48 if ((hFile = _lopen(lpFilename, OF_READ)) == HFILE_ERROR) {
49 GlobalFree16(hmf);
50 return 0;
53 if (FILE_Read(hFile, (char *)mh, MFHEADERSIZE) == HFILE_ERROR) {
54 GlobalFree16(hmf);
55 return 0;
58 size = mh->mtSize * 2; /* alloc memory for whole metafile */
59 GlobalUnlock16(hmf);
60 hmf = GlobalReAlloc16(hmf,size,GMEM_MOVEABLE);
61 mh = (METAHEADER *)GlobalLock16(hmf);
63 if (!mh) {
64 GlobalFree16(hmf);
65 return 0;
68 if (FILE_Read(hFile, (char*)mh + mh->mtHeaderSize * 2,
69 size - mh->mtHeaderSize * 2) == HFILE_ERROR) {
70 GlobalFree16(hmf);
71 return 0;
74 _lclose(hFile);
76 if (mh->mtType != 1) {
77 GlobalFree16(hmf);
78 return 0;
81 GlobalUnlock16(hmf);
82 return hmf;
86 /******************************************************************
87 * CreateMetafile GDI.125
90 HANDLE CreateMetaFile(LPCSTR lpFilename)
92 DC *dc;
93 HANDLE handle;
94 METAHEADER *mh;
95 int hFile;
97 dprintf_metafile(stddeb,"CreateMetaFile: %s\n", lpFilename);
99 handle = GDI_AllocObject(sizeof(DC), METAFILE_DC_MAGIC);
101 if (!handle)
102 return 0;
104 dc = (DC *)GDI_HEAP_LIN_ADDR(handle);
106 if (!(dc->w.hMetaFile = GlobalAlloc16(GMEM_MOVEABLE, sizeof(METAHEADER)))) {
107 GDI_FreeObject(handle);
108 return 0;
110 dc->w.bitsPerPixel = screenDepth;
111 mh = (METAHEADER *)GlobalLock16(dc->w.hMetaFile);
113 mh->mtHeaderSize = MFHEADERSIZE / 2;
114 mh->mtVersion = MFVERSION;
115 mh->mtSize = MFHEADERSIZE / 2;
116 mh->mtNoObjects = 0;
117 mh->mtMaxRecord = 0;
118 mh->mtNoParameters = 0;
120 if (lpFilename) /* disk based metafile */
122 mh->mtType = 1; /* disk */
123 hFile = _lcreat(lpFilename, 0);
124 if (_lwrite(hFile, (char *)mh, MFHEADERSIZE) == -1)
126 GlobalFree16(dc->w.hMetaFile);
127 return 0;
129 mh->mtNoParameters = hFile; /* store file descriptor here */
130 /* windows probably uses this too*/
132 else /* memory based metafile */
133 mh->mtType = 0;
135 /* create the handle table */
136 HTLen = HTINCR;
137 hHT = GlobalAlloc16(GMEM_MOVEABLE | GMEM_ZEROINIT,
138 sizeof(HANDLETABLE16) * HTLen);
140 GlobalUnlock16(dc->w.hMetaFile);
141 dprintf_metafile(stddeb,"CreateMetaFile: returning %04x\n", handle);
142 return handle;
145 /******************************************************************
146 * CopyMetafile GDI.151 Niels de Carpentier, April 1996
149 HMETAFILE CopyMetaFile(HMETAFILE hSrcMetaFile, LPCSTR lpFilename)
151 HMETAFILE handle = 0;
152 METAHEADER *mh;
153 METAHEADER *mh2;
154 int hFile;
156 dprintf_metafile(stddeb,"CopyMetaFile: %s\n", lpFilename);
158 mh = (METAHEADER *)GlobalLock16(hSrcMetaFile);
160 if (!mh)
161 return 0;
163 if (lpFilename) /* disk based metafile */
165 int i,j;
166 hFile = _lcreat(lpFilename, 0);
167 j=mh->mtType;
168 mh->mtType=1; /* disk file version stores 1 here */
169 i=_lwrite(hFile, (char *)mh, mh->mtSize * 2) ;
170 mh->mtType=j; /* restore old value [0 or 1] */
171 if (i == -1)
173 _lclose(hFile);
174 return 0;
176 _lclose(hFile);
178 else /* memory based metafile */
180 handle = GlobalAlloc16(GMEM_MOVEABLE,mh->mtSize * 2);
181 mh2 = (METAHEADER *)GlobalLock16(handle);
182 memcpy(mh2,mh, mh->mtSize * 2);
183 GlobalUnlock16(handle);
186 return handle;
190 /******************************************************************
191 * CloseMetafile GDI.126
194 HMETAFILE CloseMetaFile(HDC hdc)
196 DC *dc;
197 METAHEADER *mh;
198 HMETAFILE hmf;
199 HFILE hFile;
201 dprintf_metafile(stddeb,"CloseMetaFile\n");
203 dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
205 if (!dc)
206 return 0;
208 mh = (METAHEADER *)GlobalLock16(dc->w.hMetaFile);
210 /* Construct the end of metafile record - this is documented
211 * in SDK Knowledgebase Q99334.
214 if (!MF_MetaParam0(dc, META_EOF))
216 GlobalFree16(dc->w.hMetaFile);
217 return 0;
220 if (mh->mtType == 1) /* disk based metafile */
222 hFile = mh->mtNoParameters;
223 mh->mtNoParameters = 0;
224 if (_llseek(hFile, 0L, 0) == -1)
226 GlobalFree16(dc->w.hMetaFile);
227 return 0;
229 if (_lwrite(hFile, (char *)mh, MFHEADERSIZE) == -1)
231 GlobalFree16(dc->w.hMetaFile);
232 return 0;
234 _lclose(hFile);
237 /* delete the handle table */
238 GlobalFree16(hHT);
240 hmf = dc->w.hMetaFile;
241 GlobalUnlock16(hmf);
242 GDI_FreeObject(hdc);
243 return hmf;
247 /******************************************************************
248 * DeleteMetafile GDI.127
251 BOOL DeleteMetaFile(HMETAFILE hmf)
253 METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
255 if (!mh)
256 return FALSE;
258 GlobalFree16(hmf);
259 return TRUE;
263 /******************************************************************
264 * PlayMetafile GDI.123
267 BOOL PlayMetaFile(HDC hdc, HMETAFILE hmf)
269 METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
270 METARECORD *mr;
271 HANDLETABLE16 *ht;
272 int offset = 0;
273 WORD i;
275 dprintf_metafile(stddeb,"PlayMetaFile(%04x %04x)\n",hdc,hmf);
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 /* free objects in handle table */
294 for(i = 0; i < mh->mtNoObjects; i++)
295 if(*(ht->objectHandle + i) != 0)
296 DeleteObject(*(ht->objectHandle + i));
298 /* free handle table */
299 GlobalFree16(hHT);
301 return TRUE;
305 /******************************************************************
306 * EnumMetafile GDI.175
307 * Niels de carpentier, april 1996
310 BOOL EnumMetaFile(HDC hdc, HMETAFILE hmf, MFENUMPROC16 lpEnumFunc,LPARAM lpData)
312 METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
313 METARECORD *mr;
314 SEGPTR ht;
315 int offset = 0;
317 dprintf_metafile(stddeb,"EnumMetaFile(%04x, %04x, %08lx, %08lx)\n",
318 hdc, hmf, (DWORD)lpEnumFunc, lpData);
320 /* create the handle table */
322 hHT = GlobalAlloc16(GMEM_MOVEABLE | GMEM_ZEROINIT,
323 sizeof(HANDLETABLE16) * mh->mtNoObjects);
324 ht = WIN16_GlobalLock16(hHT);
326 offset = mh->mtHeaderSize * 2;
328 /* loop through metafile records */
330 while (offset < (mh->mtSize * 2))
332 mr = (METARECORD *)((char *)mh + offset);
333 if (!lpEnumFunc( hdc, ht, MAKE_SEGPTR(mr), /* FIXME!! */
334 mh->mtNoObjects, (LONG)lpData))
335 break;
337 offset += (mr->rdSize * 2);
340 /* free handle table */
341 GlobalFree16(hHT);
343 return TRUE;
346 /*******************************************************************
347 * MF_GetDIBitsPointer [internal helper for e.g. PlayMetaFileRecord]
349 * Returns offset to DIB bits or 0 if error
350 * (perhaps should be moved to (objects/dib.c ?)
352 static LPSTR MF_GetDIBitsPointer(LPBITMAPINFO info)
354 int offset;
355 if (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
357 if (info->bmiHeader.biClrUsed)
359 if (info->bmiHeader.biClrUsed < (1 << info->bmiHeader.biBitCount))
360 offset = info->bmiHeader.biClrUsed * 4;
361 else
362 offset = (1 << info->bmiHeader.biBitCount) * 4;
364 else
365 offset = (1 << info->bmiHeader.biBitCount) * 4;
367 else if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
369 if (info->bmiHeader.biClrUsed)
371 if (info->bmiHeader.biClrUsed < (1 << info->bmiHeader.biBitCount))
372 offset = info->bmiHeader.biClrUsed * 3;
373 else
374 offset = (1 << info->bmiHeader.biBitCount) * 3;
376 else
377 offset = (1 << info->bmiHeader.biBitCount) * 3;
379 else
381 fprintf(stderr,"Unknown size for BITMAPHEADER in MetaFile!\n");
382 return NULL;
384 return (LPSTR)info + info->bmiHeader.biSize + offset;
388 /******************************************************************
389 * PlayMetaFileRecord GDI.176
392 void PlayMetaFileRecord(HDC hdc, HANDLETABLE16 *ht, METARECORD *mr,
393 WORD nHandles)
395 short s1;
396 HANDLE hndl;
397 char *ptr;
398 BITMAPINFOHEADER *infohdr;
400 dprintf_metafile(stddeb,"PlayMetaFileRecord(%04x %08lx %08lx %04x)\n",
401 hdc,(LONG)ht, (LONG)mr, nHandles);
403 switch (mr->rdFunction)
405 case META_EOF:
406 break;
408 case META_DELETEOBJECT:
409 DeleteObject(*(ht->objectHandle + *(mr->rdParam)));
410 *(ht->objectHandle + *(mr->rdParam)) = 0;
411 break;
413 case META_SETBKCOLOR:
414 SetBkColor(hdc, *(mr->rdParam));
415 break;
417 case META_SETBKMODE:
418 SetBkMode(hdc, *(mr->rdParam));
419 break;
421 case META_SETMAPMODE:
422 SetMapMode(hdc, *(mr->rdParam));
423 break;
425 case META_SETROP2:
426 SetROP2(hdc, *(mr->rdParam));
427 break;
429 case META_SETRELABS:
430 SetRelAbs(hdc, *(mr->rdParam));
431 break;
433 case META_SETPOLYFILLMODE:
434 SetPolyFillMode(hdc, *(mr->rdParam));
435 break;
437 case META_SETSTRETCHBLTMODE:
438 SetStretchBltMode(hdc, *(mr->rdParam));
439 break;
441 case META_SETTEXTCOLOR:
442 SetTextColor(hdc, MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
443 break;
445 case META_SETWINDOWORG:
446 SetWindowOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
447 break;
449 case META_SETWINDOWEXT:
450 SetWindowExt(hdc, *(mr->rdParam + 1), *(mr->rdParam));
451 break;
453 case META_SETVIEWPORTORG:
454 SetViewportOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
455 break;
457 case META_SETVIEWPORTEXT:
458 SetViewportExt(hdc, *(mr->rdParam + 1), *(mr->rdParam));
459 break;
461 case META_OFFSETWINDOWORG:
462 OffsetWindowOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
463 break;
465 case META_SCALEWINDOWEXT:
466 ScaleWindowExt(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
467 *(mr->rdParam + 1), *(mr->rdParam));
468 break;
470 case META_OFFSETVIEWPORTORG:
471 OffsetViewportOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
472 break;
474 case META_SCALEVIEWPORTEXT:
475 ScaleViewportExt(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
476 *(mr->rdParam + 1), *(mr->rdParam));
477 break;
479 case META_LINETO:
480 LineTo(hdc, *(mr->rdParam + 1), *(mr->rdParam));
481 break;
483 case META_MOVETO:
484 MoveTo(hdc, *(mr->rdParam + 1), *(mr->rdParam));
485 break;
487 case META_EXCLUDECLIPRECT:
488 ExcludeClipRect(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
489 *(mr->rdParam + 1), *(mr->rdParam));
490 break;
492 case META_INTERSECTCLIPRECT:
493 IntersectClipRect(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
494 *(mr->rdParam + 1), *(mr->rdParam));
495 break;
497 case META_ARC:
498 Arc(hdc, *(mr->rdParam + 7), *(mr->rdParam + 6), *(mr->rdParam + 5),
499 *(mr->rdParam + 4), *(mr->rdParam + 3), *(mr->rdParam + 2),
500 *(mr->rdParam + 1), *(mr->rdParam));
501 break;
503 case META_ELLIPSE:
504 Ellipse(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
505 *(mr->rdParam + 1), *(mr->rdParam));
506 break;
508 case META_FLOODFILL:
509 FloodFill(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
510 MAKELONG(*(mr->rdParam + 1), *(mr->rdParam)));
511 break;
513 case META_PIE:
514 Pie(hdc, *(mr->rdParam + 7), *(mr->rdParam + 6), *(mr->rdParam + 5),
515 *(mr->rdParam + 4), *(mr->rdParam + 3), *(mr->rdParam + 2),
516 *(mr->rdParam + 1), *(mr->rdParam));
517 break;
519 case META_RECTANGLE:
520 Rectangle(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
521 *(mr->rdParam + 1), *(mr->rdParam));
522 break;
524 case META_ROUNDRECT:
525 RoundRect(hdc, *(mr->rdParam + 5), *(mr->rdParam + 4),
526 *(mr->rdParam + 3), *(mr->rdParam + 2),
527 *(mr->rdParam + 1), *(mr->rdParam));
528 break;
530 case META_PATBLT:
531 PatBlt(hdc, *(mr->rdParam + 5), *(mr->rdParam + 4),
532 *(mr->rdParam + 3), *(mr->rdParam + 2),
533 MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
534 break;
536 case META_SAVEDC:
537 SaveDC(hdc);
538 break;
540 case META_SETPIXEL:
541 SetPixel(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
542 MAKELONG(*(mr->rdParam + 1), *(mr->rdParam)));
543 break;
545 case META_OFFSETCLIPRGN:
546 OffsetClipRgn(hdc, *(mr->rdParam + 1), *(mr->rdParam));
547 break;
549 case META_TEXTOUT:
550 s1 = *(mr->rdParam);
551 TextOut16(hdc, *(mr->rdParam + ((s1 + 1) >> 1) + 2),
552 *(mr->rdParam + ((s1 + 1) >> 1) + 1),
553 (char *)(mr->rdParam + 1), s1);
554 break;
556 case META_POLYGON:
557 Polygon16(hdc, (LPPOINT16)(mr->rdParam + 1), *(mr->rdParam));
558 break;
560 case META_POLYPOLYGON:
561 PolyPolygon16(hdc, (LPPOINT16)(mr->rdParam + *(mr->rdParam) + 1),
562 (LPINT16)(mr->rdParam + 1), *(mr->rdParam));
563 break;
565 case META_POLYLINE:
566 Polyline16(hdc, (LPPOINT16)(mr->rdParam + 1), *(mr->rdParam));
567 break;
569 case META_RESTOREDC:
570 RestoreDC(hdc, *(mr->rdParam));
571 break;
573 case META_SELECTOBJECT:
574 SelectObject(hdc, *(ht->objectHandle + *(mr->rdParam)));
575 break;
577 case META_CHORD:
578 Chord(hdc, *(mr->rdParam + 7), *(mr->rdParam + 6), *(mr->rdParam + 5),
579 *(mr->rdParam + 4), *(mr->rdParam + 3), *(mr->rdParam + 2),
580 *(mr->rdParam + 1), *(mr->rdParam));
581 break;
583 case META_CREATEPATTERNBRUSH:
584 switch (*(mr->rdParam))
586 case BS_PATTERN:
587 infohdr = (BITMAPINFOHEADER *)(mr->rdParam + 2);
588 MF_AddHandle(ht, nHandles,
589 CreatePatternBrush(CreateBitmap(infohdr->biWidth,
590 infohdr->biHeight,
591 infohdr->biPlanes,
592 infohdr->biBitCount,
593 (LPSTR)(mr->rdParam +
594 (sizeof(BITMAPINFOHEADER) / 2) + 4))));
595 break;
597 case BS_DIBPATTERN:
598 s1 = mr->rdSize * 2 - sizeof(METARECORD) - 2;
599 hndl = GlobalAlloc16(GMEM_MOVEABLE, s1);
600 ptr = GlobalLock16(hndl);
601 memcpy(ptr, mr->rdParam + 2, s1);
602 GlobalUnlock16(hndl);
603 MF_AddHandle(ht, nHandles,
604 CreateDIBPatternBrush(hndl, *(mr->rdParam + 1)));
605 GlobalFree16(hndl);
607 break;
609 case META_CREATEPENINDIRECT:
610 MF_AddHandle(ht, nHandles,
611 CreatePenIndirect((LOGPEN16 *)(&(mr->rdParam))));
612 break;
614 case META_CREATEFONTINDIRECT:
615 MF_AddHandle(ht, nHandles,
616 CreateFontIndirect16((LOGFONT16 *)(&(mr->rdParam))));
617 break;
619 case META_CREATEBRUSHINDIRECT:
620 MF_AddHandle(ht, nHandles,
621 CreateBrushIndirect((LOGBRUSH16 *)(&(mr->rdParam))));
622 break;
624 /* W. Magro: Some new metafile operations. Not all debugged. */
625 case META_CREATEPALETTE:
626 MF_AddHandle(ht, nHandles,
627 CreatePalette((LPLOGPALETTE)mr->rdParam));
628 break;
630 case META_SETTEXTALIGN:
631 SetTextAlign(hdc, *(mr->rdParam));
632 break;
634 case META_SELECTPALETTE:
635 SelectPalette(hdc, *(ht->objectHandle + *(mr->rdParam+1)),*(mr->rdParam));
636 break;
638 case META_SETMAPPERFLAGS:
639 SetMapperFlags(hdc, *(mr->rdParam));
640 break;
642 case META_REALIZEPALETTE:
643 RealizePalette(hdc);
644 break;
646 case META_ESCAPE:
647 dprintf_metafile(stddeb,"PlayMetaFileRecord: META_ESCAPE unimplemented.\n");
648 break;
650 /* --- Begin of fixed or new metafile operations. July 1996 ----*/
651 case META_EXTTEXTOUT:
653 LPINT16 dxx;
654 s1=mr->rdParam[2]; /* String length */
655 if (mr->rdSize-(s1+1))
656 dxx=&mr->rdParam[8+(s1+1)/2]; /* start of array */
657 else
658 dxx=NULL; /* NO array present */
660 ExtTextOut16( hdc, mr->rdParam[1], /* X position */
661 mr->rdParam[0], /* Y position */
662 mr->rdParam[3], /* options */
663 (LPRECT16) &mr->rdParam[4], /* rectangle */
664 (char *)(mr->rdParam + 8), /* string */
665 s1, dxx); /* length, dx array */
666 if (dxx)
667 dprintf_metafile(stddeb,"EXTTEXTOUT len: %ld (%hd %hd) [%s].\n",
668 mr->rdSize,dxx[0],dxx[1],(char*) &(mr->rdParam[8]) );
670 break;
672 case META_STRETCHDIB:
674 LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParam[11]);
675 LPSTR bits = MF_GetDIBitsPointer(info);
676 if (bits)
677 StretchDIBits(hdc,mr->rdParam[10],mr->rdParam[9],mr->rdParam[8],
678 mr->rdParam[7],mr->rdParam[6],mr->rdParam[5],
679 mr->rdParam[4],mr->rdParam[3],bits,info,
680 mr->rdParam[2],MAKELONG(mr->rdParam[0],mr->rdParam[1]));
682 break;
684 case META_DIBSTRETCHBLT:
686 LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParam[10]);
687 LPSTR bits = MF_GetDIBitsPointer(info);
688 if (bits)
689 StretchDIBits(hdc,mr->rdParam[9],mr->rdParam[8],mr->rdParam[7],
690 mr->rdParam[6],mr->rdParam[5],mr->rdParam[4],
691 mr->rdParam[3],mr->rdParam[2],bits,info,
692 DIB_RGB_COLORS,MAKELONG(mr->rdParam[0],mr->rdParam[1]));
694 break;
696 case META_STRETCHBLT:
698 HDC hdcSrc=CreateCompatibleDC(hdc);
699 HBITMAP16 hbitmap=CreateBitmap(mr->rdParam[10], /*Width */
700 mr->rdParam[11], /*Height*/
701 mr->rdParam[13], /*Planes*/
702 mr->rdParam[14], /*BitsPixel*/
703 (LPSTR)&mr->rdParam[15]); /*bits*/
704 SelectObject(hdcSrc,hbitmap);
705 StretchBlt(hdc,mr->rdParam[9],mr->rdParam[8],
706 mr->rdParam[7],mr->rdParam[6],
707 hdcSrc,mr->rdParam[5],mr->rdParam[4],
708 mr->rdParam[3],mr->rdParam[2],
709 MAKELONG(mr->rdParam[0],mr->rdParam[1]));
710 DeleteDC(hdcSrc);
712 break;
714 case META_BITBLT: /* <-- not yet debugged */
716 HDC hdcSrc=CreateCompatibleDC(hdc);
717 HBITMAP16 hbitmap=CreateBitmap(mr->rdParam[7]/*Width */,mr->rdParam[8]/*Height*/,
718 mr->rdParam[10]/*Planes*/,mr->rdParam[11]/*BitsPixel*/,
719 (LPSTR)&mr->rdParam[12]/*bits*/);
720 SelectObject(hdcSrc,hbitmap);
721 BitBlt(hdc,mr->rdParam[6],mr->rdParam[5],
722 mr->rdParam[4],mr->rdParam[3],
723 hdcSrc,
724 mr->rdParam[2],mr->rdParam[1],
725 MAKELONG(0,mr->rdParam[0]));
726 DeleteDC(hdcSrc);
728 break;
730 default:
731 fprintf(stddeb,"PlayMetaFileRecord: Unknown record type %x\n",
732 mr->rdFunction);
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 HANDLE GetMetaFileBits(HMETAFILE hmf)
745 dprintf_metafile(stddeb,"GetMetaFileBits: hMem out: %04x\n", hmf);
747 return 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 HMETAFILE SetMetaFileBits(HANDLE hMem)
758 dprintf_metafile(stddeb,"SetMetaFileBits: hmf out: %04x\n", hMem);
760 return hMem;
763 /******************************************************************
764 * MF_WriteRecord
767 HMETAFILE MF_WriteRecord(HMETAFILE hmf, METARECORD *mr, WORD rlen)
769 DWORD len;
770 METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
772 if (mh->mtType == 0) /* memory based metafile */
774 len = mh->mtSize * 2 + rlen;
775 GlobalUnlock16(hmf);
776 hmf = GlobalReAlloc16(hmf, len, GMEM_MOVEABLE); /* hmf can change */
777 mh = (METAHEADER *)GlobalLock16(hmf);
778 memcpy((WORD *)mh + mh->mtSize, mr, rlen);
780 else if (mh->mtType == 1) /* disk based metafile */
782 dprintf_metafile(stddeb,"Writing record to disk\n");
783 if (_lwrite(mh->mtNoParameters, (char *)mr, rlen) == -1)
785 GlobalUnlock16(hmf);
786 return 0;
789 else
791 GlobalUnlock16(hmf);
792 return 0;
795 mh->mtSize += rlen / 2;
796 mh->mtMaxRecord = MAX(mh->mtMaxRecord, rlen / 2);
797 GlobalUnlock16(hmf);
798 return hmf;
802 /******************************************************************
803 * MF_AddHandle
805 * Add a handle to an external handle table and return the index
808 int MF_AddHandle(HANDLETABLE16 *ht, WORD htlen, HANDLE hobj)
810 int i;
812 for (i = 0; i < htlen; i++)
814 if (*(ht->objectHandle + i) == 0)
816 *(ht->objectHandle + i) = hobj;
817 return i;
820 return -1;
824 /******************************************************************
825 * MF_AddHandleInternal
827 * Add a handle to the internal handle table and return the index
830 int MF_AddHandleInternal(HANDLE hobj)
832 int i;
833 HANDLETABLE16 *ht = (HANDLETABLE16 *)GlobalLock16(hHT);
835 for (i = 0; i < HTLen; i++)
837 if (*(ht->objectHandle + i) == 0)
839 *(ht->objectHandle + i) = hobj;
840 GlobalUnlock16(hHT);
841 return i;
844 GlobalUnlock16(hHT);
845 if (!(hHT = GlobalReAlloc16(hHT, HTINCR, GMEM_MOVEABLE | GMEM_ZEROINIT)))
846 return -1;
847 HTLen += HTINCR;
848 ht = (HANDLETABLE16 *)GlobalLock16(hHT);
849 *(ht->objectHandle + i) = hobj;
850 GlobalUnlock16(hHT);
851 return i;
855 /******************************************************************
856 * MF_MetaParam0
859 BOOL MF_MetaParam0(DC *dc, short func)
861 char buffer[8];
862 METARECORD *mr = (METARECORD *)&buffer;
863 HMETAFILE handle;
865 mr->rdSize = 3;
866 mr->rdFunction = func;
867 handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
868 dc->w.hMetaFile = handle;
870 return handle;
874 /******************************************************************
875 * MF_MetaParam1
877 BOOL MF_MetaParam1(DC *dc, short func, short param1)
879 char buffer[8];
880 METARECORD *mr = (METARECORD *)&buffer;
881 HMETAFILE handle;
883 mr->rdSize = 4;
884 mr->rdFunction = func;
885 *(mr->rdParam) = param1;
886 handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
887 dc->w.hMetaFile = handle;
889 return handle;
893 /******************************************************************
894 * MF_MetaParam2
896 BOOL MF_MetaParam2(DC *dc, short func, short param1, short param2)
898 char buffer[10];
899 METARECORD *mr = (METARECORD *)&buffer;
900 HMETAFILE handle;
902 mr->rdSize = 5;
903 mr->rdFunction = func;
904 *(mr->rdParam) = param2;
905 *(mr->rdParam + 1) = param1;
906 handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
907 dc->w.hMetaFile = handle;
909 return handle;
913 /******************************************************************
914 * MF_MetaParam4
917 BOOL MF_MetaParam4(DC *dc, short func, short param1, short param2,
918 short param3, short param4)
920 char buffer[14];
921 METARECORD *mr = (METARECORD *)&buffer;
922 HMETAFILE handle;
924 mr->rdSize = 7;
925 mr->rdFunction = func;
926 *(mr->rdParam) = param4;
927 *(mr->rdParam + 1) = param3;
928 *(mr->rdParam + 2) = param2;
929 *(mr->rdParam + 3) = param1;
930 handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
931 dc->w.hMetaFile = handle;
933 return handle;
937 /******************************************************************
938 * MF_MetaParam6
941 BOOL MF_MetaParam6(DC *dc, short func, short param1, short param2,
942 short param3, short param4, short param5, short param6)
944 char buffer[18];
945 METARECORD *mr = (METARECORD *)&buffer;
946 HMETAFILE handle;
948 mr->rdSize = 9;
949 mr->rdFunction = func;
950 *(mr->rdParam) = param6;
951 *(mr->rdParam + 1) = param5;
952 *(mr->rdParam + 2) = param4;
953 *(mr->rdParam + 3) = param3;
954 *(mr->rdParam + 4) = param2;
955 *(mr->rdParam + 5) = param1;
956 handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
957 dc->w.hMetaFile = handle;
959 return handle;
963 /******************************************************************
964 * MF_MetaParam8
966 BOOL MF_MetaParam8(DC *dc, short func, short param1, short param2,
967 short param3, short param4, short param5,
968 short param6, short param7, short param8)
970 char buffer[22];
971 METARECORD *mr = (METARECORD *)&buffer;
972 HMETAFILE handle;
974 mr->rdSize = 11;
975 mr->rdFunction = func;
976 *(mr->rdParam) = param8;
977 *(mr->rdParam + 1) = param7;
978 *(mr->rdParam + 2) = param6;
979 *(mr->rdParam + 3) = param5;
980 *(mr->rdParam + 4) = param4;
981 *(mr->rdParam + 5) = param3;
982 *(mr->rdParam + 6) = param2;
983 *(mr->rdParam + 7) = param1;
984 handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
985 dc->w.hMetaFile = handle;
987 return handle;
991 /******************************************************************
992 * MF_CreateBrushIndirect
995 BOOL MF_CreateBrushIndirect(DC *dc, HBRUSH hBrush, LOGBRUSH16 *logbrush)
997 int index;
998 HMETAFILE handle;
999 char buffer[sizeof(METARECORD) - 2 + sizeof(LOGBRUSH16)];
1000 METARECORD *mr = (METARECORD *)&buffer;
1001 METAHEADER *mh;
1003 mr->rdSize = (sizeof(METARECORD) + sizeof(LOGBRUSH16) - 2) / 2;
1004 mr->rdFunction = META_CREATEBRUSHINDIRECT;
1005 memcpy(&(mr->rdParam), logbrush, sizeof(LOGBRUSH16));
1006 if (!(dc->w.hMetaFile = MF_WriteRecord(dc->w.hMetaFile,
1007 mr, mr->rdSize * 2)))
1008 return FALSE;
1010 mr->rdSize = sizeof(METARECORD) / 2;
1011 mr->rdFunction = META_SELECTOBJECT;
1013 if ((index = MF_AddHandleInternal(hBrush)) == -1)
1014 return FALSE;
1016 mh = (METAHEADER *)GlobalLock16(dc->w.hMetaFile);
1017 *(mr->rdParam) = index;
1018 if (index >= mh->mtNoObjects)
1019 mh->mtNoObjects++;
1021 GlobalUnlock16(dc->w.hMetaFile);
1022 handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
1023 dc->w.hMetaFile = handle;
1025 return handle;
1029 /******************************************************************
1030 * MF_CreatePatternBrush
1033 BOOL MF_CreatePatternBrush(DC *dc, HBRUSH hBrush, LOGBRUSH16 *logbrush)
1035 DWORD len, bmSize, biSize;
1036 HANDLE hmr;
1037 METARECORD *mr;
1038 BITMAPOBJ *bmp;
1039 BITMAPINFO *info;
1040 BITMAPINFOHEADER *infohdr;
1041 int index;
1042 HMETAFILE handle;
1043 char buffer[sizeof(METARECORD)];
1044 METAHEADER *mh;
1046 switch (logbrush->lbStyle)
1048 case BS_PATTERN:
1049 bmp = (BITMAPOBJ *)GDI_GetObjPtr((HANDLE)logbrush->lbHatch, BITMAP_MAGIC);
1050 if (!bmp) return FALSE;
1051 len = sizeof(METARECORD) + sizeof(BITMAPINFOHEADER) +
1052 (bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes) + 6;
1053 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1054 return FALSE;
1055 mr = (METARECORD *)GlobalLock16(hmr);
1056 memset(mr, 0, len);
1057 mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
1058 mr->rdSize = len / 2;
1059 *(mr->rdParam) = logbrush->lbStyle;
1060 *(mr->rdParam + 1) = DIB_RGB_COLORS;
1061 infohdr = (BITMAPINFOHEADER *)(mr->rdParam + 2);
1062 infohdr->biSize = sizeof(BITMAPINFOHEADER);
1063 infohdr->biWidth = bmp->bitmap.bmWidth;
1064 infohdr->biHeight = bmp->bitmap.bmHeight;
1065 infohdr->biPlanes = bmp->bitmap.bmPlanes;
1066 infohdr->biBitCount = bmp->bitmap.bmBitsPixel;
1067 memcpy(mr->rdParam + (sizeof(BITMAPINFOHEADER) / 2) + 4,
1068 PTR_SEG_TO_LIN(bmp->bitmap.bmBits),
1069 bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes);
1070 break;
1072 case BS_DIBPATTERN:
1073 info = (BITMAPINFO *)GlobalLock16((HANDLE)logbrush->lbHatch);
1074 if (info->bmiHeader.biCompression)
1075 bmSize = info->bmiHeader.biSizeImage;
1076 else
1077 bmSize = (info->bmiHeader.biWidth * info->bmiHeader.biBitCount
1078 + 31) / 32 * 8 * info->bmiHeader.biHeight;
1079 biSize = DIB_BitmapInfoSize(info, LOWORD(logbrush->lbColor));
1080 len = sizeof(METARECORD) + biSize + bmSize + 2;
1081 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1082 return FALSE;
1083 mr = (METARECORD *)GlobalLock16(hmr);
1084 memset(mr, 0, len);
1085 mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
1086 mr->rdSize = len / 2;
1087 *(mr->rdParam) = logbrush->lbStyle;
1088 *(mr->rdParam + 1) = LOWORD(logbrush->lbColor);
1089 memcpy(mr->rdParam + 2, info, biSize + bmSize);
1090 break;
1091 default:
1092 return FALSE;
1094 if (!(dc->w.hMetaFile = MF_WriteRecord(dc->w.hMetaFile, mr, len)))
1096 GlobalFree16(hmr);
1097 return FALSE;
1100 GlobalFree16(hmr);
1102 mr = (METARECORD *)&buffer;
1103 mr->rdSize = sizeof(METARECORD) / 2;
1104 mr->rdFunction = META_SELECTOBJECT;
1105 if ((index = MF_AddHandleInternal(hBrush)) == -1)
1106 return FALSE;
1108 mh = (METAHEADER *)GlobalLock16(dc->w.hMetaFile);
1109 *(mr->rdParam) = index;
1110 if (index >= mh->mtNoObjects)
1111 mh->mtNoObjects++;
1112 GlobalUnlock16(dc->w.hMetaFile);
1113 handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
1114 dc->w.hMetaFile = handle;
1116 return handle;
1120 /******************************************************************
1121 * MF_CreatePenIndirect
1124 BOOL MF_CreatePenIndirect(DC *dc, HPEN16 hPen, LOGPEN16 *logpen)
1126 int index;
1127 HMETAFILE handle;
1128 char buffer[sizeof(METARECORD) - 2 + sizeof(LOGPEN16)];
1129 METARECORD *mr = (METARECORD *)&buffer;
1130 METAHEADER *mh;
1132 mr->rdSize = (sizeof(METARECORD) + sizeof(LOGPEN16) - 2) / 2;
1133 mr->rdFunction = META_CREATEPENINDIRECT;
1134 memcpy(&(mr->rdParam), logpen, sizeof(LOGPEN16));
1135 if (!(dc->w.hMetaFile = MF_WriteRecord(dc->w.hMetaFile, mr,
1136 mr->rdSize * 2)))
1137 return FALSE;
1139 mr->rdSize = sizeof(METARECORD) / 2;
1140 mr->rdFunction = META_SELECTOBJECT;
1142 if ((index = MF_AddHandleInternal(hPen)) == -1)
1143 return FALSE;
1145 mh = (METAHEADER *)GlobalLock16(dc->w.hMetaFile);
1146 *(mr->rdParam) = index;
1147 if (index >= mh->mtNoObjects)
1148 mh->mtNoObjects++;
1149 GlobalUnlock16(dc->w.hMetaFile);
1150 handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
1151 dc->w.hMetaFile = handle;
1153 return handle;
1157 /******************************************************************
1158 * MF_CreateFontIndirect
1161 BOOL MF_CreateFontIndirect(DC *dc, HFONT hFont, LOGFONT16 *logfont)
1163 int index;
1164 HMETAFILE handle;
1165 char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT16)];
1166 METARECORD *mr = (METARECORD *)&buffer;
1167 METAHEADER *mh;
1169 mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT16) - 2) / 2;
1170 mr->rdFunction = META_CREATEFONTINDIRECT;
1171 memcpy(&(mr->rdParam), logfont, sizeof(LOGFONT16));
1172 if (!(dc->w.hMetaFile = MF_WriteRecord(dc->w.hMetaFile, mr,
1173 mr->rdSize * 2)))
1174 return FALSE;
1176 mr->rdSize = sizeof(METARECORD) / 2;
1177 mr->rdFunction = META_SELECTOBJECT;
1179 if ((index = MF_AddHandleInternal(hFont)) == -1)
1180 return FALSE;
1182 mh = (METAHEADER *)GlobalLock16(dc->w.hMetaFile);
1183 *(mr->rdParam) = index;
1184 if (index >= mh->mtNoObjects)
1185 mh->mtNoObjects++;
1186 GlobalUnlock16(dc->w.hMetaFile);
1187 handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
1188 dc->w.hMetaFile = handle;
1190 return handle;
1194 /******************************************************************
1195 * MF_TextOut
1197 BOOL MF_TextOut(DC *dc, short x, short y, LPCSTR str, short count)
1199 HMETAFILE handle;
1200 DWORD len;
1201 HANDLE hmr;
1202 METARECORD *mr;
1204 len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 4;
1205 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1206 return FALSE;
1207 mr = (METARECORD *)GlobalLock16(hmr);
1208 memset(mr, 0, len);
1210 mr->rdSize = len / 2;
1211 mr->rdFunction = META_TEXTOUT;
1212 *(mr->rdParam) = count;
1213 memcpy(mr->rdParam + 1, str, count);
1214 *(mr->rdParam + ((count + 1) >> 1) + 1) = y;
1215 *(mr->rdParam + ((count + 1) >> 1) + 2) = x;
1216 handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
1217 dc->w.hMetaFile = handle;
1218 GlobalFree16(hmr);
1219 return handle;
1222 /******************************************************************
1223 * MF_ExtTextOut
1225 BOOL MF_ExtTextOut(DC *dc, short x, short y, UINT16 flags, const RECT16 *rect,
1226 LPCSTR str, short count, const INT16 *lpDx)
1228 HMETAFILE handle;
1229 DWORD len;
1230 HANDLE hmr;
1231 METARECORD *mr;
1233 len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 4 + sizeof(RECT16);
1234 if (lpDx)
1235 len+=count*sizeof(INT16);
1236 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1237 return FALSE;
1238 mr = (METARECORD *)GlobalLock16(hmr);
1239 memset(mr, 0, len);
1241 mr->rdSize = len / 2;
1242 mr->rdFunction = META_EXTTEXTOUT;
1243 *(mr->rdParam) = y;
1244 *(mr->rdParam + 1) = x;
1245 *(mr->rdParam + 2) = count;
1246 *(mr->rdParam + 3) = flags;
1247 memcpy(mr->rdParam + 4, rect, sizeof(RECT16));
1248 memcpy(mr->rdParam + 8, str, count);
1249 if (lpDx)
1250 memcpy(mr->rdParam + 8+ ((count + 1) >> 1),lpDx,count*sizeof(INT16));
1251 handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
1252 dc->w.hMetaFile = handle;
1253 GlobalFree16(hmr);
1254 return handle;
1257 /******************************************************************
1258 * MF_MetaPoly - implements Polygon and Polyline
1260 BOOL MF_MetaPoly(DC *dc, short func, LPPOINT16 pt, short count)
1262 HMETAFILE handle;
1263 DWORD len;
1264 HANDLE hmr;
1265 METARECORD *mr;
1267 len = sizeof(METARECORD) + (count * 4);
1268 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1269 return FALSE;
1270 mr = (METARECORD *)GlobalLock16(hmr);
1271 memset(mr, 0, len);
1273 mr->rdSize = len / 2;
1274 mr->rdFunction = func;
1275 *(mr->rdParam) = count;
1276 memcpy(mr->rdParam + 1, pt, count * 4);
1277 handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
1278 dc->w.hMetaFile = handle;
1279 GlobalFree16(hmr);
1280 return handle;
1284 /******************************************************************
1285 * MF_BitBlt
1287 BOOL MF_BitBlt(DC *dcDest, short xDest, short yDest, short width,
1288 short height, HDC hdcSrc, short xSrc, short ySrc, DWORD rop)
1290 HMETAFILE handle;
1291 DWORD len;
1292 HANDLE hmr;
1293 METARECORD *mr;
1294 DC *dcSrc;
1295 BITMAP16 BM;
1297 if (!(dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC ))) return 0;
1298 GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM);
1299 len = sizeof(METARECORD) + 12 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
1300 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1301 return FALSE;
1302 mr = (METARECORD *)GlobalLock16(hmr);
1303 mr->rdFunction = META_BITBLT;
1304 *(mr->rdParam + 7) = BM.bmWidth;
1305 *(mr->rdParam + 8) = BM.bmHeight;
1306 *(mr->rdParam + 9) = BM.bmWidthBytes;
1307 *(mr->rdParam +10) = BM.bmPlanes;
1308 *(mr->rdParam +11) = BM.bmBitsPixel;
1309 dprintf_metafile(stddeb,"MF_StretchBlt->len = %ld rop=%lx \n",len,rop);
1310 if (GetBitmapBits(dcSrc->w.hBitmap,BM.bmWidthBytes * BM.bmHeight,mr->rdParam +12))
1312 mr->rdSize = len / sizeof(INT16);
1313 *(mr->rdParam) = HIWORD(rop);
1314 *(mr->rdParam + 1) = ySrc;
1315 *(mr->rdParam + 2) = xSrc;
1316 *(mr->rdParam + 3) = height;
1317 *(mr->rdParam + 4) = width;
1318 *(mr->rdParam + 5) = yDest;
1319 *(mr->rdParam + 6) = xDest;
1320 handle = MF_WriteRecord(dcDest->w.hMetaFile, mr, mr->rdSize * 2);
1322 else
1323 handle = 0;
1324 dcDest->w.hMetaFile = handle;
1325 GlobalFree16(hmr);
1326 return handle;
1330 /**********************************************************************
1331 * MF_StretchBlt
1332 * this function contains TWO ways for procesing StretchBlt in metafiles,
1333 * decide between rdFunction values META_STRETCHBLT or META_DIBSTRETCHBLT
1334 * via #define STRETCH_VIA_DIB
1336 #define STRETCH_VIA_DIB
1337 #undef STRETCH_VIA_DIB
1338 BOOL MF_StretchBlt(DC *dcDest, short xDest, short yDest, short widthDest,
1339 short heightDest, HDC hdcSrc, short xSrc, short ySrc,
1340 short widthSrc, short heightSrc, DWORD rop)
1342 HMETAFILE handle;
1343 DWORD len;
1344 HANDLE hmr;
1345 METARECORD *mr;
1346 DC *dcSrc;
1347 BITMAP16 BM;
1348 #ifdef STRETCH_VIA_DIB
1349 LPBITMAPINFOHEADER lpBMI;
1350 WORD nBPP;
1351 #endif
1352 if (!(dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC ))) return 0;
1353 GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM);
1354 #ifdef STRETCH_VIA_DIB
1355 nBPP = BM.bmPlanes * BM.bmBitsPixel;
1356 len = sizeof(METARECORD) + 10 * sizeof(INT16)
1357 + sizeof(BITMAPINFOHEADER) + (nBPP != 24 ? 1 << nBPP: 0) * sizeof(RGBQUAD)
1358 + ((BM.bmWidth * nBPP + 31) / 32) * 4 * BM.bmHeight;
1359 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1360 return FALSE;
1361 mr = (METARECORD *)GlobalLock16(hmr);
1362 mr->rdFunction = META_DIBSTRETCHBLT;
1363 lpBMI=(LPBITMAPINFOHEADER)(mr->rdParam+10);
1364 lpBMI->biSize = sizeof(BITMAPINFOHEADER);
1365 lpBMI->biWidth = BM.bmWidth;
1366 lpBMI->biHeight = BM.bmHeight;
1367 lpBMI->biPlanes = 1;
1368 lpBMI->biBitCount = nBPP; /* 1,4,8 or 24 */
1369 lpBMI->biClrUsed = nBPP != 24 ? 1 << nBPP : 0;
1370 lpBMI->biSizeImage = ((lpBMI->biWidth * nBPP + 31) / 32) * 4 * lpBMI->biHeight;
1371 lpBMI->biCompression = BI_RGB;
1372 lpBMI->biXPelsPerMeter = MulDiv32(GetDeviceCaps(hdcSrc,LOGPIXELSX),3937,100);
1373 lpBMI->biYPelsPerMeter = MulDiv32(GetDeviceCaps(hdcSrc,LOGPIXELSY),3937,100);
1374 lpBMI->biClrImportant = 0; /* 1 meter = 39.37 inch */
1376 dprintf_metafile(stddeb,"MF_StretchBltViaDIB->len = %ld rop=%lx PixYPM=%ld Caps=%d\n",
1377 len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(hdcSrc,LOGPIXELSY));
1378 if (GetDIBits(hdcSrc,dcSrc->w.hBitmap,0,(UINT)lpBMI->biHeight,
1379 MF_GetDIBitsPointer((LPBITMAPINFO)lpBMI), /* DIB bits */
1380 (LPBITMAPINFO)lpBMI,DIB_RGB_COLORS)) /* DIB info structure */
1381 #else
1382 len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
1383 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1384 return FALSE;
1385 mr = (METARECORD *)GlobalLock16(hmr);
1386 mr->rdFunction = META_STRETCHBLT;
1387 *(mr->rdParam +10) = BM.bmWidth;
1388 *(mr->rdParam +11) = BM.bmHeight;
1389 *(mr->rdParam +12) = BM.bmWidthBytes;
1390 *(mr->rdParam +13) = BM.bmPlanes;
1391 *(mr->rdParam +14) = BM.bmBitsPixel;
1392 dprintf_metafile(stddeb,"MF_StretchBlt->len = %ld rop=%lx \n",len,rop);
1393 if (GetBitmapBits(dcSrc->w.hBitmap,BM.bmWidthBytes * BM.bmHeight,mr->rdParam +15))
1394 #endif
1396 mr->rdSize = len / sizeof(INT16);
1397 *(mr->rdParam) = LOWORD(rop);
1398 *(mr->rdParam + 1) = HIWORD(rop);
1399 *(mr->rdParam + 2) = heightSrc;
1400 *(mr->rdParam + 3) = widthSrc;
1401 *(mr->rdParam + 4) = ySrc;
1402 *(mr->rdParam + 5) = xSrc;
1403 *(mr->rdParam + 6) = heightDest;
1404 *(mr->rdParam + 7) = widthDest;
1405 *(mr->rdParam + 8) = yDest;
1406 *(mr->rdParam + 9) = xDest;
1407 handle = MF_WriteRecord(dcDest->w.hMetaFile, mr, mr->rdSize * 2);
1409 else
1410 handle = 0;
1411 dcDest->w.hMetaFile = handle;
1412 GlobalFree16(hmr);
1413 return handle;