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_metafile(stddeb
,"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_metafile(stddeb
,"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_metafile(stddeb
,"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_metafile(stddeb
,"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_metafile(stddeb
,"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
);
368 SEGPTR spht
, spRecord
;
375 BOOL16 result
= TRUE
;
377 dprintf_metafile(stddeb
,"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 offset
= mh
->mtHeaderSize
* 2;
394 /* loop through metafile records */
396 spRecord
= WIN16_GlobalLock16(hmf
);
397 while (offset
< (mh
->mtSize
* 2))
399 mr
= (METARECORD
*)((char *)mh
+ offset
);
400 if (!lpEnumFunc( hdc
, (HANDLETABLE16
*)spht
,
401 (METARECORD
*)((UINT32
)spRecord
+ offset
),
402 mh
->mtNoObjects
, (LONG
)lpData
)) {
408 offset
+= (mr
->rdSize
* 2);
411 SelectObject32(hdc
, hBrush
);
412 SelectObject32(hdc
, hPen
);
413 SelectObject32(hdc
, hFont
);
415 ht
= (HANDLETABLE16
*)GlobalLock16(hHT
);
417 /* free objects in handle table */
418 for(i
= 0; i
< mh
->mtNoObjects
; i
++)
419 if(*(ht
->objectHandle
+ i
) != 0)
420 DeleteObject32(*(ht
->objectHandle
+ i
));
422 /* free handle table */
428 static BOOL32
MF_Meta_CreateRegion( METARECORD
*mr
, HRGN32 hrgn
);
430 /******************************************************************
431 * PlayMetaFileRecord16 (GDI.176)
433 * Render a single metafile record specified by *mr in the DC hdc, while
434 * using the handle table *ht, of length nHandles,
435 * to store metafile objects.
438 * The following metafile records are unimplemented:
440 * FRAMEREGION, DRAWTEXT, SETDIBTODEV, ANIMATEPALETTE, SETPALENTRIES,
441 * RESIZEPALETTE, EXTFLOODFILL, RESETDC, STARTDOC, STARTPAGE, ENDPAGE,
442 * ABORTDOC, ENDDOC, CREATEBRUSH, CREATEBITMAPINDIRECT, and CREATEBITMAP.
446 void WINAPI
PlayMetaFileRecord16(
448 /* DC to render metafile into */
450 /* pointer to handle table for metafile objects */
452 /* pointer to metafile record to render */
454 /* size of handle table */
460 BITMAPINFOHEADER
*infohdr
;
462 dprintf_metafile(stddeb
,
463 "PlayMetaFileRecord(%04x %08lx %08lx %04x) function %04x\n",
464 hdc
,(LONG
)ht
, (LONG
)mr
, nHandles
, mr
->rdFunction
);
466 switch (mr
->rdFunction
)
471 case META_DELETEOBJECT
:
472 DeleteObject32(*(ht
->objectHandle
+ *(mr
->rdParam
)));
473 *(ht
->objectHandle
+ *(mr
->rdParam
)) = 0;
476 case META_SETBKCOLOR
:
477 SetBkColor16(hdc
, MAKELONG(*(mr
->rdParam
), *(mr
->rdParam
+ 1)));
481 SetBkMode16(hdc
, *(mr
->rdParam
));
484 case META_SETMAPMODE
:
485 SetMapMode16(hdc
, *(mr
->rdParam
));
489 SetROP216(hdc
, *(mr
->rdParam
));
493 SetRelAbs16(hdc
, *(mr
->rdParam
));
496 case META_SETPOLYFILLMODE
:
497 SetPolyFillMode16(hdc
, *(mr
->rdParam
));
500 case META_SETSTRETCHBLTMODE
:
501 SetStretchBltMode16(hdc
, *(mr
->rdParam
));
504 case META_SETTEXTCOLOR
:
505 SetTextColor16(hdc
, MAKELONG(*(mr
->rdParam
), *(mr
->rdParam
+ 1)));
508 case META_SETWINDOWORG
:
509 SetWindowOrg(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
512 case META_SETWINDOWEXT
:
513 SetWindowExt(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
516 case META_SETVIEWPORTORG
:
517 SetViewportOrg(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
520 case META_SETVIEWPORTEXT
:
521 SetViewportExt(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
524 case META_OFFSETWINDOWORG
:
525 OffsetWindowOrg(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
528 case META_SCALEWINDOWEXT
:
529 ScaleWindowExt(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
530 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
533 case META_OFFSETVIEWPORTORG
:
534 OffsetViewportOrg(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
537 case META_SCALEVIEWPORTEXT
:
538 ScaleViewportExt(hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
539 *(mr
->rdParam
+ 1), *(mr
->rdParam
));
543 LineTo32(hdc
, (INT16
)*(mr
->rdParam
+ 1), (INT16
)*(mr
->rdParam
));
547 MoveTo(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
550 case META_EXCLUDECLIPRECT
:
551 ExcludeClipRect16( hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
552 *(mr
->rdParam
+ 1), *(mr
->rdParam
) );
555 case META_INTERSECTCLIPRECT
:
556 IntersectClipRect16( hdc
, *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
557 *(mr
->rdParam
+ 1), *(mr
->rdParam
) );
561 Arc32(hdc
, (INT16
)*(mr
->rdParam
+ 7), (INT16
)*(mr
->rdParam
+ 6),
562 (INT16
)*(mr
->rdParam
+ 5), (INT16
)*(mr
->rdParam
+ 4),
563 (INT16
)*(mr
->rdParam
+ 3), (INT16
)*(mr
->rdParam
+ 2),
564 (INT16
)*(mr
->rdParam
+ 1), (INT16
)*(mr
->rdParam
));
568 Ellipse32(hdc
, (INT16
)*(mr
->rdParam
+ 3), (INT16
)*(mr
->rdParam
+ 2),
569 (INT16
)*(mr
->rdParam
+ 1), (INT16
)*(mr
->rdParam
));
573 FloodFill32(hdc
, (INT16
)*(mr
->rdParam
+ 3), (INT16
)*(mr
->rdParam
+ 2),
574 MAKELONG(*(mr
->rdParam
), *(mr
->rdParam
+ 1)));
578 Pie32(hdc
, (INT16
)*(mr
->rdParam
+ 7), (INT16
)*(mr
->rdParam
+ 6),
579 (INT16
)*(mr
->rdParam
+ 5), (INT16
)*(mr
->rdParam
+ 4),
580 (INT16
)*(mr
->rdParam
+ 3), (INT16
)*(mr
->rdParam
+ 2),
581 (INT16
)*(mr
->rdParam
+ 1), (INT16
)*(mr
->rdParam
));
585 Rectangle32(hdc
, (INT16
)*(mr
->rdParam
+ 3), (INT16
)*(mr
->rdParam
+ 2),
586 (INT16
)*(mr
->rdParam
+ 1), (INT16
)*(mr
->rdParam
));
590 RoundRect32(hdc
, (INT16
)*(mr
->rdParam
+ 5), (INT16
)*(mr
->rdParam
+ 4),
591 (INT16
)*(mr
->rdParam
+ 3), (INT16
)*(mr
->rdParam
+ 2),
592 (INT16
)*(mr
->rdParam
+ 1), (INT16
)*(mr
->rdParam
));
596 PatBlt16(hdc
, *(mr
->rdParam
+ 5), *(mr
->rdParam
+ 4),
597 *(mr
->rdParam
+ 3), *(mr
->rdParam
+ 2),
598 MAKELONG(*(mr
->rdParam
), *(mr
->rdParam
+ 1)));
606 SetPixel32(hdc
, (INT16
)*(mr
->rdParam
+ 3), (INT16
)*(mr
->rdParam
+ 2),
607 MAKELONG(*(mr
->rdParam
), *(mr
->rdParam
+ 1)));
610 case META_OFFSETCLIPRGN
:
611 OffsetClipRgn16( hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
) );
616 TextOut16(hdc
, *(mr
->rdParam
+ ((s1
+ 1) >> 1) + 2),
617 *(mr
->rdParam
+ ((s1
+ 1) >> 1) + 1),
618 (char *)(mr
->rdParam
+ 1), s1
);
622 Polygon16(hdc
, (LPPOINT16
)(mr
->rdParam
+ 1), *(mr
->rdParam
));
625 case META_POLYPOLYGON
:
626 PolyPolygon16(hdc
, (LPPOINT16
)(mr
->rdParam
+ *(mr
->rdParam
) + 1),
627 (LPINT16
)(mr
->rdParam
+ 1), *(mr
->rdParam
));
631 Polyline16(hdc
, (LPPOINT16
)(mr
->rdParam
+ 1), *(mr
->rdParam
));
635 RestoreDC32(hdc
, (INT16
)*(mr
->rdParam
));
638 case META_SELECTOBJECT
:
639 SelectObject32(hdc
, *(ht
->objectHandle
+ *(mr
->rdParam
)));
643 Chord32(hdc
, (INT16
)*(mr
->rdParam
+ 7), (INT16
)*(mr
->rdParam
+ 6),
644 (INT16
)*(mr
->rdParam
+5), (INT16
)*(mr
->rdParam
+ 4),
645 (INT16
)*(mr
->rdParam
+ 3), (INT16
)*(mr
->rdParam
+ 2),
646 (INT16
)*(mr
->rdParam
+ 1), (INT16
)*(mr
->rdParam
));
649 case META_CREATEPATTERNBRUSH
:
650 switch (*(mr
->rdParam
))
653 infohdr
= (BITMAPINFOHEADER
*)(mr
->rdParam
+ 2);
654 MF_AddHandle(ht
, nHandles
,
655 CreatePatternBrush32(CreateBitmap32(infohdr
->biWidth
,
659 (LPSTR
)(mr
->rdParam
+
660 (sizeof(BITMAPINFOHEADER
) / 2) + 4))));
664 s1
= mr
->rdSize
* 2 - sizeof(METARECORD
) - 2;
665 hndl
= GlobalAlloc16(GMEM_MOVEABLE
, s1
);
666 ptr
= GlobalLock16(hndl
);
667 memcpy(ptr
, mr
->rdParam
+ 2, s1
);
668 GlobalUnlock16(hndl
);
669 MF_AddHandle(ht
, nHandles
,
670 CreateDIBPatternBrush32(hndl
, *(mr
->rdParam
+ 1)));
675 case META_CREATEPENINDIRECT
:
676 MF_AddHandle(ht
, nHandles
,
677 CreatePenIndirect16((LOGPEN16
*)(&(mr
->rdParam
))));
680 case META_CREATEFONTINDIRECT
:
681 MF_AddHandle(ht
, nHandles
,
682 CreateFontIndirect16((LOGFONT16
*)(&(mr
->rdParam
))));
685 case META_CREATEBRUSHINDIRECT
:
686 MF_AddHandle(ht
, nHandles
,
687 CreateBrushIndirect16((LOGBRUSH16
*)(&(mr
->rdParam
))));
690 /* W. Magro: Some new metafile operations. Not all debugged. */
691 case META_CREATEPALETTE
:
692 MF_AddHandle(ht
, nHandles
,
693 CreatePalette16((LPLOGPALETTE
)mr
->rdParam
));
696 case META_SETTEXTALIGN
:
697 SetTextAlign16(hdc
, *(mr
->rdParam
));
700 case META_SELECTPALETTE
:
701 SelectPalette16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParam
+1)),*(mr
->rdParam
));
704 case META_SETMAPPERFLAGS
:
705 SetMapperFlags16(hdc
, *(mr
->rdParam
));
708 case META_REALIZEPALETTE
:
709 RealizePalette16(hdc
);
713 dprintf_metafile(stddeb
,"PlayMetaFileRecord: META_ESCAPE unimplemented.\n");
716 /* --- Begin of fixed or new metafile operations. July 1996 ----*/
717 case META_EXTTEXTOUT
:
723 s1
= mr
->rdParam
[2]; /* String length */
724 len
= sizeof(METARECORD
) + (((s1
+ 1) >> 1) * 2) + 2 * sizeof(short)
725 + sizeof(UINT16
) + (mr
->rdParam
[3] ? sizeof(RECT16
) : 0); /* rec len without dx array */
727 sot
= (LPSTR
)&mr
->rdParam
[4]; /* start_of_text */
729 sot
+=sizeof(RECT16
); /* there is a rectangle, so add offset */
731 if (mr
->rdSize
== len
/ 2)
732 dxx
= NULL
; /* determine if array present */
734 if (mr
->rdSize
== (len
+ s1
* sizeof(INT16
)) / 2)
735 dxx
= (LPINT16
)(sot
+(((s1
+1)>>1)*2));
738 dprintf_metafile(stddeb
,"EXTTEXTOUT: %s len: %ld\n",
741 "Please report: PlayMetaFile/ExtTextOut len=%ld slen=%d rdSize=%ld opt=%04x\n",
742 len
,s1
,mr
->rdSize
,mr
->rdParam
[3]);
743 dxx
= NULL
; /* should't happen -- but if, we continue with NULL [for workaround] */
745 ExtTextOut16( hdc
, mr
->rdParam
[1], /* X position */
746 mr
->rdParam
[0], /* Y position */
747 mr
->rdParam
[3], /* options */
748 mr
->rdParam
[3] ? (LPRECT16
) &mr
->rdParam
[4]:NULL
, /* rectangle */
750 s1
, dxx
); /* length, dx array */
752 dprintf_metafile(stddeb
,"EXTTEXTOUT: %s len: %ld dx0: %d\n",
753 sot
,mr
->rdSize
,dxx
[0]);
757 case META_STRETCHDIB
:
759 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParam
[11]);
760 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParam
[2] );
761 StretchDIBits16(hdc
,mr
->rdParam
[10],mr
->rdParam
[9],mr
->rdParam
[8],
762 mr
->rdParam
[7],mr
->rdParam
[6],mr
->rdParam
[5],
763 mr
->rdParam
[4],mr
->rdParam
[3],bits
,info
,
764 mr
->rdParam
[2],MAKELONG(mr
->rdParam
[0],mr
->rdParam
[1]));
768 case META_DIBSTRETCHBLT
:
770 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParam
[10]);
771 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParam
[2] );
772 StretchDIBits16(hdc
,mr
->rdParam
[9],mr
->rdParam
[8],mr
->rdParam
[7],
773 mr
->rdParam
[6],mr
->rdParam
[5],mr
->rdParam
[4],
774 mr
->rdParam
[3],mr
->rdParam
[2],bits
,info
,
775 DIB_RGB_COLORS
,MAKELONG(mr
->rdParam
[0],mr
->rdParam
[1]));
779 case META_STRETCHBLT
:
781 HDC16 hdcSrc
=CreateCompatibleDC16(hdc
);
782 HBITMAP32 hbitmap
=CreateBitmap32(mr
->rdParam
[10], /*Width */
783 mr
->rdParam
[11], /*Height*/
784 mr
->rdParam
[13], /*Planes*/
785 mr
->rdParam
[14], /*BitsPixel*/
786 (LPSTR
)&mr
->rdParam
[15]); /*bits*/
787 SelectObject32(hdcSrc
,hbitmap
);
788 StretchBlt16(hdc
,mr
->rdParam
[9],mr
->rdParam
[8],
789 mr
->rdParam
[7],mr
->rdParam
[6],
790 hdcSrc
,mr
->rdParam
[5],mr
->rdParam
[4],
791 mr
->rdParam
[3],mr
->rdParam
[2],
792 MAKELONG(mr
->rdParam
[0],mr
->rdParam
[1]));
797 case META_BITBLT
: /* <-- not yet debugged */
799 HDC16 hdcSrc
=CreateCompatibleDC16(hdc
);
800 HBITMAP32 hbitmap
=CreateBitmap32(mr
->rdParam
[7]/*Width */,
801 mr
->rdParam
[8]/*Height*/,
802 mr
->rdParam
[10]/*Planes*/,
803 mr
->rdParam
[11]/*BitsPixel*/,
804 (LPSTR
)&mr
->rdParam
[12]/*bits*/);
805 SelectObject32(hdcSrc
,hbitmap
);
806 BitBlt32(hdc
,(INT16
)mr
->rdParam
[6],(INT16
)mr
->rdParam
[5],
807 (INT16
)mr
->rdParam
[4],(INT16
)mr
->rdParam
[3],
808 hdcSrc
, (INT16
)mr
->rdParam
[2],(INT16
)mr
->rdParam
[1],
809 MAKELONG(0,mr
->rdParam
[0]));
814 /* --- Begin of new metafile operations. April, 1997 (ak) ----*/
815 case META_CREATEREGION
:
817 HRGN32 hrgn
= CreateRectRgn32(0,0,0,0);
819 MF_Meta_CreateRegion(mr
, hrgn
);
820 MF_AddHandle(ht
, nHandles
, hrgn
);
824 case META_FILLREGION
:
825 FillRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParam
)),
826 *(ht
->objectHandle
+ *(mr
->rdParam
+1)));
829 case META_INVERTREGION
:
830 InvertRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParam
)));
833 case META_PAINTREGION
:
834 PaintRgn16(hdc
, *(ht
->objectHandle
+ *(mr
->rdParam
)));
837 case META_SELECTCLIPREGION
:
838 SelectClipRgn32(hdc
, *(ht
->objectHandle
+ *(mr
->rdParam
)));
841 case META_DIBCREATEPATTERNBRUSH
:
842 /* *(mr->rdParam) may be BS_PATTERN or BS_DIBPATTERN: but there's no difference */
843 dprintf_metafile(stddeb
,"META_DIBCREATEPATTERNBRUSH: %d\n",*(mr
->rdParam
));
844 s1
= mr
->rdSize
* 2 - sizeof(METARECORD
) - 2;
845 hndl
= GlobalAlloc16(GMEM_MOVEABLE
, s1
);
846 ptr
= GlobalLock16(hndl
);
847 memcpy(ptr
, mr
->rdParam
+ 2, s1
);
848 GlobalUnlock16(hndl
);
849 MF_AddHandle(ht
, nHandles
,CreateDIBPatternBrush16(hndl
, *(mr
->rdParam
+ 1)));
855 LPBITMAPINFO info
= (LPBITMAPINFO
) &(mr
->rdParam
[8]);
856 LPSTR bits
= (LPSTR
)info
+ DIB_BitmapInfoSize( info
, mr
->rdParam
[0] );
857 StretchDIBits16(hdc
,mr
->rdParam
[7],mr
->rdParam
[6],mr
->rdParam
[5],
858 mr
->rdParam
[4],mr
->rdParam
[3],mr
->rdParam
[2],
859 mr
->rdParam
[5],mr
->rdParam
[4],bits
,info
,
860 DIB_RGB_COLORS
,MAKELONG(mr
->rdParam
[0],mr
->rdParam
[1]));
864 case META_SETTEXTCHAREXTRA
:
865 SetTextCharacterExtra16(hdc
, (INT16
)*(mr
->rdParam
));
868 case META_SETTEXTJUSTIFICATION
:
869 SetTextJustification32(hdc
, *(mr
->rdParam
+ 1), *(mr
->rdParam
));
872 #define META_UNIMP(x) case x: fprintf(stderr,"PlayMetaFileRecord:record type "#x" not implemented.\n");break;
873 META_UNIMP(META_FRAMEREGION
)
874 META_UNIMP(META_DRAWTEXT
)
875 META_UNIMP(META_SETDIBTODEV
)
876 META_UNIMP(META_ANIMATEPALETTE
)
877 META_UNIMP(META_SETPALENTRIES
)
878 META_UNIMP(META_RESIZEPALETTE
)
879 META_UNIMP(META_EXTFLOODFILL
)
880 META_UNIMP(META_RESETDC
)
881 META_UNIMP(META_STARTDOC
)
882 META_UNIMP(META_STARTPAGE
)
883 META_UNIMP(META_ENDPAGE
)
884 META_UNIMP(META_ABORTDOC
)
885 META_UNIMP(META_ENDDOC
)
886 META_UNIMP(META_CREATEBRUSH
)
887 META_UNIMP(META_CREATEBITMAPINDIRECT
)
888 META_UNIMP(META_CREATEBITMAP
)
892 fprintf(stddeb
,"PlayMetaFileRecord: Unknown record type %x\n",
898 /******************************************************************
899 * GetMetaFileBits (GDI.159)
901 * Trade in a metafile object handle for a handle to the metafile memory.
905 HGLOBAL16 WINAPI
GetMetaFileBits(
906 HMETAFILE16 hmf
/* metafile handle */
909 dprintf_metafile(stddeb
,"GetMetaFileBits: hMem out: %04x\n", hmf
);
913 /******************************************************************
914 * SetMetaFileBits (GDI.160)
916 * Trade in a metafile memory handle for a handle to a metafile object.
917 * The memory region should hold a proper metafile, otherwise
918 * problems will occur when it is used. Validity of the memory is not
919 * checked. The function is essentially just the identity function.
921 HMETAFILE16 WINAPI
SetMetaFileBits(
923 /* handle to a memory region holding a metafile */
926 dprintf_metafile(stddeb
,"SetMetaFileBits: hmf out: %04x\n", hMem
);
931 /******************************************************************
932 * SetMetaFileBitsBetter (GDI.196)
934 * Trade in a metafile memory handle for a handle to a metafile object,
935 * making a cursory check (using IsValidMetaFile()) that the memory
936 * handle points to a valid metafile.
939 * Handle to a metafile on success, NULL on failure..
941 HMETAFILE16 WINAPI
SetMetaFileBitsBetter( HMETAFILE16 hMeta
)
943 if( IsValidMetaFile( hMeta
) )
944 return (HMETAFILE16
)GlobalReAlloc16( hMeta
, 0,
945 GMEM_SHARE
| GMEM_NODISCARD
| GMEM_MODIFY
);
946 return (HMETAFILE16
)0;
949 /******************************************************************
950 * MF_Meta_CreateRegion
952 * Handles META_CREATEREGION for PlayMetaFileRecord().
956 * The layout of the record looks something like this:
961 * 2 Looks like a handle? - not constant
963 * 4 Total number of bytes
964 * 5 No. of seperate bands = n [see below]
965 * 6 Largest number of x co-ords in a band
966 * 7-10 Bounding box x1 y1 x2 y2
969 * Regions are divided into bands that are uniform in the
970 * y-direction. Each band consists of pairs of on/off x-coords and is
972 * m y0 y1 x1 x2 x3 ... xm m
973 * into successive rdParam[]s.
975 * This is probably just a dump of the internal RGNOBJ?
981 static BOOL32
MF_Meta_CreateRegion( METARECORD
*mr
, HRGN32 hrgn
)
986 HRGN32 hrgn2
= CreateRectRgn32( 0, 0, 0, 0 );
988 for(band
= 0, start
= &(mr
->rdParam
[11]); band
< mr
->rdParam
[5];
989 band
++, start
= end
+ 1) {
990 if(*start
/ 2 != (*start
+ 1) / 2) {
991 fprintf(stderr
, "META_CREATEREGION: delimiter not even.\n");
992 DeleteObject32( hrgn2
);
996 end
= start
+ *start
+ 3;
997 if(end
> (WORD
*)mr
+ mr
->rdSize
) {
998 fprintf(stderr
, "META_CREATEREGION: end points outside record.\n");
999 DeleteObject32( hrgn2
);
1003 if(*start
!= *end
) {
1004 fprintf(stderr
, "META_CREATEREGION: mismatched delimiters.\n");
1005 DeleteObject32( hrgn2
);
1009 y0
= *(INT16
*)(start
+ 1);
1010 y1
= *(INT16
*)(start
+ 2);
1011 for(pair
= 0; pair
< *start
/ 2; pair
++) {
1012 SetRectRgn32( hrgn2
, *(INT16
*)(start
+ 3 + 2*pair
), y0
,
1013 *(INT16
*)(start
+ 4 + 2*pair
), y1
);
1014 CombineRgn32(hrgn
, hrgn
, hrgn2
, RGN_OR
);
1017 DeleteObject32( hrgn2
);
1022 /******************************************************************
1025 * Warning: this function can change the metafile handle.
1028 static BOOL32
MF_WriteRecord( DC
*dc
, METARECORD
*mr
, WORD rlen
)
1032 METAFILEDRV_PDEVICE
*physDev
= (METAFILEDRV_PDEVICE
*)dc
->physDev
;
1034 switch(physDev
->mh
->mtType
)
1036 case METAFILE_MEMORY
:
1037 len
= physDev
->mh
->mtSize
* 2 + rlen
;
1038 mh
= HeapReAlloc( SystemHeap
, 0, physDev
->mh
, len
);
1039 if (!mh
) return FALSE
;
1041 memcpy((WORD
*)physDev
->mh
+ physDev
->mh
->mtSize
, mr
, rlen
);
1044 dprintf_metafile(stddeb
,"Writing record to disk\n");
1045 if (_lwrite32(physDev
->mh
->mtNoParameters
, (char *)mr
, rlen
) == -1)
1049 fprintf( stderr
, "Unknown metafile type %d\n", physDev
->mh
->mtType
);
1053 physDev
->mh
->mtSize
+= rlen
/ 2;
1054 physDev
->mh
->mtMaxRecord
= MAX(physDev
->mh
->mtMaxRecord
, rlen
/ 2);
1059 /******************************************************************
1063 BOOL32
MF_MetaParam0(DC
*dc
, short func
)
1066 METARECORD
*mr
= (METARECORD
*)&buffer
;
1069 mr
->rdFunction
= func
;
1070 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1074 /******************************************************************
1077 BOOL32
MF_MetaParam1(DC
*dc
, short func
, short param1
)
1080 METARECORD
*mr
= (METARECORD
*)&buffer
;
1083 mr
->rdFunction
= func
;
1084 *(mr
->rdParam
) = param1
;
1085 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1089 /******************************************************************
1092 BOOL32
MF_MetaParam2(DC
*dc
, short func
, short param1
, short param2
)
1095 METARECORD
*mr
= (METARECORD
*)&buffer
;
1098 mr
->rdFunction
= func
;
1099 *(mr
->rdParam
) = param2
;
1100 *(mr
->rdParam
+ 1) = param1
;
1101 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1105 /******************************************************************
1109 BOOL32
MF_MetaParam4(DC
*dc
, short func
, short param1
, short param2
,
1110 short param3
, short param4
)
1113 METARECORD
*mr
= (METARECORD
*)&buffer
;
1116 mr
->rdFunction
= func
;
1117 *(mr
->rdParam
) = param4
;
1118 *(mr
->rdParam
+ 1) = param3
;
1119 *(mr
->rdParam
+ 2) = param2
;
1120 *(mr
->rdParam
+ 3) = param1
;
1121 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1125 /******************************************************************
1129 BOOL32
MF_MetaParam6(DC
*dc
, short func
, short param1
, short param2
,
1130 short param3
, short param4
, short param5
, short param6
)
1133 METARECORD
*mr
= (METARECORD
*)&buffer
;
1136 mr
->rdFunction
= func
;
1137 *(mr
->rdParam
) = param6
;
1138 *(mr
->rdParam
+ 1) = param5
;
1139 *(mr
->rdParam
+ 2) = param4
;
1140 *(mr
->rdParam
+ 3) = param3
;
1141 *(mr
->rdParam
+ 4) = param2
;
1142 *(mr
->rdParam
+ 5) = param1
;
1143 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1147 /******************************************************************
1150 BOOL32
MF_MetaParam8(DC
*dc
, short func
, short param1
, short param2
,
1151 short param3
, short param4
, short param5
,
1152 short param6
, short param7
, short param8
)
1155 METARECORD
*mr
= (METARECORD
*)&buffer
;
1158 mr
->rdFunction
= func
;
1159 *(mr
->rdParam
) = param8
;
1160 *(mr
->rdParam
+ 1) = param7
;
1161 *(mr
->rdParam
+ 2) = param6
;
1162 *(mr
->rdParam
+ 3) = param5
;
1163 *(mr
->rdParam
+ 4) = param4
;
1164 *(mr
->rdParam
+ 5) = param3
;
1165 *(mr
->rdParam
+ 6) = param2
;
1166 *(mr
->rdParam
+ 7) = param1
;
1167 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1171 /******************************************************************
1172 * MF_CreateBrushIndirect
1175 BOOL32
MF_CreateBrushIndirect(DC
*dc
, HBRUSH16 hBrush
, LOGBRUSH16
*logbrush
)
1178 char buffer
[sizeof(METARECORD
) - 2 + sizeof(*logbrush
)];
1179 METARECORD
*mr
= (METARECORD
*)&buffer
;
1181 mr
->rdSize
= (sizeof(METARECORD
) + sizeof(*logbrush
) - 2) / 2;
1182 mr
->rdFunction
= META_CREATEBRUSHINDIRECT
;
1183 memcpy(&(mr
->rdParam
), logbrush
, sizeof(*logbrush
));
1184 if (!(MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2))) return FALSE
;
1186 mr
->rdSize
= sizeof(METARECORD
) / 2;
1187 mr
->rdFunction
= META_SELECTOBJECT
;
1189 if ((index
= MF_AddHandleDC( dc
)) == -1) return FALSE
;
1190 *(mr
->rdParam
) = index
;
1191 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1195 /******************************************************************
1196 * MF_CreatePatternBrush
1199 BOOL32
MF_CreatePatternBrush(DC
*dc
, HBRUSH16 hBrush
, LOGBRUSH16
*logbrush
)
1201 DWORD len
, bmSize
, biSize
;
1206 BITMAPINFOHEADER
*infohdr
;
1208 char buffer
[sizeof(METARECORD
)];
1210 switch (logbrush
->lbStyle
)
1213 bmp
= (BITMAPOBJ
*)GDI_GetObjPtr((HGDIOBJ16
)logbrush
->lbHatch
, BITMAP_MAGIC
);
1214 if (!bmp
) return FALSE
;
1215 len
= sizeof(METARECORD
) + sizeof(BITMAPINFOHEADER
) +
1216 (bmp
->bitmap
.bmHeight
* bmp
->bitmap
.bmWidthBytes
) + 6;
1217 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1219 GDI_HEAP_UNLOCK((HGDIOBJ16
)logbrush
->lbHatch
);
1222 mr
= (METARECORD
*)GlobalLock16(hmr
);
1224 mr
->rdFunction
= META_DIBCREATEPATTERNBRUSH
;
1225 mr
->rdSize
= len
/ 2;
1226 *(mr
->rdParam
) = logbrush
->lbStyle
;
1227 *(mr
->rdParam
+ 1) = DIB_RGB_COLORS
;
1228 infohdr
= (BITMAPINFOHEADER
*)(mr
->rdParam
+ 2);
1229 infohdr
->biSize
= sizeof(BITMAPINFOHEADER
);
1230 infohdr
->biWidth
= bmp
->bitmap
.bmWidth
;
1231 infohdr
->biHeight
= bmp
->bitmap
.bmHeight
;
1232 infohdr
->biPlanes
= bmp
->bitmap
.bmPlanes
;
1233 infohdr
->biBitCount
= bmp
->bitmap
.bmBitsPixel
;
1234 memcpy(mr
->rdParam
+ (sizeof(BITMAPINFOHEADER
) / 2) + 4,
1235 PTR_SEG_TO_LIN(bmp
->bitmap
.bmBits
),
1236 bmp
->bitmap
.bmHeight
* bmp
->bitmap
.bmWidthBytes
);
1237 GDI_HEAP_UNLOCK(logbrush
->lbHatch
);
1241 info
= (BITMAPINFO
*)GlobalLock16((HGLOBAL16
)logbrush
->lbHatch
);
1242 if (info
->bmiHeader
.biCompression
)
1243 bmSize
= info
->bmiHeader
.biSizeImage
;
1245 bmSize
= (info
->bmiHeader
.biWidth
* info
->bmiHeader
.biBitCount
1246 + 31) / 32 * 8 * info
->bmiHeader
.biHeight
;
1247 biSize
= DIB_BitmapInfoSize(info
, LOWORD(logbrush
->lbColor
));
1248 len
= sizeof(METARECORD
) + biSize
+ bmSize
+ 2;
1249 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1251 mr
= (METARECORD
*)GlobalLock16(hmr
);
1253 mr
->rdFunction
= META_DIBCREATEPATTERNBRUSH
;
1254 mr
->rdSize
= len
/ 2;
1255 *(mr
->rdParam
) = logbrush
->lbStyle
;
1256 *(mr
->rdParam
+ 1) = LOWORD(logbrush
->lbColor
);
1257 memcpy(mr
->rdParam
+ 2, info
, biSize
+ bmSize
);
1262 if (!(MF_WriteRecord(dc
, mr
, len
)))
1270 mr
= (METARECORD
*)&buffer
;
1271 mr
->rdSize
= sizeof(METARECORD
) / 2;
1272 mr
->rdFunction
= META_SELECTOBJECT
;
1274 if ((index
= MF_AddHandleDC( dc
)) == -1) return FALSE
;
1275 *(mr
->rdParam
) = index
;
1276 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1280 /******************************************************************
1281 * MF_CreatePenIndirect
1284 BOOL32
MF_CreatePenIndirect(DC
*dc
, HPEN16 hPen
, LOGPEN16
*logpen
)
1287 char buffer
[sizeof(METARECORD
) - 2 + sizeof(*logpen
)];
1288 METARECORD
*mr
= (METARECORD
*)&buffer
;
1290 mr
->rdSize
= (sizeof(METARECORD
) + sizeof(*logpen
) - 2) / 2;
1291 mr
->rdFunction
= META_CREATEPENINDIRECT
;
1292 memcpy(&(mr
->rdParam
), logpen
, sizeof(*logpen
));
1293 if (!(MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2))) return FALSE
;
1295 mr
->rdSize
= sizeof(METARECORD
) / 2;
1296 mr
->rdFunction
= META_SELECTOBJECT
;
1298 if ((index
= MF_AddHandleDC( dc
)) == -1) return FALSE
;
1299 *(mr
->rdParam
) = index
;
1300 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1304 /******************************************************************
1305 * MF_CreateFontIndirect
1308 BOOL32
MF_CreateFontIndirect(DC
*dc
, HFONT16 hFont
, LOGFONT16
*logfont
)
1311 char buffer
[sizeof(METARECORD
) - 2 + sizeof(LOGFONT16
)];
1312 METARECORD
*mr
= (METARECORD
*)&buffer
;
1314 mr
->rdSize
= (sizeof(METARECORD
) + sizeof(LOGFONT16
) - 2) / 2;
1315 mr
->rdFunction
= META_CREATEFONTINDIRECT
;
1316 memcpy(&(mr
->rdParam
), logfont
, sizeof(LOGFONT16
));
1317 if (!(MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2))) return FALSE
;
1319 mr
->rdSize
= sizeof(METARECORD
) / 2;
1320 mr
->rdFunction
= META_SELECTOBJECT
;
1322 if ((index
= MF_AddHandleDC( dc
)) == -1) return FALSE
;
1323 *(mr
->rdParam
) = index
;
1324 return MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1328 /******************************************************************
1331 BOOL32
MF_TextOut(DC
*dc
, short x
, short y
, LPCSTR str
, short count
)
1338 len
= sizeof(METARECORD
) + (((count
+ 1) >> 1) * 2) + 4;
1339 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1341 mr
= (METARECORD
*)GlobalLock16(hmr
);
1344 mr
->rdSize
= len
/ 2;
1345 mr
->rdFunction
= META_TEXTOUT
;
1346 *(mr
->rdParam
) = count
;
1347 memcpy(mr
->rdParam
+ 1, str
, count
);
1348 *(mr
->rdParam
+ ((count
+ 1) >> 1) + 1) = y
;
1349 *(mr
->rdParam
+ ((count
+ 1) >> 1) + 2) = x
;
1350 ret
= MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1355 /******************************************************************
1358 BOOL32
MF_ExtTextOut(DC
*dc
, short x
, short y
, UINT16 flags
, const RECT16
*rect
,
1359 LPCSTR str
, short count
, const INT16
*lpDx
)
1366 if((!flags
&& rect
) || (flags
&& !rect
))
1367 fprintf(stderr
, "MF_ExtTextOut: Inconsistent flags and rect\n");
1368 len
= sizeof(METARECORD
) + (((count
+ 1) >> 1) * 2) + 2 * sizeof(short)
1371 len
+= sizeof(RECT16
);
1373 len
+=count
*sizeof(INT16
);
1374 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1376 mr
= (METARECORD
*)GlobalLock16(hmr
);
1379 mr
->rdSize
= len
/ 2;
1380 mr
->rdFunction
= META_EXTTEXTOUT
;
1382 *(mr
->rdParam
+ 1) = x
;
1383 *(mr
->rdParam
+ 2) = count
;
1384 *(mr
->rdParam
+ 3) = flags
;
1385 if (rect
) memcpy(mr
->rdParam
+ 4, rect
, sizeof(RECT16
));
1386 memcpy(mr
->rdParam
+ (rect
? 8 : 4), str
, count
);
1388 memcpy(mr
->rdParam
+ (rect
? 8 : 4) + ((count
+ 1) >> 1),lpDx
,
1389 count
*sizeof(INT16
));
1390 ret
= MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1395 /******************************************************************
1396 * MF_MetaPoly - implements Polygon and Polyline
1398 BOOL32
MF_MetaPoly(DC
*dc
, short func
, LPPOINT16 pt
, short count
)
1405 len
= sizeof(METARECORD
) + (count
* 4);
1406 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1408 mr
= (METARECORD
*)GlobalLock16(hmr
);
1411 mr
->rdSize
= len
/ 2;
1412 mr
->rdFunction
= func
;
1413 *(mr
->rdParam
) = count
;
1414 memcpy(mr
->rdParam
+ 1, pt
, count
* 4);
1415 ret
= MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2);
1421 /******************************************************************
1424 BOOL32
MF_BitBlt(DC
*dcDest
, short xDest
, short yDest
, short width
,
1425 short height
, DC
*dcSrc
, short xSrc
, short ySrc
, DWORD rop
)
1433 GetObject16(dcSrc
->w
.hBitmap
, sizeof(BITMAP16
), &BM
);
1434 len
= sizeof(METARECORD
) + 12 * sizeof(INT16
) + BM
.bmWidthBytes
* BM
.bmHeight
;
1435 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1437 mr
= (METARECORD
*)GlobalLock16(hmr
);
1438 mr
->rdFunction
= META_BITBLT
;
1439 *(mr
->rdParam
+ 7) = BM
.bmWidth
;
1440 *(mr
->rdParam
+ 8) = BM
.bmHeight
;
1441 *(mr
->rdParam
+ 9) = BM
.bmWidthBytes
;
1442 *(mr
->rdParam
+10) = BM
.bmPlanes
;
1443 *(mr
->rdParam
+11) = BM
.bmBitsPixel
;
1444 dprintf_metafile(stddeb
,"MF_StretchBlt->len = %ld rop=%lx \n",len
,rop
);
1445 if (GetBitmapBits32(dcSrc
->w
.hBitmap
,BM
.bmWidthBytes
* BM
.bmHeight
,
1448 mr
->rdSize
= len
/ sizeof(INT16
);
1449 *(mr
->rdParam
) = HIWORD(rop
);
1450 *(mr
->rdParam
+ 1) = ySrc
;
1451 *(mr
->rdParam
+ 2) = xSrc
;
1452 *(mr
->rdParam
+ 3) = height
;
1453 *(mr
->rdParam
+ 4) = width
;
1454 *(mr
->rdParam
+ 5) = yDest
;
1455 *(mr
->rdParam
+ 6) = xDest
;
1456 ret
= MF_WriteRecord( dcDest
, mr
, mr
->rdSize
* 2);
1465 /**********************************************************************
1467 * this function contains TWO ways for procesing StretchBlt in metafiles,
1468 * decide between rdFunction values META_STRETCHBLT or META_DIBSTRETCHBLT
1469 * via #define STRETCH_VIA_DIB
1471 #define STRETCH_VIA_DIB
1472 #undef STRETCH_VIA_DIB
1473 BOOL32
MF_StretchBlt(DC
*dcDest
, short xDest
, short yDest
, short widthDest
,
1474 short heightDest
, DC
*dcSrc
, short xSrc
, short ySrc
,
1475 short widthSrc
, short heightSrc
, DWORD rop
)
1482 #ifdef STRETCH_VIA_DIB
1483 LPBITMAPINFOHEADER lpBMI
;
1486 GetObject16(dcSrc
->w
.hBitmap
, sizeof(BITMAP16
), &BM
);
1487 #ifdef STRETCH_VIA_DIB
1488 nBPP
= BM
.bmPlanes
* BM
.bmBitsPixel
;
1489 len
= sizeof(METARECORD
) + 10 * sizeof(INT16
)
1490 + sizeof(BITMAPINFOHEADER
) + (nBPP
!= 24 ? 1 << nBPP
: 0) * sizeof(RGBQUAD
)
1491 + ((BM
.bmWidth
* nBPP
+ 31) / 32) * 4 * BM
.bmHeight
;
1492 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1494 mr
= (METARECORD
*)GlobalLock16(hmr
);
1495 mr
->rdFunction
= META_DIBSTRETCHBLT
;
1496 lpBMI
=(LPBITMAPINFOHEADER
)(mr
->rdParam
+10);
1497 lpBMI
->biSize
= sizeof(BITMAPINFOHEADER
);
1498 lpBMI
->biWidth
= BM
.bmWidth
;
1499 lpBMI
->biHeight
= BM
.bmHeight
;
1500 lpBMI
->biPlanes
= 1;
1501 lpBMI
->biBitCount
= nBPP
; /* 1,4,8 or 24 */
1502 lpBMI
->biClrUsed
= nBPP
!= 24 ? 1 << nBPP
: 0;
1503 lpBMI
->biSizeImage
= ((lpBMI
->biWidth
* nBPP
+ 31) / 32) * 4 * lpBMI
->biHeight
;
1504 lpBMI
->biCompression
= BI_RGB
;
1505 lpBMI
->biXPelsPerMeter
= MulDiv32(GetDeviceCaps(dcSrc
->hSelf
,LOGPIXELSX
),3937,100);
1506 lpBMI
->biYPelsPerMeter
= MulDiv32(GetDeviceCaps(dcSrc
->hSelf
,LOGPIXELSY
),3937,100);
1507 lpBMI
->biClrImportant
= 0; /* 1 meter = 39.37 inch */
1509 dprintf_metafile(stddeb
,"MF_StretchBltViaDIB->len = %ld rop=%lx PixYPM=%ld Caps=%d\n",
1510 len
,rop
,lpBMI
->biYPelsPerMeter
,GetDeviceCaps(hdcSrc
,LOGPIXELSY
));
1511 if (GetDIBits(hdcSrc
,dcSrc
->w
.hBitmap
,0,(UINT32
)lpBMI
->biHeight
,
1512 (LPSTR
)lpBMI
+ DIB_BitmapInfoSize( (BITMAPINFO
*)lpBMI
,
1514 (LPBITMAPINFO
)lpBMI
, DIB_RGB_COLORS
))
1516 len
= sizeof(METARECORD
) + 15 * sizeof(INT16
) + BM
.bmWidthBytes
* BM
.bmHeight
;
1517 if (!(hmr
= GlobalAlloc16(GMEM_MOVEABLE
, len
)))
1519 mr
= (METARECORD
*)GlobalLock16(hmr
);
1520 mr
->rdFunction
= META_STRETCHBLT
;
1521 *(mr
->rdParam
+10) = BM
.bmWidth
;
1522 *(mr
->rdParam
+11) = BM
.bmHeight
;
1523 *(mr
->rdParam
+12) = BM
.bmWidthBytes
;
1524 *(mr
->rdParam
+13) = BM
.bmPlanes
;
1525 *(mr
->rdParam
+14) = BM
.bmBitsPixel
;
1526 dprintf_metafile(stddeb
,"MF_StretchBlt->len = %ld rop=%lx \n",len
,rop
);
1527 if (GetBitmapBits32( dcSrc
->w
.hBitmap
, BM
.bmWidthBytes
* BM
.bmHeight
,
1531 mr
->rdSize
= len
/ sizeof(INT16
);
1532 *(mr
->rdParam
) = LOWORD(rop
);
1533 *(mr
->rdParam
+ 1) = HIWORD(rop
);
1534 *(mr
->rdParam
+ 2) = heightSrc
;
1535 *(mr
->rdParam
+ 3) = widthSrc
;
1536 *(mr
->rdParam
+ 4) = ySrc
;
1537 *(mr
->rdParam
+ 5) = xSrc
;
1538 *(mr
->rdParam
+ 6) = heightDest
;
1539 *(mr
->rdParam
+ 7) = widthDest
;
1540 *(mr
->rdParam
+ 8) = yDest
;
1541 *(mr
->rdParam
+ 9) = xDest
;
1542 ret
= MF_WriteRecord( dcDest
, mr
, mr
->rdSize
* 2);
1551 /******************************************************************
1554 INT16
MF_CreateRegion(DC
*dc
, HRGN32 hrgn
)
1559 RECT32
*pCurRect
, *pEndRect
;
1560 WORD Bands
= 0, MaxBands
= 0;
1561 WORD
*Param
, *StartBand
;
1564 len
= GetRegionData( hrgn
, 0, NULL
);
1565 if( !(rgndata
= HeapAlloc( SystemHeap
, 0, len
)) ) {
1566 fprintf(stderr
, "MF_CreateRegion: can't alloc rgndata buffer\n");
1569 GetRegionData( hrgn
, len
, rgndata
);
1571 /* Overestimate of length:
1572 * Assume every rect is a separate band -> 6 WORDs per rect
1574 len
= sizeof(METARECORD
) + 20 + (rgndata
->rdh
.nCount
* 12);
1575 if( !(mr
= HeapAlloc( SystemHeap
, 0, len
)) ) {
1576 fprintf(stderr
, "MF_CreateRegion: can't alloc METARECORD buffer\n");
1577 HeapFree( SystemHeap
, 0, rgndata
);
1583 Param
= mr
->rdParam
+ 11;
1586 pEndRect
= (RECT32
*)rgndata
->Buffer
+ rgndata
->rdh
.nCount
;
1587 for(pCurRect
= (RECT32
*)rgndata
->Buffer
; pCurRect
< pEndRect
; pCurRect
++)
1589 if( StartBand
&& pCurRect
->top
== *(StartBand
+ 1) )
1591 *Param
++ = pCurRect
->left
;
1592 *Param
++ = pCurRect
->right
;
1598 *StartBand
= Param
- StartBand
- 3;
1599 *Param
++ = *StartBand
;
1600 if(*StartBand
> MaxBands
)
1601 MaxBands
= *StartBand
;
1604 StartBand
= Param
++;
1605 *Param
++ = pCurRect
->top
;
1606 *Param
++ = pCurRect
->bottom
;
1607 *Param
++ = pCurRect
->left
;
1608 *Param
++ = pCurRect
->right
;
1611 len
= Param
- (WORD
*)mr
;
1615 mr
->rdParam
[2] = 0x1234;
1617 mr
->rdParam
[4] = len
* 2;
1618 mr
->rdParam
[5] = Bands
;
1619 mr
->rdParam
[6] = MaxBands
;
1620 mr
->rdParam
[7] = rgndata
->rdh
.rcBound
.left
;
1621 mr
->rdParam
[8] = rgndata
->rdh
.rcBound
.top
;
1622 mr
->rdParam
[9] = rgndata
->rdh
.rcBound
.right
;
1623 mr
->rdParam
[10] = rgndata
->rdh
.rcBound
.bottom
;
1624 mr
->rdFunction
= META_CREATEREGION
;
1625 mr
->rdSize
= len
/ 2;
1626 ret
= MF_WriteRecord( dc
, mr
, mr
->rdSize
* 2 );
1627 HeapFree( SystemHeap
, 0, mr
);
1628 HeapFree( SystemHeap
, 0, rgndata
);
1631 fprintf(stderr
, "MF_CreateRegion: MF_WriteRecord failed\n");
1634 return MF_AddHandleDC( dc
);