Release 971221
[wine/multimedia.git] / objects / metafile.c
blob373c851589172d9d91008ee7b71accfff734453a
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 if (!mr->rdSize) {
281 fprintf(stderr,"METAFILE entry got size 0 at offset %d, total mf length is %ld\n",offset,mh->mtSize*2);
282 break; /* would loop endlessly otherwise */
284 offset += mr->rdSize * 2;
285 PlayMetaFileRecord16( hdc, ht, mr, mh->mtNoObjects );
288 SelectObject32(hdc, hBrush);
289 SelectObject32(hdc, hPen);
290 SelectObject32(hdc, hFont);
292 /* free objects in handle table */
293 for(i = 0; i < mh->mtNoObjects; i++)
294 if(*(ht->objectHandle + i) != 0)
295 DeleteObject32(*(ht->objectHandle + i));
297 /* free handle table */
298 GlobalFree16(hHT);
300 return TRUE;
304 /******************************************************************
305 * EnumMetaFile16 (GDI.175)
306 * Niels de carpentier, april 1996
308 BOOL16 WINAPI EnumMetaFile16( HDC16 hdc, HMETAFILE16 hmf,
309 MFENUMPROC16 lpEnumFunc, LPARAM lpData )
311 METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
312 METARECORD *mr;
313 HANDLETABLE16 *ht;
314 HGLOBAL16 hHT;
315 SEGPTR spht, spRecord;
316 int offset = 0;
317 WORD i;
318 HPEN32 hPen;
319 HBRUSH32 hBrush;
320 HFONT32 hFont;
321 DC *dc;
323 dprintf_metafile(stddeb,"EnumMetaFile(%04x, %04x, %08lx, %08lx)\n",
324 hdc, hmf, (DWORD)lpEnumFunc, lpData);
326 if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
327 hPen = dc->w.hPen;
328 hBrush = dc->w.hBrush;
329 hFont = dc->w.hFont;
330 GDI_HEAP_UNLOCK(hdc);
332 /* create the handle table */
334 hHT = GlobalAlloc16(GMEM_MOVEABLE | GMEM_ZEROINIT,
335 sizeof(HANDLETABLE16) * mh->mtNoObjects);
336 spht = WIN16_GlobalLock16(hHT);
338 offset = mh->mtHeaderSize * 2;
340 /* loop through metafile records */
342 spRecord = WIN16_GlobalLock16(hmf);
343 while (offset < (mh->mtSize * 2))
345 mr = (METARECORD *)((char *)mh + offset);
346 if (!lpEnumFunc( hdc, (HANDLETABLE16 *)spht,
347 (METARECORD *)((UINT32)spRecord + offset),
348 mh->mtNoObjects, (LONG)lpData))
349 break;
351 offset += (mr->rdSize * 2);
354 SelectObject32(hdc, hBrush);
355 SelectObject32(hdc, hPen);
356 SelectObject32(hdc, hFont);
358 ht = (HANDLETABLE16 *)GlobalLock16(hHT);
360 /* free objects in handle table */
361 for(i = 0; i < mh->mtNoObjects; i++)
362 if(*(ht->objectHandle + i) != 0)
363 DeleteObject32(*(ht->objectHandle + i));
365 /* free handle table */
366 GlobalFree16(hHT);
368 return TRUE;
372 /******************************************************************
373 * PlayMetaFileRecord16 (GDI.176)
375 void WINAPI PlayMetaFileRecord16( HDC16 hdc, HANDLETABLE16 *ht, METARECORD *mr,
376 UINT16 nHandles )
378 short s1;
379 HANDLE16 hndl;
380 char *ptr;
381 BITMAPINFOHEADER *infohdr;
383 dprintf_metafile(stddeb,"PlayMetaFileRecord(%04x %08lx %08lx %04x)\n",
384 hdc,(LONG)ht, (LONG)mr, nHandles);
386 switch (mr->rdFunction)
388 case META_EOF:
389 break;
391 case META_DELETEOBJECT:
392 DeleteObject32(*(ht->objectHandle + *(mr->rdParam)));
393 *(ht->objectHandle + *(mr->rdParam)) = 0;
394 break;
396 case META_SETBKCOLOR:
397 SetBkColor16(hdc, MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
398 break;
400 case META_SETBKMODE:
401 SetBkMode16(hdc, *(mr->rdParam));
402 break;
404 case META_SETMAPMODE:
405 SetMapMode16(hdc, *(mr->rdParam));
406 break;
408 case META_SETROP2:
409 SetROP216(hdc, *(mr->rdParam));
410 break;
412 case META_SETRELABS:
413 SetRelAbs16(hdc, *(mr->rdParam));
414 break;
416 case META_SETPOLYFILLMODE:
417 SetPolyFillMode16(hdc, *(mr->rdParam));
418 break;
420 case META_SETSTRETCHBLTMODE:
421 SetStretchBltMode16(hdc, *(mr->rdParam));
422 break;
423 case META_SETTEXTCOLOR:
424 SetTextColor16(hdc, MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
425 break;
427 case META_SETWINDOWORG:
428 SetWindowOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
429 break;
431 case META_SETWINDOWEXT:
432 SetWindowExt(hdc, *(mr->rdParam + 1), *(mr->rdParam));
433 break;
435 case META_SETVIEWPORTORG:
436 SetViewportOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
437 break;
439 case META_SETVIEWPORTEXT:
440 SetViewportExt(hdc, *(mr->rdParam + 1), *(mr->rdParam));
441 break;
443 case META_OFFSETWINDOWORG:
444 OffsetWindowOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
445 break;
447 case META_SCALEWINDOWEXT:
448 ScaleWindowExt(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
449 *(mr->rdParam + 1), *(mr->rdParam));
450 break;
452 case META_OFFSETVIEWPORTORG:
453 OffsetViewportOrg(hdc, *(mr->rdParam + 1), *(mr->rdParam));
454 break;
456 case META_SCALEVIEWPORTEXT:
457 ScaleViewportExt(hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
458 *(mr->rdParam + 1), *(mr->rdParam));
459 break;
461 case META_LINETO:
462 LineTo32(hdc, (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
463 break;
465 case META_MOVETO:
466 MoveTo(hdc, *(mr->rdParam + 1), *(mr->rdParam));
467 break;
469 case META_EXCLUDECLIPRECT:
470 ExcludeClipRect16( hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
471 *(mr->rdParam + 1), *(mr->rdParam) );
472 break;
474 case META_INTERSECTCLIPRECT:
475 IntersectClipRect16( hdc, *(mr->rdParam + 3), *(mr->rdParam + 2),
476 *(mr->rdParam + 1), *(mr->rdParam) );
477 break;
479 case META_ARC:
480 Arc32(hdc, (INT16)*(mr->rdParam + 7), (INT16)*(mr->rdParam + 6),
481 (INT16)*(mr->rdParam + 5), (INT16)*(mr->rdParam + 4),
482 (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
483 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
484 break;
486 case META_ELLIPSE:
487 Ellipse32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
488 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
489 break;
491 case META_FLOODFILL:
492 FloodFill32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
493 MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
494 break;
496 case META_PIE:
497 Pie32(hdc, (INT16)*(mr->rdParam + 7), (INT16)*(mr->rdParam + 6),
498 (INT16)*(mr->rdParam + 5), (INT16)*(mr->rdParam + 4),
499 (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
500 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
501 break;
503 case META_RECTANGLE:
504 Rectangle32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
505 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
506 break;
508 case META_ROUNDRECT:
509 RoundRect32(hdc, (INT16)*(mr->rdParam + 5), (INT16)*(mr->rdParam + 4),
510 (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
511 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
512 break;
514 case META_PATBLT:
515 PatBlt16(hdc, *(mr->rdParam + 5), *(mr->rdParam + 4),
516 *(mr->rdParam + 3), *(mr->rdParam + 2),
517 MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
518 break;
520 case META_SAVEDC:
521 SaveDC32(hdc);
522 break;
524 case META_SETPIXEL:
525 SetPixel32(hdc, (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
526 MAKELONG(*(mr->rdParam), *(mr->rdParam + 1)));
527 break;
529 case META_OFFSETCLIPRGN:
530 OffsetClipRgn16( hdc, *(mr->rdParam + 1), *(mr->rdParam) );
531 break;
533 case META_TEXTOUT:
534 s1 = *(mr->rdParam);
535 TextOut16(hdc, *(mr->rdParam + ((s1 + 1) >> 1) + 2),
536 *(mr->rdParam + ((s1 + 1) >> 1) + 1),
537 (char *)(mr->rdParam + 1), s1);
538 break;
540 case META_POLYGON:
541 Polygon16(hdc, (LPPOINT16)(mr->rdParam + 1), *(mr->rdParam));
542 break;
544 case META_POLYPOLYGON:
545 PolyPolygon16(hdc, (LPPOINT16)(mr->rdParam + *(mr->rdParam) + 1),
546 (LPINT16)(mr->rdParam + 1), *(mr->rdParam));
547 break;
549 case META_POLYLINE:
550 Polyline16(hdc, (LPPOINT16)(mr->rdParam + 1), *(mr->rdParam));
551 break;
553 case META_RESTOREDC:
554 RestoreDC32(hdc, (INT16)*(mr->rdParam));
555 break;
557 case META_SELECTOBJECT:
558 SelectObject32(hdc, *(ht->objectHandle + *(mr->rdParam)));
559 break;
561 case META_CHORD:
562 Chord32(hdc, (INT16)*(mr->rdParam + 7), (INT16)*(mr->rdParam + 6),
563 (INT16)*(mr->rdParam+5), (INT16)*(mr->rdParam + 4),
564 (INT16)*(mr->rdParam + 3), (INT16)*(mr->rdParam + 2),
565 (INT16)*(mr->rdParam + 1), (INT16)*(mr->rdParam));
566 break;
568 case META_CREATEPATTERNBRUSH:
569 switch (*(mr->rdParam))
571 case BS_PATTERN:
572 infohdr = (BITMAPINFOHEADER *)(mr->rdParam + 2);
573 MF_AddHandle(ht, nHandles,
574 CreatePatternBrush32(CreateBitmap32(infohdr->biWidth,
575 infohdr->biHeight,
576 infohdr->biPlanes,
577 infohdr->biBitCount,
578 (LPSTR)(mr->rdParam +
579 (sizeof(BITMAPINFOHEADER) / 2) + 4))));
580 break;
582 case BS_DIBPATTERN:
583 s1 = mr->rdSize * 2 - sizeof(METARECORD) - 2;
584 hndl = GlobalAlloc16(GMEM_MOVEABLE, s1);
585 ptr = GlobalLock16(hndl);
586 memcpy(ptr, mr->rdParam + 2, s1);
587 GlobalUnlock16(hndl);
588 MF_AddHandle(ht, nHandles,
589 CreateDIBPatternBrush32(hndl, *(mr->rdParam + 1)));
590 GlobalFree16(hndl);
592 break;
594 case META_CREATEPENINDIRECT:
595 MF_AddHandle(ht, nHandles,
596 CreatePenIndirect16((LOGPEN16 *)(&(mr->rdParam))));
597 break;
599 case META_CREATEFONTINDIRECT:
600 MF_AddHandle(ht, nHandles,
601 CreateFontIndirect16((LOGFONT16 *)(&(mr->rdParam))));
602 break;
604 case META_CREATEBRUSHINDIRECT:
605 MF_AddHandle(ht, nHandles,
606 CreateBrushIndirect16((LOGBRUSH16 *)(&(mr->rdParam))));
607 break;
609 /* W. Magro: Some new metafile operations. Not all debugged. */
610 case META_CREATEPALETTE:
611 MF_AddHandle(ht, nHandles,
612 CreatePalette16((LPLOGPALETTE)mr->rdParam));
613 break;
615 case META_SETTEXTALIGN:
616 SetTextAlign16(hdc, *(mr->rdParam));
617 break;
619 case META_SELECTPALETTE:
620 SelectPalette16(hdc, *(ht->objectHandle + *(mr->rdParam+1)),*(mr->rdParam));
621 break;
623 case META_SETMAPPERFLAGS:
624 SetMapperFlags16(hdc, *(mr->rdParam));
625 break;
627 case META_REALIZEPALETTE:
628 RealizePalette16(hdc);
629 break;
631 case META_ESCAPE:
632 dprintf_metafile(stddeb,"PlayMetaFileRecord: META_ESCAPE unimplemented.\n");
633 break;
635 /* --- Begin of fixed or new metafile operations. July 1996 ----*/
636 case META_EXTTEXTOUT:
638 LPINT16 dxx;
639 LPSTR sot;
640 DWORD len;
642 s1 = mr->rdParam[2]; /* String length */
643 len = sizeof(METARECORD) + (((s1 + 1) >> 1) * 2) + 2 * sizeof(short)
644 + sizeof(UINT16) + (mr->rdParam[3] ? sizeof(RECT16) : 0); /* rec len without dx array */
646 sot= (LPSTR)&mr->rdParam[4]; /* start_of_text */
647 if (mr->rdParam[3])
648 sot+=sizeof(RECT16); /* there is a rectangle, so add offset */
650 if (mr->rdSize == len / 2)
651 dxx = NULL; /* determine if array present */
652 else
653 if (mr->rdSize == (len + s1 * sizeof(INT16)) / 2)
654 dxx = (LPINT16)(sot+(((s1+1)>>1)*2));
655 else
657 dprintf_metafile(stddeb,"EXTTEXTOUT: %s len: %ld\n",
658 sot,mr->rdSize);
659 fprintf(stderr,
660 "Please report: PlayMetaFile/ExtTextOut len=%ld slen=%d rdSize=%ld opt=%04x\n",
661 len,s1,mr->rdSize,mr->rdParam[3]);
662 dxx = NULL; /* should't happen -- but if, we continue with NULL [for workaround] */
664 ExtTextOut16( hdc, mr->rdParam[1], /* X position */
665 mr->rdParam[0], /* Y position */
666 mr->rdParam[3], /* options */
667 mr->rdParam[3] ? (LPRECT16) &mr->rdParam[4]:NULL, /* rectangle */
668 sot, /* string */
669 s1, dxx); /* length, dx array */
670 if (dxx)
671 dprintf_metafile(stddeb,"EXTTEXTOUT: %s len: %ld dx0: %d\n",
672 sot,mr->rdSize,dxx[0]);
674 break;
676 case META_STRETCHDIB:
678 LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParam[11]);
679 LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize( info, mr->rdParam[2] );
680 StretchDIBits16(hdc,mr->rdParam[10],mr->rdParam[9],mr->rdParam[8],
681 mr->rdParam[7],mr->rdParam[6],mr->rdParam[5],
682 mr->rdParam[4],mr->rdParam[3],bits,info,
683 mr->rdParam[2],MAKELONG(mr->rdParam[0],mr->rdParam[1]));
685 break;
687 case META_DIBSTRETCHBLT:
689 LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParam[10]);
690 LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize( info, mr->rdParam[2] );
691 StretchDIBits16(hdc,mr->rdParam[9],mr->rdParam[8],mr->rdParam[7],
692 mr->rdParam[6],mr->rdParam[5],mr->rdParam[4],
693 mr->rdParam[3],mr->rdParam[2],bits,info,
694 DIB_RGB_COLORS,MAKELONG(mr->rdParam[0],mr->rdParam[1]));
696 break;
698 case META_STRETCHBLT:
700 HDC16 hdcSrc=CreateCompatibleDC16(hdc);
701 HBITMAP32 hbitmap=CreateBitmap32(mr->rdParam[10], /*Width */
702 mr->rdParam[11], /*Height*/
703 mr->rdParam[13], /*Planes*/
704 mr->rdParam[14], /*BitsPixel*/
705 (LPSTR)&mr->rdParam[15]); /*bits*/
706 SelectObject32(hdcSrc,hbitmap);
707 StretchBlt16(hdc,mr->rdParam[9],mr->rdParam[8],
708 mr->rdParam[7],mr->rdParam[6],
709 hdcSrc,mr->rdParam[5],mr->rdParam[4],
710 mr->rdParam[3],mr->rdParam[2],
711 MAKELONG(mr->rdParam[0],mr->rdParam[1]));
712 DeleteDC32(hdcSrc);
714 break;
716 case META_BITBLT: /* <-- not yet debugged */
718 HDC16 hdcSrc=CreateCompatibleDC16(hdc);
719 HBITMAP32 hbitmap=CreateBitmap32(mr->rdParam[7]/*Width */,
720 mr->rdParam[8]/*Height*/,
721 mr->rdParam[10]/*Planes*/,
722 mr->rdParam[11]/*BitsPixel*/,
723 (LPSTR)&mr->rdParam[12]/*bits*/);
724 SelectObject32(hdcSrc,hbitmap);
725 BitBlt32(hdc,(INT16)mr->rdParam[6],(INT16)mr->rdParam[5],
726 (INT16)mr->rdParam[4],(INT16)mr->rdParam[3],
727 hdcSrc, (INT16)mr->rdParam[2],(INT16)mr->rdParam[1],
728 MAKELONG(0,mr->rdParam[0]));
729 DeleteDC32(hdcSrc);
731 break;
733 /* --- Begin of new metafile operations. April, 1997 (ak) ----*/
734 case META_CREATEREGION:
736 int i;
737 HRGN32 h2,hrgn=CreateRectRgn32(mr->rdParam[7],mr->rdParam[8],
738 mr->rdParam[9],mr->rdParam[10]);
739 for (i = 0; i < mr->rdParam[5]; i++)
741 if (mr->rdParam[11+i*6]==2)
743 h2=CreateRectRgn32(mr->rdParam[14+i*6],mr->rdParam[12+i*6],
744 mr->rdParam[15+i*6],mr->rdParam[13+i*6]);
745 CombineRgn32(hrgn,hrgn,h2,mr->rdParam[16+i*6]); /* e.g. RGN_OR */
746 DeleteObject32( h2 );
749 MF_AddHandle(ht, nHandles,hrgn);
751 break;
753 case META_FILLREGION:
754 FillRgn16(hdc, *(ht->objectHandle + *(mr->rdParam)),
755 *(ht->objectHandle + *(mr->rdParam+1)));
756 break;
758 case META_INVERTREGION:
759 InvertRgn16(hdc, *(ht->objectHandle + *(mr->rdParam)));
760 break;
762 case META_PAINTREGION:
763 PaintRgn16(hdc, *(ht->objectHandle + *(mr->rdParam)));
764 break;
766 case META_SELECTCLIPREGION:
767 SelectClipRgn32(hdc, *(ht->objectHandle + *(mr->rdParam)));
768 break;
770 case META_DIBCREATEPATTERNBRUSH:
771 /* *(mr->rdParam) may be BS_PATTERN or BS_DIBPATTERN: but there's no difference */
772 dprintf_metafile(stddeb,"META_DIBCREATEPATTERNBRUSH: %d\n",*(mr->rdParam));
773 s1 = mr->rdSize * 2 - sizeof(METARECORD) - 2;
774 hndl = GlobalAlloc16(GMEM_MOVEABLE, s1);
775 ptr = GlobalLock16(hndl);
776 memcpy(ptr, mr->rdParam + 2, s1);
777 GlobalUnlock16(hndl);
778 MF_AddHandle(ht, nHandles,CreateDIBPatternBrush16(hndl, *(mr->rdParam + 1)));
779 GlobalFree16(hndl);
780 break;
782 case META_DIBBITBLT:
784 LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParam[8]);
785 LPSTR bits = (LPSTR)info + DIB_BitmapInfoSize( info, mr->rdParam[0] );
786 StretchDIBits16(hdc,mr->rdParam[7],mr->rdParam[6],mr->rdParam[5],
787 mr->rdParam[4],mr->rdParam[3],mr->rdParam[2],
788 mr->rdParam[5],mr->rdParam[4],bits,info,
789 DIB_RGB_COLORS,MAKELONG(mr->rdParam[0],mr->rdParam[1]));
791 break;
793 case META_SETTEXTCHAREXTRA:
794 SetTextCharacterExtra16(hdc, (INT16)*(mr->rdParam));
795 break;
797 case META_SETTEXTJUSTIFICATION:
798 SetTextJustification32(hdc, *(mr->rdParam + 1), *(mr->rdParam));
799 break;
801 #define META_UNIMP(x) case x: fprintf(stderr,"PlayMetaFileRecord:record type "#x" not implemented.\n");break;
802 META_UNIMP(META_FRAMEREGION)
803 META_UNIMP(META_DRAWTEXT)
804 META_UNIMP(META_SETDIBTODEV)
805 META_UNIMP(META_ANIMATEPALETTE)
806 META_UNIMP(META_SETPALENTRIES)
807 META_UNIMP(META_RESIZEPALETTE)
808 META_UNIMP(META_EXTFLOODFILL)
809 META_UNIMP(META_RESETDC)
810 META_UNIMP(META_STARTDOC)
811 META_UNIMP(META_STARTPAGE)
812 META_UNIMP(META_ENDPAGE)
813 META_UNIMP(META_ABORTDOC)
814 META_UNIMP(META_ENDDOC)
815 META_UNIMP(META_CREATEBRUSH)
816 META_UNIMP(META_CREATEBITMAPINDIRECT)
817 META_UNIMP(META_CREATEBITMAP)
818 #undef META_UNIMP
820 default:
821 fprintf(stddeb,"PlayMetaFileRecord: Unknown record type %x\n",
822 mr->rdFunction);
827 /******************************************************************
828 * GetMetaFileBits (GDI.159)
830 * Trade in a meta file object handle for a handle to the meta file memory
833 HGLOBAL16 WINAPI GetMetaFileBits(HMETAFILE16 hmf)
835 dprintf_metafile(stddeb,"GetMetaFileBits: hMem out: %04x\n", hmf);
837 return hmf;
840 /******************************************************************
841 * SetMetaFileBits (GDI.160)
843 * Trade in a meta file memory handle for a handle to a meta file object
845 HMETAFILE16 WINAPI SetMetaFileBits( HGLOBAL16 hMem )
847 dprintf_metafile(stddeb,"SetMetaFileBits: hmf out: %04x\n", hMem);
849 return hMem;
852 /******************************************************************
853 * SetMetaFileBitsBetter (GDI.196)
855 HMETAFILE16 WINAPI SetMetaFileBitsBetter( HMETAFILE16 hMeta )
857 if( IsValidMetaFile( hMeta ) )
858 return (HMETAFILE16)GlobalReAlloc16( hMeta, 0,
859 GMEM_SHARE | GMEM_NODISCARD | GMEM_MODIFY);
860 return (HMETAFILE16)0;
863 /******************************************************************
864 * MF_WriteRecord
866 * Warning: this function can change the metafile handle.
869 static BOOL32 MF_WriteRecord( DC *dc, METARECORD *mr, WORD rlen)
871 DWORD len;
872 METAHEADER *mh;
873 METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
875 switch(physDev->mh->mtType)
877 case METAFILE_MEMORY:
878 len = physDev->mh->mtSize * 2 + rlen;
879 mh = HeapReAlloc( SystemHeap, 0, physDev->mh, len );
880 if (!mh) return FALSE;
881 physDev->mh = mh;
882 memcpy((WORD *)physDev->mh + physDev->mh->mtSize, mr, rlen);
883 break;
884 case METAFILE_DISK:
885 dprintf_metafile(stddeb,"Writing record to disk\n");
886 if (_lwrite32(physDev->mh->mtNoParameters, (char *)mr, rlen) == -1)
887 return FALSE;
888 break;
889 default:
890 fprintf( stderr, "Unknown metafile type %d\n", physDev->mh->mtType );
891 return FALSE;
894 physDev->mh->mtSize += rlen / 2;
895 physDev->mh->mtMaxRecord = MAX(physDev->mh->mtMaxRecord, rlen / 2);
896 return TRUE;
900 /******************************************************************
901 * MF_MetaParam0
904 BOOL32 MF_MetaParam0(DC *dc, short func)
906 char buffer[8];
907 METARECORD *mr = (METARECORD *)&buffer;
909 mr->rdSize = 3;
910 mr->rdFunction = func;
911 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
915 /******************************************************************
916 * MF_MetaParam1
918 BOOL32 MF_MetaParam1(DC *dc, short func, short param1)
920 char buffer[8];
921 METARECORD *mr = (METARECORD *)&buffer;
923 mr->rdSize = 4;
924 mr->rdFunction = func;
925 *(mr->rdParam) = param1;
926 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
930 /******************************************************************
931 * MF_MetaParam2
933 BOOL32 MF_MetaParam2(DC *dc, short func, short param1, short param2)
935 char buffer[10];
936 METARECORD *mr = (METARECORD *)&buffer;
938 mr->rdSize = 5;
939 mr->rdFunction = func;
940 *(mr->rdParam) = param2;
941 *(mr->rdParam + 1) = param1;
942 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
946 /******************************************************************
947 * MF_MetaParam4
950 BOOL32 MF_MetaParam4(DC *dc, short func, short param1, short param2,
951 short param3, short param4)
953 char buffer[14];
954 METARECORD *mr = (METARECORD *)&buffer;
956 mr->rdSize = 7;
957 mr->rdFunction = func;
958 *(mr->rdParam) = param4;
959 *(mr->rdParam + 1) = param3;
960 *(mr->rdParam + 2) = param2;
961 *(mr->rdParam + 3) = param1;
962 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
966 /******************************************************************
967 * MF_MetaParam6
970 BOOL32 MF_MetaParam6(DC *dc, short func, short param1, short param2,
971 short param3, short param4, short param5, short param6)
973 char buffer[18];
974 METARECORD *mr = (METARECORD *)&buffer;
976 mr->rdSize = 9;
977 mr->rdFunction = func;
978 *(mr->rdParam) = param6;
979 *(mr->rdParam + 1) = param5;
980 *(mr->rdParam + 2) = param4;
981 *(mr->rdParam + 3) = param3;
982 *(mr->rdParam + 4) = param2;
983 *(mr->rdParam + 5) = param1;
984 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
988 /******************************************************************
989 * MF_MetaParam8
991 BOOL32 MF_MetaParam8(DC *dc, short func, short param1, short param2,
992 short param3, short param4, short param5,
993 short param6, short param7, short param8)
995 char buffer[22];
996 METARECORD *mr = (METARECORD *)&buffer;
998 mr->rdSize = 11;
999 mr->rdFunction = func;
1000 *(mr->rdParam) = param8;
1001 *(mr->rdParam + 1) = param7;
1002 *(mr->rdParam + 2) = param6;
1003 *(mr->rdParam + 3) = param5;
1004 *(mr->rdParam + 4) = param4;
1005 *(mr->rdParam + 5) = param3;
1006 *(mr->rdParam + 6) = param2;
1007 *(mr->rdParam + 7) = param1;
1008 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1012 /******************************************************************
1013 * MF_CreateBrushIndirect
1016 BOOL32 MF_CreateBrushIndirect(DC *dc, HBRUSH16 hBrush, LOGBRUSH16 *logbrush)
1018 int index;
1019 char buffer[sizeof(METARECORD) - 2 + sizeof(*logbrush)];
1020 METARECORD *mr = (METARECORD *)&buffer;
1022 mr->rdSize = (sizeof(METARECORD) + sizeof(*logbrush) - 2) / 2;
1023 mr->rdFunction = META_CREATEBRUSHINDIRECT;
1024 memcpy(&(mr->rdParam), logbrush, sizeof(*logbrush));
1025 if (!(MF_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
1027 mr->rdSize = sizeof(METARECORD) / 2;
1028 mr->rdFunction = META_SELECTOBJECT;
1030 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1031 *(mr->rdParam) = index;
1032 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1036 /******************************************************************
1037 * MF_CreatePatternBrush
1040 BOOL32 MF_CreatePatternBrush(DC *dc, HBRUSH16 hBrush, LOGBRUSH16 *logbrush)
1042 DWORD len, bmSize, biSize;
1043 HGLOBAL16 hmr;
1044 METARECORD *mr;
1045 BITMAPOBJ *bmp;
1046 BITMAPINFO *info;
1047 BITMAPINFOHEADER *infohdr;
1048 int index;
1049 char buffer[sizeof(METARECORD)];
1051 switch (logbrush->lbStyle)
1053 case BS_PATTERN:
1054 bmp = (BITMAPOBJ *)GDI_GetObjPtr((HGDIOBJ16)logbrush->lbHatch, BITMAP_MAGIC);
1055 if (!bmp) return FALSE;
1056 len = sizeof(METARECORD) + sizeof(BITMAPINFOHEADER) +
1057 (bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes) + 6;
1058 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1060 GDI_HEAP_UNLOCK((HGDIOBJ16)logbrush->lbHatch);
1061 return FALSE;
1063 mr = (METARECORD *)GlobalLock16(hmr);
1064 memset(mr, 0, len);
1065 mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
1066 mr->rdSize = len / 2;
1067 *(mr->rdParam) = logbrush->lbStyle;
1068 *(mr->rdParam + 1) = DIB_RGB_COLORS;
1069 infohdr = (BITMAPINFOHEADER *)(mr->rdParam + 2);
1070 infohdr->biSize = sizeof(BITMAPINFOHEADER);
1071 infohdr->biWidth = bmp->bitmap.bmWidth;
1072 infohdr->biHeight = bmp->bitmap.bmHeight;
1073 infohdr->biPlanes = bmp->bitmap.bmPlanes;
1074 infohdr->biBitCount = bmp->bitmap.bmBitsPixel;
1075 memcpy(mr->rdParam + (sizeof(BITMAPINFOHEADER) / 2) + 4,
1076 PTR_SEG_TO_LIN(bmp->bitmap.bmBits),
1077 bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes);
1078 GDI_HEAP_UNLOCK(logbrush->lbHatch);
1079 break;
1081 case BS_DIBPATTERN:
1082 info = (BITMAPINFO *)GlobalLock16((HGLOBAL16)logbrush->lbHatch);
1083 if (info->bmiHeader.biCompression)
1084 bmSize = info->bmiHeader.biSizeImage;
1085 else
1086 bmSize = (info->bmiHeader.biWidth * info->bmiHeader.biBitCount
1087 + 31) / 32 * 8 * info->bmiHeader.biHeight;
1088 biSize = DIB_BitmapInfoSize(info, LOWORD(logbrush->lbColor));
1089 len = sizeof(METARECORD) + biSize + bmSize + 2;
1090 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1091 return FALSE;
1092 mr = (METARECORD *)GlobalLock16(hmr);
1093 memset(mr, 0, len);
1094 mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
1095 mr->rdSize = len / 2;
1096 *(mr->rdParam) = logbrush->lbStyle;
1097 *(mr->rdParam + 1) = LOWORD(logbrush->lbColor);
1098 memcpy(mr->rdParam + 2, info, biSize + bmSize);
1099 break;
1100 default:
1101 return FALSE;
1103 if (!(MF_WriteRecord(dc, mr, len)))
1105 GlobalFree16(hmr);
1106 return FALSE;
1109 GlobalFree16(hmr);
1111 mr = (METARECORD *)&buffer;
1112 mr->rdSize = sizeof(METARECORD) / 2;
1113 mr->rdFunction = META_SELECTOBJECT;
1115 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1116 *(mr->rdParam) = index;
1117 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1121 /******************************************************************
1122 * MF_CreatePenIndirect
1125 BOOL32 MF_CreatePenIndirect(DC *dc, HPEN16 hPen, LOGPEN16 *logpen)
1127 int index;
1128 char buffer[sizeof(METARECORD) - 2 + sizeof(*logpen)];
1129 METARECORD *mr = (METARECORD *)&buffer;
1131 mr->rdSize = (sizeof(METARECORD) + sizeof(*logpen) - 2) / 2;
1132 mr->rdFunction = META_CREATEPENINDIRECT;
1133 memcpy(&(mr->rdParam), logpen, sizeof(*logpen));
1134 if (!(MF_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
1136 mr->rdSize = sizeof(METARECORD) / 2;
1137 mr->rdFunction = META_SELECTOBJECT;
1139 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1140 *(mr->rdParam) = index;
1141 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1145 /******************************************************************
1146 * MF_CreateFontIndirect
1149 BOOL32 MF_CreateFontIndirect(DC *dc, HFONT16 hFont, LOGFONT16 *logfont)
1151 int index;
1152 char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT16)];
1153 METARECORD *mr = (METARECORD *)&buffer;
1155 mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT16) - 2) / 2;
1156 mr->rdFunction = META_CREATEFONTINDIRECT;
1157 memcpy(&(mr->rdParam), logfont, sizeof(LOGFONT16));
1158 if (!(MF_WriteRecord( dc, mr, mr->rdSize * 2))) return FALSE;
1160 mr->rdSize = sizeof(METARECORD) / 2;
1161 mr->rdFunction = META_SELECTOBJECT;
1163 if ((index = MF_AddHandleDC( dc )) == -1) return FALSE;
1164 *(mr->rdParam) = index;
1165 return MF_WriteRecord( dc, mr, mr->rdSize * 2);
1169 /******************************************************************
1170 * MF_TextOut
1172 BOOL32 MF_TextOut(DC *dc, short x, short y, LPCSTR str, short count)
1174 BOOL32 ret;
1175 DWORD len;
1176 HGLOBAL16 hmr;
1177 METARECORD *mr;
1179 len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 4;
1180 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1181 return FALSE;
1182 mr = (METARECORD *)GlobalLock16(hmr);
1183 memset(mr, 0, len);
1185 mr->rdSize = len / 2;
1186 mr->rdFunction = META_TEXTOUT;
1187 *(mr->rdParam) = count;
1188 memcpy(mr->rdParam + 1, str, count);
1189 *(mr->rdParam + ((count + 1) >> 1) + 1) = y;
1190 *(mr->rdParam + ((count + 1) >> 1) + 2) = x;
1191 ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
1192 GlobalFree16(hmr);
1193 return ret;
1196 /******************************************************************
1197 * MF_ExtTextOut
1199 BOOL32 MF_ExtTextOut(DC*dc, short x, short y, UINT16 flags, const RECT16 *rect,
1200 LPCSTR str, short count, const INT16 *lpDx)
1202 BOOL32 ret;
1203 DWORD len;
1204 HGLOBAL16 hmr;
1205 METARECORD *mr;
1207 if((!flags && rect) || (flags && !rect))
1208 fprintf(stderr, "MF_ExtTextOut: Inconsistent flags and rect\n");
1209 len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 2 * sizeof(short)
1210 + sizeof(UINT16);
1211 if(rect)
1212 len += sizeof(RECT16);
1213 if (lpDx)
1214 len+=count*sizeof(INT16);
1215 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1216 return FALSE;
1217 mr = (METARECORD *)GlobalLock16(hmr);
1218 memset(mr, 0, len);
1220 mr->rdSize = len / 2;
1221 mr->rdFunction = META_EXTTEXTOUT;
1222 *(mr->rdParam) = y;
1223 *(mr->rdParam + 1) = x;
1224 *(mr->rdParam + 2) = count;
1225 *(mr->rdParam + 3) = flags;
1226 if (rect) memcpy(mr->rdParam + 4, rect, sizeof(RECT16));
1227 memcpy(mr->rdParam + (rect ? 8 : 4), str, count);
1228 if (lpDx)
1229 memcpy(mr->rdParam + (rect ? 8 : 4) + ((count + 1) >> 1),lpDx,
1230 count*sizeof(INT16));
1231 ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
1232 GlobalFree16(hmr);
1233 return ret;
1236 /******************************************************************
1237 * MF_MetaPoly - implements Polygon and Polyline
1239 BOOL32 MF_MetaPoly(DC *dc, short func, LPPOINT16 pt, short count)
1241 BOOL32 ret;
1242 DWORD len;
1243 HGLOBAL16 hmr;
1244 METARECORD *mr;
1246 len = sizeof(METARECORD) + (count * 4);
1247 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1248 return FALSE;
1249 mr = (METARECORD *)GlobalLock16(hmr);
1250 memset(mr, 0, len);
1252 mr->rdSize = len / 2;
1253 mr->rdFunction = func;
1254 *(mr->rdParam) = count;
1255 memcpy(mr->rdParam + 1, pt, count * 4);
1256 ret = MF_WriteRecord( dc, mr, mr->rdSize * 2);
1257 GlobalFree16(hmr);
1258 return ret;
1262 /******************************************************************
1263 * MF_BitBlt
1265 BOOL32 MF_BitBlt(DC *dcDest, short xDest, short yDest, short width,
1266 short height, DC *dcSrc, short xSrc, short ySrc, DWORD rop)
1268 BOOL32 ret;
1269 DWORD len;
1270 HGLOBAL16 hmr;
1271 METARECORD *mr;
1272 BITMAP16 BM;
1274 GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM);
1275 len = sizeof(METARECORD) + 12 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
1276 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1277 return FALSE;
1278 mr = (METARECORD *)GlobalLock16(hmr);
1279 mr->rdFunction = META_BITBLT;
1280 *(mr->rdParam + 7) = BM.bmWidth;
1281 *(mr->rdParam + 8) = BM.bmHeight;
1282 *(mr->rdParam + 9) = BM.bmWidthBytes;
1283 *(mr->rdParam +10) = BM.bmPlanes;
1284 *(mr->rdParam +11) = BM.bmBitsPixel;
1285 dprintf_metafile(stddeb,"MF_StretchBlt->len = %ld rop=%lx \n",len,rop);
1286 if (GetBitmapBits32(dcSrc->w.hBitmap,BM.bmWidthBytes * BM.bmHeight,
1287 mr->rdParam +12))
1289 mr->rdSize = len / sizeof(INT16);
1290 *(mr->rdParam) = HIWORD(rop);
1291 *(mr->rdParam + 1) = ySrc;
1292 *(mr->rdParam + 2) = xSrc;
1293 *(mr->rdParam + 3) = height;
1294 *(mr->rdParam + 4) = width;
1295 *(mr->rdParam + 5) = yDest;
1296 *(mr->rdParam + 6) = xDest;
1297 ret = MF_WriteRecord( dcDest, mr, mr->rdSize * 2);
1299 else
1300 ret = FALSE;
1301 GlobalFree16(hmr);
1302 return ret;
1306 /**********************************************************************
1307 * MF_StretchBlt
1308 * this function contains TWO ways for procesing StretchBlt in metafiles,
1309 * decide between rdFunction values META_STRETCHBLT or META_DIBSTRETCHBLT
1310 * via #define STRETCH_VIA_DIB
1312 #define STRETCH_VIA_DIB
1313 #undef STRETCH_VIA_DIB
1314 BOOL32 MF_StretchBlt(DC *dcDest, short xDest, short yDest, short widthDest,
1315 short heightDest, DC *dcSrc, short xSrc, short ySrc,
1316 short widthSrc, short heightSrc, DWORD rop)
1318 BOOL32 ret;
1319 DWORD len;
1320 HGLOBAL16 hmr;
1321 METARECORD *mr;
1322 BITMAP16 BM;
1323 #ifdef STRETCH_VIA_DIB
1324 LPBITMAPINFOHEADER lpBMI;
1325 WORD nBPP;
1326 #endif
1327 GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM);
1328 #ifdef STRETCH_VIA_DIB
1329 nBPP = BM.bmPlanes * BM.bmBitsPixel;
1330 len = sizeof(METARECORD) + 10 * sizeof(INT16)
1331 + sizeof(BITMAPINFOHEADER) + (nBPP != 24 ? 1 << nBPP: 0) * sizeof(RGBQUAD)
1332 + ((BM.bmWidth * nBPP + 31) / 32) * 4 * BM.bmHeight;
1333 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1334 return FALSE;
1335 mr = (METARECORD *)GlobalLock16(hmr);
1336 mr->rdFunction = META_DIBSTRETCHBLT;
1337 lpBMI=(LPBITMAPINFOHEADER)(mr->rdParam+10);
1338 lpBMI->biSize = sizeof(BITMAPINFOHEADER);
1339 lpBMI->biWidth = BM.bmWidth;
1340 lpBMI->biHeight = BM.bmHeight;
1341 lpBMI->biPlanes = 1;
1342 lpBMI->biBitCount = nBPP; /* 1,4,8 or 24 */
1343 lpBMI->biClrUsed = nBPP != 24 ? 1 << nBPP : 0;
1344 lpBMI->biSizeImage = ((lpBMI->biWidth * nBPP + 31) / 32) * 4 * lpBMI->biHeight;
1345 lpBMI->biCompression = BI_RGB;
1346 lpBMI->biXPelsPerMeter = MulDiv32(GetDeviceCaps(dcSrc->hSelf,LOGPIXELSX),3937,100);
1347 lpBMI->biYPelsPerMeter = MulDiv32(GetDeviceCaps(dcSrc->hSelf,LOGPIXELSY),3937,100);
1348 lpBMI->biClrImportant = 0; /* 1 meter = 39.37 inch */
1350 dprintf_metafile(stddeb,"MF_StretchBltViaDIB->len = %ld rop=%lx PixYPM=%ld Caps=%d\n",
1351 len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(hdcSrc,LOGPIXELSY));
1352 if (GetDIBits(hdcSrc,dcSrc->w.hBitmap,0,(UINT32)lpBMI->biHeight,
1353 (LPSTR)lpBMI + DIB_BitmapInfoSize( (BITMAPINFO *)lpBMI,
1354 DIB_RGB_COLORS ),
1355 (LPBITMAPINFO)lpBMI, DIB_RGB_COLORS))
1356 #else
1357 len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
1358 if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
1359 return FALSE;
1360 mr = (METARECORD *)GlobalLock16(hmr);
1361 mr->rdFunction = META_STRETCHBLT;
1362 *(mr->rdParam +10) = BM.bmWidth;
1363 *(mr->rdParam +11) = BM.bmHeight;
1364 *(mr->rdParam +12) = BM.bmWidthBytes;
1365 *(mr->rdParam +13) = BM.bmPlanes;
1366 *(mr->rdParam +14) = BM.bmBitsPixel;
1367 dprintf_metafile(stddeb,"MF_StretchBlt->len = %ld rop=%lx \n",len,rop);
1368 if (GetBitmapBits32( dcSrc->w.hBitmap, BM.bmWidthBytes * BM.bmHeight,
1369 mr->rdParam +15))
1370 #endif
1372 mr->rdSize = len / sizeof(INT16);
1373 *(mr->rdParam) = LOWORD(rop);
1374 *(mr->rdParam + 1) = HIWORD(rop);
1375 *(mr->rdParam + 2) = heightSrc;
1376 *(mr->rdParam + 3) = widthSrc;
1377 *(mr->rdParam + 4) = ySrc;
1378 *(mr->rdParam + 5) = xSrc;
1379 *(mr->rdParam + 6) = heightDest;
1380 *(mr->rdParam + 7) = widthDest;
1381 *(mr->rdParam + 8) = yDest;
1382 *(mr->rdParam + 9) = xDest;
1383 ret = MF_WriteRecord( dcDest, mr, mr->rdSize * 2);
1385 else
1386 ret = FALSE;
1387 GlobalFree16(hmr);
1388 return ret;