Release 971116
[wine/multimedia.git] / objects / metafile.c
blob7785313ee39904dbc70e86638d5d87303172f78b
1 /*
2 * Metafile functions
4 * Copyright David W. Metcalfe, 1994
5 * Niels de Carpentier, Albrecht Kleine, Huw Davies 1996
7 */
9 #include <string.h>
10 #include <fcntl.h>
11 #include "gdi.h"
12 #include "bitmap.h"
13 #include "file.h"
14 #include "heap.h"
15 #include "metafile.h"
16 #include "metafiledrv.h"
17 #include "stddebug.h"
18 #include "debug.h"
20 /******************************************************************
21 * MF_AddHandle
23 * Add a handle to an external handle table and return the index
26 static int MF_AddHandle(HANDLETABLE16 *ht, WORD htlen, HGDIOBJ16 hobj)
28 int i;
30 for (i = 0; i < htlen; i++)
32 if (*(ht->objectHandle + i) == 0)
34 *(ht->objectHandle + i) = hobj;
35 return i;
38 return -1;
42 /******************************************************************
43 * MF_AddHandleDC
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
47 * handles.
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 HMETAFILE32 WINAPI GetMetaFile32A( LPCSTR lpFilename )
71 HMETAFILE16 hmf;
72 METAHEADER *mh;
73 HFILE32 hFile;
74 DWORD size;
76 dprintf_metafile(stddeb,"GetMetaFile: %s\n", lpFilename);
78 if (!lpFilename)
79 return 0;
81 hmf = GlobalAlloc16(GMEM_MOVEABLE, MFHEADERSIZE);
82 mh = (METAHEADER *)GlobalLock16(hmf);
84 if (!mh)
86 GlobalFree16(hmf);
87 return 0;
90 if ((hFile = _lopen32(lpFilename, OF_READ)) == HFILE_ERROR32)
92 GlobalFree16(hmf);
93 return 0;
96 if (_lread32(hFile, (char *)mh, MFHEADERSIZE) == HFILE_ERROR32)
98 _lclose32( hFile );
99 GlobalFree16(hmf);
100 return 0;
103 size = mh->mtSize * 2; /* alloc memory for whole metafile */
104 GlobalUnlock16(hmf);
105 hmf = GlobalReAlloc16(hmf,size,GMEM_MOVEABLE);
106 mh = (METAHEADER *)GlobalLock16(hmf);
108 if (!mh)
110 _lclose32( hFile );
111 GlobalFree16(hmf);
112 return 0;
115 if (_lread32(hFile, (char*)mh + mh->mtHeaderSize * 2,
116 size - mh->mtHeaderSize * 2) == HFILE_ERROR32)
118 _lclose32( hFile );
119 GlobalFree16(hmf);
120 return 0;
123 _lclose32(hFile);
125 if (mh->mtType != 1)
127 GlobalFree16(hmf);
128 return 0;
131 GlobalUnlock16(hmf);
132 return hmf;
137 /******************************************************************
138 * GetMetafile32W (GDI32.199)
140 HMETAFILE32 WINAPI GetMetaFile32W( LPCWSTR lpFilename )
142 LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFilename );
143 HMETAFILE32 ret = GetMetaFile32A( p );
144 HeapFree( GetProcessHeap(), 0, p );
145 return ret;
149 /******************************************************************
150 * CopyMetaFile16 (GDI.151)
153 HMETAFILE16 WINAPI CopyMetaFile16( HMETAFILE16 hSrcMetaFile, LPCSTR lpFilename )
155 return CopyMetaFile32A( hSrcMetaFile, lpFilename );
159 /******************************************************************
160 * CopyMetaFile32A (GDI32.23)
162 HMETAFILE32 WINAPI CopyMetaFile32A(HMETAFILE32 hSrcMetaFile, LPCSTR lpFilename)
164 HMETAFILE16 handle = 0;
165 METAHEADER *mh;
166 METAHEADER *mh2;
167 HFILE32 hFile;
169 dprintf_metafile(stddeb,"CopyMetaFile: %s\n", lpFilename);
171 mh = (METAHEADER *)GlobalLock16(hSrcMetaFile);
173 if (!mh)
174 return 0;
176 if (lpFilename) /* disk based metafile */
178 int i,j;
179 hFile = _lcreat32(lpFilename, 0);
180 j=mh->mtType;
181 mh->mtType=1; /* disk file version stores 1 here */
182 i=_lwrite32(hFile, (char *)mh, mh->mtSize * 2) ;
183 mh->mtType=j; /* restore old value [0 or 1] */
184 _lclose32(hFile);
185 if (i == -1)
186 return 0;
187 /* FIXME: return value */
189 else /* memory based metafile */
191 handle = GlobalAlloc16(GMEM_MOVEABLE,mh->mtSize * 2);
192 mh2 = (METAHEADER *)GlobalLock16(handle);
193 memcpy(mh2,mh, mh->mtSize * 2);
194 GlobalUnlock16(handle);
197 return handle;
201 /******************************************************************
202 * CopyMetaFile32W (GDI32.24)
204 HMETAFILE32 WINAPI CopyMetaFile32W( HMETAFILE32 hSrcMetaFile,
205 LPCWSTR lpFilename )
207 LPSTR p = HEAP_strdupWtoA( GetProcessHeap(), 0, lpFilename );
208 HMETAFILE32 ret = CopyMetaFile32A( hSrcMetaFile, p );
209 HeapFree( GetProcessHeap(), 0, p );
210 return ret;
214 /******************************************************************
215 * IsValidMetaFile (GDI.410)
216 * (This is not exactly what windows does, see "Undoc Win")
219 BOOL16 WINAPI IsValidMetaFile(HMETAFILE16 hmf)
221 BOOL16 resu=FALSE;
222 METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
223 if (mh) {
224 if (mh->mtType == 1 || mh->mtType == 0)
225 if (mh->mtHeaderSize == MFHEADERSIZE/sizeof(INT16))
226 if (mh->mtVersion == MFVERSION)
227 resu=TRUE;
228 GlobalUnlock16(hmf);
230 dprintf_metafile(stddeb,"IsValidMetaFile %x => %d\n",hmf,resu);
231 return resu;
235 /******************************************************************
236 * PlayMetafile16 (GDI.123)
238 BOOL16 WINAPI PlayMetaFile16( HDC16 hdc, HMETAFILE16 hmf )
240 return PlayMetaFile32( hdc, hmf );
244 /******************************************************************
245 * PlayMetafile32 (GDI32.265)
247 BOOL32 WINAPI PlayMetaFile32( HDC32 hdc, HMETAFILE32 hmf )
249 METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
250 METARECORD *mr;
251 HANDLETABLE16 *ht;
252 HGLOBAL16 hHT;
253 int offset = 0;
254 WORD i;
255 HPEN32 hPen;
256 HBRUSH32 hBrush;
257 HFONT32 hFont;
258 DC *dc;
260 dprintf_metafile(stddeb,"PlayMetaFile(%04x %04x)\n",hdc,hmf);
262 if (!mh) return FALSE;
263 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
264 hPen = dc->w.hPen;
265 hBrush = dc->w.hBrush;
266 hFont = dc->w.hFont;
267 GDI_HEAP_UNLOCK(hdc);
268 /* create the handle table */
269 hHT = GlobalAlloc16(GMEM_MOVEABLE|GMEM_ZEROINIT,
270 sizeof(HANDLETABLE16) * mh->mtNoObjects);
271 ht = (HANDLETABLE16 *)GlobalLock16(hHT);
273 /* loop through metafile playing records */
274 offset = mh->mtHeaderSize * 2;
275 while (offset < mh->mtSize * 2)
277 mr = (METARECORD *)((char *)mh + offset);
278 dprintf_metafile(stddeb,"offset = %04x size = %08lx function = %04x\n",
279 offset,mr->rdSize,mr->rdFunction);
280 offset += mr->rdSize * 2;
281 PlayMetaFileRecord16( hdc, ht, mr, mh->mtNoObjects );
284 SelectObject32(hdc, hBrush);
285 SelectObject32(hdc, hPen);
286 SelectObject32(hdc, hFont);
288 /* free objects in handle table */
289 for(i = 0; i < mh->mtNoObjects; i++)
290 if(*(ht->objectHandle + i) != 0)
291 DeleteObject32(*(ht->objectHandle + i));
293 /* free handle table */
294 GlobalFree16(hHT);
296 return TRUE;
300 /******************************************************************
301 * EnumMetaFile16 (GDI.175)
302 * Niels de carpentier, april 1996
304 BOOL16 WINAPI EnumMetaFile16( HDC16 hdc, HMETAFILE16 hmf,
305 MFENUMPROC16 lpEnumFunc, LPARAM lpData )
307 METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
308 METARECORD *mr;
309 HANDLETABLE16 *ht;
310 HGLOBAL16 hHT;
311 SEGPTR spht, spRecord;
312 int offset = 0;
313 WORD i;
314 HPEN32 hPen;
315 HBRUSH32 hBrush;
316 HFONT32 hFont;
317 DC *dc;
319 dprintf_metafile(stddeb,"EnumMetaFile(%04x, %04x, %08lx, %08lx)\n",
320 hdc, hmf, (DWORD)lpEnumFunc, lpData);
322 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
323 hPen = dc->w.hPen;
324 hBrush = dc->w.hBrush;
325 hFont = dc->w.hFont;
326 GDI_HEAP_UNLOCK(hdc);
328 /* create the handle table */
330 hHT = GlobalAlloc16(GMEM_MOVEABLE | GMEM_ZEROINIT,
331 sizeof(HANDLETABLE16) * mh->mtNoObjects);
332 spht = WIN16_GlobalLock16(hHT);
334 offset = mh->mtHeaderSize * 2;
336 /* loop through metafile records */
338 spRecord = WIN16_GlobalLock16(hmf);
339 while (offset < (mh->mtSize * 2))
341 mr = (METARECORD *)((char *)mh + offset);
342 if (!lpEnumFunc( hdc, (HANDLETABLE16 *)spht,
343 (METARECORD *)((UINT32)spRecord + offset),
344 mh->mtNoObjects, (LONG)lpData))
345 break;
347 offset += (mr->rdSize * 2);
350 SelectObject32(hdc, hBrush);
351 SelectObject32(hdc, hPen);
352 SelectObject32(hdc, hFont);
354 ht = (HANDLETABLE16 *)GlobalLock16(hHT);
356 /* free objects in handle table */
357 for(i = 0; i < mh->mtNoObjects; i++)
358 if(*(ht->objectHandle + i) != 0)
359 DeleteObject32(*(ht->objectHandle + i));
361 /* free handle table */
362 GlobalFree16(hHT);
364 return TRUE;
368 /******************************************************************
369 * PlayMetaFileRecord16 (GDI.176)
371 void WINAPI PlayMetaFileRecord16( HDC16 hdc, HANDLETABLE16 *ht, METARECORD *mr,
372 UINT16 nHandles )
374 short s1;
375 HANDLE16 hndl;
376 char *ptr;
377 BITMAPINFOHEADER *infohdr;
379 dprintf_metafile(stddeb,"PlayMetaFileRecord(%04x %08lx %08lx %04x)\n",
380 hdc,(LONG)ht, (LONG)mr, nHandles);
382 switch (mr->rdFunction)
384 case META_EOF:
385 break;
387 case META_DELETEOBJECT:
388 DeleteObject32(*(ht->objectHandle + *(mr->rdParam)));
389 *(ht->objectHandle + *(mr->rdParam)) = 0;
390 break;
392 case META_SETBKCOLOR:
393 SetBkColor16(hdc, MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
394 break;
396 case META_SETBKMODE:
397 SetBkMode16(hdc, *(mr->rdParam));
398 break;
400 case META_SETMAPMODE:
401 SetMapMode16(hdc, *(mr->rdParam));
402 break;
404 case META_SETROP2:
405 SetROP216(hdc, *(mr->rdParam));
406 break;
408 case META_SETRELABS:
409 SetRelAbs16(hdc, *(mr->rdParam));
410 break;
412 case META_SETPOLYFILLMODE:
413 SetPolyFillMode16(hdc, *(mr->rdParam));
414 break;
416 case META_SETSTRETCHBLTMODE:
417 SetStretchBltMode16(hdc, *(mr->rdParam));
418 break;
419 case META_SETTEXTCOLOR:
420 SetTextColor16(hdc, MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
421 break;
423 case META_SETWINDOWORG:
424 SetWindowOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
425 break;
427 case META_SETWINDOWEXT:
428 SetWindowExt(hdc, *(mr->rdParam + 1), *(mr->rdParam));
429 break;
431 case META_SETVIEWPORTORG:
432 SetViewportOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
433 break;
435 case META_SETVIEWPORTEXT:
436 SetViewportExt(hdc, *(mr->rdParam + 1), *(mr->rdParam));
437 break;
439 case META_OFFSETWINDOWORG:
440 OffsetWindowOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
441 break;
443 case META_SCALEWINDOWEXT:
444 ScaleWindowExt(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
445 *(mr->rdParam + 1), *(mr->rdParam));
446 break;
448 case META_OFFSETVIEWPORTORG:
449 OffsetViewportOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
450 break;
452 case META_SCALEVIEWPORTEXT:
453 ScaleViewportExt(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
454 *(mr->rdParam + 1), *(mr->rdParam));
455 break;
457 case META_LINETO:
458 LineTo32(hdc, (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
459 break;
461 case META_MOVETO:
462 MoveTo(hdc, *(mr->rdParam + 1), *(mr->rdParam));
463 break;
465 case META_EXCLUDECLIPRECT:
466 ExcludeClipRect16( hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
467 *(mr->rdParam + 1), *(mr->rdParam) );
468 break;
470 case META_INTERSECTCLIPRECT:
471 IntersectClipRect16( hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
472 *(mr->rdParam + 1), *(mr->rdParam) );
473 break;
475 case META_ARC:
476 Arc32(hdc, (INT16)*(mr->rdParam + 7), (INT16)*(mr->rdParam + 6),
477 (INT16)*(mr->rdParam + 5), (INT16)*(mr->rdParam + 4),
478 (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
479 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
480 break;
482 case META_ELLIPSE:
483 Ellipse32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
484 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
485 break;
487 case META_FLOODFILL:
488 FloodFill32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
489 MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
490 break;
492 case META_PIE:
493 Pie32(hdc, (INT16)*(mr->rdParam + 7), (INT16)*(mr->rdParam + 6),
494 (INT16)*(mr->rdParam + 5), (INT16)*(mr->rdParam + 4),
495 (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
496 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
497 break;
499 case META_RECTANGLE:
500 Rectangle32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
501 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
502 break;
504 case META_ROUNDRECT:
505 RoundRect32(hdc, (INT16)*(mr->rdParam + 5), (INT16)*(mr->rdParam + 4),
506 (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
507 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
508 break;
510 case META_PATBLT:
511 PatBlt16(hdc, *(mr->rdParam + 5), *(mr->rdParam + 4),
512 *(mr->rdParam + 3), *(mr->rdParam + 2),
513 MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
514 break;
516 case META_SAVEDC:
517 SaveDC32(hdc);
518 break;
520 case META_SETPIXEL:
521 SetPixel32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
522 MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
523 break;
525 case META_OFFSETCLIPRGN:
526 OffsetClipRgn16( hdc, *(mr->rdParam + 1), *(mr->rdParam) );
527 break;
529 case META_TEXTOUT:
530 s1 = *(mr->rdParam);
531 TextOut16(hdc, *(mr->rdParam + ((s1 + 1) >> 1) + 2),
532 *(mr->rdParam + ((s1 + 1) >> 1) + 1),
533 (char *)(mr->rdParam + 1), s1);
534 break;
536 case META_POLYGON:
537 Polygon16(hdc, (LPPOINT16)(mr->rdParam + 1), *(mr->rdParam));
538 break;
540 case META_POLYPOLYGON:
541 PolyPolygon16(hdc, (LPPOINT16)(mr->rdParam + *(mr->rdParam) + 1),
542 (LPINT16)(mr->rdParam + 1), *(mr->rdParam));
543 break;
545 case META_POLYLINE:
546 Polyline16(hdc, (LPPOINT16)(mr->rdParam + 1), *(mr->rdParam));
547 break;
549 case META_RESTOREDC:
550 RestoreDC32(hdc, (INT16)*(mr->rdParam));
551 break;
553 case META_SELECTOBJECT:
554 SelectObject32(hdc, *(ht->objectHandle + *(mr->rdParam)));
555 break;
557 case META_CHORD:
558 Chord32(hdc, (INT16)*(mr->rdParam + 7), (INT16)*(mr->rdParam + 6),
559 (INT16)*(mr->rdParam+5), (INT16)*(mr->rdParam + 4),
560 (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
561 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
562 break;
564 case META_CREATEPATTERNBRUSH:
565 switch (*(mr->rdParam))
567 case BS_PATTERN:
568 infohdr = (BITMAPINFOHEADER *)(mr->rdParam + 2);
569 MF_AddHandle(ht, nHandles,
570 CreatePatternBrush32(CreateBitmap32(infohdr->biWidth,
571 infohdr->biHeight,
572 infohdr->biPlanes,
573 infohdr->biBitCount,
574 (LPSTR)(mr->rdParam +
575 (sizeof(BITMAPINFOHEADER) / 2) + 4))));
576 break;
578 case BS_DIBPATTERN:
579 s1 = mr->rdSize * 2 - sizeof(METARECORD) - 2;
580 hndl = GlobalAlloc16(GMEM_MOVEABLE, s1);
581 ptr = GlobalLock16(hndl);
582 memcpy(ptr, mr->rdParam + 2, s1);
583 GlobalUnlock16(hndl);
584 MF_AddHandle(ht, nHandles,
585 CreateDIBPatternBrush32(hndl, *(mr->rdParam + 1)));
586 GlobalFree16(hndl);
588 break;
590 case META_CREATEPENINDIRECT:
591 MF_AddHandle(ht, nHandles,
592 CreatePenIndirect16((LOGPEN16 *)(&(mr->rdParam))));
593 break;
595 case META_CREATEFONTINDIRECT:
596 MF_AddHandle(ht, nHandles,
597 CreateFontIndirect16((LOGFONT16 *)(&(mr->rdParam))));
598 break;
600 case META_CREATEBRUSHINDIRECT:
601 MF_AddHandle(ht, nHandles,
602 CreateBrushIndirect16((LOGBRUSH16 *)(&(mr->rdParam))));
603 break;
605 /* W. Magro: Some new metafile operations. Not all debugged. */
606 case META_CREATEPALETTE:
607 MF_AddHandle(ht, nHandles,
608 CreatePalette16((LPLOGPALETTE)mr->rdParam));
609 break;
611 case META_SETTEXTALIGN:
612 SetTextAlign16(hdc, *(mr->rdParam));
613 break;
615 case META_SELECTPALETTE:
616 SelectPalette16(hdc, *(ht->objectHandle + *(mr->rdParam+1)),*(mr->rdParam));
617 break;
619 case META_SETMAPPERFLAGS:
620 SetMapperFlags16(hdc, *(mr->rdParam));
621 break;
623 case META_REALIZEPALETTE:
624 RealizePalette16(hdc);
625 break;
627 case META_ESCAPE:
628 dprintf_metafile(stddeb,"PlayMetaFileRecord: META_ESCAPE unimplemented.\n");
629 break;
631 /* --- Begin of fixed or new metafile operations. July 1996 ----*/
632 case META_EXTTEXTOUT:
634 LPINT16 dxx;
635 LPSTR sot;
636 DWORD len;
638 s1 = mr->rdParam[2]; /* String length */
639 len = sizeof(METARECORD) + (((s1 + 1) >> 1) * 2) + 2 * sizeof(short)
640 + sizeof(UINT16) + (mr->rdParam[3] ? sizeof(RECT16) : 0); /* rec len without dx array */
642 sot= (LPSTR)&mr->rdParam[4]; /* start_of_text */
643 if (mr->rdParam[3])
644 sot+=sizeof(RECT16); /* there is a rectangle, so add offset */
646 if (mr->rdSize == len / 2)
647 dxx = NULL; /* determine if array present */
648 else
649 if (mr->rdSize == (len + s1 * sizeof(INT16)) / 2)
650 dxx = (LPINT16)(sot+(((s1+1)>>1)*2));
651 else
653 fprintf(stderr,
654 "Please report: PlayMetaFile/ExtTextOut len=%ld slen=%d rdSize=%ld opt=%04x\n",
655 len,s1,mr->rdSize,mr->rdParam[3]);
656 dxx = NULL; /* should't happen -- but if, we continue with NULL [for workaround] */
658 ExtTextOut16( hdc, mr->rdParam[1], /* X position */
659 mr->rdParam[0], /* Y position */
660 mr->rdParam[3], /* options */
661 mr->rdParam[3] ? (LPRECT16) &mr->rdParam[4]:NULL, /* rectangle */
662 sot, /* string */
663 s1, dxx); /* length, dx array */
664 if (dxx)
665 dprintf_metafile(stddeb,"EXTTEXTOUT: %s len: %ld dx0: %d\n",
666 sot,mr->rdSize,dxx[0]);
668 break;
670 case META_STRETCHDIB:
672 LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParam[11]);
673 LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize( info, mr->rdParam[2] );
674 StretchDIBits16(hdc,mr->rdParam[10],mr->rdParam[9],mr->rdParam[8],
675 mr->rdParam[7],mr->rdParam[6],mr->rdParam[5],
676 mr->rdParam[4],mr->rdParam[3],bits,info,
677 mr->rdParam[2],MAKELONG(mr->rdParam[0],mr->rdParam[1]));
679 break;
681 case META_DIBSTRETCHBLT:
683 LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParam[10]);
684 LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize( info, mr->rdParam[2] );
685 StretchDIBits16(hdc,mr->rdParam[9],mr->rdParam[8],mr->rdParam[7],
686 mr->rdParam[6],mr->rdParam[5],mr->rdParam[4],
687 mr->rdParam[3],mr->rdParam[2],bits,info,
688 DIB_RGB_COLORS,MAKELONG(mr->rdParam[0],mr->rdParam[1]));
690 break;
692 case META_STRETCHBLT:
694 HDC16 hdcSrc=CreateCompatibleDC16(hdc);
695 HBITMAP32 hbitmap=CreateBitmap32(mr->rdParam[10], /*Width */
696 mr->rdParam[11], /*Height*/
697 mr->rdParam[13], /*Planes*/
698 mr->rdParam[14], /*BitsPixel*/
699 (LPSTR)&mr->rdParam[15]); /*bits*/
700 SelectObject32(hdcSrc,hbitmap);
701 StretchBlt16(hdc,mr->rdParam[9],mr->rdParam[8],
702 mr->rdParam[7],mr->rdParam[6],
703 hdcSrc,mr->rdParam[5],mr->rdParam[4],
704 mr->rdParam[3],mr->rdParam[2],
705 MAKELONG(mr->rdParam[0],mr->rdParam[1]));
706 DeleteDC32(hdcSrc);
708 break;
710 case META_BITBLT: /* <-- not yet debugged */
712 HDC16 hdcSrc=CreateCompatibleDC16(hdc);
713 HBITMAP32 hbitmap=CreateBitmap32(mr->rdParam[7]/*Width */,
714 mr->rdParam[8]/*Height*/,
715 mr->rdParam[10]/*Planes*/,
716 mr->rdParam[11]/*BitsPixel*/,
717 (LPSTR)&mr->rdParam[12]/*bits*/);
718 SelectObject32(hdcSrc,hbitmap);
719 BitBlt32(hdc,(INT16)mr->rdParam[6],(INT16)mr->rdParam[5],
720 (INT16)mr->rdParam[4],(INT16)mr->rdParam[3],
721 hdcSrc, (INT16)mr->rdParam[2],(INT16)mr->rdParam[1],
722 MAKELONG(0,mr->rdParam[0]));
723 DeleteDC32(hdcSrc);
725 break;
727 /* --- Begin of new metafile operations. April, 1997 (ak) ----*/
728 case META_CREATEREGION:
730 int i;
731 HRGN32 h2,hrgn=CreateRectRgn32(mr->rdParam[7],mr->rdParam[8],
732 mr->rdParam[9],mr->rdParam[10]);
733 for (i = 0; i < mr->rdParam[5]; i++)
735 if (mr->rdParam[11+i*6]==2)
737 h2=CreateRectRgn32(mr->rdParam[14+i*6],mr->rdParam[12+i*6],
738 mr->rdParam[15+i*6],mr->rdParam[13+i*6]);
739 CombineRgn32(hrgn,hrgn,h2,mr->rdParam[16+i*6]); /* e.g. RGN_OR */
740 DeleteObject32( h2 );
743 MF_AddHandle(ht, nHandles,hrgn);
745 break;
747 case META_FILLREGION:
748 FillRgn16(hdc, *(ht->objectHandle + *(mr->rdParam)),
749 *(ht->objectHandle + *(mr->rdParam+1)));
750 break;
752 case META_INVERTREGION:
753 InvertRgn16(hdc, *(ht->objectHandle + *(mr->rdParam)));
754 break;
756 case META_PAINTREGION:
757 PaintRgn16(hdc, *(ht->objectHandle + *(mr->rdParam)));
758 break;
760 case META_SELECTCLIPREGION:
761 SelectClipRgn32(hdc, *(ht->objectHandle + *(mr->rdParam)));
762 break;
764 case META_DIBCREATEPATTERNBRUSH:
765 /* *(mr->rdParam) may be BS_PATTERN or BS_DIBPATTERN: but there's no difference */
766 dprintf_metafile(stddeb,"META_DIBCREATEPATTERNBRUSH: %d\n",*(mr->rdParam));
767 s1 = mr->rdSize * 2 - sizeof(METARECORD) - 2;
768 hndl = GlobalAlloc16(GMEM_MOVEABLE, s1);
769 ptr = GlobalLock16(hndl);
770 memcpy(ptr, mr->rdParam + 2, s1);
771 GlobalUnlock16(hndl);
772 MF_AddHandle(ht, nHandles,CreateDIBPatternBrush16(hndl, *(mr->rdParam + 1)));
773 GlobalFree16(hndl);
774 break;
776 case META_DIBBITBLT:
778 LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParam[8]);
779 LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize( info, mr->rdParam[0] );
780 StretchDIBits16(hdc,mr->rdParam[7],mr->rdParam[6],mr->rdParam[5],
781 mr->rdParam[4],mr->rdParam[3],mr->rdParam[2],
782 mr->rdParam[5],mr->rdParam[4],bits,info,
783 DIB_RGB_COLORS,MAKELONG(mr->rdParam[0],mr->rdParam[1]));
785 break;
787 case META_SETTEXTCHAREXTRA:
788 SetTextCharacterExtra16(hdc, (INT16)*(mr->rdParam));
789 break;
791 case META_SETTEXTJUSTIFICATION:
792 SetTextJustification32(hdc, *(mr->rdParam + 1), *(mr->rdParam));
793 break;
795 #define META_UNIMP(x) case x: fprintf(stderr,"PlayMetaFileRecord:record type "#x" not implemented.\n");break;
796 META_UNIMP(META_FRAMEREGION)
797 META_UNIMP(META_DRAWTEXT)
798 META_UNIMP(META_SETDIBTODEV)
799 META_UNIMP(META_ANIMATEPALETTE)
800 META_UNIMP(META_SETPALENTRIES)
801 META_UNIMP(META_RESIZEPALETTE)
802 META_UNIMP(META_EXTFLOODFILL)
803 META_UNIMP(META_RESETDC)
804 META_UNIMP(META_STARTDOC)
805 META_UNIMP(META_STARTPAGE)
806 META_UNIMP(META_ENDPAGE)
807 META_UNIMP(META_ABORTDOC)
808 META_UNIMP(META_ENDDOC)
809 META_UNIMP(META_CREATEBRUSH)
810 META_UNIMP(META_CREATEBITMAPINDIRECT)
811 META_UNIMP(META_CREATEBITMAP)
812 #undef META_UNIMP
814 default:
815 fprintf(stddeb,"PlayMetaFileRecord: Unknown record type %x\n",
816 mr->rdFunction);
821 /******************************************************************
822 * GetMetaFileBits (GDI.159)
824 * Trade in a meta file object handle for a handle to the meta file memory
827 HGLOBAL16 WINAPI GetMetaFileBits(HMETAFILE16 hmf)
829 dprintf_metafile(stddeb,"GetMetaFileBits: hMem out: %04x\n", hmf);
831 return hmf;
834 /******************************************************************
835 * SetMetaFileBits (GDI.160)
837 * Trade in a meta file memory handle for a handle to a meta file object
839 HMETAFILE16 WINAPI SetMetaFileBits( HGLOBAL16 hMem )
841 dprintf_metafile(stddeb,"SetMetaFileBits: hmf out: %04x\n", hMem);
843 return hMem;
846 /******************************************************************
847 * SetMetaFileBitsBetter (GDI.196)
849 HMETAFILE16 WINAPI SetMetaFileBitsBetter( HMETAFILE16 hMeta )
851 if( IsValidMetaFile( hMeta ) )
852 return (HMETAFILE16)GlobalReAlloc16( hMeta, 0,
853 GMEM_SHARE | GMEM_NODISCARD | GMEM_MODIFY);
854 return (HMETAFILE16)0;
857 /******************************************************************
858 * MF_WriteRecord
860 * Warning: this function can change the metafile handle.
863 static BOOL32 MF_WriteRecord( DC *dc, METARECORD *mr, WORD rlen)
865 DWORD len;
866 METAHEADER *mh;
867 METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
869 switch(physDev->mh->mtType)
871 case METAFILE_MEMORY:
872 len = physDev->mh->mtSize * 2 + rlen;
873 mh = HeapReAlloc( SystemHeap, 0, physDev->mh, len );
874 if (!mh) return FALSE;
875 physDev->mh = mh;
876 memcpy((WORD *)physDev->mh + physDev->mh->mtSize, mr, rlen);
877 break;
878 case METAFILE_DISK:
879 dprintf_metafile(stddeb,"Writing record to disk\n");
880 if (_lwrite32(physDev->mh->mtNoParameters, (char *)mr, rlen) == -1)
881 return FALSE;
882 break;
883 default:
884 fprintf( stderr, "Unknown metafile type %d\n", physDev->mh->mtType );
885 return FALSE;
888 physDev->mh->mtSize += rlen / 2;
889 physDev->mh->mtMaxRecord = MAX(physDev->mh->mtMaxRecord, rlen / 2);
890 return TRUE;
894 /******************************************************************
895 * MF_MetaParam0
898 BOOL32 MF_MetaParam0(DC *dc, short func)
900 char buffer[8];
901 METARECORD *mr = (METARECORD *)&buffer;
903 mr->rdSize = 3;
904 mr->rdFunction = func;
905 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
909 /******************************************************************
910 * MF_MetaParam1
912 BOOL32 MF_MetaParam1(DC *dc, short func, short param1)
914 char buffer[8];
915 METARECORD *mr = (METARECORD *)&buffer;
917 mr->rdSize = 4;
918 mr->rdFunction = func;
919 *(mr->rdParam) = param1;
920 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
924 /******************************************************************
925 * MF_MetaParam2
927 BOOL32 MF_MetaParam2(DC *dc, short func, short param1, short param2)
929 char buffer[10];
930 METARECORD *mr = (METARECORD *)&buffer;
932 mr->rdSize = 5;
933 mr->rdFunction = func;
934 *(mr->rdParam) = param2;
935 *(mr->rdParam + 1) = param1;
936 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
940 /******************************************************************
941 * MF_MetaParam4
944 BOOL32 MF_MetaParam4(DC *dc, short func, short param1, short param2,
945 short param3, short param4)
947 char buffer[14];
948 METARECORD *mr = (METARECORD *)&buffer;
950 mr->rdSize = 7;
951 mr->rdFunction = func;
952 *(mr->rdParam) = param4;
953 *(mr->rdParam + 1) = param3;
954 *(mr->rdParam + 2) = param2;
955 *(mr->rdParam + 3) = param1;
956 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
960 /******************************************************************
961 * MF_MetaParam6
964 BOOL32 MF_MetaParam6(DC *dc, short func, short param1, short param2,
965 short param3, short param4, short param5, short param6)
967 char buffer[18];
968 METARECORD *mr = (METARECORD *)&buffer;
970 mr->rdSize = 9;
971 mr->rdFunction = func;
972 *(mr->rdParam) = param6;
973 *(mr->rdParam + 1) = param5;
974 *(mr->rdParam + 2) = param4;
975 *(mr->rdParam + 3) = param3;
976 *(mr->rdParam + 4) = param2;
977 *(mr->rdParam + 5) = param1;
978 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
982 /******************************************************************
983 * MF_MetaParam8
985 BOOL32 MF_MetaParam8(DC *dc, short func, short param1, short param2,
986 short param3, short param4, short param5,
987 short param6, short param7, short param8)
989 char buffer[22];
990 METARECORD *mr = (METARECORD *)&buffer;
992 mr->rdSize = 11;
993 mr->rdFunction = func;
994 *(mr->rdParam) = param8;
995 *(mr->rdParam + 1) = param7;
996 *(mr->rdParam + 2) = param6;
997 *(mr->rdParam + 3) = param5;
998 *(mr->rdParam + 4) = param4;
999 *(mr->rdParam + 5) = param3;
1000 *(mr->rdParam + 6) = param2;
1001 *(mr->rdParam + 7) = param1;
1002 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1006 /******************************************************************
1007 * MF_CreateBrushIndirect
1010 BOOL32 MF_CreateBrushIndirect(DC *dc, HBRUSH16 hBrush, LOGBRUSH16 *logbrush)
1012 int index;
1013 char buffer[sizeof(METARECORD) - 2 + sizeof(*logbrush)];
1014 METARECORD *mr = (METARECORD *)&buffer;
1016 mr->rdSize = (sizeof(METARECORD) + sizeof(*logbrush) - 2) / 2;
1017 mr->rdFunction = META_CREATEBRUSHINDIRECT;
1018 memcpy(&(mr->rdParam), logbrush, sizeof(*logbrush));
1019 if (!(MF_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
1021 mr->rdSize = sizeof(METARECORD) / 2;
1022 mr->rdFunction = META_SELECTOBJECT;
1024 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1025 *(mr->rdParam) = index;
1026 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1030 /******************************************************************
1031 * MF_CreatePatternBrush
1034 BOOL32 MF_CreatePatternBrush(DC *dc, HBRUSH16 hBrush, LOGBRUSH16 *logbrush)
1036 DWORD len, bmSize, biSize;
1037 HGLOBAL16 hmr;
1038 METARECORD *mr;
1039 BITMAPOBJ *bmp;
1040 BITMAPINFO *info;
1041 BITMAPINFOHEADER *infohdr;
1042 int index;
1043 char buffer[sizeof(METARECORD)];
1045 switch (logbrush->lbStyle)
1047 case BS_PATTERN:
1048 bmp = (BITMAPOBJ *)GDI_GetObjPtr((HGDIOBJ16)logbrush->lbHatch, BITMAP_MAGIC);
1049 if (!bmp) return FALSE;
1050 len = sizeof(METARECORD) + sizeof(BITMAPINFOHEADER) +
1051 (bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes) + 6;
1052 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1054 GDI_HEAP_UNLOCK((HGDIOBJ16)logbrush->lbHatch);
1055 return FALSE;
1057 mr = (METARECORD *)GlobalLock16(hmr);
1058 memset(mr, 0, len);
1059 mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
1060 mr->rdSize = len / 2;
1061 *(mr->rdParam) = logbrush->lbStyle;
1062 *(mr->rdParam + 1) = DIB_RGB_COLORS;
1063 infohdr = (BITMAPINFOHEADER *)(mr->rdParam + 2);
1064 infohdr->biSize = sizeof(BITMAPINFOHEADER);
1065 infohdr->biWidth = bmp->bitmap.bmWidth;
1066 infohdr->biHeight = bmp->bitmap.bmHeight;
1067 infohdr->biPlanes = bmp->bitmap.bmPlanes;
1068 infohdr->biBitCount = bmp->bitmap.bmBitsPixel;
1069 memcpy(mr->rdParam + (sizeof(BITMAPINFOHEADER) / 2) + 4,
1070 PTR_SEG_TO_LIN(bmp->bitmap.bmBits),
1071 bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes);
1072 GDI_HEAP_UNLOCK(logbrush->lbHatch);
1073 break;
1075 case BS_DIBPATTERN:
1076 info = (BITMAPINFO *)GlobalLock16((HGLOBAL16)logbrush->lbHatch);
1077 if (info->bmiHeader.biCompression)
1078 bmSize = info->bmiHeader.biSizeImage;
1079 else
1080 bmSize = (info->bmiHeader.biWidth * info->bmiHeader.biBitCount
1081 + 31) / 32 * 8 * info->bmiHeader.biHeight;
1082 biSize = DIB_BitmapInfoSize(info, LOWORD(logbrush->lbColor));
1083 len = sizeof(METARECORD) + biSize + bmSize + 2;
1084 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1085 return FALSE;
1086 mr = (METARECORD *)GlobalLock16(hmr);
1087 memset(mr, 0, len);
1088 mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
1089 mr->rdSize = len / 2;
1090 *(mr->rdParam) = logbrush->lbStyle;
1091 *(mr->rdParam + 1) = LOWORD(logbrush->lbColor);
1092 memcpy(mr->rdParam + 2, info, biSize + bmSize);
1093 break;
1094 default:
1095 return FALSE;
1097 if (!(MF_WriteRecord(dc, mr, len)))
1099 GlobalFree16(hmr);
1100 return FALSE;
1103 GlobalFree16(hmr);
1105 mr = (METARECORD *)&buffer;
1106 mr->rdSize = sizeof(METARECORD) / 2;
1107 mr->rdFunction = META_SELECTOBJECT;
1109 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1110 *(mr->rdParam) = index;
1111 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1115 /******************************************************************
1116 * MF_CreatePenIndirect
1119 BOOL32 MF_CreatePenIndirect(DC *dc, HPEN16 hPen, LOGPEN16 *logpen)
1121 int index;
1122 char buffer[sizeof(METARECORD) - 2 + sizeof(*logpen)];
1123 METARECORD *mr = (METARECORD *)&buffer;
1125 mr->rdSize = (sizeof(METARECORD) + sizeof(*logpen) - 2) / 2;
1126 mr->rdFunction = META_CREATEPENINDIRECT;
1127 memcpy(&(mr->rdParam), logpen, sizeof(*logpen));
1128 if (!(MF_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
1130 mr->rdSize = sizeof(METARECORD) / 2;
1131 mr->rdFunction = META_SELECTOBJECT;
1133 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1134 *(mr->rdParam) = index;
1135 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1139 /******************************************************************
1140 * MF_CreateFontIndirect
1143 BOOL32 MF_CreateFontIndirect(DC *dc, HFONT16 hFont, LOGFONT16 *logfont)
1145 int index;
1146 char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT16)];
1147 METARECORD *mr = (METARECORD *)&buffer;
1149 mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT16) - 2) / 2;
1150 mr->rdFunction = META_CREATEFONTINDIRECT;
1151 memcpy(&(mr->rdParam), logfont, sizeof(LOGFONT16));
1152 if (!(MF_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
1154 mr->rdSize = sizeof(METARECORD) / 2;
1155 mr->rdFunction = META_SELECTOBJECT;
1157 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1158 *(mr->rdParam) = index;
1159 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1163 /******************************************************************
1164 * MF_TextOut
1166 BOOL32 MF_TextOut(DC *dc, short x, short y, LPCSTR str, short count)
1168 BOOL32 ret;
1169 DWORD len;
1170 HGLOBAL16 hmr;
1171 METARECORD *mr;
1173 len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 4;
1174 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1175 return FALSE;
1176 mr = (METARECORD *)GlobalLock16(hmr);
1177 memset(mr, 0, len);
1179 mr->rdSize = len / 2;
1180 mr->rdFunction = META_TEXTOUT;
1181 *(mr->rdParam) = count;
1182 memcpy(mr->rdParam + 1, str, count);
1183 *(mr->rdParam + ((count + 1) >> 1) + 1) = y;
1184 *(mr->rdParam + ((count + 1) >> 1) + 2) = x;
1185 ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
1186 GlobalFree16(hmr);
1187 return ret;
1190 /******************************************************************
1191 * MF_ExtTextOut
1193 BOOL32 MF_ExtTextOut(DC*dc, short x, short y, UINT16 flags, const RECT16 *rect,
1194 LPCSTR str, short count, const INT16 *lpDx)
1196 BOOL32 ret;
1197 DWORD len;
1198 HGLOBAL16 hmr;
1199 METARECORD *mr;
1201 if((!flags && rect) || (flags && !rect))
1202 fprintf(stderr, "MF_ExtTextOut: Inconsistent flags and rect\n");
1203 len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 2 * sizeof(short)
1204 + sizeof(UINT16);
1205 if(rect)
1206 len += sizeof(RECT16);
1207 if (lpDx)
1208 len+=count*sizeof(INT16);
1209 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1210 return FALSE;
1211 mr = (METARECORD *)GlobalLock16(hmr);
1212 memset(mr, 0, len);
1214 mr->rdSize = len / 2;
1215 mr->rdFunction = META_EXTTEXTOUT;
1216 *(mr->rdParam) = y;
1217 *(mr->rdParam + 1) = x;
1218 *(mr->rdParam + 2) = count;
1219 *(mr->rdParam + 3) = flags;
1220 if (rect) memcpy(mr->rdParam + 4, rect, sizeof(RECT16));
1221 memcpy(mr->rdParam + (rect ? 8 : 4), str, count);
1222 if (lpDx)
1223 memcpy(mr->rdParam + (rect ? 8 : 4) + ((count + 1) >> 1),lpDx,
1224 count*sizeof(INT16));
1225 ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
1226 GlobalFree16(hmr);
1227 return ret;
1230 /******************************************************************
1231 * MF_MetaPoly - implements Polygon and Polyline
1233 BOOL32 MF_MetaPoly(DC *dc, short func, LPPOINT16 pt, short count)
1235 BOOL32 ret;
1236 DWORD len;
1237 HGLOBAL16 hmr;
1238 METARECORD *mr;
1240 len = sizeof(METARECORD) + (count * 4);
1241 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1242 return FALSE;
1243 mr = (METARECORD *)GlobalLock16(hmr);
1244 memset(mr, 0, len);
1246 mr->rdSize = len / 2;
1247 mr->rdFunction = func;
1248 *(mr->rdParam) = count;
1249 memcpy(mr->rdParam + 1, pt, count * 4);
1250 ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
1251 GlobalFree16(hmr);
1252 return ret;
1256 /******************************************************************
1257 * MF_BitBlt
1259 BOOL32 MF_BitBlt(DC *dcDest, short xDest, short yDest, short width,
1260 short height, DC *dcSrc, short xSrc, short ySrc, DWORD rop)
1262 BOOL32 ret;
1263 DWORD len;
1264 HGLOBAL16 hmr;
1265 METARECORD *mr;
1266 BITMAP16 BM;
1268 GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM);
1269 len = sizeof(METARECORD) + 12 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
1270 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1271 return FALSE;
1272 mr = (METARECORD *)GlobalLock16(hmr);
1273 mr->rdFunction = META_BITBLT;
1274 *(mr->rdParam + 7) = BM.bmWidth;
1275 *(mr->rdParam + 8) = BM.bmHeight;
1276 *(mr->rdParam + 9) = BM.bmWidthBytes;
1277 *(mr->rdParam +10) = BM.bmPlanes;
1278 *(mr->rdParam +11) = BM.bmBitsPixel;
1279 dprintf_metafile(stddeb,"MF_StretchBlt->len = %ld rop=%lx \n",len,rop);
1280 if (GetBitmapBits32(dcSrc->w.hBitmap,BM.bmWidthBytes * BM.bmHeight,
1281 mr->rdParam +12))
1283 mr->rdSize = len / sizeof(INT16);
1284 *(mr->rdParam) = HIWORD(rop);
1285 *(mr->rdParam + 1) = ySrc;
1286 *(mr->rdParam + 2) = xSrc;
1287 *(mr->rdParam + 3) = height;
1288 *(mr->rdParam + 4) = width;
1289 *(mr->rdParam + 5) = yDest;
1290 *(mr->rdParam + 6) = xDest;
1291 ret = MF_WriteRecord( dcDest, mr, mr->rdSize * 2);
1293 else
1294 ret = FALSE;
1295 GlobalFree16(hmr);
1296 return ret;
1300 /**********************************************************************
1301 * MF_StretchBlt
1302 * this function contains TWO ways for procesing StretchBlt in metafiles,
1303 * decide between rdFunction values META_STRETCHBLT or META_DIBSTRETCHBLT
1304 * via #define STRETCH_VIA_DIB
1306 #define STRETCH_VIA_DIB
1307 #undef STRETCH_VIA_DIB
1308 BOOL32 MF_StretchBlt(DC *dcDest, short xDest, short yDest, short widthDest,
1309 short heightDest, DC *dcSrc, short xSrc, short ySrc,
1310 short widthSrc, short heightSrc, DWORD rop)
1312 BOOL32 ret;
1313 DWORD len;
1314 HGLOBAL16 hmr;
1315 METARECORD *mr;
1316 BITMAP16 BM;
1317 #ifdef STRETCH_VIA_DIB
1318 LPBITMAPINFOHEADER lpBMI;
1319 WORD nBPP;
1320 #endif
1321 GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM);
1322 #ifdef STRETCH_VIA_DIB
1323 nBPP = BM.bmPlanes * BM.bmBitsPixel;
1324 len = sizeof(METARECORD) + 10 * sizeof(INT16)
1325 + sizeof(BITMAPINFOHEADER) + (nBPP != 24 ? 1 << nBPP: 0) * sizeof(RGBQUAD)
1326 + ((BM.bmWidth * nBPP + 31) / 32) * 4 * BM.bmHeight;
1327 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1328 return FALSE;
1329 mr = (METARECORD *)GlobalLock16(hmr);
1330 mr->rdFunction = META_DIBSTRETCHBLT;
1331 lpBMI=(LPBITMAPINFOHEADER)(mr->rdParam+10);
1332 lpBMI->biSize = sizeof(BITMAPINFOHEADER);
1333 lpBMI->biWidth = BM.bmWidth;
1334 lpBMI->biHeight = BM.bmHeight;
1335 lpBMI->biPlanes = 1;
1336 lpBMI->biBitCount = nBPP; /* 1,4,8 or 24 */
1337 lpBMI->biClrUsed = nBPP != 24 ? 1 << nBPP : 0;
1338 lpBMI->biSizeImage = ((lpBMI->biWidth * nBPP + 31) / 32) * 4 * lpBMI->biHeight;
1339 lpBMI->biCompression = BI_RGB;
1340 lpBMI->biXPelsPerMeter = MulDiv32(GetDeviceCaps(dcSrc->hSelf,LOGPIXELSX),3937,100);
1341 lpBMI->biYPelsPerMeter = MulDiv32(GetDeviceCaps(dcSrc->hSelf,LOGPIXELSY),3937,100);
1342 lpBMI->biClrImportant = 0; /* 1 meter = 39.37 inch */
1344 dprintf_metafile(stddeb,"MF_StretchBltViaDIB->len = %ld rop=%lx PixYPM=%ld Caps=%d\n",
1345 len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(hdcSrc,LOGPIXELSY));
1346 if (GetDIBits(hdcSrc,dcSrc->w.hBitmap,0,(UINT32)lpBMI->biHeight,
1347 (LPSTR)lpBMI + DIB_BitmapInfoSize( (BITMAPINFO *)lpBMI,
1348 DIB_RGB_COLORS ),
1349 (LPBITMAPINFO)lpBMI, DIB_RGB_COLORS))
1350 #else
1351 len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
1352 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1353 return FALSE;
1354 mr = (METARECORD *)GlobalLock16(hmr);
1355 mr->rdFunction = META_STRETCHBLT;
1356 *(mr->rdParam +10) = BM.bmWidth;
1357 *(mr->rdParam +11) = BM.bmHeight;
1358 *(mr->rdParam +12) = BM.bmWidthBytes;
1359 *(mr->rdParam +13) = BM.bmPlanes;
1360 *(mr->rdParam +14) = BM.bmBitsPixel;
1361 dprintf_metafile(stddeb,"MF_StretchBlt->len = %ld rop=%lx \n",len,rop);
1362 if (GetBitmapBits32( dcSrc->w.hBitmap, BM.bmWidthBytes * BM.bmHeight,
1363 mr->rdParam +15))
1364 #endif
1366 mr->rdSize = len / sizeof(INT16);
1367 *(mr->rdParam) = LOWORD(rop);
1368 *(mr->rdParam + 1) = HIWORD(rop);
1369 *(mr->rdParam + 2) = heightSrc;
1370 *(mr->rdParam + 3) = widthSrc;
1371 *(mr->rdParam + 4) = ySrc;
1372 *(mr->rdParam + 5) = xSrc;
1373 *(mr->rdParam + 6) = heightDest;
1374 *(mr->rdParam + 7) = widthDest;
1375 *(mr->rdParam + 8) = yDest;
1376 *(mr->rdParam + 9) = xDest;
1377 ret = MF_WriteRecord( dcDest, mr, mr->rdSize * 2);
1379 else
1380 ret = FALSE;
1381 GlobalFree16(hmr);
1382 return ret;