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
);