4 * Copyright David W. Metcalfe, 1994
5 * Niels de Carpentier, Albrecht Kleine, Huw Davies 1996
17 #include "metafiledrv.h"
21 /******************************************************************
24 * Add a handle to an external handle table and return the index
27 static int MF_AddHandle(HANDLETABLE16 *ht, WORD htlen, HGDIOBJ16 hobj)
31 for (i = 0; i < htlen; i++)
33 if (*(ht->objectHandle + i) == 0)
35 *(ht->objectHandle + i) = hobj;
43 /******************************************************************
46 * Note: this function assumes that we never delete objects.
47 * If we do someday, we'll need to maintain a table to re-use deleted
50 static int MF_AddHandleDC( DC *dc )
52 METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
53 physDev->mh->mtNoObjects++;
54 return physDev->nextHandle++;
58 /******************************************************************
59 * GetMetaFile16 (GDI.124)
61 HMETAFILE16 WINAPI GetMetaFile16( LPCSTR lpFilename )
63 return GetMetaFile32A( lpFilename );
67 /******************************************************************
68 * GetMetaFile32A (GDI32.197)
70 * Read a metafile from a file. Returns handle to a disk-based metafile.
72 HMETAFILE32 WINAPI GetMetaFile32A(
74 /* pointer to string containing filename to read */
82 dprintf_info(metafile,"GetMetaFile: %s\n", lpFilename);
87 hmf = GlobalAlloc16(GMEM_MOVEABLE, MFHEADERSIZE);
88 mh = (METAHEADER *)GlobalLock16(hmf);
96 if ((hFile = _lopen32(lpFilename, OF_READ)) == HFILE_ERROR32)
102 if (_lread32(hFile, (char *)mh, MFHEADERSIZE) == HFILE_ERROR32)
109 size = mh->mtSize * 2; /* alloc memory for whole metafile */
111 hmf = GlobalReAlloc16(hmf,size,GMEM_MOVEABLE);
112 mh = (METAHEADER *)GlobalLock16(hmf);
121 if (_lread32(hFile, (char*)mh + mh->mtHeaderSize * 2,
122 size - mh->mtHeaderSize * 2) == HFILE_ERROR32)
143 /******************************************************************
144 * GetMetaFile32W (GDI32.199)
146 HMETAFILE32 WINAPI GetMetaFile32W( LPCWSTR lpFilename )
148 LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFilename );
149 HMETAFILE32 ret = GetMetaFile32A( p );
150 HeapFree( GetProcessHeap(), 0, p );
155 /******************************************************************
156 * CopyMetaFile16 (GDI.151)
159 HMETAFILE16 WINAPI CopyMetaFile16( HMETAFILE16 hSrcMetaFile, LPCSTR lpFilename )
161 return CopyMetaFile32A( hSrcMetaFile, lpFilename );
165 /******************************************************************
166 * CopyMetaFile32A (GDI32.23)
168 * Copies the metafile corresponding to hSrcMetaFile to either
169 * a disk file, if a filename is given, or to a new memory based
170 * metafile, if lpFileName is NULL.
174 * Handle to metafile copy on success, NULL on failure.
178 * Copying to disk returns NULL even if successful.
180 HMETAFILE32 WINAPI CopyMetaFile32A(
181 HMETAFILE32 hSrcMetaFile,
182 /* handle of metafile to copy */
184 /* filename if copying to a file */
187 HMETAFILE16 handle = 0;
192 dprintf_info(metafile,"CopyMetaFile: %s\n", lpFilename);
194 mh = (METAHEADER *)GlobalLock16(hSrcMetaFile);
199 if (lpFilename) /* disk based metafile */
202 hFile = _lcreat32(lpFilename, 0);
204 mh->mtType=1; /* disk file version stores 1 here */
205 i=_lwrite32(hFile, (char *)mh, mh->mtSize * 2) ;
206 mh->mtType=j; /* restore old value [0 or 1] */
210 /* FIXME: return value */
212 else /* memory based metafile */
214 handle = GlobalAlloc16(GMEM_MOVEABLE,mh->mtSize * 2);
215 mh2 = (METAHEADER *)GlobalLock16(handle);
216 memcpy(mh2,mh, mh->mtSize * 2);
217 GlobalUnlock16(handle);
224 /******************************************************************
225 * CopyMetaFile32W (GDI32.24)
227 HMETAFILE32 WINAPI CopyMetaFile32W( HMETAFILE32 hSrcMetaFile,
230 LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFilename );
231 HMETAFILE32 ret = CopyMetaFile32A( hSrcMetaFile, p );
232 HeapFree( GetProcessHeap(), 0, p );
237 /******************************************************************
238 * IsValidMetaFile (GDI.410)
240 * Attempts to check if a given metafile is correctly formatted.
241 * Currently, the only things verified are several properties of the
245 * TRUE if hmf passes some tests for being a valid metafile, FALSE otherwise.
248 * This is not exactly what windows does, see _Undocumented_Windows_
252 BOOL16 WINAPI IsValidMetaFile(HMETAFILE16 hmf)
255 METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
257 if (mh->mtType == 1 || mh->mtType == 0)
258 if (mh->mtHeaderSize == MFHEADERSIZE/sizeof(INT16))
259 if (mh->mtVersion == MFVERSION)
263 dprintf_info(metafile,"IsValidMetaFile %x => %d\n",hmf,resu);
268 /******************************************************************
269 * PlayMetaFile16 (GDI.123)
272 BOOL16 WINAPI PlayMetaFile16( HDC16 hdc, HMETAFILE16 hmf )
274 return PlayMetaFile32( hdc, hmf );
277 /******************************************************************
278 * PlayMetaFile32 (GDI32.265)
280 * Renders the metafile specified by hmf in the DC specified by
281 * hdc. Returns FALSE on failure, TRUE on success.
283 BOOL32 WINAPI PlayMetaFile32(
284 HDC32 hdc, /* handle of DC to render in */
285 HMETAFILE32 hmf /* handle of metafile to render */
288 METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
299 dprintf_info(metafile,"PlayMetaFile(%04x %04x)\n",hdc,hmf);
300 if (!mh) return FALSE;
301 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
303 hBrush = dc->w.hBrush;
305 GDI_HEAP_UNLOCK(hdc);
306 /* create the handle table */
307 hHT = GlobalAlloc16(GMEM_MOVEABLE|GMEM_ZEROINIT,
308 sizeof(HANDLETABLE16) * mh->mtNoObjects);
309 ht = (HANDLETABLE16 *)GlobalLock16(hHT);
312 /* loop through metafile playing records */
313 offset = mh->mtHeaderSize * 2;
314 while (offset < mh->mtSize * 2)
316 mr = (METARECORD *)((char *)mh + offset);
317 dprintf_info(metafile,"offset = %04x size = %08lx\n",
320 fprintf(stderr,"METAFILE entry got size 0 at offset %d, total mf length is %ld\n",offset,mh->mtSize*2);
321 break; /* would loop endlessly otherwise */
323 offset += mr->rdSize * 2;
324 PlayMetaFileRecord16( hdc, ht, mr, mh->mtNoObjects );
327 SelectObject32(hdc, hBrush);
328 SelectObject32(hdc, hPen);
329 SelectObject32(hdc, hFont);
331 /* free objects in handle table */
332 for(i = 0; i < mh->mtNoObjects; i++)
333 if(*(ht->objectHandle + i) != 0)
334 DeleteObject32(*(ht->objectHandle + i));
336 /* free handle table */
343 /******************************************************************
344 * EnumMetaFile16 (GDI.175)
346 * Loop through the metafile records in hmf, calling the user-specified
347 * function for each one, stopping when the user's function returns FALSE
348 * (which is considered to be failure)
349 * or when no records are left (which is considered to be success).
352 * TRUE on success, FALSE on failure.
355 * Niels de carpentier, april 1996
357 BOOL16 WINAPI EnumMetaFile16(
360 MFENUMPROC16 lpEnumFunc,
364 METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
375 BOOL16 result = TRUE;
377 dprintf_info(metafile,"EnumMetaFile(%04x, %04x, %08lx, %08lx)\n",
378 hdc, hmf, (DWORD)lpEnumFunc, lpData);
380 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
382 hBrush = dc->w.hBrush;
384 GDI_HEAP_UNLOCK(hdc);
386 /* create the handle table */
388 hHT = GlobalAlloc16(GMEM_MOVEABLE | GMEM_ZEROINIT,
389 sizeof(HANDLETABLE16) * mh->mtNoObjects);
390 spht = WIN16_GlobalLock16(hHT);
392 seg = GlobalHandleToSel(hmf);
393 offset = mh->mtHeaderSize * 2;
395 /* loop through metafile records */
397 while (offset < (mh->mtSize * 2))
399 mr = (METARECORD *)((char *)mh + offset);
400 if (!lpEnumFunc( hdc, (HANDLETABLE16 *)spht,
401 (METARECORD *) PTR_SEG_OFF_TO_HUGEPTR(seg, offset),
402 mh->mtNoObjects, (LONG)lpData ))
409 offset += (mr->rdSize * 2);
412 SelectObject32(hdc, hBrush);
413 SelectObject32(hdc, hPen);
414 SelectObject32(hdc, hFont);
416 ht = (HANDLETABLE16 *)GlobalLock16(hHT);
418 /* free objects in handle table */
419 for(i = 0; i < mh->mtNoObjects; i++)
420 if(*(ht->objectHandle + i) != 0)
421 DeleteObject32(*(ht->objectHandle + i));
423 /* free handle table */
429 static BOOL32 MF_Meta_CreateRegion( METARECORD *mr, HRGN32 hrgn );
431 /******************************************************************
432 * PlayMetaFileRecord16 (GDI.176)
434 * Render a single metafile record specified by *mr in the DC hdc, while
435 * using the handle table *ht, of length nHandles,
436 * to store metafile objects.
439 * The following metafile records are unimplemented:
441 * FRAMEREGION, DRAWTEXT, SETDIBTODEV, ANIMATEPALETTE, SETPALENTRIES,
442 * RESIZEPALETTE, EXTFLOODFILL, RESETDC, STARTDOC, STARTPAGE, ENDPAGE,
443 * ABORTDOC, ENDDOC, CREATEBRUSH, CREATEBITMAPINDIRECT, and CREATEBITMAP.
447 void WINAPI PlayMetaFileRecord16(
449 /* DC to render metafile into */
451 /* pointer to handle table for metafile objects */
453 /* pointer to metafile record to render */
455 /* size of handle table */
461 BITMAPINFOHEADER *infohdr;
463 dprintf_info(metafile,
464 "PlayMetaFileRecord(%04x %08lx %08lx %04x) function %04x\n",
465 hdc,(LONG)ht, (LONG)mr, nHandles, mr->rdFunction);
467 switch (mr->rdFunction)
472 case META_DELETEOBJECT:
473 DeleteObject32(*(ht->objectHandle + *(mr->rdParam)));
474 *(ht->objectHandle + *(mr->rdParam)) = 0;
477 case META_SETBKCOLOR:
478 SetBkColor16(hdc, MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
482 SetBkMode16(hdc, *(mr->rdParam));
485 case META_SETMAPMODE:
486 SetMapMode16(hdc, *(mr->rdParam));
490 SetROP216(hdc, *(mr->rdParam));
494 SetRelAbs16(hdc, *(mr->rdParam));
497 case META_SETPOLYFILLMODE:
498 SetPolyFillMode16(hdc, *(mr->rdParam));
501 case META_SETSTRETCHBLTMODE:
502 SetStretchBltMode16(hdc, *(mr->rdParam));
505 case META_SETTEXTCOLOR:
506 SetTextColor16(hdc, MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
509 case META_SETWINDOWORG:
510 SetWindowOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
513 case META_SETWINDOWEXT:
514 SetWindowExt(hdc, *(mr->rdParam + 1), *(mr->rdParam));
517 case META_SETVIEWPORTORG:
518 SetViewportOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
521 case META_SETVIEWPORTEXT:
522 SetViewportExt(hdc, *(mr->rdParam + 1), *(mr->rdParam));
525 case META_OFFSETWINDOWORG:
526 OffsetWindowOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
529 case META_SCALEWINDOWEXT:
530 ScaleWindowExt(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
531 *(mr->rdParam + 1), *(mr->rdParam));
534 case META_OFFSETVIEWPORTORG:
535 OffsetViewportOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
538 case META_SCALEVIEWPORTEXT:
539 ScaleViewportExt(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
540 *(mr->rdParam + 1), *(mr->rdParam));
544 LineTo32(hdc, (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
548 MoveTo(hdc, *(mr->rdParam + 1), *(mr->rdParam));
551 case META_EXCLUDECLIPRECT:
552 ExcludeClipRect16( hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
553 *(mr->rdParam + 1), *(mr->rdParam) );
556 case META_INTERSECTCLIPRECT:
557 IntersectClipRect16( hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
558 *(mr->rdParam + 1), *(mr->rdParam) );
562 Arc32(hdc, (INT16)*(mr->rdParam + 7), (INT16)*(mr->rdParam + 6),
563 (INT16)*(mr->rdParam + 5), (INT16)*(mr->rdParam + 4),
564 (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
565 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
569 Ellipse32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
570 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
574 FloodFill32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
575 MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
579 Pie32(hdc, (INT16)*(mr->rdParam + 7), (INT16)*(mr->rdParam + 6),
580 (INT16)*(mr->rdParam + 5), (INT16)*(mr->rdParam + 4),
581 (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
582 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
586 Rectangle32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
587 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
591 RoundRect32(hdc, (INT16)*(mr->rdParam + 5), (INT16)*(mr->rdParam + 4),
592 (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
593 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
597 PatBlt16(hdc, *(mr->rdParam + 5), *(mr->rdParam + 4),
598 *(mr->rdParam + 3), *(mr->rdParam + 2),
599 MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
607 SetPixel32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
608 MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
611 case META_OFFSETCLIPRGN:
612 OffsetClipRgn16( hdc, *(mr->rdParam + 1), *(mr->rdParam) );
617 TextOut16(hdc, *(mr->rdParam + ((s1 + 1) >> 1) + 2),
618 *(mr->rdParam + ((s1 + 1) >> 1) + 1),
619 (char *)(mr->rdParam + 1), s1);
623 Polygon16(hdc, (LPPOINT16)(mr->rdParam + 1), *(mr->rdParam));
626 case META_POLYPOLYGON:
627 PolyPolygon16(hdc, (LPPOINT16)(mr->rdParam + *(mr->rdParam) + 1),
628 (LPINT16)(mr->rdParam + 1), *(mr->rdParam));
632 Polyline16(hdc, (LPPOINT16)(mr->rdParam + 1), *(mr->rdParam));
636 RestoreDC32(hdc, (INT16)*(mr->rdParam));
639 case META_SELECTOBJECT:
640 SelectObject32(hdc, *(ht->objectHandle + *(mr->rdParam)));
644 Chord32(hdc, (INT16)*(mr->rdParam + 7), (INT16)*(mr->rdParam + 6),
645 (INT16)*(mr->rdParam+5), (INT16)*(mr->rdParam + 4),
646 (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
647 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
650 case META_CREATEPATTERNBRUSH:
651 switch (*(mr->rdParam))
654 infohdr = (BITMAPINFOHEADER *)(mr->rdParam + 2);
655 MF_AddHandle(ht, nHandles,
656 CreatePatternBrush32(CreateBitmap32(infohdr->biWidth,
660 (LPSTR)(mr->rdParam +
661 (sizeof(BITMAPINFOHEADER) / 2) + 4))));
665 s1 = mr->rdSize * 2 - sizeof(METARECORD) - 2;
666 hndl = GlobalAlloc16(GMEM_MOVEABLE, s1);
667 ptr = GlobalLock16(hndl);
668 memcpy(ptr, mr->rdParam + 2, s1);
669 GlobalUnlock16(hndl);
670 MF_AddHandle(ht, nHandles,
671 CreateDIBPatternBrush32(hndl, *(mr->rdParam + 1)));
676 case META_CREATEPENINDIRECT:
677 MF_AddHandle(ht, nHandles,
678 CreatePenIndirect16((LOGPEN16 *)(&(mr->rdParam))));
681 case META_CREATEFONTINDIRECT:
682 MF_AddHandle(ht, nHandles,
683 CreateFontIndirect16((LOGFONT16 *)(&(mr->rdParam))));
686 case META_CREATEBRUSHINDIRECT:
687 MF_AddHandle(ht, nHandles,
688 CreateBrushIndirect16((LOGBRUSH16 *)(&(mr->rdParam))));
691 /* W. Magro: Some new metafile operations. Not all debugged. */
692 case META_CREATEPALETTE:
693 MF_AddHandle(ht, nHandles,
694 CreatePalette16((LPLOGPALETTE)mr->rdParam));
697 case META_SETTEXTALIGN:
698 SetTextAlign16(hdc, *(mr->rdParam));
701 case META_SELECTPALETTE:
702 SelectPalette16(hdc, *(ht->objectHandle + *(mr->rdParam+1)),*(mr->rdParam));
705 case META_SETMAPPERFLAGS:
706 SetMapperFlags16(hdc, *(mr->rdParam));
709 case META_REALIZEPALETTE:
710 RealizePalette16(hdc);
714 dprintf_fixme(metafile, "PlayMetaFileRecord: META_ESCAPE unimplemented.\n");
717 /* --- Begin of fixed or new metafile operations. July 1996 ----*/
718 case META_EXTTEXTOUT:
724 s1 = mr->rdParam[2]; /* String length */
725 len = sizeof(METARECORD) + (((s1 + 1) >> 1) * 2) + 2 * sizeof(short)
726 + sizeof(UINT16) + (mr->rdParam[3] ? sizeof(RECT16) : 0); /* rec len without dx array */
728 sot= (LPSTR)&mr->rdParam[4]; /* start_of_text */
730 sot+=sizeof(RECT16); /* there is a rectangle, so add offset */
732 if (mr->rdSize == len / 2)
733 dxx = NULL; /* determine if array present */
735 if (mr->rdSize == (len + s1 * sizeof(INT16)) / 2)
736 dxx = (LPINT16)(sot+(((s1+1)>>1)*2));
739 dprintf_info(metafile,"EXTTEXTOUT: %s len: %ld\n",
742 "Please report: PlayMetaFile/ExtTextOut len=%ld slen=%d rdSize=%ld opt=%04x\n",
743 len,s1,mr->rdSize,mr->rdParam[3]);
744 dxx = NULL; /* should't happen -- but if, we continue with NULL [for workaround] */
746 ExtTextOut16( hdc, mr->rdParam[1], /* X position */
747 mr->rdParam[0], /* Y position */
748 mr->rdParam[3], /* options */
749 mr->rdParam[3] ? (LPRECT16) &mr->rdParam[4]:NULL, /* rectangle */
751 s1, dxx); /* length, dx array */
753 dprintf_info(metafile,"EXTTEXTOUT: %s len: %ld dx0: %d\n",
754 sot,mr->rdSize,dxx[0]);
758 case META_STRETCHDIB:
760 LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParam[11]);
761 LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize( info, mr->rdParam[2] );
762 StretchDIBits16(hdc,mr->rdParam[10],mr->rdParam[9],mr->rdParam[8],
763 mr->rdParam[7],mr->rdParam[6],mr->rdParam[5],
764 mr->rdParam[4],mr->rdParam[3],bits,info,
765 mr->rdParam[2],MAKELONG(mr->rdParam[0],mr->rdParam[1]));
769 case META_DIBSTRETCHBLT:
771 LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParam[10]);
772 LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize( info, mr->rdParam[2] );
773 StretchDIBits16(hdc,mr->rdParam[9],mr->rdParam[8],mr->rdParam[7],
774 mr->rdParam[6],mr->rdParam[5],mr->rdParam[4],
775 mr->rdParam[3],mr->rdParam[2],bits,info,
776 DIB_RGB_COLORS,MAKELONG(mr->rdParam[0],mr->rdParam[1]));
780 case META_STRETCHBLT:
782 HDC16 hdcSrc=CreateCompatibleDC16(hdc);
783 HBITMAP32 hbitmap=CreateBitmap32(mr->rdParam[10], /*Width */
784 mr->rdParam[11], /*Height*/
785 mr->rdParam[13], /*Planes*/
786 mr->rdParam[14], /*BitsPixel*/
787 (LPSTR)&mr->rdParam[15]); /*bits*/
788 SelectObject32(hdcSrc,hbitmap);
789 StretchBlt16(hdc,mr->rdParam[9],mr->rdParam[8],
790 mr->rdParam[7],mr->rdParam[6],
791 hdcSrc,mr->rdParam[5],mr->rdParam[4],
792 mr->rdParam[3],mr->rdParam[2],
793 MAKELONG(mr->rdParam[0],mr->rdParam[1]));
798 case META_BITBLT: /* <-- not yet debugged */
800 HDC16 hdcSrc=CreateCompatibleDC16(hdc);
801 HBITMAP32 hbitmap=CreateBitmap32(mr->rdParam[7]/*Width */,
802 mr->rdParam[8]/*Height*/,
803 mr->rdParam[10]/*Planes*/,
804 mr->rdParam[11]/*BitsPixel*/,
805 (LPSTR)&mr->rdParam[12]/*bits*/);
806 SelectObject32(hdcSrc,hbitmap);
807 BitBlt32(hdc,(INT16)mr->rdParam[6],(INT16)mr->rdParam[5],
808 (INT16)mr->rdParam[4],(INT16)mr->rdParam[3],
809 hdcSrc, (INT16)mr->rdParam[2],(INT16)mr->rdParam[1],
810 MAKELONG(0,mr->rdParam[0]));
815 /* --- Begin of new metafile operations. April, 1997 (ak) ----*/
816 case META_CREATEREGION:
818 HRGN32 hrgn = CreateRectRgn32(0,0,0,0);
820 MF_Meta_CreateRegion(mr, hrgn);
821 MF_AddHandle(ht, nHandles, hrgn);
825 case META_FILLREGION:
826 FillRgn16(hdc, *(ht->objectHandle + *(mr->rdParam)),
827 *(ht->objectHandle + *(mr->rdParam+1)));
830 case META_INVERTREGION:
831 InvertRgn16(hdc, *(ht->objectHandle + *(mr->rdParam)));
834 case META_PAINTREGION:
835 PaintRgn16(hdc, *(ht->objectHandle + *(mr->rdParam)));
838 case META_SELECTCLIPREGION:
839 SelectClipRgn32(hdc, *(ht->objectHandle + *(mr->rdParam)));
842 case META_DIBCREATEPATTERNBRUSH:
843 /* *(mr->rdParam) may be BS_PATTERN or BS_DIBPATTERN: but there's no difference */
844 dprintf_info(metafile,"META_DIBCREATEPATTERNBRUSH: %d\n",*(mr->rdParam));
845 s1 = mr->rdSize * 2 - sizeof(METARECORD) - 2;
846 hndl = GlobalAlloc16(GMEM_MOVEABLE, s1);
847 ptr = GlobalLock16(hndl);
848 memcpy(ptr, mr->rdParam + 2, s1);
849 GlobalUnlock16(hndl);
850 MF_AddHandle(ht, nHandles,CreateDIBPatternBrush16(hndl, *(mr->rdParam + 1)));
856 LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParam[8]);
857 LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize( info, mr->rdParam[0] );
858 StretchDIBits16(hdc,mr->rdParam[7],mr->rdParam[6],mr->rdParam[5],
859 mr->rdParam[4],mr->rdParam[3],mr->rdParam[2],
860 mr->rdParam[5],mr->rdParam[4],bits,info,
861 DIB_RGB_COLORS,MAKELONG(mr->rdParam[0],mr->rdParam[1]));
865 case META_SETTEXTCHAREXTRA:
866 SetTextCharacterExtra16(hdc, (INT16)*(mr->rdParam));
869 case META_SETTEXTJUSTIFICATION:
870 SetTextJustification32(hdc, *(mr->rdParam + 1), *(mr->rdParam));
873 #define META_UNIMP(x) case x: fprintf(stderr,"PlayMetaFileRecord:record type "#x" not implemented.\n");break;
874 META_UNIMP(META_FRAMEREGION)
875 META_UNIMP(META_DRAWTEXT)
876 META_UNIMP(META_SETDIBTODEV)
877 META_UNIMP(META_ANIMATEPALETTE)
878 META_UNIMP(META_SETPALENTRIES)
879 META_UNIMP(META_RESIZEPALETTE)
880 META_UNIMP(META_EXTFLOODFILL)
881 META_UNIMP(META_RESETDC)
882 META_UNIMP(META_STARTDOC)
883 META_UNIMP(META_STARTPAGE)
884 META_UNIMP(META_ENDPAGE)
885 META_UNIMP(META_ABORTDOC)
886 META_UNIMP(META_ENDDOC)
887 META_UNIMP(META_CREATEBRUSH)
888 META_UNIMP(META_CREATEBITMAPINDIRECT)
889 META_UNIMP(META_CREATEBITMAP)
893 fprintf(stddeb,"PlayMetaFileRecord: Unknown record type %x\n",
899 /******************************************************************
900 * GetMetaFileBits (GDI.159)
902 * Trade in a metafile object handle for a handle to the metafile memory.
906 HGLOBAL16 WINAPI GetMetaFileBits(
907 HMETAFILE16 hmf /* metafile handle */
910 dprintf_info(metafile,"GetMetaFileBits: hMem out: %04x\n", hmf);
914 /******************************************************************
915 * SetMetaFileBits (GDI.160)
917 * Trade in a metafile memory handle for a handle to a metafile object.
918 * The memory region should hold a proper metafile, otherwise
919 * problems will occur when it is used. Validity of the memory is not
920 * checked. The function is essentially just the identity function.
922 HMETAFILE16 WINAPI SetMetaFileBits(
924 /* handle to a memory region holding a metafile */
927 dprintf_info(metafile,"SetMetaFileBits: hmf out: %04x\n", hMem);
932 /******************************************************************
933 * SetMetaFileBitsBetter (GDI.196)
935 * Trade in a metafile memory handle for a handle to a metafile object,
936 * making a cursory check (using IsValidMetaFile()) that the memory
937 * handle points to a valid metafile.
940 * Handle to a metafile on success, NULL on failure..
942 HMETAFILE16 WINAPI SetMetaFileBitsBetter( HMETAFILE16 hMeta )
944 if( IsValidMetaFile( hMeta ) )
945 return (HMETAFILE16)GlobalReAlloc16( hMeta, 0,
946 GMEM_SHARE | GMEM_NODISCARD | GMEM_MODIFY);
947 return (HMETAFILE16)0;
950 /******************************************************************
951 * MF_Meta_CreateRegion
953 * Handles META_CREATEREGION for PlayMetaFileRecord().
957 * The layout of the record looks something like this:
962 * 2 Looks like a handle? - not constant
964 * 4 Total number of bytes
965 * 5 No. of seperate bands = n [see below]
966 * 6 Largest number of x co-ords in a band
967 * 7-10 Bounding box x1 y1 x2 y2
970 * Regions are divided into bands that are uniform in the
971 * y-direction. Each band consists of pairs of on/off x-coords and is
973 * m y0 y1 x1 x2 x3 ... xm m
974 * into successive rdParam[]s.
976 * This is probably just a dump of the internal RGNOBJ?
982 static BOOL32 MF_Meta_CreateRegion( METARECORD *mr, HRGN32 hrgn )
987 HRGN32 hrgn2 = CreateRectRgn32( 0, 0, 0, 0 );
989 for(band = 0, start = &(mr->rdParam[11]); band < mr->rdParam[5];
990 band++, start = end + 1) {
991 if(*start / 2 != (*start + 1) / 2) {
992 fprintf(stderr, "META_CREATEREGION: delimiter not even.\n");
993 DeleteObject32( hrgn2 );
997 end = start + *start + 3;
998 if(end > (WORD *)mr + mr->rdSize) {
999 fprintf(stderr, "META_CREATEREGION: end points outside record.\n");
1000 DeleteObject32( hrgn2 );
1004 if(*start != *end) {
1005 fprintf(stderr, "META_CREATEREGION: mismatched delimiters.\n");
1006 DeleteObject32( hrgn2 );
1010 y0 = *(INT16 *)(start + 1);
1011 y1 = *(INT16 *)(start + 2);
1012 for(pair = 0; pair < *start / 2; pair++) {
1013 SetRectRgn32( hrgn2, *(INT16 *)(start + 3 + 2*pair), y0,
1014 *(INT16 *)(start + 4 + 2*pair), y1 );
1015 CombineRgn32(hrgn, hrgn, hrgn2, RGN_OR);
1018 DeleteObject32( hrgn2 );
1023 /******************************************************************
1026 * Warning: this function can change the metafile handle.
1029 static BOOL32 MF_WriteRecord( DC *dc, METARECORD *mr, DWORD rlen)
1033 METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
1035 switch(physDev->mh->mtType)
1037 case METAFILE_MEMORY:
1038 len = physDev->mh->mtSize * 2 + rlen;
1039 mh = HeapReAlloc( SystemHeap, 0, physDev->mh, len );
1040 if (!mh) return FALSE;
1042 memcpy((WORD *)physDev->mh + physDev->mh->mtSize, mr, rlen);
1045 dprintf_info(metafile,"Writing record to disk\n");
1046 if (_lwrite32(physDev->mh->mtNoParameters, (char *)mr, rlen) == -1)
1050 fprintf( stderr, "Unknown metafile type %d\n", physDev->mh->mtType );
1054 physDev->mh->mtSize += rlen / 2;
1055 physDev->mh->mtMaxRecord = MAX(physDev->mh->mtMaxRecord, rlen / 2);
1060 /******************************************************************
1064 BOOL32 MF_MetaParam0(DC *dc, short func)
1067 METARECORD *mr = (METARECORD *)&buffer;
1070 mr->rdFunction = func;
1071 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1075 /******************************************************************
1078 BOOL32 MF_MetaParam1(DC *dc, short func, short param1)
1081 METARECORD *mr = (METARECORD *)&buffer;
1084 mr->rdFunction = func;
1085 *(mr->rdParam) = param1;
1086 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1090 /******************************************************************
1093 BOOL32 MF_MetaParam2(DC *dc, short func, short param1, short param2)
1096 METARECORD *mr = (METARECORD *)&buffer;
1099 mr->rdFunction = func;
1100 *(mr->rdParam) = param2;
1101 *(mr->rdParam + 1) = param1;
1102 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1106 /******************************************************************
1110 BOOL32 MF_MetaParam4(DC *dc, short func, short param1, short param2,
1111 short param3, short param4)
1114 METARECORD *mr = (METARECORD *)&buffer;
1117 mr->rdFunction = func;
1118 *(mr->rdParam) = param4;
1119 *(mr->rdParam + 1) = param3;
1120 *(mr->rdParam + 2) = param2;
1121 *(mr->rdParam + 3) = param1;
1122 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1126 /******************************************************************
1130 BOOL32 MF_MetaParam6(DC *dc, short func, short param1, short param2,
1131 short param3, short param4, short param5, short param6)
1134 METARECORD *mr = (METARECORD *)&buffer;
1137 mr->rdFunction = func;
1138 *(mr->rdParam) = param6;
1139 *(mr->rdParam + 1) = param5;
1140 *(mr->rdParam + 2) = param4;
1141 *(mr->rdParam + 3) = param3;
1142 *(mr->rdParam + 4) = param2;
1143 *(mr->rdParam + 5) = param1;
1144 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1148 /******************************************************************
1151 BOOL32 MF_MetaParam8(DC *dc, short func, short param1, short param2,
1152 short param3, short param4, short param5,
1153 short param6, short param7, short param8)
1156 METARECORD *mr = (METARECORD *)&buffer;
1159 mr->rdFunction = func;
1160 *(mr->rdParam) = param8;
1161 *(mr->rdParam + 1) = param7;
1162 *(mr->rdParam + 2) = param6;
1163 *(mr->rdParam + 3) = param5;
1164 *(mr->rdParam + 4) = param4;
1165 *(mr->rdParam + 5) = param3;
1166 *(mr->rdParam + 6) = param2;
1167 *(mr->rdParam + 7) = param1;
1168 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1172 /******************************************************************
1173 * MF_CreateBrushIndirect
1176 BOOL32 MF_CreateBrushIndirect(DC *dc, HBRUSH16 hBrush, LOGBRUSH16 *logbrush)
1179 char buffer[sizeof(METARECORD) - 2 + sizeof(*logbrush)];
1180 METARECORD *mr = (METARECORD *)&buffer;
1182 mr->rdSize = (sizeof(METARECORD) + sizeof(*logbrush) - 2) / 2;
1183 mr->rdFunction = META_CREATEBRUSHINDIRECT;
1184 memcpy(&(mr->rdParam), logbrush, sizeof(*logbrush));
1185 if (!(MF_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
1187 mr->rdSize = sizeof(METARECORD) / 2;
1188 mr->rdFunction = META_SELECTOBJECT;
1190 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1191 *(mr->rdParam) = index;
1192 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1196 /******************************************************************
1197 * MF_CreatePatternBrush
1200 BOOL32 MF_CreatePatternBrush(DC *dc, HBRUSH16 hBrush, LOGBRUSH16 *logbrush)
1202 DWORD len, bmSize, biSize;
1207 BITMAPINFOHEADER *infohdr;
1209 char buffer[sizeof(METARECORD)];
1211 switch (logbrush->lbStyle)
1214 bmp = (BITMAPOBJ *)GDI_GetObjPtr((HGDIOBJ16)logbrush->lbHatch, BITMAP_MAGIC);
1215 if (!bmp) return FALSE;
1216 len = sizeof(METARECORD) + sizeof(BITMAPINFOHEADER) +
1217 (bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes) + 6;
1218 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1220 GDI_HEAP_UNLOCK((HGDIOBJ16)logbrush->lbHatch);
1223 mr = (METARECORD *)GlobalLock16(hmr);
1225 mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
1226 mr->rdSize = len / 2;
1227 *(mr->rdParam) = logbrush->lbStyle;
1228 *(mr->rdParam + 1) = DIB_RGB_COLORS;
1229 infohdr = (BITMAPINFOHEADER *)(mr->rdParam + 2);
1230 infohdr->biSize = sizeof(BITMAPINFOHEADER);
1231 infohdr->biWidth = bmp->bitmap.bmWidth;
1232 infohdr->biHeight = bmp->bitmap.bmHeight;
1233 infohdr->biPlanes = bmp->bitmap.bmPlanes;
1234 infohdr->biBitCount = bmp->bitmap.bmBitsPixel;
1235 memcpy(mr->rdParam + (sizeof(BITMAPINFOHEADER) / 2) + 4,
1236 PTR_SEG_TO_LIN(bmp->bitmap.bmBits),
1237 bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes);
1238 GDI_HEAP_UNLOCK(logbrush->lbHatch);
1242 info = (BITMAPINFO *)GlobalLock16((HGLOBAL16)logbrush->lbHatch);
1243 if (info->bmiHeader.biCompression)
1244 bmSize = info->bmiHeader.biSizeImage;
1246 bmSize = (info->bmiHeader.biWidth * info->bmiHeader.biBitCount
1247 + 31) / 32 * 8 * info->bmiHeader.biHeight;
1248 biSize = DIB_BitmapInfoSize(info, LOWORD(logbrush->lbColor));
1249 len = sizeof(METARECORD) + biSize + bmSize + 2;
1250 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1252 mr = (METARECORD *)GlobalLock16(hmr);
1254 mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
1255 mr->rdSize = len / 2;
1256 *(mr->rdParam) = logbrush->lbStyle;
1257 *(mr->rdParam + 1) = LOWORD(logbrush->lbColor);
1258 memcpy(mr->rdParam + 2, info, biSize + bmSize);
1263 if (!(MF_WriteRecord(dc, mr, len)))
1271 mr = (METARECORD *)&buffer;
1272 mr->rdSize = sizeof(METARECORD) / 2;
1273 mr->rdFunction = META_SELECTOBJECT;
1275 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1276 *(mr->rdParam) = index;
1277 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1281 /******************************************************************
1282 * MF_CreatePenIndirect
1285 BOOL32 MF_CreatePenIndirect(DC *dc, HPEN16 hPen, LOGPEN16 *logpen)
1288 char buffer[sizeof(METARECORD) - 2 + sizeof(*logpen)];
1289 METARECORD *mr = (METARECORD *)&buffer;
1291 mr->rdSize = (sizeof(METARECORD) + sizeof(*logpen) - 2) / 2;
1292 mr->rdFunction = META_CREATEPENINDIRECT;
1293 memcpy(&(mr->rdParam), logpen, sizeof(*logpen));
1294 if (!(MF_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
1296 mr->rdSize = sizeof(METARECORD) / 2;
1297 mr->rdFunction = META_SELECTOBJECT;
1299 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1300 *(mr->rdParam) = index;
1301 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1305 /******************************************************************
1306 * MF_CreateFontIndirect
1309 BOOL32 MF_CreateFontIndirect(DC *dc, HFONT16 hFont, LOGFONT16 *logfont)
1312 char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT16)];
1313 METARECORD *mr = (METARECORD *)&buffer;
1315 mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT16) - 2) / 2;
1316 mr->rdFunction = META_CREATEFONTINDIRECT;
1317 memcpy(&(mr->rdParam), logfont, sizeof(LOGFONT16));
1318 if (!(MF_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
1320 mr->rdSize = sizeof(METARECORD) / 2;
1321 mr->rdFunction = META_SELECTOBJECT;
1323 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1324 *(mr->rdParam) = index;
1325 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1329 /******************************************************************
1332 BOOL32 MF_TextOut(DC *dc, short x, short y, LPCSTR str, short count)
1339 len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 4;
1340 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1342 mr = (METARECORD *)GlobalLock16(hmr);
1345 mr->rdSize = len / 2;
1346 mr->rdFunction = META_TEXTOUT;
1347 *(mr->rdParam) = count;
1348 memcpy(mr->rdParam + 1, str, count);
1349 *(mr->rdParam + ((count + 1) >> 1) + 1) = y;
1350 *(mr->rdParam + ((count + 1) >> 1) + 2) = x;
1351 ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
1356 /******************************************************************
1359 BOOL32 MF_ExtTextOut(DC*dc, short x, short y, UINT16 flags, const RECT16 *rect,
1360 LPCSTR str, short count, const INT16 *lpDx)
1367 if((!flags && rect) || (flags && !rect))
1368 fprintf(stderr, "MF_ExtTextOut: Inconsistent flags and rect\n");
1369 len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 2 * sizeof(short)
1372 len += sizeof(RECT16);
1374 len+=count*sizeof(INT16);
1375 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1377 mr = (METARECORD *)GlobalLock16(hmr);
1380 mr->rdSize = len / 2;
1381 mr->rdFunction = META_EXTTEXTOUT;
1383 *(mr->rdParam + 1) = x;
1384 *(mr->rdParam + 2) = count;
1385 *(mr->rdParam + 3) = flags;
1386 if (rect) memcpy(mr->rdParam + 4, rect, sizeof(RECT16));
1387 memcpy(mr->rdParam + (rect ? 8 : 4), str, count);
1389 memcpy(mr->rdParam + (rect ? 8 : 4) + ((count + 1) >> 1),lpDx,
1390 count*sizeof(INT16));
1391 ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
1396 /******************************************************************
1397 * MF_MetaPoly - implements Polygon and Polyline
1399 BOOL32 MF_MetaPoly(DC *dc, short func, LPPOINT16 pt, short count)
1406 len = sizeof(METARECORD) + (count * 4);
1407 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1409 mr = (METARECORD *)GlobalLock16(hmr);
1412 mr->rdSize = len / 2;
1413 mr->rdFunction = func;
1414 *(mr->rdParam) = count;
1415 memcpy(mr->rdParam + 1, pt, count * 4);
1416 ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
1422 /******************************************************************
1425 BOOL32 MF_BitBlt(DC *dcDest, short xDest, short yDest, short width,
1426 short height, DC *dcSrc, short xSrc, short ySrc, DWORD rop)
1434 GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM);
1435 len = sizeof(METARECORD) + 12 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
1436 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1438 mr = (METARECORD *)GlobalLock16(hmr);
1439 mr->rdFunction = META_BITBLT;
1440 *(mr->rdParam + 7) = BM.bmWidth;
1441 *(mr->rdParam + 8) = BM.bmHeight;
1442 *(mr->rdParam + 9) = BM.bmWidthBytes;
1443 *(mr->rdParam +10) = BM.bmPlanes;
1444 *(mr->rdParam +11) = BM.bmBitsPixel;
1445 dprintf_info(metafile,"MF_StretchBlt->len = %ld rop=%lx \n",len,rop);
1446 if (GetBitmapBits32(dcSrc->w.hBitmap,BM.bmWidthBytes * BM.bmHeight,
1449 mr->rdSize = len / sizeof(INT16);
1450 *(mr->rdParam) = HIWORD(rop);
1451 *(mr->rdParam + 1) = ySrc;
1452 *(mr->rdParam + 2) = xSrc;
1453 *(mr->rdParam + 3) = height;
1454 *(mr->rdParam + 4) = width;
1455 *(mr->rdParam + 5) = yDest;
1456 *(mr->rdParam + 6) = xDest;
1457 ret = MF_WriteRecord( dcDest, mr, mr->rdSize * 2);
1466 /**********************************************************************
1468 * this function contains TWO ways for procesing StretchBlt in metafiles,
1469 * decide between rdFunction values META_STRETCHBLT or META_DIBSTRETCHBLT
1470 * via #define STRETCH_VIA_DIB
1472 #define STRETCH_VIA_DIB
1473 #undef STRETCH_VIA_DIB
1474 BOOL32 MF_StretchBlt(DC *dcDest, short xDest, short yDest, short widthDest,
1475 short heightDest, DC *dcSrc, short xSrc, short ySrc,
1476 short widthSrc, short heightSrc, DWORD rop)
1483 #ifdef STRETCH_VIA_DIB
1484 LPBITMAPINFOHEADER lpBMI;
1487 GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM);
1488 #ifdef STRETCH_VIA_DIB
1489 nBPP = BM.bmPlanes * BM.bmBitsPixel;
1490 len = sizeof(METARECORD) + 10 * sizeof(INT16)
1491 + sizeof(BITMAPINFOHEADER) + (nBPP != 24 ? 1 << nBPP: 0) * sizeof(RGBQUAD)
1492 + ((BM.bmWidth * nBPP + 31) / 32) * 4 * BM.bmHeight;
1493 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1495 mr = (METARECORD *)GlobalLock16(hmr);
1496 mr->rdFunction = META_DIBSTRETCHBLT;
1497 lpBMI=(LPBITMAPINFOHEADER)(mr->rdParam+10);
1498 lpBMI->biSize = sizeof(BITMAPINFOHEADER);
1499 lpBMI->biWidth = BM.bmWidth;
1500 lpBMI->biHeight = BM.bmHeight;
1501 lpBMI->biPlanes = 1;
1502 lpBMI->biBitCount = nBPP; /* 1,4,8 or 24 */
1503 lpBMI->biClrUsed = nBPP != 24 ? 1 << nBPP : 0;
1504 lpBMI->biSizeImage = ((lpBMI->biWidth * nBPP + 31) / 32) * 4 * lpBMI->biHeight;
1505 lpBMI->biCompression = BI_RGB;
1506 lpBMI->biXPelsPerMeter = MulDiv32(GetDeviceCaps(dcSrc->hSelf,LOGPIXELSX),3937,100);
1507 lpBMI->biYPelsPerMeter = MulDiv32(GetDeviceCaps(dcSrc->hSelf,LOGPIXELSY),3937,100);
1508 lpBMI->biClrImportant = 0; /* 1 meter = 39.37 inch */
1510 dprintf_info(metafile,"MF_StretchBltViaDIB->len = %ld rop=%lx PixYPM=%ld Caps=%d\n",
1511 len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(hdcSrc,LOGPIXELSY));
1512 if (GetDIBits(hdcSrc,dcSrc->w.hBitmap,0,(UINT32)lpBMI->biHeight,
1513 (LPSTR)lpBMI + DIB_BitmapInfoSize( (BITMAPINFO *)lpBMI,
1515 (LPBITMAPINFO)lpBMI, DIB_RGB_COLORS))
1517 len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
1518 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1520 mr = (METARECORD *)GlobalLock16(hmr);
1521 mr->rdFunction = META_STRETCHBLT;
1522 *(mr->rdParam +10) = BM.bmWidth;
1523 *(mr->rdParam +11) = BM.bmHeight;
1524 *(mr->rdParam +12) = BM.bmWidthBytes;
1525 *(mr->rdParam +13) = BM.bmPlanes;
1526 *(mr->rdParam +14) = BM.bmBitsPixel;
1527 dprintf_info(metafile,"MF_StretchBlt->len = %ld rop=%lx \n",len,rop);
1528 if (GetBitmapBits32( dcSrc->w.hBitmap, BM.bmWidthBytes * BM.bmHeight,
1532 mr->rdSize = len / sizeof(INT16);
1533 *(mr->rdParam) = LOWORD(rop);
1534 *(mr->rdParam + 1) = HIWORD(rop);
1535 *(mr->rdParam + 2) = heightSrc;
1536 *(mr->rdParam + 3) = widthSrc;
1537 *(mr->rdParam + 4) = ySrc;
1538 *(mr->rdParam + 5) = xSrc;
1539 *(mr->rdParam + 6) = heightDest;
1540 *(mr->rdParam + 7) = widthDest;
1541 *(mr->rdParam + 8) = yDest;
1542 *(mr->rdParam + 9) = xDest;
1543 ret = MF_WriteRecord( dcDest, mr, mr->rdSize * 2);
1552 /******************************************************************
1555 INT16 MF_CreateRegion(DC *dc, HRGN32 hrgn)
1560 RECT32 *pCurRect, *pEndRect;
1561 WORD Bands = 0, MaxBands = 0;
1562 WORD *Param, *StartBand;
1565 len = GetRegionData( hrgn, 0, NULL );
1566 if( !(rgndata = HeapAlloc( SystemHeap, 0, len )) ) {
1567 fprintf(stderr, "MF_CreateRegion: can't alloc rgndata buffer\n");
1570 GetRegionData( hrgn, len, rgndata );
1572 /* Overestimate of length:
1573 * Assume every rect is a separate band -> 6 WORDs per rect
1575 len = sizeof(METARECORD) + 20 + (rgndata->rdh.nCount * 12);
1576 if( !(mr = HeapAlloc( SystemHeap, 0, len )) ) {
1577 fprintf(stderr, "MF_CreateRegion: can't alloc METARECORD buffer\n");
1578 HeapFree( SystemHeap, 0, rgndata );
1584 Param = mr->rdParam + 11;
1587 pEndRect = (RECT32 *)rgndata->Buffer + rgndata->rdh.nCount;
1588 for(pCurRect = (RECT32 *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
1590 if( StartBand && pCurRect->top == *(StartBand + 1) )
1592 *Param++ = pCurRect->left;
1593 *Param++ = pCurRect->right;
1599 *StartBand = Param - StartBand - 3;
1600 *Param++ = *StartBand;
1601 if(*StartBand > MaxBands)
1602 MaxBands = *StartBand;
1605 StartBand = Param++;
1606 *Param++ = pCurRect->top;
1607 *Param++ = pCurRect->bottom;
1608 *Param++ = pCurRect->left;
1609 *Param++ = pCurRect->right;
1612 len = Param - (WORD *)mr;
1616 mr->rdParam[2] = 0x1234;
1618 mr->rdParam[4] = len * 2;
1619 mr->rdParam[5] = Bands;
1620 mr->rdParam[6] = MaxBands;
1621 mr->rdParam[7] = rgndata->rdh.rcBound.left;
1622 mr->rdParam[8] = rgndata->rdh.rcBound.top;
1623 mr->rdParam[9] = rgndata->rdh.rcBound.right;
1624 mr->rdParam[10] = rgndata->rdh.rcBound.bottom;
1625 mr->rdFunction = META_CREATEREGION;
1626 mr->rdSize = len / 2;
1627 ret = MF_WriteRecord( dc, mr, mr->rdSize * 2 );
1628 HeapFree( SystemHeap, 0, mr );
1629 HeapFree( SystemHeap, 0, rgndata );
1632 fprintf(stderr, "MF_CreateRegion: MF_WriteRecord failed\n");
1635 return MF_AddHandleDC( dc );