4 * Copyright David W. Metcalfe, 1994
5 * Niels de Carpentier, Albrecht Kleine, Huw Davies 1996
11 #include "wine/winbase16.h"
12 #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 WINAPI GetMetaFile16( LPCSTR lpFilename )
62 return GetMetaFile32A( lpFilename );
66 /******************************************************************
67 * GetMetaFile32A (GDI32.197)
69 * Read a metafile from a file. Returns handle to a disk-based metafile.
71 HMETAFILE32 WINAPI GetMetaFile32A(
73 /* pointer to string containing filename to read */
81 TRACE(metafile,"%s\n", lpFilename);
86 hmf = GlobalAlloc16(GMEM_MOVEABLE, MFHEADERSIZE);
87 mh = (METAHEADER *)GlobalLock16(hmf);
95 if ((hFile = _lopen32(lpFilename, OF_READ)) == HFILE_ERROR32)
101 if (_lread32(hFile, (char *)mh, MFHEADERSIZE) == HFILE_ERROR32)
108 size = mh->mtSize * 2; /* alloc memory for whole metafile */
110 hmf = GlobalReAlloc16(hmf,size,GMEM_MOVEABLE);
111 mh = (METAHEADER *)GlobalLock16(hmf);
120 if (_lread32(hFile, (char*)mh + mh->mtHeaderSize * 2,
121 size - mh->mtHeaderSize * 2) == HFILE_ERROR32)
142 /******************************************************************
143 * GetMetaFile32W (GDI32.199)
145 HMETAFILE32 WINAPI GetMetaFile32W( LPCWSTR lpFilename )
147 LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFilename );
148 HMETAFILE32 ret = GetMetaFile32A( p );
149 HeapFree( GetProcessHeap(), 0, p );
154 /******************************************************************
155 * CopyMetaFile16 (GDI.151)
158 HMETAFILE16 WINAPI CopyMetaFile16( HMETAFILE16 hSrcMetaFile, LPCSTR lpFilename )
160 return CopyMetaFile32A( hSrcMetaFile, lpFilename );
164 /******************************************************************
165 * CopyMetaFile32A (GDI32.23)
167 * Copies the metafile corresponding to hSrcMetaFile to either
168 * a disk file, if a filename is given, or to a new memory based
169 * metafile, if lpFileName is NULL.
173 * Handle to metafile copy on success, NULL on failure.
177 * Copying to disk returns NULL even if successful.
179 HMETAFILE32 WINAPI CopyMetaFile32A(
180 HMETAFILE32 hSrcMetaFile, /* handle of metafile to copy */
181 LPCSTR lpFilename /* filename if copying to a file */
183 HMETAFILE16 handle = 0;
188 TRACE(metafile,"(%08x,%s)\n", hSrcMetaFile, lpFilename);
190 mh = (METAHEADER *)GlobalLock16(hSrcMetaFile);
195 if (lpFilename) /* disk based metafile */
198 hFile = _lcreat32(lpFilename, 0);
200 mh->mtType=1; /* disk file version stores 1 here */
201 i=_lwrite32(hFile, (char *)mh, mh->mtSize * 2) ;
202 mh->mtType=j; /* restore old value [0 or 1] */
206 /* FIXME: return value */
208 else /* memory based metafile */
210 handle = GlobalAlloc16(GMEM_MOVEABLE,mh->mtSize * 2);
211 mh2 = (METAHEADER *)GlobalLock16(handle);
212 memcpy(mh2,mh, mh->mtSize * 2);
213 GlobalUnlock16(handle);
216 GlobalUnlock16(hSrcMetaFile);
221 /******************************************************************
222 * CopyMetaFile32W (GDI32.24)
224 HMETAFILE32 WINAPI CopyMetaFile32W( HMETAFILE32 hSrcMetaFile,
227 LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFilename );
228 HMETAFILE32 ret = CopyMetaFile32A( hSrcMetaFile, p );
229 HeapFree( GetProcessHeap(), 0, p );
234 /******************************************************************
235 * IsValidMetaFile (GDI.410)
237 * Attempts to check if a given metafile is correctly formatted.
238 * Currently, the only things verified are several properties of the
242 * TRUE if hmf passes some tests for being a valid metafile, FALSE otherwise.
245 * This is not exactly what windows does, see _Undocumented_Windows_
249 BOOL16 WINAPI IsValidMetaFile(HMETAFILE16 hmf)
252 METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
254 if (mh->mtType == 1 || mh->mtType == 0)
255 if (mh->mtHeaderSize == MFHEADERSIZE/sizeof(INT16))
256 if (mh->mtVersion == MFVERSION)
260 TRACE(metafile,"IsValidMetaFile %x => %d\n",hmf,resu);
265 /******************************************************************
266 * PlayMetaFile16 (GDI.123)
269 BOOL16 WINAPI PlayMetaFile16( HDC16 hdc, HMETAFILE16 hmf )
271 return PlayMetaFile32( hdc, hmf );
274 /******************************************************************
275 * PlayMetaFile32 (GDI32.265)
277 * Renders the metafile specified by hmf in the DC specified by
278 * hdc. Returns FALSE on failure, TRUE on success.
280 BOOL32 WINAPI PlayMetaFile32(
281 HDC32 hdc, /* handle of DC to render in */
282 HMETAFILE32 hmf /* handle of metafile to render */
285 METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
296 TRACE(metafile,"(%04x %04x)\n",hdc,hmf);
297 if (!mh) return FALSE;
299 /* save the current pen, brush and font */
300 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
302 hBrush = dc->w.hBrush;
304 GDI_HEAP_UNLOCK(hdc);
305 /* create the handle table */
306 hHT = GlobalAlloc16(GMEM_MOVEABLE|GMEM_ZEROINIT,
307 sizeof(HANDLETABLE16) * mh->mtNoObjects);
308 ht = (HANDLETABLE16 *)GlobalLock16(hHT);
311 /* loop through metafile playing records */
312 offset = mh->mtHeaderSize * 2;
313 while (offset < mh->mtSize * 2)
315 mr = (METARECORD *)((char *)mh + offset);
316 TRACE(metafile,"offset=%04x,size=%08lx\n",
319 TRACE(metafile,"Entry got size 0 at offset %d, total mf length is %ld\n",
320 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 TRACE(metafile,"(%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 BOOL32 WINAPI EnumMetaFile32(
432 MFENUMPROC32 lpEnumFunc,
435 METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
438 BOOL32 result = TRUE;
440 DC *dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
445 TRACE(metafile,"(%08x,%08x,%p,%p)\n",
446 hdc, hmf, lpEnumFunc, (void*)lpData);
449 /* save the current pen, brush and font */
452 hBrush = dc->w.hBrush;
454 GDI_HEAP_UNLOCK(hdc);
457 ht = (HANDLETABLE32 *) GlobalAlloc32(GPTR,
458 sizeof(HANDLETABLE32) * mh->mtNoObjects);
460 /* loop through metafile records */
461 offset = mh->mtHeaderSize * 2;
463 while (offset < (mh->mtSize * 2))
465 mr = (METARECORD *)((char *)mh + offset);
466 if (!lpEnumFunc( hdc, ht, mr, mh->mtNoObjects, (LONG)lpData ))
472 offset += (mr->rdSize * 2);
475 /* restore pen, brush and font */
476 SelectObject32(hdc, hBrush);
477 SelectObject32(hdc, hPen);
478 SelectObject32(hdc, hFont);
480 /* free objects in handle table */
481 for(i = 0; i < mh->mtNoObjects; i++)
482 if(*(ht->objectHandle + i) != 0)
483 DeleteObject32(*(ht->objectHandle + i));
485 /* free handle table */
486 GlobalFree32((HGLOBAL32)ht);
491 static BOOL32 MF_Meta_CreateRegion( METARECORD *mr, HRGN32 hrgn );
493 /******************************************************************
494 * PlayMetaFileRecord16 (GDI.176)
496 * Render a single metafile record specified by *mr in the DC hdc, while
497 * using the handle table *ht, of length nHandles,
498 * to store metafile objects.
501 * The following metafile records are unimplemented:
503 * FRAMEREGION, DRAWTEXT, SETDIBTODEV, ANIMATEPALETTE, SETPALENTRIES,
504 * RESIZEPALETTE, EXTFLOODFILL, RESETDC, STARTDOC, STARTPAGE, ENDPAGE,
505 * ABORTDOC, ENDDOC, CREATEBRUSH, CREATEBITMAPINDIRECT, and CREATEBITMAP.
508 void WINAPI PlayMetaFileRecord16(
509 HDC16 hdc, /* DC to render metafile into */
510 HANDLETABLE16 *ht, /* pointer to handle table for metafile objects */
511 METARECORD *mr, /* pointer to metafile record to render */
512 UINT16 nHandles /* size of handle table */
517 BITMAPINFOHEADER *infohdr;
519 TRACE(metafile,"(%04x %08lx %08lx %04x) function %04x\n",
520 hdc,(LONG)ht, (LONG)mr, nHandles, mr->rdFunction);
522 switch (mr->rdFunction)
527 case META_DELETEOBJECT:
528 DeleteObject32(*(ht->objectHandle + *(mr->rdParm)));
529 *(ht->objectHandle + *(mr->rdParm)) = 0;
532 case META_SETBKCOLOR:
533 SetBkColor16(hdc, MAKELONG(*(mr->rdParm), *(mr->rdParm + 1)));
537 SetBkMode16(hdc, *(mr->rdParm));
540 case META_SETMAPMODE:
541 SetMapMode16(hdc, *(mr->rdParm));
545 SetROP216(hdc, *(mr->rdParm));
549 SetRelAbs16(hdc, *(mr->rdParm));
552 case META_SETPOLYFILLMODE:
553 SetPolyFillMode16(hdc, *(mr->rdParm));
556 case META_SETSTRETCHBLTMODE:
557 SetStretchBltMode16(hdc, *(mr->rdParm));
560 case META_SETTEXTCOLOR:
561 SetTextColor16(hdc, MAKELONG(*(mr->rdParm), *(mr->rdParm + 1)));
564 case META_SETWINDOWORG:
565 SetWindowOrg(hdc, *(mr->rdParm + 1), *(mr->rdParm));
568 case META_SETWINDOWEXT:
569 SetWindowExt(hdc, *(mr->rdParm + 1), *(mr->rdParm));
572 case META_SETVIEWPORTORG:
573 SetViewportOrg(hdc, *(mr->rdParm + 1), *(mr->rdParm));
576 case META_SETVIEWPORTEXT:
577 SetViewportExt(hdc, *(mr->rdParm + 1), *(mr->rdParm));
580 case META_OFFSETWINDOWORG:
581 OffsetWindowOrg(hdc, *(mr->rdParm + 1), *(mr->rdParm));
584 case META_SCALEWINDOWEXT:
585 ScaleWindowExt(hdc, *(mr->rdParm + 3), *(mr->rdParm + 2),
586 *(mr->rdParm + 1), *(mr->rdParm));
589 case META_OFFSETVIEWPORTORG:
590 OffsetViewportOrg(hdc, *(mr->rdParm + 1), *(mr->rdParm));
593 case META_SCALEVIEWPORTEXT:
594 ScaleViewportExt(hdc, *(mr->rdParm + 3), *(mr->rdParm + 2),
595 *(mr->rdParm + 1), *(mr->rdParm));
599 LineTo32(hdc, (INT16)*(mr->rdParm + 1), (INT16)*(mr->rdParm));
603 MoveTo(hdc, *(mr->rdParm + 1), *(mr->rdParm));
606 case META_EXCLUDECLIPRECT:
607 ExcludeClipRect16( hdc, *(mr->rdParm + 3), *(mr->rdParm + 2),
608 *(mr->rdParm + 1), *(mr->rdParm) );
611 case META_INTERSECTCLIPRECT:
612 IntersectClipRect16( hdc, *(mr->rdParm + 3), *(mr->rdParm + 2),
613 *(mr->rdParm + 1), *(mr->rdParm) );
617 Arc32(hdc, (INT16)*(mr->rdParm + 7), (INT16)*(mr->rdParm + 6),
618 (INT16)*(mr->rdParm + 5), (INT16)*(mr->rdParm + 4),
619 (INT16)*(mr->rdParm + 3), (INT16)*(mr->rdParm + 2),
620 (INT16)*(mr->rdParm + 1), (INT16)*(mr->rdParm));
624 Ellipse32(hdc, (INT16)*(mr->rdParm + 3), (INT16)*(mr->rdParm + 2),
625 (INT16)*(mr->rdParm + 1), (INT16)*(mr->rdParm));
629 FloodFill32(hdc, (INT16)*(mr->rdParm + 3), (INT16)*(mr->rdParm + 2),
630 MAKELONG(*(mr->rdParm), *(mr->rdParm + 1)));
634 Pie32(hdc, (INT16)*(mr->rdParm + 7), (INT16)*(mr->rdParm + 6),
635 (INT16)*(mr->rdParm + 5), (INT16)*(mr->rdParm + 4),
636 (INT16)*(mr->rdParm + 3), (INT16)*(mr->rdParm + 2),
637 (INT16)*(mr->rdParm + 1), (INT16)*(mr->rdParm));
641 Rectangle32(hdc, (INT16)*(mr->rdParm + 3), (INT16)*(mr->rdParm + 2),
642 (INT16)*(mr->rdParm + 1), (INT16)*(mr->rdParm));
646 RoundRect32(hdc, (INT16)*(mr->rdParm + 5), (INT16)*(mr->rdParm + 4),
647 (INT16)*(mr->rdParm + 3), (INT16)*(mr->rdParm + 2),
648 (INT16)*(mr->rdParm + 1), (INT16)*(mr->rdParm));
652 PatBlt16(hdc, *(mr->rdParm + 5), *(mr->rdParm + 4),
653 *(mr->rdParm + 3), *(mr->rdParm + 2),
654 MAKELONG(*(mr->rdParm), *(mr->rdParm + 1)));
662 SetPixel32(hdc, (INT16)*(mr->rdParm + 3), (INT16)*(mr->rdParm + 2),
663 MAKELONG(*(mr->rdParm), *(mr->rdParm + 1)));
666 case META_OFFSETCLIPRGN:
667 OffsetClipRgn16( hdc, *(mr->rdParm + 1), *(mr->rdParm) );
672 TextOut16(hdc, *(mr->rdParm + ((s1 + 1) >> 1) + 2),
673 *(mr->rdParm + ((s1 + 1) >> 1) + 1),
674 (char *)(mr->rdParm + 1), s1);
678 Polygon16(hdc, (LPPOINT16)(mr->rdParm + 1), *(mr->rdParm));
681 case META_POLYPOLYGON:
682 PolyPolygon16(hdc, (LPPOINT16)(mr->rdParm + *(mr->rdParm) + 1),
683 (LPINT16)(mr->rdParm + 1), *(mr->rdParm));
687 Polyline16(hdc, (LPPOINT16)(mr->rdParm + 1), *(mr->rdParm));
691 RestoreDC32(hdc, (INT16)*(mr->rdParm));
694 case META_SELECTOBJECT:
695 SelectObject32(hdc, *(ht->objectHandle + *(mr->rdParm)));
699 Chord32(hdc, (INT16)*(mr->rdParm + 7), (INT16)*(mr->rdParm + 6),
700 (INT16)*(mr->rdParm+5), (INT16)*(mr->rdParm + 4),
701 (INT16)*(mr->rdParm + 3), (INT16)*(mr->rdParm + 2),
702 (INT16)*(mr->rdParm + 1), (INT16)*(mr->rdParm));
705 case META_CREATEPATTERNBRUSH:
706 switch (*(mr->rdParm))
709 infohdr = (BITMAPINFOHEADER *)(mr->rdParm + 2);
710 MF_AddHandle(ht, nHandles,
711 CreatePatternBrush32(CreateBitmap32(infohdr->biWidth,
716 (sizeof(BITMAPINFOHEADER) / 2) + 4))));
720 s1 = mr->rdSize * 2 - sizeof(METARECORD) - 2;
721 hndl = GlobalAlloc16(GMEM_MOVEABLE, s1);
722 ptr = GlobalLock16(hndl);
723 memcpy(ptr, mr->rdParm + 2, s1);
724 GlobalUnlock16(hndl);
725 MF_AddHandle(ht, nHandles,
726 CreateDIBPatternBrush32(hndl, *(mr->rdParm + 1)));
731 case META_CREATEPENINDIRECT:
732 MF_AddHandle(ht, nHandles,
733 CreatePenIndirect16((LOGPEN16 *)(&(mr->rdParm))));
736 case META_CREATEFONTINDIRECT:
737 MF_AddHandle(ht, nHandles,
738 CreateFontIndirect16((LOGFONT16 *)(&(mr->rdParm))));
741 case META_CREATEBRUSHINDIRECT:
742 MF_AddHandle(ht, nHandles,
743 CreateBrushIndirect16((LOGBRUSH16 *)(&(mr->rdParm))));
746 /* W. Magro: Some new metafile operations. Not all debugged. */
747 case META_CREATEPALETTE:
748 MF_AddHandle(ht, nHandles,
749 CreatePalette16((LPLOGPALETTE)mr->rdParm));
752 case META_SETTEXTALIGN:
753 SetTextAlign16(hdc, *(mr->rdParm));
756 case META_SELECTPALETTE:
757 SelectPalette16(hdc, *(ht->objectHandle + *(mr->rdParm+1)),*(mr->rdParm));
760 case META_SETMAPPERFLAGS:
761 SetMapperFlags16(hdc, *(mr->rdParm));
764 case META_REALIZEPALETTE:
765 RealizePalette16(hdc);
769 FIXME(metafile, "META_ESCAPE unimplemented.\n");
772 /* --- Begin of fixed or new metafile operations. July 1996 ----*/
773 case META_EXTTEXTOUT:
779 s1 = mr->rdParm[2]; /* String length */
780 len = sizeof(METARECORD) + (((s1 + 1) >> 1) * 2) + 2 * sizeof(short)
781 + sizeof(UINT16) + (mr->rdParm[3] ? sizeof(RECT16) : 0); /* rec len without dx array */
783 sot= (LPSTR)&mr->rdParm[4]; /* start_of_text */
785 sot+=sizeof(RECT16); /* there is a rectangle, so add offset */
787 if (mr->rdSize == len / 2)
788 dxx = NULL; /* determine if array present */
790 if (mr->rdSize == (len + s1 * sizeof(INT16)) / 2)
791 dxx = (LPINT16)(sot+(((s1+1)>>1)*2));
794 TRACE(metafile,"%s len: %ld\n",
797 "Please report: PlayMetaFile/ExtTextOut len=%ld slen=%d rdSize=%ld opt=%04x\n",
798 len,s1,mr->rdSize,mr->rdParm[3]);
799 dxx = NULL; /* should't happen -- but if, we continue with NULL [for workaround] */
801 ExtTextOut16( hdc, mr->rdParm[1], /* X position */
802 mr->rdParm[0], /* Y position */
803 mr->rdParm[3], /* options */
804 mr->rdParm[3] ? (LPRECT16) &mr->rdParm[4]:NULL, /* rectangle */
806 s1, dxx); /* length, dx array */
808 TRACE(metafile,"%s len: %ld dx0: %d\n",
809 sot,mr->rdSize,dxx[0]);
813 case META_STRETCHDIB:
815 LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParm[11]);
816 LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize( info, mr->rdParm[2] );
817 StretchDIBits16(hdc,mr->rdParm[10],mr->rdParm[9],mr->rdParm[8],
818 mr->rdParm[7],mr->rdParm[6],mr->rdParm[5],
819 mr->rdParm[4],mr->rdParm[3],bits,info,
820 mr->rdParm[2],MAKELONG(mr->rdParm[0],mr->rdParm[1]));
824 case META_DIBSTRETCHBLT:
826 LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParm[10]);
827 LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize( info, mr->rdParm[2] );
828 StretchDIBits16(hdc,mr->rdParm[9],mr->rdParm[8],mr->rdParm[7],
829 mr->rdParm[6],mr->rdParm[5],mr->rdParm[4],
830 mr->rdParm[3],mr->rdParm[2],bits,info,
831 DIB_RGB_COLORS,MAKELONG(mr->rdParm[0],mr->rdParm[1]));
835 case META_STRETCHBLT:
837 HDC16 hdcSrc=CreateCompatibleDC16(hdc);
838 HBITMAP32 hbitmap=CreateBitmap32(mr->rdParm[10], /*Width */
839 mr->rdParm[11], /*Height*/
840 mr->rdParm[13], /*Planes*/
841 mr->rdParm[14], /*BitsPixel*/
842 (LPSTR)&mr->rdParm[15]); /*bits*/
843 SelectObject32(hdcSrc,hbitmap);
844 StretchBlt16(hdc,mr->rdParm[9],mr->rdParm[8],
845 mr->rdParm[7],mr->rdParm[6],
846 hdcSrc,mr->rdParm[5],mr->rdParm[4],
847 mr->rdParm[3],mr->rdParm[2],
848 MAKELONG(mr->rdParm[0],mr->rdParm[1]));
853 case META_BITBLT: /* <-- not yet debugged */
855 HDC16 hdcSrc=CreateCompatibleDC16(hdc);
856 HBITMAP32 hbitmap=CreateBitmap32(mr->rdParm[7]/*Width */,
857 mr->rdParm[8]/*Height*/,
858 mr->rdParm[10]/*Planes*/,
859 mr->rdParm[11]/*BitsPixel*/,
860 (LPSTR)&mr->rdParm[12]/*bits*/);
861 SelectObject32(hdcSrc,hbitmap);
862 BitBlt32(hdc,(INT16)mr->rdParm[6],(INT16)mr->rdParm[5],
863 (INT16)mr->rdParm[4],(INT16)mr->rdParm[3],
864 hdcSrc, (INT16)mr->rdParm[2],(INT16)mr->rdParm[1],
865 MAKELONG(0,mr->rdParm[0]));
870 /* --- Begin of new metafile operations. April, 1997 (ak) ----*/
871 case META_CREATEREGION:
873 HRGN32 hrgn = CreateRectRgn32(0,0,0,0);
875 MF_Meta_CreateRegion(mr, hrgn);
876 MF_AddHandle(ht, nHandles, hrgn);
880 case META_FILLREGION:
881 FillRgn16(hdc, *(ht->objectHandle + *(mr->rdParm)),
882 *(ht->objectHandle + *(mr->rdParm+1)));
885 case META_INVERTREGION:
886 InvertRgn16(hdc, *(ht->objectHandle + *(mr->rdParm)));
889 case META_PAINTREGION:
890 PaintRgn16(hdc, *(ht->objectHandle + *(mr->rdParm)));
893 case META_SELECTCLIPREGION:
894 SelectClipRgn32(hdc, *(ht->objectHandle + *(mr->rdParm)));
897 case META_DIBCREATEPATTERNBRUSH:
898 /* *(mr->rdParm) may be BS_PATTERN or BS_DIBPATTERN: but there's no difference */
899 TRACE(metafile,"%d\n",*(mr->rdParm));
900 s1 = mr->rdSize * 2 - sizeof(METARECORD) - 2;
901 hndl = GlobalAlloc16(GMEM_MOVEABLE, s1);
902 ptr = GlobalLock16(hndl);
903 memcpy(ptr, mr->rdParm + 2, s1);
904 GlobalUnlock16(hndl);
905 MF_AddHandle(ht, nHandles,CreateDIBPatternBrush16(hndl, *(mr->rdParm + 1)));
911 LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParm[8]);
912 LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize( info, mr->rdParm[0] );
913 StretchDIBits16(hdc,mr->rdParm[7],mr->rdParm[6],mr->rdParm[5],
914 mr->rdParm[4],mr->rdParm[3],mr->rdParm[2],
915 mr->rdParm[5],mr->rdParm[4],bits,info,
916 DIB_RGB_COLORS,MAKELONG(mr->rdParm[0],mr->rdParm[1]));
920 case META_SETTEXTCHAREXTRA:
921 SetTextCharacterExtra16(hdc, (INT16)*(mr->rdParm));
924 case META_SETTEXTJUSTIFICATION:
925 SetTextJustification32(hdc, *(mr->rdParm + 1), *(mr->rdParm));
928 #define META_UNIMP(x) case x: FIXME(metafile, "PlayMetaFileRecord:record type "#x" not implemented.\n");break;
929 META_UNIMP(META_FRAMEREGION)
930 META_UNIMP(META_DRAWTEXT)
931 META_UNIMP(META_SETDIBTODEV)
932 META_UNIMP(META_ANIMATEPALETTE)
933 META_UNIMP(META_SETPALENTRIES)
934 META_UNIMP(META_RESIZEPALETTE)
935 META_UNIMP(META_EXTFLOODFILL)
936 META_UNIMP(META_RESETDC)
937 META_UNIMP(META_STARTDOC)
938 META_UNIMP(META_STARTPAGE)
939 META_UNIMP(META_ENDPAGE)
940 META_UNIMP(META_ABORTDOC)
941 META_UNIMP(META_ENDDOC)
942 META_UNIMP(META_CREATEBRUSH)
943 META_UNIMP(META_CREATEBITMAPINDIRECT)
944 META_UNIMP(META_CREATEBITMAP)
948 WARN(metafile, "PlayMetaFileRecord: Unknown record type %x\n",
954 BOOL32 WINAPI PlayMetaFileRecord32(
956 HANDLETABLE32 *handletable,
957 METARECORD *metarecord,
961 HANDLETABLE16 * ht = (void *)GlobalAlloc32(GPTR,
962 handles*sizeof(HANDLETABLE16));
964 TRACE(metafile, "(%08x,%p,%p,%d)\n", hdc, handletable, metarecord, handles);
965 for (i=0; i<handles; i++)
966 ht->objectHandle[i] = handletable->objectHandle[i];
967 PlayMetaFileRecord16(hdc, ht, metarecord, handles);
968 for (i=0; i<handles; i++)
969 handletable->objectHandle[i] = ht->objectHandle[i];
970 GlobalFree32((HGLOBAL32)ht);
974 /******************************************************************
975 * GetMetaFileBits (GDI.159)
977 * Trade in a metafile object handle for a handle to the metafile memory.
981 HGLOBAL16 WINAPI GetMetaFileBits(
982 HMETAFILE16 hmf /* metafile handle */
985 TRACE(metafile,"hMem out: %04x\n", hmf);
989 /******************************************************************
990 * SetMetaFileBits (GDI.160)
992 * Trade in a metafile memory handle for a handle to a metafile object.
993 * The memory region should hold a proper metafile, otherwise
994 * problems will occur when it is used. Validity of the memory is not
995 * checked. The function is essentially just the identity function.
997 HMETAFILE16 WINAPI SetMetaFileBits(
999 /* handle to a memory region holding a metafile */
1002 TRACE(metafile,"hmf out: %04x\n", hMem);
1007 /******************************************************************
1008 * SetMetaFileBitsBetter (GDI.196)
1010 * Trade in a metafile memory handle for a handle to a metafile object,
1011 * making a cursory check (using IsValidMetaFile()) that the memory
1012 * handle points to a valid metafile.
1015 * Handle to a metafile on success, NULL on failure..
1017 HMETAFILE16 WINAPI SetMetaFileBitsBetter( HMETAFILE16 hMeta )
1019 if( IsValidMetaFile( hMeta ) )
1020 return (HMETAFILE16)GlobalReAlloc16( hMeta, 0,
1021 GMEM_SHARE | GMEM_NODISCARD | GMEM_MODIFY);
1022 return (HMETAFILE16)0;
1025 /******************************************************************
1026 * SetMetaFileBitsEx (GDI32.323)
1028 * Create a metafile from raw data. No checking of the data is performed.
1029 * Use _GetMetaFileBitsEx_ to get raw data from a metafile.
1031 HMETAFILE32 WINAPI SetMetaFileBitsEx(
1032 UINT32 size, /* size of metafile, in bytes */
1033 const BYTE *lpData /* pointer to metafile data */
1036 HMETAFILE32 hmf = GlobalAlloc16(GHND, size);
1037 BYTE *p = GlobalLock16(hmf) ;
1038 TRACE(metafile, "(%d,%p) returning %08x\n", size, lpData, hmf);
1039 if (!hmf || !p) return 0;
1040 memcpy(p, lpData, size);
1041 GlobalUnlock16(hmf);
1045 /*****************************************************************
1046 * GetMetaFileBitsEx (GDI32.198) Get raw metafile data
1048 * Copies the data from metafile _hmf_ into the buffer _buf_.
1049 * If _buf_ is zero, returns size of buffer required. Otherwise,
1050 * returns number of bytes copied.
1052 UINT32 WINAPI GetMetaFileBitsEx(
1053 HMETAFILE32 hmf, /* metafile */
1054 UINT32 nSize, /* size of buf */
1055 LPVOID buf /* buffer to receive raw metafile data */
1057 METAHEADER *h = GlobalLock16(hmf);
1060 TRACE(metafile, "(%08x,%d,%p)\n", hmf, nSize, buf);
1061 if (!h) return 0; /* FIXME: error code */
1062 mfSize = h->mtSize * 2;
1064 GlobalUnlock16(hmf);
1065 TRACE(metafile,"returning size %d\n", mfSize);
1068 if(mfSize > nSize) mfSize = nSize;
1069 memmove(buf, h, mfSize);
1070 GlobalUnlock16(hmf);
1074 /******************************************************************
1075 * GetWinMetaFileBits [GDI32.241]
1077 UINT32 WINAPI GetWinMetaFileBits(HENHMETAFILE32 hemf,
1078 UINT32 cbBuffer, LPBYTE lpbBuffer,
1079 INT32 fnMapMode, HDC32 hdcRef)
1081 FIXME(metafile, "(%d,%d,%p,%d,%d): stub\n",
1082 hemf, cbBuffer, lpbBuffer, fnMapMode, hdcRef);
1086 /******************************************************************
1087 * MF_Meta_CreateRegion
1089 * Handles META_CREATEREGION for PlayMetaFileRecord().
1093 * The layout of the record looks something like this:
1098 * 2 Looks like a handle? - not constant
1100 * 4 Total number of bytes
1101 * 5 No. of seperate bands = n [see below]
1102 * 6 Largest number of x co-ords in a band
1103 * 7-10 Bounding box x1 y1 x2 y2
1106 * Regions are divided into bands that are uniform in the
1107 * y-direction. Each band consists of pairs of on/off x-coords and is
1109 * m y0 y1 x1 x2 x3 ... xm m
1110 * into successive rdParm[]s.
1112 * This is probably just a dump of the internal RGNOBJ?
1118 static BOOL32 MF_Meta_CreateRegion( METARECORD *mr, HRGN32 hrgn )
1123 HRGN32 hrgn2 = CreateRectRgn32( 0, 0, 0, 0 );
1125 for(band = 0, start = &(mr->rdParm[11]); band < mr->rdParm[5];
1126 band++, start = end + 1) {
1127 if(*start / 2 != (*start + 1) / 2) {
1128 WARN(metafile, "Delimiter not even.\n");
1129 DeleteObject32( hrgn2 );
1133 end = start + *start + 3;
1134 if(end > (WORD *)mr + mr->rdSize) {
1135 WARN(metafile, "End points outside record.\n");
1136 DeleteObject32( hrgn2 );
1140 if(*start != *end) {
1141 WARN(metafile, "Mismatched delimiters.\n");
1142 DeleteObject32( hrgn2 );
1146 y0 = *(INT16 *)(start + 1);
1147 y1 = *(INT16 *)(start + 2);
1148 for(pair = 0; pair < *start / 2; pair++) {
1149 SetRectRgn32( hrgn2, *(INT16 *)(start + 3 + 2*pair), y0,
1150 *(INT16 *)(start + 4 + 2*pair), y1 );
1151 CombineRgn32(hrgn, hrgn, hrgn2, RGN_OR);
1154 DeleteObject32( hrgn2 );
1159 /******************************************************************
1162 * Warning: this function can change the metafile handle.
1165 static BOOL32 MF_WriteRecord( DC *dc, METARECORD *mr, DWORD rlen)
1169 METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
1171 switch(physDev->mh->mtType)
1173 case METAFILE_MEMORY:
1174 len = physDev->mh->mtSize * 2 + rlen;
1175 mh = HeapReAlloc( SystemHeap, 0, physDev->mh, len );
1176 if (!mh) return FALSE;
1178 memcpy((WORD *)physDev->mh + physDev->mh->mtSize, mr, rlen);
1181 TRACE(metafile,"Writing record to disk\n");
1182 if (_lwrite32(physDev->mh->mtNoParameters, (char *)mr, rlen) == -1)
1186 ERR(metafile, "Unknown metafile type %d\n", physDev->mh->mtType );
1190 physDev->mh->mtSize += rlen / 2;
1191 physDev->mh->mtMaxRecord = MAX(physDev->mh->mtMaxRecord, rlen / 2);
1196 /******************************************************************
1200 BOOL32 MF_MetaParam0(DC *dc, short func)
1203 METARECORD *mr = (METARECORD *)&buffer;
1206 mr->rdFunction = func;
1207 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1211 /******************************************************************
1214 BOOL32 MF_MetaParam1(DC *dc, short func, short param1)
1217 METARECORD *mr = (METARECORD *)&buffer;
1220 mr->rdFunction = func;
1221 *(mr->rdParm) = param1;
1222 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1226 /******************************************************************
1229 BOOL32 MF_MetaParam2(DC *dc, short func, short param1, short param2)
1232 METARECORD *mr = (METARECORD *)&buffer;
1235 mr->rdFunction = func;
1236 *(mr->rdParm) = param2;
1237 *(mr->rdParm + 1) = param1;
1238 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1242 /******************************************************************
1246 BOOL32 MF_MetaParam4(DC *dc, short func, short param1, short param2,
1247 short param3, short param4)
1250 METARECORD *mr = (METARECORD *)&buffer;
1253 mr->rdFunction = func;
1254 *(mr->rdParm) = param4;
1255 *(mr->rdParm + 1) = param3;
1256 *(mr->rdParm + 2) = param2;
1257 *(mr->rdParm + 3) = param1;
1258 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1262 /******************************************************************
1266 BOOL32 MF_MetaParam6(DC *dc, short func, short param1, short param2,
1267 short param3, short param4, short param5, short param6)
1270 METARECORD *mr = (METARECORD *)&buffer;
1273 mr->rdFunction = func;
1274 *(mr->rdParm) = param6;
1275 *(mr->rdParm + 1) = param5;
1276 *(mr->rdParm + 2) = param4;
1277 *(mr->rdParm + 3) = param3;
1278 *(mr->rdParm + 4) = param2;
1279 *(mr->rdParm + 5) = param1;
1280 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1284 /******************************************************************
1287 BOOL32 MF_MetaParam8(DC *dc, short func, short param1, short param2,
1288 short param3, short param4, short param5,
1289 short param6, short param7, short param8)
1292 METARECORD *mr = (METARECORD *)&buffer;
1295 mr->rdFunction = func;
1296 *(mr->rdParm) = param8;
1297 *(mr->rdParm + 1) = param7;
1298 *(mr->rdParm + 2) = param6;
1299 *(mr->rdParm + 3) = param5;
1300 *(mr->rdParm + 4) = param4;
1301 *(mr->rdParm + 5) = param3;
1302 *(mr->rdParm + 6) = param2;
1303 *(mr->rdParm + 7) = param1;
1304 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1308 /******************************************************************
1309 * MF_CreateBrushIndirect
1312 BOOL32 MF_CreateBrushIndirect(DC *dc, HBRUSH16 hBrush, LOGBRUSH16 *logbrush)
1315 char buffer[sizeof(METARECORD) - 2 + sizeof(*logbrush)];
1316 METARECORD *mr = (METARECORD *)&buffer;
1318 mr->rdSize = (sizeof(METARECORD) + sizeof(*logbrush) - 2) / 2;
1319 mr->rdFunction = META_CREATEBRUSHINDIRECT;
1320 memcpy(&(mr->rdParm), logbrush, sizeof(*logbrush));
1321 if (!(MF_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
1323 mr->rdSize = sizeof(METARECORD) / 2;
1324 mr->rdFunction = META_SELECTOBJECT;
1326 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1327 *(mr->rdParm) = index;
1328 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1332 /******************************************************************
1333 * MF_CreatePatternBrush
1336 BOOL32 MF_CreatePatternBrush(DC *dc, HBRUSH16 hBrush, LOGBRUSH16 *logbrush)
1338 DWORD len, bmSize, biSize;
1343 BITMAPINFOHEADER *infohdr;
1345 char buffer[sizeof(METARECORD)];
1347 switch (logbrush->lbStyle)
1350 bmp = (BITMAPOBJ *)GDI_GetObjPtr((HGDIOBJ16)logbrush->lbHatch, BITMAP_MAGIC);
1351 if (!bmp) return FALSE;
1352 len = sizeof(METARECORD) + sizeof(BITMAPINFOHEADER) +
1353 (bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes) + 6;
1354 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1356 GDI_HEAP_UNLOCK((HGDIOBJ16)logbrush->lbHatch);
1359 mr = (METARECORD *)GlobalLock16(hmr);
1361 mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
1362 mr->rdSize = len / 2;
1363 *(mr->rdParm) = logbrush->lbStyle;
1364 *(mr->rdParm + 1) = DIB_RGB_COLORS;
1365 infohdr = (BITMAPINFOHEADER *)(mr->rdParm + 2);
1366 infohdr->biSize = sizeof(BITMAPINFOHEADER);
1367 infohdr->biWidth = bmp->bitmap.bmWidth;
1368 infohdr->biHeight = bmp->bitmap.bmHeight;
1369 infohdr->biPlanes = bmp->bitmap.bmPlanes;
1370 infohdr->biBitCount = bmp->bitmap.bmBitsPixel;
1371 memcpy(mr->rdParm + (sizeof(BITMAPINFOHEADER) / 2) + 4,
1372 PTR_SEG_TO_LIN(bmp->bitmap.bmBits),
1373 bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes);
1374 GDI_HEAP_UNLOCK(logbrush->lbHatch);
1378 info = (BITMAPINFO *)GlobalLock16((HGLOBAL16)logbrush->lbHatch);
1379 if (info->bmiHeader.biCompression)
1380 bmSize = info->bmiHeader.biSizeImage;
1382 bmSize = (info->bmiHeader.biWidth * info->bmiHeader.biBitCount
1383 + 31) / 32 * 8 * info->bmiHeader.biHeight;
1384 biSize = DIB_BitmapInfoSize(info, LOWORD(logbrush->lbColor));
1385 len = sizeof(METARECORD) + biSize + bmSize + 2;
1386 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1388 mr = (METARECORD *)GlobalLock16(hmr);
1390 mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
1391 mr->rdSize = len / 2;
1392 *(mr->rdParm) = logbrush->lbStyle;
1393 *(mr->rdParm + 1) = LOWORD(logbrush->lbColor);
1394 memcpy(mr->rdParm + 2, info, biSize + bmSize);
1399 if (!(MF_WriteRecord(dc, mr, len)))
1407 mr = (METARECORD *)&buffer;
1408 mr->rdSize = sizeof(METARECORD) / 2;
1409 mr->rdFunction = META_SELECTOBJECT;
1411 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1412 *(mr->rdParm) = index;
1413 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1417 /******************************************************************
1418 * MF_CreatePenIndirect
1421 BOOL32 MF_CreatePenIndirect(DC *dc, HPEN16 hPen, LOGPEN16 *logpen)
1424 char buffer[sizeof(METARECORD) - 2 + sizeof(*logpen)];
1425 METARECORD *mr = (METARECORD *)&buffer;
1427 mr->rdSize = (sizeof(METARECORD) + sizeof(*logpen) - 2) / 2;
1428 mr->rdFunction = META_CREATEPENINDIRECT;
1429 memcpy(&(mr->rdParm), logpen, sizeof(*logpen));
1430 if (!(MF_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
1432 mr->rdSize = sizeof(METARECORD) / 2;
1433 mr->rdFunction = META_SELECTOBJECT;
1435 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1436 *(mr->rdParm) = index;
1437 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1441 /******************************************************************
1442 * MF_CreateFontIndirect
1445 BOOL32 MF_CreateFontIndirect(DC *dc, HFONT16 hFont, LOGFONT16 *logfont)
1448 char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT16)];
1449 METARECORD *mr = (METARECORD *)&buffer;
1451 mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT16) - 2) / 2;
1452 mr->rdFunction = META_CREATEFONTINDIRECT;
1453 memcpy(&(mr->rdParm), logfont, sizeof(LOGFONT16));
1454 if (!(MF_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
1456 mr->rdSize = sizeof(METARECORD) / 2;
1457 mr->rdFunction = META_SELECTOBJECT;
1459 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1460 *(mr->rdParm) = index;
1461 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1465 /******************************************************************
1468 BOOL32 MF_TextOut(DC *dc, short x, short y, LPCSTR str, short count)
1475 len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 4;
1476 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1478 mr = (METARECORD *)GlobalLock16(hmr);
1481 mr->rdSize = len / 2;
1482 mr->rdFunction = META_TEXTOUT;
1483 *(mr->rdParm) = count;
1484 memcpy(mr->rdParm + 1, str, count);
1485 *(mr->rdParm + ((count + 1) >> 1) + 1) = y;
1486 *(mr->rdParm + ((count + 1) >> 1) + 2) = x;
1487 ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
1492 /******************************************************************
1495 BOOL32 MF_ExtTextOut(DC*dc, short x, short y, UINT16 flags, const RECT16 *rect,
1496 LPCSTR str, short count, const INT16 *lpDx)
1503 if((!flags && rect) || (flags && !rect))
1504 WARN(metafile, "Inconsistent flags and rect\n");
1505 len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 2 * sizeof(short)
1508 len += sizeof(RECT16);
1510 len+=count*sizeof(INT16);
1511 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1513 mr = (METARECORD *)GlobalLock16(hmr);
1516 mr->rdSize = len / 2;
1517 mr->rdFunction = META_EXTTEXTOUT;
1519 *(mr->rdParm + 1) = x;
1520 *(mr->rdParm + 2) = count;
1521 *(mr->rdParm + 3) = flags;
1522 if (rect) memcpy(mr->rdParm + 4, rect, sizeof(RECT16));
1523 memcpy(mr->rdParm + (rect ? 8 : 4), str, count);
1525 memcpy(mr->rdParm + (rect ? 8 : 4) + ((count + 1) >> 1),lpDx,
1526 count*sizeof(INT16));
1527 ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
1532 /******************************************************************
1533 * MF_MetaPoly - implements Polygon and Polyline
1535 BOOL32 MF_MetaPoly(DC *dc, short func, LPPOINT16 pt, short count)
1542 len = sizeof(METARECORD) + (count * 4);
1543 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1545 mr = (METARECORD *)GlobalLock16(hmr);
1548 mr->rdSize = len / 2;
1549 mr->rdFunction = func;
1550 *(mr->rdParm) = count;
1551 memcpy(mr->rdParm + 1, pt, count * 4);
1552 ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
1558 /******************************************************************
1561 BOOL32 MF_BitBlt(DC *dcDest, short xDest, short yDest, short width,
1562 short height, DC *dcSrc, short xSrc, short ySrc, DWORD rop)
1570 GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM);
1571 len = sizeof(METARECORD) + 12 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
1572 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1574 mr = (METARECORD *)GlobalLock16(hmr);
1575 mr->rdFunction = META_BITBLT;
1576 *(mr->rdParm + 7) = BM.bmWidth;
1577 *(mr->rdParm + 8) = BM.bmHeight;
1578 *(mr->rdParm + 9) = BM.bmWidthBytes;
1579 *(mr->rdParm +10) = BM.bmPlanes;
1580 *(mr->rdParm +11) = BM.bmBitsPixel;
1581 TRACE(metafile,"MF_StretchBlt->len = %ld rop=%lx \n",len,rop);
1582 if (GetBitmapBits32(dcSrc->w.hBitmap,BM.bmWidthBytes * BM.bmHeight,
1585 mr->rdSize = len / sizeof(INT16);
1586 *(mr->rdParm) = HIWORD(rop);
1587 *(mr->rdParm + 1) = ySrc;
1588 *(mr->rdParm + 2) = xSrc;
1589 *(mr->rdParm + 3) = height;
1590 *(mr->rdParm + 4) = width;
1591 *(mr->rdParm + 5) = yDest;
1592 *(mr->rdParm + 6) = xDest;
1593 ret = MF_WriteRecord( dcDest, mr, mr->rdSize * 2);
1602 /**********************************************************************
1604 * this function contains TWO ways for procesing StretchBlt in metafiles,
1605 * decide between rdFunction values META_STRETCHBLT or META_DIBSTRETCHBLT
1606 * via #define STRETCH_VIA_DIB
1608 #define STRETCH_VIA_DIB
1609 #undef STRETCH_VIA_DIB
1610 BOOL32 MF_StretchBlt(DC *dcDest, short xDest, short yDest, short widthDest,
1611 short heightDest, DC *dcSrc, short xSrc, short ySrc,
1612 short widthSrc, short heightSrc, DWORD rop)
1619 #ifdef STRETCH_VIA_DIB
1620 LPBITMAPINFOHEADER lpBMI;
1623 GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM);
1624 #ifdef STRETCH_VIA_DIB
1625 nBPP = BM.bmPlanes * BM.bmBitsPixel;
1626 len = sizeof(METARECORD) + 10 * sizeof(INT16)
1627 + sizeof(BITMAPINFOHEADER) + (nBPP != 24 ? 1 << nBPP: 0) * sizeof(RGBQUAD)
1628 + ((BM.bmWidth * nBPP + 31) / 32) * 4 * BM.bmHeight;
1629 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1631 mr = (METARECORD *)GlobalLock16(hmr);
1632 mr->rdFunction = META_DIBSTRETCHBLT;
1633 lpBMI=(LPBITMAPINFOHEADER)(mr->rdParm+10);
1634 lpBMI->biSize = sizeof(BITMAPINFOHEADER);
1635 lpBMI->biWidth = BM.bmWidth;
1636 lpBMI->biHeight = BM.bmHeight;
1637 lpBMI->biPlanes = 1;
1638 lpBMI->biBitCount = nBPP; /* 1,4,8 or 24 */
1639 lpBMI->biClrUsed = nBPP != 24 ? 1 << nBPP : 0;
1640 lpBMI->biSizeImage = ((lpBMI->biWidth * nBPP + 31) / 32) * 4 * lpBMI->biHeight;
1641 lpBMI->biCompression = BI_RGB;
1642 lpBMI->biXPelsPerMeter = MulDiv32(GetDeviceCaps(dcSrc->hSelf,LOGPIXELSX),3937,100);
1643 lpBMI->biYPelsPerMeter = MulDiv32(GetDeviceCaps(dcSrc->hSelf,LOGPIXELSY),3937,100);
1644 lpBMI->biClrImportant = 0; /* 1 meter = 39.37 inch */
1646 TRACE(metafile,"MF_StretchBltViaDIB->len = %ld rop=%lx PixYPM=%ld Caps=%d\n",
1647 len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(hdcSrc,LOGPIXELSY));
1648 if (GetDIBits(hdcSrc,dcSrc->w.hBitmap,0,(UINT32)lpBMI->biHeight,
1649 (LPSTR)lpBMI + DIB_BitmapInfoSize( (BITMAPINFO *)lpBMI,
1651 (LPBITMAPINFO)lpBMI, DIB_RGB_COLORS))
1653 len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
1654 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1656 mr = (METARECORD *)GlobalLock16(hmr);
1657 mr->rdFunction = META_STRETCHBLT;
1658 *(mr->rdParm +10) = BM.bmWidth;
1659 *(mr->rdParm +11) = BM.bmHeight;
1660 *(mr->rdParm +12) = BM.bmWidthBytes;
1661 *(mr->rdParm +13) = BM.bmPlanes;
1662 *(mr->rdParm +14) = BM.bmBitsPixel;
1663 TRACE(metafile,"MF_StretchBlt->len = %ld rop=%lx \n",len,rop);
1664 if (GetBitmapBits32( dcSrc->w.hBitmap, BM.bmWidthBytes * BM.bmHeight,
1668 mr->rdSize = len / sizeof(INT16);
1669 *(mr->rdParm) = LOWORD(rop);
1670 *(mr->rdParm + 1) = HIWORD(rop);
1671 *(mr->rdParm + 2) = heightSrc;
1672 *(mr->rdParm + 3) = widthSrc;
1673 *(mr->rdParm + 4) = ySrc;
1674 *(mr->rdParm + 5) = xSrc;
1675 *(mr->rdParm + 6) = heightDest;
1676 *(mr->rdParm + 7) = widthDest;
1677 *(mr->rdParm + 8) = yDest;
1678 *(mr->rdParm + 9) = xDest;
1679 ret = MF_WriteRecord( dcDest, mr, mr->rdSize * 2);
1688 /******************************************************************
1691 INT16 MF_CreateRegion(DC *dc, HRGN32 hrgn)
1696 RECT32 *pCurRect, *pEndRect;
1697 WORD Bands = 0, MaxBands = 0;
1698 WORD *Param, *StartBand;
1701 len = GetRegionData32( hrgn, 0, NULL );
1702 if( !(rgndata = HeapAlloc( SystemHeap, 0, len )) ) {
1703 WARN(metafile, "MF_CreateRegion: can't alloc rgndata buffer\n");
1706 GetRegionData32( hrgn, len, rgndata );
1708 /* Overestimate of length:
1709 * Assume every rect is a separate band -> 6 WORDs per rect
1711 len = sizeof(METARECORD) + 20 + (rgndata->rdh.nCount * 12);
1712 if( !(mr = HeapAlloc( SystemHeap, 0, len )) ) {
1713 WARN(metafile, "MF_CreateRegion: can't alloc METARECORD buffer\n");
1714 HeapFree( SystemHeap, 0, rgndata );
1720 Param = mr->rdParm + 11;
1723 pEndRect = (RECT32 *)rgndata->Buffer + rgndata->rdh.nCount;
1724 for(pCurRect = (RECT32 *)rgndata->Buffer; pCurRect < pEndRect; pCurRect++)
1726 if( StartBand && pCurRect->top == *(StartBand + 1) )
1728 *Param++ = pCurRect->left;
1729 *Param++ = pCurRect->right;
1735 *StartBand = Param - StartBand - 3;
1736 *Param++ = *StartBand;
1737 if(*StartBand > MaxBands)
1738 MaxBands = *StartBand;
1741 StartBand = Param++;
1742 *Param++ = pCurRect->top;
1743 *Param++ = pCurRect->bottom;
1744 *Param++ = pCurRect->left;
1745 *Param++ = pCurRect->right;
1748 len = Param - (WORD *)mr;
1752 mr->rdParm[2] = 0x1234;
1754 mr->rdParm[4] = len * 2;
1755 mr->rdParm[5] = Bands;
1756 mr->rdParm[6] = MaxBands;
1757 mr->rdParm[7] = rgndata->rdh.rcBound.left;
1758 mr->rdParm[8] = rgndata->rdh.rcBound.top;
1759 mr->rdParm[9] = rgndata->rdh.rcBound.right;
1760 mr->rdParm[10] = rgndata->rdh.rcBound.bottom;
1761 mr->rdFunction = META_CREATEREGION;
1762 mr->rdSize = len / 2;
1763 ret = MF_WriteRecord( dc, mr, mr->rdSize * 2 );
1764 HeapFree( SystemHeap, 0, mr );
1765 HeapFree( SystemHeap, 0, rgndata );
1768 WARN(metafile, "MF_CreateRegion: MF_WriteRecord failed\n");
1771 return MF_AddHandleDC( dc );