4 * Copyright David W. Metcalfe, 1994
5 * Niels de Carpentier, Albrecht Kleine, Huw Davies 1996
16 #include "metafiledrv.h"
20 /******************************************************************
23 * Add a handle to an external handle table and return the index
26 static int MF_AddHandle(HANDLETABLE16 *ht, WORD htlen, HGDIOBJ16 hobj)
30 for (i = 0; i < htlen; i++)
32 if (*(ht->objectHandle + i) == 0)
34 *(ht->objectHandle + i) = hobj;
42 /******************************************************************
45 * Note: this function assumes that we never delete objects.
46 * If we do someday, we'll need to maintain a table to re-use deleted
49 static int MF_AddHandleDC( DC *dc )
51 METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
52 physDev->mh->mtNoObjects++;
53 return physDev->nextHandle++;
57 /******************************************************************
58 * GetMetafile16 (GDI.124)
60 HMETAFILE16 GetMetaFile16( LPCSTR lpFilename )
62 return GetMetaFile32A( lpFilename );
66 /******************************************************************
67 * GetMetafile32A (GDI32.197)
69 HMETAFILE32 GetMetaFile32A( LPCSTR lpFilename )
76 dprintf_metafile(stddeb,"GetMetaFile: %s\n", lpFilename);
81 hmf = GlobalAlloc16(GMEM_MOVEABLE, MFHEADERSIZE);
82 mh = (METAHEADER *)GlobalLock16(hmf);
90 if ((hFile = _lopen32(lpFilename, OF_READ)) == HFILE_ERROR32)
96 if (_lread32(hFile, (char *)mh, MFHEADERSIZE) == HFILE_ERROR32)
103 size = mh->mtSize * 2; /* alloc memory for whole metafile */
105 hmf = GlobalReAlloc16(hmf,size,GMEM_MOVEABLE);
106 mh = (METAHEADER *)GlobalLock16(hmf);
115 if (_lread32(hFile, (char*)mh + mh->mtHeaderSize * 2,
116 size - mh->mtHeaderSize * 2) == HFILE_ERROR32)
137 /******************************************************************
138 * GetMetafile32W (GDI32.199)
140 HMETAFILE32 GetMetaFile32W( LPCWSTR lpFilename )
142 LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFilename );
143 HMETAFILE32 ret = GetMetaFile32A( p );
144 HeapFree( GetProcessHeap(), 0, p );
149 /******************************************************************
150 * CopyMetaFile16 (GDI.151)
153 HMETAFILE16 CopyMetaFile16( HMETAFILE16 hSrcMetaFile, LPCSTR lpFilename )
155 return CopyMetaFile32A( hSrcMetaFile, lpFilename );
159 /******************************************************************
160 * CopyMetaFile32A (GDI32.23)
162 HMETAFILE32 CopyMetaFile32A( HMETAFILE32 hSrcMetaFile, LPCSTR lpFilename )
164 HMETAFILE16 handle = 0;
169 dprintf_metafile(stddeb,"CopyMetaFile: %s\n", lpFilename);
171 mh = (METAHEADER *)GlobalLock16(hSrcMetaFile);
176 if (lpFilename) /* disk based metafile */
179 hFile = _lcreat32(lpFilename, 0);
181 mh->mtType=1; /* disk file version stores 1 here */
182 i=_lwrite32(hFile, (char *)mh, mh->mtSize * 2) ;
183 mh->mtType=j; /* restore old value [0 or 1] */
187 /* FIXME: return value */
189 else /* memory based metafile */
191 handle = GlobalAlloc16(GMEM_MOVEABLE,mh->mtSize * 2);
192 mh2 = (METAHEADER *)GlobalLock16(handle);
193 memcpy(mh2,mh, mh->mtSize * 2);
194 GlobalUnlock16(handle);
201 /******************************************************************
202 * CopyMetaFile32W (GDI32.24)
204 HMETAFILE32 CopyMetaFile32W( HMETAFILE32 hSrcMetaFile, LPCWSTR lpFilename )
206 LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFilename );
207 HMETAFILE32 ret = CopyMetaFile32A( hSrcMetaFile, p );
208 HeapFree( GetProcessHeap(), 0, p );
213 /******************************************************************
214 * IsValidMetaFile (GDI.410)
215 * (This is not exactly what windows does, see "Undoc Win")
218 BOOL16 IsValidMetaFile(HMETAFILE16 hmf)
221 METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
223 if (mh->mtType == 1 || mh->mtType == 0)
224 if (mh->mtHeaderSize == MFHEADERSIZE/sizeof(INT16))
225 if (mh->mtVersion == MFVERSION)
229 dprintf_metafile(stddeb,"IsValidMetaFile %x => %d\n",hmf,resu);
234 /******************************************************************
235 * PlayMetafile16 (GDI.123)
237 BOOL16 PlayMetaFile16( HDC16 hdc, HMETAFILE16 hmf )
239 return PlayMetaFile32( hdc, hmf );
243 /******************************************************************
244 * PlayMetafile32 (GDI32.265)
246 BOOL32 PlayMetaFile32( HDC32 hdc, HMETAFILE32 hmf )
248 METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
259 dprintf_metafile(stddeb,"PlayMetaFile(%04x %04x)\n",hdc,hmf);
261 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
263 hBrush = dc->w.hBrush;
266 /* create the handle table */
267 hHT = GlobalAlloc16(GMEM_MOVEABLE|GMEM_ZEROINIT,
268 sizeof(HANDLETABLE16) * mh->mtNoObjects);
269 ht = (HANDLETABLE16 *)GlobalLock16(hHT);
271 /* loop through metafile playing records */
272 offset = mh->mtHeaderSize * 2;
273 while (offset < mh->mtSize * 2)
275 mr = (METARECORD *)((char *)mh + offset);
276 dprintf_metafile(stddeb,"offset = %04x size = %08lx function = %04x\n",
277 offset,mr->rdSize,mr->rdFunction);
278 offset += mr->rdSize * 2;
279 PlayMetaFileRecord16( hdc, ht, mr, mh->mtNoObjects );
282 SelectObject32(hdc, hBrush);
283 SelectObject32(hdc, hPen);
284 SelectObject32(hdc, hFont);
286 /* free objects in handle table */
287 for(i = 0; i < mh->mtNoObjects; i++)
288 if(*(ht->objectHandle + i) != 0)
289 DeleteObject32(*(ht->objectHandle + i));
291 /* free handle table */
298 /******************************************************************
299 * EnumMetaFile16 (GDI.175)
300 * Niels de carpentier, april 1996
302 BOOL16 EnumMetaFile16( HDC16 hdc, HMETAFILE16 hmf, MFENUMPROC16 lpEnumFunc,
305 METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
309 SEGPTR spht, spRecord;
317 dprintf_metafile(stddeb,"EnumMetaFile(%04x, %04x, %08lx, %08lx)\n",
318 hdc, hmf, (DWORD)lpEnumFunc, lpData);
320 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
322 hBrush = dc->w.hBrush;
325 /* create the handle table */
327 hHT = GlobalAlloc16(GMEM_MOVEABLE | GMEM_ZEROINIT,
328 sizeof(HANDLETABLE16) * mh->mtNoObjects);
329 spht = WIN16_GlobalLock16(hHT);
331 offset = mh->mtHeaderSize * 2;
333 /* loop through metafile records */
335 spRecord = WIN16_GlobalLock16(hmf);
336 while (offset < (mh->mtSize * 2))
338 mr = (METARECORD *)((char *)mh + offset);
339 if (!lpEnumFunc( hdc, (HANDLETABLE16 *)spht,
340 (METARECORD *)((UINT32)spRecord + offset),
341 mh->mtNoObjects, (LONG)lpData))
344 offset += (mr->rdSize * 2);
347 SelectObject32(hdc, hBrush);
348 SelectObject32(hdc, hPen);
349 SelectObject32(hdc, hFont);
351 ht = (HANDLETABLE16 *)GlobalLock16(hHT);
353 /* free objects in handle table */
354 for(i = 0; i < mh->mtNoObjects; i++)
355 if(*(ht->objectHandle + i) != 0)
356 DeleteObject32(*(ht->objectHandle + i));
358 /* free handle table */
365 /******************************************************************
366 * PlayMetaFileRecord16 (GDI.176)
368 void PlayMetaFileRecord16( HDC16 hdc, HANDLETABLE16 *ht, METARECORD *mr,
374 BITMAPINFOHEADER *infohdr;
376 dprintf_metafile(stddeb,"PlayMetaFileRecord(%04x %08lx %08lx %04x)\n",
377 hdc,(LONG)ht, (LONG)mr, nHandles);
379 switch (mr->rdFunction)
384 case META_DELETEOBJECT:
385 DeleteObject32(*(ht->objectHandle + *(mr->rdParam)));
386 *(ht->objectHandle + *(mr->rdParam)) = 0;
389 case META_SETBKCOLOR:
390 SetBkColor16(hdc, MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
394 SetBkMode16(hdc, *(mr->rdParam));
397 case META_SETMAPMODE:
398 SetMapMode16(hdc, *(mr->rdParam));
402 SetROP216(hdc, *(mr->rdParam));
406 SetRelAbs16(hdc, *(mr->rdParam));
409 case META_SETPOLYFILLMODE:
410 SetPolyFillMode16(hdc, *(mr->rdParam));
413 case META_SETSTRETCHBLTMODE:
414 SetStretchBltMode16(hdc, *(mr->rdParam));
416 case META_SETTEXTCOLOR:
417 SetTextColor16(hdc, MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
420 case META_SETWINDOWORG:
421 SetWindowOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
424 case META_SETWINDOWEXT:
425 SetWindowExt(hdc, *(mr->rdParam + 1), *(mr->rdParam));
428 case META_SETVIEWPORTORG:
429 SetViewportOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
432 case META_SETVIEWPORTEXT:
433 SetViewportExt(hdc, *(mr->rdParam + 1), *(mr->rdParam));
436 case META_OFFSETWINDOWORG:
437 OffsetWindowOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
440 case META_SCALEWINDOWEXT:
441 ScaleWindowExt(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
442 *(mr->rdParam + 1), *(mr->rdParam));
445 case META_OFFSETVIEWPORTORG:
446 OffsetViewportOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
449 case META_SCALEVIEWPORTEXT:
450 ScaleViewportExt(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
451 *(mr->rdParam + 1), *(mr->rdParam));
455 LineTo32(hdc, (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
459 MoveTo(hdc, *(mr->rdParam + 1), *(mr->rdParam));
462 case META_EXCLUDECLIPRECT:
463 ExcludeClipRect16( hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
464 *(mr->rdParam + 1), *(mr->rdParam) );
467 case META_INTERSECTCLIPRECT:
468 IntersectClipRect16( hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
469 *(mr->rdParam + 1), *(mr->rdParam) );
473 Arc32(hdc, (INT16)*(mr->rdParam + 7), (INT16)*(mr->rdParam + 6),
474 (INT16)*(mr->rdParam + 5), (INT16)*(mr->rdParam + 4),
475 (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
476 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
480 Ellipse32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
481 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
485 FloodFill32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
486 MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
490 Pie32(hdc, (INT16)*(mr->rdParam + 7), (INT16)*(mr->rdParam + 6),
491 (INT16)*(mr->rdParam + 5), (INT16)*(mr->rdParam + 4),
492 (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
493 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
497 Rectangle32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
498 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
502 RoundRect32(hdc, (INT16)*(mr->rdParam + 5), (INT16)*(mr->rdParam + 4),
503 (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
504 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
508 PatBlt16(hdc, *(mr->rdParam + 5), *(mr->rdParam + 4),
509 *(mr->rdParam + 3), *(mr->rdParam + 2),
510 MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
518 SetPixel32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
519 MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
522 case META_OFFSETCLIPRGN:
523 OffsetClipRgn16( hdc, *(mr->rdParam + 1), *(mr->rdParam) );
528 TextOut16(hdc, *(mr->rdParam + ((s1 + 1) >> 1) + 2),
529 *(mr->rdParam + ((s1 + 1) >> 1) + 1),
530 (char *)(mr->rdParam + 1), s1);
534 Polygon16(hdc, (LPPOINT16)(mr->rdParam + 1), *(mr->rdParam));
537 case META_POLYPOLYGON:
538 PolyPolygon16(hdc, (LPPOINT16)(mr->rdParam + *(mr->rdParam) + 1),
539 (LPINT16)(mr->rdParam + 1), *(mr->rdParam));
543 Polyline16(hdc, (LPPOINT16)(mr->rdParam + 1), *(mr->rdParam));
547 RestoreDC32(hdc, (INT16)*(mr->rdParam));
550 case META_SELECTOBJECT:
551 SelectObject32(hdc, *(ht->objectHandle + *(mr->rdParam)));
555 Chord32(hdc, (INT16)*(mr->rdParam + 7), (INT16)*(mr->rdParam + 6),
556 (INT16)*(mr->rdParam+5), (INT16)*(mr->rdParam + 4),
557 (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
558 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
561 case META_CREATEPATTERNBRUSH:
562 switch (*(mr->rdParam))
565 infohdr = (BITMAPINFOHEADER *)(mr->rdParam + 2);
566 MF_AddHandle(ht, nHandles,
567 CreatePatternBrush32(CreateBitmap32(infohdr->biWidth,
571 (LPSTR)(mr->rdParam +
572 (sizeof(BITMAPINFOHEADER) / 2) + 4))));
576 s1 = mr->rdSize * 2 - sizeof(METARECORD) - 2;
577 hndl = GlobalAlloc16(GMEM_MOVEABLE, s1);
578 ptr = GlobalLock16(hndl);
579 memcpy(ptr, mr->rdParam + 2, s1);
580 GlobalUnlock16(hndl);
581 MF_AddHandle(ht, nHandles,
582 CreateDIBPatternBrush32(hndl, *(mr->rdParam + 1)));
587 case META_CREATEPENINDIRECT:
588 MF_AddHandle(ht, nHandles,
589 CreatePenIndirect16((LOGPEN16 *)(&(mr->rdParam))));
592 case META_CREATEFONTINDIRECT:
593 MF_AddHandle(ht, nHandles,
594 CreateFontIndirect16((LOGFONT16 *)(&(mr->rdParam))));
597 case META_CREATEBRUSHINDIRECT:
598 MF_AddHandle(ht, nHandles,
599 CreateBrushIndirect16((LOGBRUSH16 *)(&(mr->rdParam))));
602 /* W. Magro: Some new metafile operations. Not all debugged. */
603 case META_CREATEPALETTE:
604 MF_AddHandle(ht, nHandles,
605 CreatePalette16((LPLOGPALETTE)mr->rdParam));
608 case META_SETTEXTALIGN:
609 SetTextAlign16(hdc, *(mr->rdParam));
612 case META_SELECTPALETTE:
613 SelectPalette16(hdc, *(ht->objectHandle + *(mr->rdParam+1)),*(mr->rdParam));
616 case META_SETMAPPERFLAGS:
617 SetMapperFlags16(hdc, *(mr->rdParam));
620 case META_REALIZEPALETTE:
621 RealizePalette16(hdc);
625 dprintf_metafile(stddeb,"PlayMetaFileRecord: META_ESCAPE unimplemented.\n");
628 /* --- Begin of fixed or new metafile operations. July 1996 ----*/
629 case META_EXTTEXTOUT:
635 s1 = mr->rdParam[2]; /* String length */
636 len = sizeof(METARECORD) + (((s1 + 1) >> 1) * 2) + 2 * sizeof(short)
637 + sizeof(UINT16) + (mr->rdParam[3] ? sizeof(RECT16) : 0); /* rec len without dx array */
639 sot= (LPSTR)&mr->rdParam[4]; /* start_of_text */
641 sot+=sizeof(RECT16); /* there is a rectangle, so add offset */
643 if (mr->rdSize == len / 2)
644 dxx = NULL; /* determine if array present */
646 if (mr->rdSize == (len + s1 * sizeof(INT16)) / 2)
647 dxx = (LPINT16)(sot+(((s1+1)>>1)*2));
651 "Please report: PlayMetaFile/ExtTextOut len=%ld slen=%d rdSize=%ld opt=%04x\n",
652 len,s1,mr->rdSize,mr->rdParam[3]);
653 dxx = NULL; /* should't happen -- but if, we continue with NULL [for workaround] */
655 ExtTextOut16( hdc, mr->rdParam[1], /* X position */
656 mr->rdParam[0], /* Y position */
657 mr->rdParam[3], /* options */
658 mr->rdParam[3] ? (LPRECT16) &mr->rdParam[4]:NULL, /* rectangle */
660 s1, dxx); /* length, dx array */
662 dprintf_metafile(stddeb,"EXTTEXTOUT: %s len: %ld dx0: %d\n",
663 sot,mr->rdSize,dxx[0]);
667 case META_STRETCHDIB:
669 LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParam[11]);
670 LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize( info, mr->rdParam[2] );
671 StretchDIBits16(hdc,mr->rdParam[10],mr->rdParam[9],mr->rdParam[8],
672 mr->rdParam[7],mr->rdParam[6],mr->rdParam[5],
673 mr->rdParam[4],mr->rdParam[3],bits,info,
674 mr->rdParam[2],MAKELONG(mr->rdParam[0],mr->rdParam[1]));
678 case META_DIBSTRETCHBLT:
680 LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParam[10]);
681 LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize( info, mr->rdParam[2] );
682 StretchDIBits16(hdc,mr->rdParam[9],mr->rdParam[8],mr->rdParam[7],
683 mr->rdParam[6],mr->rdParam[5],mr->rdParam[4],
684 mr->rdParam[3],mr->rdParam[2],bits,info,
685 DIB_RGB_COLORS,MAKELONG(mr->rdParam[0],mr->rdParam[1]));
689 case META_STRETCHBLT:
691 HDC16 hdcSrc=CreateCompatibleDC16(hdc);
692 HBITMAP32 hbitmap=CreateBitmap32(mr->rdParam[10], /*Width */
693 mr->rdParam[11], /*Height*/
694 mr->rdParam[13], /*Planes*/
695 mr->rdParam[14], /*BitsPixel*/
696 (LPSTR)&mr->rdParam[15]); /*bits*/
697 SelectObject32(hdcSrc,hbitmap);
698 StretchBlt16(hdc,mr->rdParam[9],mr->rdParam[8],
699 mr->rdParam[7],mr->rdParam[6],
700 hdcSrc,mr->rdParam[5],mr->rdParam[4],
701 mr->rdParam[3],mr->rdParam[2],
702 MAKELONG(mr->rdParam[0],mr->rdParam[1]));
707 case META_BITBLT: /* <-- not yet debugged */
709 HDC16 hdcSrc=CreateCompatibleDC16(hdc);
710 HBITMAP32 hbitmap=CreateBitmap32(mr->rdParam[7]/*Width */,
711 mr->rdParam[8]/*Height*/,
712 mr->rdParam[10]/*Planes*/,
713 mr->rdParam[11]/*BitsPixel*/,
714 (LPSTR)&mr->rdParam[12]/*bits*/);
715 SelectObject32(hdcSrc,hbitmap);
716 BitBlt32(hdc,(INT16)mr->rdParam[6],(INT16)mr->rdParam[5],
717 (INT16)mr->rdParam[4],(INT16)mr->rdParam[3],
718 hdcSrc, (INT16)mr->rdParam[2],(INT16)mr->rdParam[1],
719 MAKELONG(0,mr->rdParam[0]));
724 /* --- Begin of new metafile operations. April, 1997 (ak) ----*/
725 case META_CREATEREGION:
728 HRGN32 h1,h2,hrgn=CreateRectRgn32(mr->rdParam[7],mr->rdParam[8],
729 mr->rdParam[9],mr->rdParam[10]);
730 for (i=0,h1=CreateRectRgn32(0,0,0,0);i<mr->rdParam[5];i++)
732 if (mr->rdParam[11+i*6]==2)
734 h2=CreateRectRgn32(mr->rdParam[14+i*6],mr->rdParam[12+i*6],
735 mr->rdParam[15+i*6],mr->rdParam[13+i*6]);
736 CombineRgn32(hrgn,h1,h2,mr->rdParam[16+i*6]); /* e.g. RGN_OR */
740 MF_AddHandle(ht, nHandles,hrgn);
744 case META_FILLREGION:
745 FillRgn16(hdc, *(ht->objectHandle + *(mr->rdParam)),
746 *(ht->objectHandle + *(mr->rdParam+1)));
749 case META_INVERTREGION:
750 InvertRgn16(hdc, *(ht->objectHandle + *(mr->rdParam)));
753 case META_PAINTREGION:
754 PaintRgn16(hdc, *(ht->objectHandle + *(mr->rdParam)));
757 case META_SELECTCLIPREGION:
758 SelectClipRgn32(hdc, *(ht->objectHandle + *(mr->rdParam)));
761 case META_DIBCREATEPATTERNBRUSH:
762 /* *(mr->rdParam) may be BS_PATTERN or BS_DIBPATTERN: but there's no difference */
763 dprintf_metafile(stddeb,"META_DIBCREATEPATTERNBRUSH: %d\n",*(mr->rdParam));
764 s1 = mr->rdSize * 2 - sizeof(METARECORD) - 2;
765 hndl = GlobalAlloc16(GMEM_MOVEABLE, s1);
766 ptr = GlobalLock16(hndl);
767 memcpy(ptr, mr->rdParam + 2, s1);
768 GlobalUnlock16(hndl);
769 MF_AddHandle(ht, nHandles,CreateDIBPatternBrush16(hndl, *(mr->rdParam + 1)));
775 LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParam[8]);
776 LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize( info, mr->rdParam[0] );
777 StretchDIBits16(hdc,mr->rdParam[7],mr->rdParam[6],mr->rdParam[5],
778 mr->rdParam[4],mr->rdParam[3],mr->rdParam[2],
779 mr->rdParam[5],mr->rdParam[4],bits,info,
780 DIB_RGB_COLORS,MAKELONG(mr->rdParam[0],mr->rdParam[1]));
784 case META_SETTEXTJUSTIFICATION:
785 SetTextJustification32(hdc, *(mr->rdParam + 1), *(mr->rdParam));
788 #define META_UNIMP(x) case x: fprintf(stderr,"PlayMetaFileRecord:record type "#x" not implemented.\n");break;
789 META_UNIMP(META_SETTEXTCHAREXTRA)
790 META_UNIMP(META_FRAMEREGION)
791 META_UNIMP(META_DRAWTEXT)
792 META_UNIMP(META_SETDIBTODEV)
793 META_UNIMP(META_ANIMATEPALETTE)
794 META_UNIMP(META_SETPALENTRIES)
795 META_UNIMP(META_RESIZEPALETTE)
796 META_UNIMP(META_EXTFLOODFILL)
797 META_UNIMP(META_RESETDC)
798 META_UNIMP(META_STARTDOC)
799 META_UNIMP(META_STARTPAGE)
800 META_UNIMP(META_ENDPAGE)
801 META_UNIMP(META_ABORTDOC)
802 META_UNIMP(META_ENDDOC)
803 META_UNIMP(META_CREATEBRUSH)
804 META_UNIMP(META_CREATEBITMAPINDIRECT)
805 META_UNIMP(META_CREATEBITMAP)
809 fprintf(stddeb,"PlayMetaFileRecord: Unknown record type %x\n",
815 /******************************************************************
816 * GetMetaFileBits (GDI.159)
818 * Trade in a meta file object handle for a handle to the meta file memory
821 HGLOBAL16 GetMetaFileBits(HMETAFILE16 hmf)
823 dprintf_metafile(stddeb,"GetMetaFileBits: hMem out: %04x\n", hmf);
828 /******************************************************************
829 * SetMetaFileBits (GDI.160)
831 * Trade in a meta file memory handle for a handle to a meta file object
833 HMETAFILE16 SetMetaFileBits( HGLOBAL16 hMem )
835 dprintf_metafile(stddeb,"SetMetaFileBits: hmf out: %04x\n", hMem);
840 /******************************************************************
841 * SetMetaFileBitsBetter (GDI.196)
843 HMETAFILE16 SetMetaFileBitsBetter( HMETAFILE16 hMeta )
845 if( IsValidMetaFile( hMeta ) )
846 return (HMETAFILE16)GlobalReAlloc16( hMeta, 0,
847 GMEM_SHARE | GMEM_NODISCARD | GMEM_MODIFY);
848 return (HMETAFILE16)0;
851 /******************************************************************
854 * Warning: this function can change the metafile handle.
857 static BOOL32 MF_WriteRecord( DC *dc, METARECORD *mr, WORD rlen)
861 METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
863 switch(physDev->mh->mtType)
865 case METAFILE_MEMORY:
866 len = physDev->mh->mtSize * 2 + rlen;
867 mh = HeapReAlloc( SystemHeap, 0, physDev->mh, len );
868 if (!mh) return FALSE;
870 memcpy((WORD *)physDev->mh + physDev->mh->mtSize, mr, rlen);
873 dprintf_metafile(stddeb,"Writing record to disk\n");
874 if (_lwrite32(physDev->mh->mtNoParameters, (char *)mr, rlen) == -1)
878 fprintf( stderr, "Unknown metafile type %d\n", physDev->mh->mtType );
882 physDev->mh->mtSize += rlen / 2;
883 physDev->mh->mtMaxRecord = MAX(physDev->mh->mtMaxRecord, rlen / 2);
888 /******************************************************************
892 BOOL32 MF_MetaParam0(DC *dc, short func)
895 METARECORD *mr = (METARECORD *)&buffer;
898 mr->rdFunction = func;
899 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
903 /******************************************************************
906 BOOL32 MF_MetaParam1(DC *dc, short func, short param1)
909 METARECORD *mr = (METARECORD *)&buffer;
912 mr->rdFunction = func;
913 *(mr->rdParam) = param1;
914 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
918 /******************************************************************
921 BOOL32 MF_MetaParam2(DC *dc, short func, short param1, short param2)
924 METARECORD *mr = (METARECORD *)&buffer;
927 mr->rdFunction = func;
928 *(mr->rdParam) = param2;
929 *(mr->rdParam + 1) = param1;
930 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
934 /******************************************************************
938 BOOL32 MF_MetaParam4(DC *dc, short func, short param1, short param2,
939 short param3, short param4)
942 METARECORD *mr = (METARECORD *)&buffer;
945 mr->rdFunction = func;
946 *(mr->rdParam) = param4;
947 *(mr->rdParam + 1) = param3;
948 *(mr->rdParam + 2) = param2;
949 *(mr->rdParam + 3) = param1;
950 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
954 /******************************************************************
958 BOOL32 MF_MetaParam6(DC *dc, short func, short param1, short param2,
959 short param3, short param4, short param5, short param6)
962 METARECORD *mr = (METARECORD *)&buffer;
965 mr->rdFunction = func;
966 *(mr->rdParam) = param6;
967 *(mr->rdParam + 1) = param5;
968 *(mr->rdParam + 2) = param4;
969 *(mr->rdParam + 3) = param3;
970 *(mr->rdParam + 4) = param2;
971 *(mr->rdParam + 5) = param1;
972 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
976 /******************************************************************
979 BOOL32 MF_MetaParam8(DC *dc, short func, short param1, short param2,
980 short param3, short param4, short param5,
981 short param6, short param7, short param8)
984 METARECORD *mr = (METARECORD *)&buffer;
987 mr->rdFunction = func;
988 *(mr->rdParam) = param8;
989 *(mr->rdParam + 1) = param7;
990 *(mr->rdParam + 2) = param6;
991 *(mr->rdParam + 3) = param5;
992 *(mr->rdParam + 4) = param4;
993 *(mr->rdParam + 5) = param3;
994 *(mr->rdParam + 6) = param2;
995 *(mr->rdParam + 7) = param1;
996 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1000 /******************************************************************
1001 * MF_CreateBrushIndirect
1004 BOOL32 MF_CreateBrushIndirect(DC *dc, HBRUSH16 hBrush, LOGBRUSH16 *logbrush)
1007 char buffer[sizeof(METARECORD) - 2 + sizeof(*logbrush)];
1008 METARECORD *mr = (METARECORD *)&buffer;
1010 mr->rdSize = (sizeof(METARECORD) + sizeof(*logbrush) - 2) / 2;
1011 mr->rdFunction = META_CREATEBRUSHINDIRECT;
1012 memcpy(&(mr->rdParam), logbrush, sizeof(*logbrush));
1013 if (!(MF_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
1015 mr->rdSize = sizeof(METARECORD) / 2;
1016 mr->rdFunction = META_SELECTOBJECT;
1018 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1019 *(mr->rdParam) = index;
1020 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1024 /******************************************************************
1025 * MF_CreatePatternBrush
1028 BOOL32 MF_CreatePatternBrush(DC *dc, HBRUSH16 hBrush, LOGBRUSH16 *logbrush)
1030 DWORD len, bmSize, biSize;
1035 BITMAPINFOHEADER *infohdr;
1037 char buffer[sizeof(METARECORD)];
1039 switch (logbrush->lbStyle)
1042 bmp = (BITMAPOBJ *)GDI_GetObjPtr((HGDIOBJ16)logbrush->lbHatch, BITMAP_MAGIC);
1043 if (!bmp) return FALSE;
1044 len = sizeof(METARECORD) + sizeof(BITMAPINFOHEADER) +
1045 (bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes) + 6;
1046 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1048 mr = (METARECORD *)GlobalLock16(hmr);
1050 mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
1051 mr->rdSize = len / 2;
1052 *(mr->rdParam) = logbrush->lbStyle;
1053 *(mr->rdParam + 1) = DIB_RGB_COLORS;
1054 infohdr = (BITMAPINFOHEADER *)(mr->rdParam + 2);
1055 infohdr->biSize = sizeof(BITMAPINFOHEADER);
1056 infohdr->biWidth = bmp->bitmap.bmWidth;
1057 infohdr->biHeight = bmp->bitmap.bmHeight;
1058 infohdr->biPlanes = bmp->bitmap.bmPlanes;
1059 infohdr->biBitCount = bmp->bitmap.bmBitsPixel;
1060 memcpy(mr->rdParam + (sizeof(BITMAPINFOHEADER) / 2) + 4,
1061 PTR_SEG_TO_LIN(bmp->bitmap.bmBits),
1062 bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes);
1066 info = (BITMAPINFO *)GlobalLock16((HGLOBAL16)logbrush->lbHatch);
1067 if (info->bmiHeader.biCompression)
1068 bmSize = info->bmiHeader.biSizeImage;
1070 bmSize = (info->bmiHeader.biWidth * info->bmiHeader.biBitCount
1071 + 31) / 32 * 8 * info->bmiHeader.biHeight;
1072 biSize = DIB_BitmapInfoSize(info, LOWORD(logbrush->lbColor));
1073 len = sizeof(METARECORD) + biSize + bmSize + 2;
1074 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1076 mr = (METARECORD *)GlobalLock16(hmr);
1078 mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
1079 mr->rdSize = len / 2;
1080 *(mr->rdParam) = logbrush->lbStyle;
1081 *(mr->rdParam + 1) = LOWORD(logbrush->lbColor);
1082 memcpy(mr->rdParam + 2, info, biSize + bmSize);
1087 if (!(MF_WriteRecord(dc, mr, len)))
1095 mr = (METARECORD *)&buffer;
1096 mr->rdSize = sizeof(METARECORD) / 2;
1097 mr->rdFunction = META_SELECTOBJECT;
1099 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1100 *(mr->rdParam) = index;
1101 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1105 /******************************************************************
1106 * MF_CreatePenIndirect
1109 BOOL32 MF_CreatePenIndirect(DC *dc, HPEN16 hPen, LOGPEN16 *logpen)
1112 char buffer[sizeof(METARECORD) - 2 + sizeof(*logpen)];
1113 METARECORD *mr = (METARECORD *)&buffer;
1115 mr->rdSize = (sizeof(METARECORD) + sizeof(*logpen) - 2) / 2;
1116 mr->rdFunction = META_CREATEPENINDIRECT;
1117 memcpy(&(mr->rdParam), logpen, sizeof(*logpen));
1118 if (!(MF_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
1120 mr->rdSize = sizeof(METARECORD) / 2;
1121 mr->rdFunction = META_SELECTOBJECT;
1123 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1124 *(mr->rdParam) = index;
1125 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1129 /******************************************************************
1130 * MF_CreateFontIndirect
1133 BOOL32 MF_CreateFontIndirect(DC *dc, HFONT16 hFont, LOGFONT16 *logfont)
1136 char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT16)];
1137 METARECORD *mr = (METARECORD *)&buffer;
1139 mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT16) - 2) / 2;
1140 mr->rdFunction = META_CREATEFONTINDIRECT;
1141 memcpy(&(mr->rdParam), logfont, sizeof(LOGFONT16));
1142 if (!(MF_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
1144 mr->rdSize = sizeof(METARECORD) / 2;
1145 mr->rdFunction = META_SELECTOBJECT;
1147 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1148 *(mr->rdParam) = index;
1149 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1153 /******************************************************************
1156 BOOL32 MF_TextOut(DC *dc, short x, short y, LPCSTR str, short count)
1163 len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 4;
1164 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1166 mr = (METARECORD *)GlobalLock16(hmr);
1169 mr->rdSize = len / 2;
1170 mr->rdFunction = META_TEXTOUT;
1171 *(mr->rdParam) = count;
1172 memcpy(mr->rdParam + 1, str, count);
1173 *(mr->rdParam + ((count + 1) >> 1) + 1) = y;
1174 *(mr->rdParam + ((count + 1) >> 1) + 2) = x;
1175 ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
1180 /******************************************************************
1183 BOOL32 MF_ExtTextOut(DC*dc, short x, short y, UINT16 flags, const RECT16 *rect,
1184 LPCSTR str, short count, const INT16 *lpDx)
1191 if((!flags && rect) || (flags && !rect))
1192 fprintf(stderr, "MF_ExtTextOut: Inconsistent flags and rect\n");
1193 len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 2 * sizeof(short)
1196 len += sizeof(RECT16);
1198 len+=count*sizeof(INT16);
1199 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1201 mr = (METARECORD *)GlobalLock16(hmr);
1204 mr->rdSize = len / 2;
1205 mr->rdFunction = META_EXTTEXTOUT;
1207 *(mr->rdParam + 1) = x;
1208 *(mr->rdParam + 2) = count;
1209 *(mr->rdParam + 3) = flags;
1210 if (rect) memcpy(mr->rdParam + 4, rect, sizeof(RECT16));
1211 memcpy(mr->rdParam + (rect ? 8 : 4), str, count);
1213 memcpy(mr->rdParam + (rect ? 8 : 4) + ((count + 1) >> 1),lpDx,
1214 count*sizeof(INT16));
1215 ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
1220 /******************************************************************
1221 * MF_MetaPoly - implements Polygon and Polyline
1223 BOOL32 MF_MetaPoly(DC *dc, short func, LPPOINT16 pt, short count)
1230 len = sizeof(METARECORD) + (count * 4);
1231 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1233 mr = (METARECORD *)GlobalLock16(hmr);
1236 mr->rdSize = len / 2;
1237 mr->rdFunction = func;
1238 *(mr->rdParam) = count;
1239 memcpy(mr->rdParam + 1, pt, count * 4);
1240 ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
1246 /******************************************************************
1249 BOOL32 MF_BitBlt(DC *dcDest, short xDest, short yDest, short width,
1250 short height, DC *dcSrc, short xSrc, short ySrc, DWORD rop)
1258 GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM);
1259 len = sizeof(METARECORD) + 12 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
1260 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1262 mr = (METARECORD *)GlobalLock16(hmr);
1263 mr->rdFunction = META_BITBLT;
1264 *(mr->rdParam + 7) = BM.bmWidth;
1265 *(mr->rdParam + 8) = BM.bmHeight;
1266 *(mr->rdParam + 9) = BM.bmWidthBytes;
1267 *(mr->rdParam +10) = BM.bmPlanes;
1268 *(mr->rdParam +11) = BM.bmBitsPixel;
1269 dprintf_metafile(stddeb,"MF_StretchBlt->len = %ld rop=%lx \n",len,rop);
1270 if (GetBitmapBits32(dcSrc->w.hBitmap,BM.bmWidthBytes * BM.bmHeight,
1273 mr->rdSize = len / sizeof(INT16);
1274 *(mr->rdParam) = HIWORD(rop);
1275 *(mr->rdParam + 1) = ySrc;
1276 *(mr->rdParam + 2) = xSrc;
1277 *(mr->rdParam + 3) = height;
1278 *(mr->rdParam + 4) = width;
1279 *(mr->rdParam + 5) = yDest;
1280 *(mr->rdParam + 6) = xDest;
1281 ret = MF_WriteRecord( dcDest, mr, mr->rdSize * 2);
1290 /**********************************************************************
1292 * this function contains TWO ways for procesing StretchBlt in metafiles,
1293 * decide between rdFunction values META_STRETCHBLT or META_DIBSTRETCHBLT
1294 * via #define STRETCH_VIA_DIB
1296 #define STRETCH_VIA_DIB
1297 #undef STRETCH_VIA_DIB
1298 BOOL32 MF_StretchBlt(DC *dcDest, short xDest, short yDest, short widthDest,
1299 short heightDest, DC *dcSrc, short xSrc, short ySrc,
1300 short widthSrc, short heightSrc, DWORD rop)
1307 #ifdef STRETCH_VIA_DIB
1308 LPBITMAPINFOHEADER lpBMI;
1311 GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM);
1312 #ifdef STRETCH_VIA_DIB
1313 nBPP = BM.bmPlanes * BM.bmBitsPixel;
1314 len = sizeof(METARECORD) + 10 * sizeof(INT16)
1315 + sizeof(BITMAPINFOHEADER) + (nBPP != 24 ? 1 << nBPP: 0) * sizeof(RGBQUAD)
1316 + ((BM.bmWidth * nBPP + 31) / 32) * 4 * BM.bmHeight;
1317 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1319 mr = (METARECORD *)GlobalLock16(hmr);
1320 mr->rdFunction = META_DIBSTRETCHBLT;
1321 lpBMI=(LPBITMAPINFOHEADER)(mr->rdParam+10);
1322 lpBMI->biSize = sizeof(BITMAPINFOHEADER);
1323 lpBMI->biWidth = BM.bmWidth;
1324 lpBMI->biHeight = BM.bmHeight;
1325 lpBMI->biPlanes = 1;
1326 lpBMI->biBitCount = nBPP; /* 1,4,8 or 24 */
1327 lpBMI->biClrUsed = nBPP != 24 ? 1 << nBPP : 0;
1328 lpBMI->biSizeImage = ((lpBMI->biWidth * nBPP + 31) / 32) * 4 * lpBMI->biHeight;
1329 lpBMI->biCompression = BI_RGB;
1330 lpBMI->biXPelsPerMeter = MulDiv32(GetDeviceCaps(dcSrc->hSelf,LOGPIXELSX),3937,100);
1331 lpBMI->biYPelsPerMeter = MulDiv32(GetDeviceCaps(dcSrc->hSelf,LOGPIXELSY),3937,100);
1332 lpBMI->biClrImportant = 0; /* 1 meter = 39.37 inch */
1334 dprintf_metafile(stddeb,"MF_StretchBltViaDIB->len = %ld rop=%lx PixYPM=%ld Caps=%d\n",
1335 len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(hdcSrc,LOGPIXELSY));
1336 if (GetDIBits(hdcSrc,dcSrc->w.hBitmap,0,(UINT32)lpBMI->biHeight,
1337 (LPSTR)lpBMI + DIB_BitmapInfoSize( (BITMAPINFO *)lpBMI,
1339 (LPBITMAPINFO)lpBMI, DIB_RGB_COLORS))
1341 len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
1342 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1344 mr = (METARECORD *)GlobalLock16(hmr);
1345 mr->rdFunction = META_STRETCHBLT;
1346 *(mr->rdParam +10) = BM.bmWidth;
1347 *(mr->rdParam +11) = BM.bmHeight;
1348 *(mr->rdParam +12) = BM.bmWidthBytes;
1349 *(mr->rdParam +13) = BM.bmPlanes;
1350 *(mr->rdParam +14) = BM.bmBitsPixel;
1351 dprintf_metafile(stddeb,"MF_StretchBlt->len = %ld rop=%lx \n",len,rop);
1352 if (GetBitmapBits32( dcSrc->w.hBitmap, BM.bmWidthBytes * BM.bmHeight,
1356 mr->rdSize = len / sizeof(INT16);
1357 *(mr->rdParam) = LOWORD(rop);
1358 *(mr->rdParam + 1) = HIWORD(rop);
1359 *(mr->rdParam + 2) = heightSrc;
1360 *(mr->rdParam + 3) = widthSrc;
1361 *(mr->rdParam + 4) = ySrc;
1362 *(mr->rdParam + 5) = xSrc;
1363 *(mr->rdParam + 6) = heightDest;
1364 *(mr->rdParam + 7) = widthDest;
1365 *(mr->rdParam + 8) = yDest;
1366 *(mr->rdParam + 9) = xDest;
1367 ret = MF_WriteRecord( dcDest, mr, mr->rdSize * 2);