ReactOS  0.4.15-dev-3326-ga91f5e8
enhmetafile.c
Go to the documentation of this file.
1 /*
2  * Enhanced metafile functions
3  * Copyright 1998 Douglas Ridgway
4  * 1999 Huw D M Davies
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * NOTES:
21  *
22  * The enhanced format consists of the following elements:
23  *
24  * A header
25  * A table of handles to GDI objects
26  * An array of metafile records
27  * A private palette
28  *
29  *
30  * The standard format consists of a header and an array of metafile records.
31  *
32  */
33 
34 #include "config.h"
35 #include "wine/port.h"
36 
37 #include <stdarg.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <assert.h>
41 #include "windef.h"
42 #include "winbase.h"
43 #include "wingdi.h"
44 #include "winnls.h"
45 #include "winerror.h"
46 #include "gdi_private.h"
47 #include "wine/debug.h"
48 
50 
51 
54 {
55  0, 0, &enhmetafile_cs,
57  0, 0, { (DWORD_PTR)(__FILE__ ": enhmetafile_cs") }
58 };
59 static CRITICAL_SECTION enhmetafile_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
60 
61 typedef struct
62 {
64  BOOL on_disk; /* true if metafile is on disk */
66 
67 static const struct emr_name {
69  const char *name;
70 } emr_names[] = {
71 #define X(p) {p, #p}
72 X(EMR_HEADER),
74 X(EMR_POLYGON),
85 X(EMR_EOF),
91 X(EMR_SETROP2),
104 X(EMR_SAVEDC),
112 X(EMR_ANGLEARC),
113 X(EMR_ELLIPSE),
116 X(EMR_ARC),
117 X(EMR_CHORD),
118 X(EMR_PIE),
125 X(EMR_LINETO),
126 X(EMR_ARCTO),
127 X(EMR_POLYDRAW),
131 X(EMR_ENDPATH),
133 X(EMR_FILLPATH),
141 X(EMR_FILLRGN),
142 X(EMR_FRAMERGN),
144 X(EMR_PAINTRGN),
146 X(EMR_BITBLT),
148 X(EMR_MASKBLT),
149 X(EMR_PLGBLT),
175 X(EMR_DRAWESCAPE),
176 X(EMR_EXTESCAPE),
177 X(EMR_STARTDOC),
178 X(EMR_SMALLTEXTOUT),
179 X(EMR_FORCEUFIMAPPING),
180 X(EMR_NAMEDESCAPE),
181 X(EMR_COLORCORRECTPALETTE),
182 X(EMR_SETICMPROFILEA),
183 X(EMR_SETICMPROFILEW),
184 X(EMR_ALPHABLEND),
185 X(EMR_SETLAYOUT),
186 X(EMR_TRANSPARENTBLT),
187 X(EMR_RESERVED_117),
188 X(EMR_GRADIENTFILL),
190 X(EMR_SETTEXTJUSTIFICATION),
191 X(EMR_COLORMATCHTOTARGETW),
192 X(EMR_CREATECOLORSPACEW)
193 #undef X
194 };
195 
196 /****************************************************************************
197  * get_emr_name
198  */
199 static const char *get_emr_name(DWORD type)
200 {
201  unsigned int i;
202  for(i = 0; i < sizeof(emr_names) / sizeof(emr_names[0]); i++)
203  if(type == emr_names[i].type) return emr_names[i].name;
204  TRACE("Unknown record type %d\n", type);
205  return NULL;
206 }
207 
208 /***********************************************************************
209  * is_dib_monochrome
210  *
211  * Returns whether a DIB can be converted to a monochrome DDB.
212  *
213  * A DIB can be converted if its color table contains only black and
214  * white. Black must be the first color in the color table.
215  *
216  * Note : If the first color in the color table is white followed by
217  * black, we can't convert it to a monochrome DDB with
218  * SetDIBits, because black and white would be inverted.
219  */
220 static inline BOOL is_dib_monochrome( const BITMAPINFO* info )
221 {
222  if (info->bmiHeader.biBitCount != 1) return FALSE;
223 
224  if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
225  {
226  const RGBTRIPLE *rgb = ((const BITMAPCOREINFO *) info)->bmciColors;
227 
228  /* Check if the first color is black */
229  if ((rgb->rgbtRed == 0) && (rgb->rgbtGreen == 0) && (rgb->rgbtBlue == 0))
230  {
231  rgb++;
232  /* Check if the second color is white */
233  return ((rgb->rgbtRed == 0xff) && (rgb->rgbtGreen == 0xff)
234  && (rgb->rgbtBlue == 0xff));
235  }
236  else return FALSE;
237  }
238  else /* assume BITMAPINFOHEADER */
239  {
240  const RGBQUAD *rgb = info->bmiColors;
241 
242  /* Check if the first color is black */
243  if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) &&
244  (rgb->rgbBlue == 0) && (rgb->rgbReserved == 0))
245  {
246  rgb++;
247 
248  /* Check if the second color is white */
249  return ((rgb->rgbRed == 0xff) && (rgb->rgbGreen == 0xff)
250  && (rgb->rgbBlue == 0xff) && (rgb->rgbReserved == 0));
251  }
252  else return FALSE;
253  }
254 }
255 
256 /****************************************************************************
257  * EMF_Create_HENHMETAFILE
258  */
259 HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, DWORD filesize, BOOL on_disk )
260 {
261  HENHMETAFILE hmf;
262  ENHMETAFILEOBJ *metaObj;
263 
264  if (emh->iType != EMR_HEADER)
265  {
267  return 0;
268  }
269  if (emh->dSignature != ENHMETA_SIGNATURE ||
270  (emh->nBytes & 3)) /* refuse to load unaligned EMF as Windows does */
271  {
272  WARN("Invalid emf header type 0x%08x sig 0x%08x.\n",
273  emh->iType, emh->dSignature);
274  return 0;
275  }
276  if (filesize < emh->nBytes)
277  {
278  WARN("File truncated (got %u bytes, header says %u)\n", emh->nBytes, filesize);
279  return 0;
280  }
281 
282  if (!(metaObj = HeapAlloc( GetProcessHeap(), 0, sizeof(*metaObj) ))) return 0;
283 
284  metaObj->emh = emh;
285  metaObj->on_disk = on_disk;
286 
287  if (!(hmf = alloc_gdi_handle( metaObj, OBJ_ENHMETAFILE, NULL )))
288  HeapFree( GetProcessHeap(), 0, metaObj );
289  return hmf;
290 }
291 
292 /****************************************************************************
293  * EMF_Delete_HENHMETAFILE
294  */
295 static BOOL EMF_Delete_HENHMETAFILE( HENHMETAFILE hmf )
296 {
297  ENHMETAFILEOBJ *metaObj;
298  BOOL Ret = FALSE;
299 
301  metaObj = free_gdi_handle( hmf );
302  if(metaObj)
303  {
304  if(metaObj->on_disk)
305  UnmapViewOfFile( metaObj->emh );
306  else
307  HeapFree( GetProcessHeap(), 0, metaObj->emh );
308  HeapFree( GetProcessHeap(), 0, metaObj );
309  Ret = TRUE;
310  }
312  return Ret;
313 }
314 
315 /******************************************************************
316  * EMF_GetEnhMetaHeader
317  *
318  * Returns ptr to ENHMETAHEADER associated with HENHMETAFILE
319  */
320 static ENHMETAHEADER *EMF_GetEnhMetaHeader( HENHMETAFILE hmf )
321 {
323  ENHMETAFILEOBJ *metaObj;
324 
326  metaObj = GDI_GetObjPtr( hmf, OBJ_ENHMETAFILE );
327  TRACE("hmf %p -> enhmetaObj %p\n", hmf, metaObj);
328  if (metaObj)
329  {
330  ret = metaObj->emh;
331  GDI_ReleaseObj( hmf );
332  }
334  return ret;
335 }
336 
337 /*****************************************************************************
338  * EMF_GetEnhMetaFile
339  *
340  */
341 static HENHMETAFILE EMF_GetEnhMetaFile( HANDLE hFile )
342 {
343  ENHMETAHEADER *emh;
344  HANDLE hMapping;
345  HENHMETAFILE hemf;
346  DWORD filesize;
347 
348  filesize = GetFileSize( hFile, NULL );
349 
350  hMapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
351  emh = MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 );
352  CloseHandle( hMapping );
353 
354  if (!emh) return 0;
355 
356  hemf = EMF_Create_HENHMETAFILE( emh, filesize, TRUE );
357  if (!hemf)
358  UnmapViewOfFile( emh );
359  return hemf;
360 }
361 
362 
363 /*****************************************************************************
364  * GetEnhMetaFileA (GDI32.@)
365  *
366  *
367  */
368 HENHMETAFILE WINAPI GetEnhMetaFileA(
369  LPCSTR lpszMetaFile /* [in] filename of enhanced metafile */
370  )
371 {
372  HENHMETAFILE hmf;
373  HANDLE hFile;
374 
375  hFile = CreateFileA(lpszMetaFile, GENERIC_READ, FILE_SHARE_READ, 0,
376  OPEN_EXISTING, 0, 0);
377  if (hFile == INVALID_HANDLE_VALUE) {
378  WARN("could not open %s\n", lpszMetaFile);
379  return 0;
380  }
381  hmf = EMF_GetEnhMetaFile( hFile );
382  CloseHandle( hFile );
383  return hmf;
384 }
385 
386 /*****************************************************************************
387  * GetEnhMetaFileW (GDI32.@)
388  */
389 HENHMETAFILE WINAPI GetEnhMetaFileW(
390  LPCWSTR lpszMetaFile) /* [in] filename of enhanced metafile */
391 {
392  HENHMETAFILE hmf;
393  HANDLE hFile;
394 
395  hFile = CreateFileW(lpszMetaFile, GENERIC_READ, FILE_SHARE_READ, 0,
396  OPEN_EXISTING, 0, 0);
397  if (hFile == INVALID_HANDLE_VALUE) {
398  WARN("could not open %s\n", debugstr_w(lpszMetaFile));
399  return 0;
400  }
401  hmf = EMF_GetEnhMetaFile( hFile );
402  CloseHandle( hFile );
403  return hmf;
404 }
405 
406 /*****************************************************************************
407  * GetEnhMetaFileHeader (GDI32.@)
408  *
409  * Retrieves the record containing the header for the specified
410  * enhanced-format metafile.
411  *
412  * RETURNS
413  * If buf is NULL, returns the size of buffer required.
414  * Otherwise, copy up to bufsize bytes of enhanced metafile header into
415  * buf.
416  */
418  HENHMETAFILE hmf, /* [in] enhanced metafile */
419  UINT bufsize, /* [in] size of buffer */
420  LPENHMETAHEADER buf /* [out] buffer */
421  )
422 {
423  LPENHMETAHEADER emh;
424  UINT size;
425 
426  emh = EMF_GetEnhMetaHeader(hmf);
427  if(!emh) return FALSE;
428  size = emh->nSize;
429  if (!buf) return size;
430  size = min(size, bufsize);
431  memmove(buf, emh, size);
432  return size;
433 }
434 
435 
436 /*****************************************************************************
437  * GetEnhMetaFileDescriptionA (GDI32.@)
438  *
439  * See GetEnhMetaFileDescriptionW.
440  */
442  HENHMETAFILE hmf, /* [in] enhanced metafile */
443  UINT size, /* [in] size of buf */
444  LPSTR buf /* [out] buffer to receive description */
445  )
446 {
448  DWORD len;
449  WCHAR *descrW;
450 
451  if(!emh) return FALSE;
452  if(emh->nDescription == 0 || emh->offDescription == 0) return 0;
453  descrW = (WCHAR *) ((char *) emh + emh->offDescription);
454  len = WideCharToMultiByte( CP_ACP, 0, descrW, emh->nDescription, NULL, 0, NULL, NULL );
455 
456  if (!buf || !size ) return len;
457 
458  len = min( size, len );
459  WideCharToMultiByte( CP_ACP, 0, descrW, emh->nDescription, buf, len, NULL, NULL );
460  return len;
461 }
462 
463 /*****************************************************************************
464  * GetEnhMetaFileDescriptionW (GDI32.@)
465  *
466  * Copies the description string of an enhanced metafile into a buffer
467  * _buf_.
468  *
469  * RETURNS
470  * If _buf_ is NULL, returns size of _buf_ required. Otherwise, returns
471  * number of characters copied.
472  */
474  HENHMETAFILE hmf, /* [in] enhanced metafile */
475  UINT size, /* [in] size of buf */
476  LPWSTR buf /* [out] buffer to receive description */
477  )
478 {
480 
481  if(!emh) return FALSE;
482  if(emh->nDescription == 0 || emh->offDescription == 0) return 0;
483  if (!buf || !size ) return emh->nDescription;
484 
485  memmove(buf, (char *) emh + emh->offDescription, min(size,emh->nDescription)*sizeof(WCHAR));
486  return min(size, emh->nDescription);
487 }
488 
489 /****************************************************************************
490  * SetEnhMetaFileBits (GDI32.@)
491  *
492  * Creates an enhanced metafile by copying _bufsize_ bytes from _buf_.
493  */
495 {
497  HENHMETAFILE hmf;
498  memmove(emh, buf, bufsize);
499  hmf = EMF_Create_HENHMETAFILE( emh, bufsize, FALSE );
500  if (!hmf)
501  HeapFree( GetProcessHeap(), 0, emh );
502  return hmf;
503 }
504 
505 /*****************************************************************************
506  * GetEnhMetaFileBits (GDI32.@)
507  *
508  */
510  HENHMETAFILE hmf,
511  UINT bufsize,
512  LPBYTE buf
513 )
514 {
516  UINT size;
517 
518  if(!emh) return 0;
519 
520  size = emh->nBytes;
521  if( buf == NULL ) return size;
522 
523  size = min( size, bufsize );
524  memmove(buf, emh, size);
525  return size;
526 }
527 
528 typedef struct EMF_dc_state
529 {
541 } EMF_dc_state;
542 
543 typedef struct enum_emh_data
544 {
549 } enum_emh_data;
550 
551 #define ENUM_GET_PRIVATE_DATA(ht) \
552  ((enum_emh_data*)(((unsigned char*)(ht))-sizeof (enum_emh_data)))
553 
554 #define WIDTH(rect) ( (rect).right - (rect).left )
555 #define HEIGHT(rect) ( (rect).bottom - (rect).top )
556 
557 #define IS_WIN9X() (GetVersion()&0x80000000)
558 
560 {
561  XFORM mapping_mode_trans, final_trans;
562  double scaleX, scaleY;
563 
564  scaleX = (double)info->state.vportExtX / (double)info->state.wndExtX;
565  scaleY = (double)info->state.vportExtY / (double)info->state.wndExtY;
566  mapping_mode_trans.eM11 = scaleX;
567  mapping_mode_trans.eM12 = 0.0;
568  mapping_mode_trans.eM21 = 0.0;
569  mapping_mode_trans.eM22 = scaleY;
570  mapping_mode_trans.eDx = (double)info->state.vportOrgX - scaleX * (double)info->state.wndOrgX;
571  mapping_mode_trans.eDy = (double)info->state.vportOrgY - scaleY * (double)info->state.wndOrgY;
572 
573  CombineTransform(&final_trans, &info->state.world_transform, &mapping_mode_trans);
574  CombineTransform(&final_trans, &final_trans, &info->init_transform);
575 
576  if (!SetWorldTransform(hdc, &final_trans))
577  {
578  ERR("World transform failed!\n");
579  }
580 }
581 
583 {
584  if (abs(level) > info->save_level || level == 0) return;
585 
586  if (level < 0) level = info->save_level + level + 1;
587 
588  while (info->save_level >= level)
589  {
590  EMF_dc_state *state = info->saved_state;
591  info->saved_state = state->next;
592  state->next = NULL;
593  if (--info->save_level < level)
594  info->state = *state;
595  HeapFree( GetProcessHeap(), 0, state );
596  }
597 }
598 
600 {
601  EMF_dc_state *state = HeapAlloc( GetProcessHeap(), 0, sizeof(*state));
602  if (state)
603  {
604  *state = info->state;
605  state->next = info->saved_state;
606  info->saved_state = state;
607  info->save_level++;
608  TRACE("save_level %d\n", info->save_level);
609  }
610 }
611 
613 {
614  INT horzSize = GetDeviceCaps( hdc, HORZSIZE );
615  INT vertSize = GetDeviceCaps( hdc, VERTSIZE );
616  INT horzRes = GetDeviceCaps( hdc, HORZRES );
617  INT vertRes = GetDeviceCaps( hdc, VERTRES );
618 
619  TRACE("%d\n", info->state.mode);
620 
621  switch(info->state.mode)
622  {
623  case MM_TEXT:
624  info->state.wndExtX = 1;
625  info->state.wndExtY = 1;
626  info->state.vportExtX = 1;
627  info->state.vportExtY = 1;
628  break;
629  case MM_LOMETRIC:
630  case MM_ISOTROPIC:
631  info->state.wndExtX = horzSize * 10;
632  info->state.wndExtY = vertSize * 10;
633  info->state.vportExtX = horzRes;
634  info->state.vportExtY = -vertRes;
635  break;
636  case MM_HIMETRIC:
637  info->state.wndExtX = horzSize * 100;
638  info->state.wndExtY = vertSize * 100;
639  info->state.vportExtX = horzRes;
640  info->state.vportExtY = -vertRes;
641  break;
642  case MM_LOENGLISH:
643  info->state.wndExtX = MulDiv(1000, horzSize, 254);
644  info->state.wndExtY = MulDiv(1000, vertSize, 254);
645  info->state.vportExtX = horzRes;
646  info->state.vportExtY = -vertRes;
647  break;
648  case MM_HIENGLISH:
649  info->state.wndExtX = MulDiv(10000, horzSize, 254);
650  info->state.wndExtY = MulDiv(10000, vertSize, 254);
651  info->state.vportExtX = horzRes;
652  info->state.vportExtY = -vertRes;
653  break;
654  case MM_TWIPS:
655  info->state.wndExtX = MulDiv(14400, horzSize, 254);
656  info->state.wndExtY = MulDiv(14400, vertSize, 254);
657  info->state.vportExtX = horzRes;
658  info->state.vportExtY = -vertRes;
659  break;
660  case MM_ANISOTROPIC:
661  break;
662  default:
663  return;
664  }
665 }
666 
667 /***********************************************************************
668  * EMF_FixIsotropic
669  *
670  * Fix viewport extensions for isotropic mode.
671  */
672 
674 {
675  double xdim = fabs((double)info->state.vportExtX * GetDeviceCaps( hdc, HORZSIZE ) /
676  (GetDeviceCaps( hdc, HORZRES ) * info->state.wndExtX));
677  double ydim = fabs((double)info->state.vportExtY * GetDeviceCaps( hdc, VERTSIZE ) /
678  (GetDeviceCaps( hdc, VERTRES ) * info->state.wndExtY));
679 
680  if (xdim > ydim)
681  {
682  INT mincx = (info->state.vportExtX >= 0) ? 1 : -1;
683  info->state.vportExtX = floor(info->state.vportExtX * ydim / xdim + 0.5);
684  if (!info->state.vportExtX) info->state.vportExtX = mincx;
685  }
686  else
687  {
688  INT mincy = (info->state.vportExtY >= 0) ? 1 : -1;
689  info->state.vportExtY = floor(info->state.vportExtY * xdim / ydim + 0.5);
690  if (!info->state.vportExtY) info->state.vportExtY = mincy;
691  }
692 }
693 
694 /*****************************************************************************
695  * emr_produces_output
696  *
697  * Returns TRUE if the record type writes something to the dc. Used by
698  * PlayEnhMetaFileRecord to determine whether it needs to update the
699  * dc's xform when in win9x mode.
700  *
701  * FIXME: need to test which records should be here.
702  */
704 {
705  switch(type) {
706  case EMR_POLYBEZIER:
707  case EMR_POLYGON:
708  case EMR_POLYLINE:
709  case EMR_POLYBEZIERTO:
710  case EMR_POLYLINETO:
711  case EMR_POLYPOLYLINE:
712  case EMR_POLYPOLYGON:
713  case EMR_SETPIXELV:
714  case EMR_MOVETOEX:
715  case EMR_EXCLUDECLIPRECT:
717  case EMR_SELECTOBJECT:
718  case EMR_ANGLEARC:
719  case EMR_ELLIPSE:
720  case EMR_RECTANGLE:
721  case EMR_ROUNDRECT:
722  case EMR_ARC:
723  case EMR_CHORD:
724  case EMR_PIE:
725  case EMR_EXTFLOODFILL:
726  case EMR_LINETO:
727  case EMR_ARCTO:
728  case EMR_POLYDRAW:
729  case EMR_GDICOMMENT:
730  case EMR_FILLRGN:
731  case EMR_FRAMERGN:
732  case EMR_INVERTRGN:
733  case EMR_PAINTRGN:
734  case EMR_BITBLT:
735  case EMR_STRETCHBLT:
736  case EMR_MASKBLT:
737  case EMR_PLGBLT:
739  case EMR_STRETCHDIBITS:
740  case EMR_EXTTEXTOUTA:
741  case EMR_EXTTEXTOUTW:
742  case EMR_POLYBEZIER16:
743  case EMR_POLYGON16:
744  case EMR_POLYLINE16:
745  case EMR_POLYBEZIERTO16:
746  case EMR_POLYLINETO16:
747  case EMR_POLYPOLYLINE16:
748  case EMR_POLYPOLYGON16:
749  case EMR_POLYDRAW16:
750  case EMR_POLYTEXTOUTA:
751  case EMR_POLYTEXTOUTW:
752  case EMR_SMALLTEXTOUT:
753  case EMR_ALPHABLEND:
754  case EMR_TRANSPARENTBLT:
755  return TRUE;
756  default:
757  return FALSE;
758  }
759 }
760 
761 
762 /*****************************************************************************
763  * PlayEnhMetaFileRecord (GDI32.@)
764  *
765  * Render a single enhanced metafile record in the device context hdc.
766  *
767  * RETURNS
768  * TRUE (non zero) on success, FALSE on error.
769  * BUGS
770  * Many unimplemented records.
771  * No error handling on record play failures (ie checking return codes)
772  *
773  * NOTES
774  * WinNT actually updates the current world transform in this function
775  * whereas Win9x does not.
776  */
778  HDC hdc, /* [in] device context in which to render EMF record */
779  LPHANDLETABLE handletable, /* [in] array of handles to be used in rendering record */
780  const ENHMETARECORD *mr, /* [in] EMF record to render */
781  UINT handles /* [in] size of handle array */
782  )
783 {
784  int type;
785  RECT tmprc;
786  enum_emh_data *info = ENUM_GET_PRIVATE_DATA(handletable);
787 
788  TRACE("hdc = %p, handletable = %p, record = %p, numHandles = %d\n",
789  hdc, handletable, mr, handles);
790  if (!mr) return FALSE;
791 
792  type = mr->iType;
793 
794  TRACE("record %s\n", get_emr_name(type));
795  switch(type)
796  {
797  case EMR_HEADER:
798  break;
799  case EMR_EOF:
800  break;
801  case EMR_GDICOMMENT:
802  {
803  const EMRGDICOMMENT *lpGdiComment = (const EMRGDICOMMENT *)mr;
804  /* In an enhanced metafile, there can be both public and private GDI comments */
805  GdiComment( hdc, lpGdiComment->cbData, lpGdiComment->Data );
806  break;
807  }
808  case EMR_SETMAPMODE:
809  {
810  const EMRSETMAPMODE *pSetMapMode = (const EMRSETMAPMODE *)mr;
811 
812  if (info->state.mode == pSetMapMode->iMode &&
813  (info->state.mode == MM_ISOTROPIC || info->state.mode == MM_ANISOTROPIC))
814  break;
815  info->state.mode = pSetMapMode->iMode;
817 
818  if (!IS_WIN9X())
820 
821  break;
822  }
823  case EMR_SETBKMODE:
824  {
825  const EMRSETBKMODE *pSetBkMode = (const EMRSETBKMODE *)mr;
826  SetBkMode(hdc, pSetBkMode->iMode);
827  break;
828  }
829  case EMR_SETBKCOLOR:
830  {
831  const EMRSETBKCOLOR *pSetBkColor = (const EMRSETBKCOLOR *)mr;
832  SetBkColor(hdc, pSetBkColor->crColor);
833  break;
834  }
835  case EMR_SETPOLYFILLMODE:
836  {
837  const EMRSETPOLYFILLMODE *pSetPolyFillMode = (const EMRSETPOLYFILLMODE *)mr;
838  SetPolyFillMode(hdc, pSetPolyFillMode->iMode);
839  break;
840  }
841  case EMR_SETROP2:
842  {
843  const EMRSETROP2 *pSetROP2 = (const EMRSETROP2 *)mr;
844  SetROP2(hdc, pSetROP2->iMode);
845  break;
846  }
848  {
849  const EMRSETSTRETCHBLTMODE *pSetStretchBltMode = (const EMRSETSTRETCHBLTMODE *)mr;
850  SetStretchBltMode(hdc, pSetStretchBltMode->iMode);
851  break;
852  }
853  case EMR_SETTEXTALIGN:
854  {
855  const EMRSETTEXTALIGN *pSetTextAlign = (const EMRSETTEXTALIGN *)mr;
856  SetTextAlign(hdc, pSetTextAlign->iMode);
857  break;
858  }
859  case EMR_SETTEXTCOLOR:
860  {
861  const EMRSETTEXTCOLOR *pSetTextColor = (const EMRSETTEXTCOLOR *)mr;
862  SetTextColor(hdc, pSetTextColor->crColor);
863  break;
864  }
865  case EMR_SAVEDC:
866  {
867  if (SaveDC( hdc ))
868  EMF_SaveDC( info );
869  break;
870  }
871  case EMR_RESTOREDC:
872  {
873  const EMRRESTOREDC *pRestoreDC = (const EMRRESTOREDC *)mr;
874  TRACE("EMR_RESTORE: %d\n", pRestoreDC->iRelative);
875  if (RestoreDC( hdc, pRestoreDC->iRelative ))
876  EMF_RestoreDC( info, pRestoreDC->iRelative );
877  break;
878  }
880  {
881  const EMRINTERSECTCLIPRECT *pClipRect = (const EMRINTERSECTCLIPRECT *)mr;
882  TRACE("EMR_INTERSECTCLIPRECT: rect %d,%d - %d, %d\n",
883  pClipRect->rclClip.left, pClipRect->rclClip.top,
884  pClipRect->rclClip.right, pClipRect->rclClip.bottom);
885  IntersectClipRect(hdc, pClipRect->rclClip.left, pClipRect->rclClip.top,
886  pClipRect->rclClip.right, pClipRect->rclClip.bottom);
887  break;
888  }
889  case EMR_SELECTOBJECT:
890  {
891  const EMRSELECTOBJECT *pSelectObject = (const EMRSELECTOBJECT *)mr;
892  if( pSelectObject->ihObject & 0x80000000 ) {
893  /* High order bit is set - it's a stock object
894  * Strip the high bit to get the index.
895  * See MSDN article Q142319
896  */
897  SelectObject( hdc, GetStockObject( pSelectObject->ihObject &
898  0x7fffffff ) );
899  } else {
900  /* High order bit wasn't set - not a stock object
901  */
902  SelectObject( hdc,
903  (handletable->objectHandle)[pSelectObject->ihObject] );
904  }
905  break;
906  }
907  case EMR_DELETEOBJECT:
908  {
909  const EMRDELETEOBJECT *pDeleteObject = (const EMRDELETEOBJECT *)mr;
910  DeleteObject( (handletable->objectHandle)[pDeleteObject->ihObject]);
911  (handletable->objectHandle)[pDeleteObject->ihObject] = 0;
912  break;
913  }
914  case EMR_SETWINDOWORGEX:
915  {
916  const EMRSETWINDOWORGEX *pSetWindowOrgEx = (const EMRSETWINDOWORGEX *)mr;
917 
918  info->state.wndOrgX = pSetWindowOrgEx->ptlOrigin.x;
919  info->state.wndOrgY = pSetWindowOrgEx->ptlOrigin.y;
920 
921  TRACE("SetWindowOrgEx: %d,%d\n", info->state.wndOrgX, info->state.wndOrgY);
922 
923  if (!IS_WIN9X())
925 
926  break;
927  }
928  case EMR_SETWINDOWEXTEX:
929  {
930  const EMRSETWINDOWEXTEX *pSetWindowExtEx = (const EMRSETWINDOWEXTEX *)mr;
931 
932  if (info->state.mode != MM_ISOTROPIC && info->state.mode != MM_ANISOTROPIC)
933  break;
934  info->state.wndExtX = pSetWindowExtEx->szlExtent.cx;
935  info->state.wndExtY = pSetWindowExtEx->szlExtent.cy;
936  if (info->state.mode == MM_ISOTROPIC)
938 
939  TRACE("SetWindowExtEx: %d,%d\n",info->state.wndExtX, info->state.wndExtY);
940 
941  if (!IS_WIN9X())
943 
944  break;
945  }
947  {
948  const EMRSETVIEWPORTORGEX *pSetViewportOrgEx = (const EMRSETVIEWPORTORGEX *)mr;
949 
950  info->state.vportOrgX = pSetViewportOrgEx->ptlOrigin.x;
951  info->state.vportOrgY = pSetViewportOrgEx->ptlOrigin.y;
952  TRACE("SetViewportOrgEx: %d,%d\n", info->state.vportOrgX, info->state.vportOrgY);
953 
954  if (!IS_WIN9X())
956 
957  break;
958  }
960  {
961  const EMRSETVIEWPORTEXTEX *pSetViewportExtEx = (const EMRSETVIEWPORTEXTEX *)mr;
962 
963  if (info->state.mode != MM_ISOTROPIC && info->state.mode != MM_ANISOTROPIC)
964  break;
965  info->state.vportExtX = pSetViewportExtEx->szlExtent.cx;
966  info->state.vportExtY = pSetViewportExtEx->szlExtent.cy;
967  if (info->state.mode == MM_ISOTROPIC)
969  TRACE("SetViewportExtEx: %d,%d\n", info->state.vportExtX, info->state.vportExtY);
970 
971  if (!IS_WIN9X())
973 
974  break;
975  }
976  case EMR_CREATEPEN:
977  {
978  const EMRCREATEPEN *pCreatePen = (const EMRCREATEPEN *)mr;
979  (handletable->objectHandle)[pCreatePen->ihPen] =
980  CreatePenIndirect(&pCreatePen->lopn);
981  break;
982  }
983  case EMR_EXTCREATEPEN:
984  {
985  const EMREXTCREATEPEN *pPen = (const EMREXTCREATEPEN *)mr;
986  LOGBRUSH lb;
987  lb.lbStyle = pPen->elp.elpBrushStyle;
988  lb.lbColor = pPen->elp.elpColor;
989  lb.lbHatch = pPen->elp.elpHatch;
990 
991  if(pPen->offBmi || pPen->offBits)
992  FIXME("EMR_EXTCREATEPEN: Need to copy brush bitmap\n");
993 
994  (handletable->objectHandle)[pPen->ihPen] =
995  ExtCreatePen(pPen->elp.elpPenStyle, pPen->elp.elpWidth, &lb,
996  pPen->elp.elpNumEntries, pPen->elp.elpNumEntries ? pPen->elp.elpStyleEntry : NULL);
997  break;
998  }
1000  {
1001  const EMRCREATEBRUSHINDIRECT *pBrush = (const EMRCREATEBRUSHINDIRECT *)mr;
1002  LOGBRUSH brush;
1003  brush.lbStyle = pBrush->lb.lbStyle;
1004  brush.lbColor = pBrush->lb.lbColor;
1005  brush.lbHatch = pBrush->lb.lbHatch;
1006  (handletable->objectHandle)[pBrush->ihBrush] = CreateBrushIndirect(&brush);
1007  break;
1008  }
1010  {
1011  const EMREXTCREATEFONTINDIRECTW *pFont = (const EMREXTCREATEFONTINDIRECTW *)mr;
1012  (handletable->objectHandle)[pFont->ihFont] =
1014  break;
1015  }
1016  case EMR_MOVETOEX:
1017  {
1018  const EMRMOVETOEX *pMoveToEx = (const EMRMOVETOEX *)mr;
1019  MoveToEx(hdc, pMoveToEx->ptl.x, pMoveToEx->ptl.y, NULL);
1020  break;
1021  }
1022  case EMR_LINETO:
1023  {
1024  const EMRLINETO *pLineTo = (const EMRLINETO *)mr;
1025  LineTo(hdc, pLineTo->ptl.x, pLineTo->ptl.y);
1026  break;
1027  }
1028  case EMR_RECTANGLE:
1029  {
1030  const EMRRECTANGLE *pRect = (const EMRRECTANGLE *)mr;
1031  Rectangle(hdc, pRect->rclBox.left, pRect->rclBox.top,
1032  pRect->rclBox.right, pRect->rclBox.bottom);
1033  break;
1034  }
1035  case EMR_ELLIPSE:
1036  {
1037  const EMRELLIPSE *pEllipse = (const EMRELLIPSE *)mr;
1038  Ellipse(hdc, pEllipse->rclBox.left, pEllipse->rclBox.top,
1039  pEllipse->rclBox.right, pEllipse->rclBox.bottom);
1040  break;
1041  }
1042  case EMR_POLYGON16:
1043  {
1044  const EMRPOLYGON16 *pPoly = (const EMRPOLYGON16 *)mr;
1045  /* Shouldn't use Polygon16 since pPoly->cpts is DWORD */
1046  POINT *pts = HeapAlloc( GetProcessHeap(), 0,
1047  pPoly->cpts * sizeof(POINT) );
1048  DWORD i;
1049  for(i = 0; i < pPoly->cpts; i++)
1050  {
1051  pts[i].x = pPoly->apts[i].x;
1052  pts[i].y = pPoly->apts[i].y;
1053  }
1054  Polygon(hdc, pts, pPoly->cpts);
1055  HeapFree( GetProcessHeap(), 0, pts );
1056  break;
1057  }
1058  case EMR_POLYLINE16:
1059  {
1060  const EMRPOLYLINE16 *pPoly = (const EMRPOLYLINE16 *)mr;
1061  /* Shouldn't use Polyline16 since pPoly->cpts is DWORD */
1062  POINT *pts = HeapAlloc( GetProcessHeap(), 0,
1063  pPoly->cpts * sizeof(POINT) );
1064  DWORD i;
1065  for(i = 0; i < pPoly->cpts; i++)
1066  {
1067  pts[i].x = pPoly->apts[i].x;
1068  pts[i].y = pPoly->apts[i].y;
1069  }
1070  Polyline(hdc, pts, pPoly->cpts);
1071  HeapFree( GetProcessHeap(), 0, pts );
1072  break;
1073  }
1074  case EMR_POLYLINETO16:
1075  {
1076  const EMRPOLYLINETO16 *pPoly = (const EMRPOLYLINETO16 *)mr;
1077  /* Shouldn't use PolylineTo16 since pPoly->cpts is DWORD */
1078  POINT *pts = HeapAlloc( GetProcessHeap(), 0,
1079  pPoly->cpts * sizeof(POINT) );
1080  DWORD i;
1081  for(i = 0; i < pPoly->cpts; i++)
1082  {
1083  pts[i].x = pPoly->apts[i].x;
1084  pts[i].y = pPoly->apts[i].y;
1085  }
1086  PolylineTo(hdc, pts, pPoly->cpts);
1087  HeapFree( GetProcessHeap(), 0, pts );
1088  break;
1089  }
1090  case EMR_POLYBEZIER16:
1091  {
1092  const EMRPOLYBEZIER16 *pPoly = (const EMRPOLYBEZIER16 *)mr;
1093  /* Shouldn't use PolyBezier16 since pPoly->cpts is DWORD */
1094  POINT *pts = HeapAlloc( GetProcessHeap(), 0,
1095  pPoly->cpts * sizeof(POINT) );
1096  DWORD i;
1097  for(i = 0; i < pPoly->cpts; i++)
1098  {
1099  pts[i].x = pPoly->apts[i].x;
1100  pts[i].y = pPoly->apts[i].y;
1101  }
1102  PolyBezier(hdc, pts, pPoly->cpts);
1103  HeapFree( GetProcessHeap(), 0, pts );
1104  break;
1105  }
1106  case EMR_POLYBEZIERTO16:
1107  {
1108  const EMRPOLYBEZIERTO16 *pPoly = (const EMRPOLYBEZIERTO16 *)mr;
1109  /* Shouldn't use PolyBezierTo16 since pPoly->cpts is DWORD */
1110  POINT *pts = HeapAlloc( GetProcessHeap(), 0,
1111  pPoly->cpts * sizeof(POINT) );
1112  DWORD i;
1113  for(i = 0; i < pPoly->cpts; i++)
1114  {
1115  pts[i].x = pPoly->apts[i].x;
1116  pts[i].y = pPoly->apts[i].y;
1117  }
1118  PolyBezierTo(hdc, pts, pPoly->cpts);
1119  HeapFree( GetProcessHeap(), 0, pts );
1120  break;
1121  }
1122  case EMR_POLYPOLYGON16:
1123  {
1124  const EMRPOLYPOLYGON16 *pPolyPoly = (const EMRPOLYPOLYGON16 *)mr;
1125  /* NB POINTS array doesn't start at pPolyPoly->apts it's actually
1126  pPolyPoly->aPolyCounts + pPolyPoly->nPolys */
1127 
1128  const POINTS *pts = (const POINTS *)(pPolyPoly->aPolyCounts + pPolyPoly->nPolys);
1129  POINT *pt = HeapAlloc( GetProcessHeap(), 0, pPolyPoly->cpts * sizeof(POINT) );
1130  DWORD i;
1131  for(i = 0; i < pPolyPoly->cpts; i++)
1132  {
1133  pt[i].x = pts[i].x;
1134  pt[i].y = pts[i].y;
1135  }
1136  PolyPolygon(hdc, pt, (const INT*)pPolyPoly->aPolyCounts, pPolyPoly->nPolys);
1137  HeapFree( GetProcessHeap(), 0, pt );
1138  break;
1139  }
1140  case EMR_POLYPOLYLINE16:
1141  {
1142  const EMRPOLYPOLYLINE16 *pPolyPoly = (const EMRPOLYPOLYLINE16 *)mr;
1143  /* NB POINTS array doesn't start at pPolyPoly->apts it's actually
1144  pPolyPoly->aPolyCounts + pPolyPoly->nPolys */
1145 
1146  const POINTS *pts = (const POINTS *)(pPolyPoly->aPolyCounts + pPolyPoly->nPolys);
1147  POINT *pt = HeapAlloc( GetProcessHeap(), 0, pPolyPoly->cpts * sizeof(POINT) );
1148  DWORD i;
1149  for(i = 0; i < pPolyPoly->cpts; i++)
1150  {
1151  pt[i].x = pts[i].x;
1152  pt[i].y = pts[i].y;
1153  }
1154  PolyPolyline(hdc, pt, pPolyPoly->aPolyCounts, pPolyPoly->nPolys);
1155  HeapFree( GetProcessHeap(), 0, pt );
1156  break;
1157  }
1158 
1159  case EMR_POLYDRAW16:
1160  {
1161  const EMRPOLYDRAW16 *pPolyDraw16 = (const EMRPOLYDRAW16 *)mr;
1162  const POINTS *ptl = pPolyDraw16->apts;
1163  POINT *pts = HeapAlloc(GetProcessHeap(), 0, pPolyDraw16->cpts * sizeof(POINT));
1164  DWORD i;
1165 
1166  /* NB abTypes array doesn't start at pPolyDraw16->abTypes. It's actually
1167  pPolyDraw16->apts + pPolyDraw16->cpts. */
1168  const BYTE *types = (BYTE*)(pPolyDraw16->apts + pPolyDraw16->cpts);
1169 
1170  if (!pts)
1171  break;
1172 
1173  for (i = 0; i < pPolyDraw16->cpts; ++i)
1174  {
1175  pts[i].x = ptl[i].x;
1176  pts[i].y = ptl[i].y;
1177  }
1178 
1179  PolyDraw(hdc, pts, types, pPolyDraw16->cpts);
1180  HeapFree(GetProcessHeap(), 0, pts);
1181  break;
1182  }
1183 
1184  case EMR_STRETCHDIBITS:
1185  {
1186  const EMRSTRETCHDIBITS *pStretchDIBits = (const EMRSTRETCHDIBITS *)mr;
1187 
1189  pStretchDIBits->xDest,
1190  pStretchDIBits->yDest,
1191  pStretchDIBits->cxDest,
1192  pStretchDIBits->cyDest,
1193  pStretchDIBits->xSrc,
1194  pStretchDIBits->ySrc,
1195  pStretchDIBits->cxSrc,
1196  pStretchDIBits->cySrc,
1197  (const BYTE *)mr + pStretchDIBits->offBitsSrc,
1198  (const BITMAPINFO *)((const BYTE *)mr + pStretchDIBits->offBmiSrc),
1199  pStretchDIBits->iUsageSrc,
1200  pStretchDIBits->dwRop);
1201  break;
1202  }
1203 
1204  case EMR_EXTTEXTOUTA:
1205  {
1206  const EMREXTTEXTOUTA *pExtTextOutA = (const EMREXTTEXTOUTA *)mr;
1207  RECT rc;
1208  const INT *dx = NULL;
1209  int old_mode;
1210 
1211  rc.left = pExtTextOutA->emrtext.rcl.left;
1212  rc.top = pExtTextOutA->emrtext.rcl.top;
1213  rc.right = pExtTextOutA->emrtext.rcl.right;
1214  rc.bottom = pExtTextOutA->emrtext.rcl.bottom;
1215  TRACE("EMR_EXTTEXTOUTA: x,y = %d, %d. rect = %s. flags %08x\n",
1216  pExtTextOutA->emrtext.ptlReference.x, pExtTextOutA->emrtext.ptlReference.y,
1217  wine_dbgstr_rect(&rc), pExtTextOutA->emrtext.fOptions);
1218 
1219  old_mode = SetGraphicsMode(hdc, pExtTextOutA->iGraphicsMode);
1220  /* Reselect the font back into the dc so that the transformation
1221  gets updated. */
1223 
1224  /* Linux version of pstoedit produces EMFs with offDx set to 0.
1225  * These files can be enumerated and played under Win98 just
1226  * fine, but at least Win2k chokes on them.
1227  */
1228  if (pExtTextOutA->emrtext.offDx)
1229  dx = (const INT *)((const BYTE *)mr + pExtTextOutA->emrtext.offDx);
1230 
1231  ExtTextOutA(hdc, pExtTextOutA->emrtext.ptlReference.x, pExtTextOutA->emrtext.ptlReference.y,
1232  pExtTextOutA->emrtext.fOptions, &rc,
1233  (LPCSTR)((const BYTE *)mr + pExtTextOutA->emrtext.offString), pExtTextOutA->emrtext.nChars,
1234  dx);
1235 
1236  SetGraphicsMode(hdc, old_mode);
1237  break;
1238  }
1239 
1240  case EMR_EXTTEXTOUTW:
1241  {
1242  const EMREXTTEXTOUTW *pExtTextOutW = (const EMREXTTEXTOUTW *)mr;
1243  RECT rc;
1244  const INT *dx = NULL;
1245  int old_mode;
1246 
1247  rc.left = pExtTextOutW->emrtext.rcl.left;
1248  rc.top = pExtTextOutW->emrtext.rcl.top;
1249  rc.right = pExtTextOutW->emrtext.rcl.right;
1250  rc.bottom = pExtTextOutW->emrtext.rcl.bottom;
1251  TRACE("EMR_EXTTEXTOUTW: x,y = %d, %d. rect = %s. flags %08x\n",
1252  pExtTextOutW->emrtext.ptlReference.x, pExtTextOutW->emrtext.ptlReference.y,
1253  wine_dbgstr_rect(&rc), pExtTextOutW->emrtext.fOptions);
1254 
1255  old_mode = SetGraphicsMode(hdc, pExtTextOutW->iGraphicsMode);
1256  /* Reselect the font back into the dc so that the transformation
1257  gets updated. */
1259 
1260  /* Linux version of pstoedit produces EMFs with offDx set to 0.
1261  * These files can be enumerated and played under Win98 just
1262  * fine, but at least Win2k chokes on them.
1263  */
1264  if (pExtTextOutW->emrtext.offDx)
1265  dx = (const INT *)((const BYTE *)mr + pExtTextOutW->emrtext.offDx);
1266 
1267  ExtTextOutW(hdc, pExtTextOutW->emrtext.ptlReference.x, pExtTextOutW->emrtext.ptlReference.y,
1268  pExtTextOutW->emrtext.fOptions, &rc,
1269  (LPCWSTR)((const BYTE *)mr + pExtTextOutW->emrtext.offString), pExtTextOutW->emrtext.nChars,
1270  dx);
1271 
1272  SetGraphicsMode(hdc, old_mode);
1273  break;
1274  }
1275 
1276  case EMR_CREATEPALETTE:
1277  {
1278  const EMRCREATEPALETTE *lpCreatePal = (const EMRCREATEPALETTE *)mr;
1279 
1280  (handletable->objectHandle)[ lpCreatePal->ihPal ] =
1281  CreatePalette( &lpCreatePal->lgpl );
1282 
1283  break;
1284  }
1285 
1286  case EMR_SELECTPALETTE:
1287  {
1288  const EMRSELECTPALETTE *lpSelectPal = (const EMRSELECTPALETTE *)mr;
1289 
1290  if( lpSelectPal->ihPal & 0x80000000 ) {
1291  SelectPalette( hdc, GetStockObject(lpSelectPal->ihPal & 0x7fffffff), TRUE);
1292  } else {
1293  SelectPalette( hdc, (handletable->objectHandle)[lpSelectPal->ihPal], TRUE);
1294  }
1295  break;
1296  }
1297 
1298  case EMR_REALIZEPALETTE:
1299  {
1300  RealizePalette( hdc );
1301  break;
1302  }
1303 
1304  case EMR_EXTSELECTCLIPRGN:
1305  {
1306  const EMREXTSELECTCLIPRGN *lpRgn = (const EMREXTSELECTCLIPRGN *)mr;
1307 #ifdef __REACTOS__
1308  const RGNDATA *pRgnData = (const RGNDATA *)lpRgn->RgnData;
1309  DWORD dwSize = sizeof(RGNDATAHEADER) + pRgnData->rdh.nCount * sizeof(RECT);
1310 #endif
1311  HRGN hRgn = 0;
1312 
1313  if (mr->nSize >= sizeof(*lpRgn) + sizeof(RGNDATAHEADER))
1314 #ifdef __REACTOS__
1315  hRgn = ExtCreateRegion( &info->init_transform, dwSize, pRgnData );
1316 #else
1317  hRgn = ExtCreateRegion( &info->init_transform, 0, (const RGNDATA *)lpRgn->RgnData );
1318 #endif
1319  ExtSelectClipRgn(hdc, hRgn, (INT)(lpRgn->iMode));
1320  /* ExtSelectClipRgn created a copy of the region */
1321  DeleteObject(hRgn);
1322  break;
1323  }
1324 
1325  case EMR_SETMETARGN:
1326  {
1327  SetMetaRgn( hdc );
1328  break;
1329  }
1330 
1331  case EMR_SETWORLDTRANSFORM:
1332  {
1333  const EMRSETWORLDTRANSFORM *lpXfrm = (const EMRSETWORLDTRANSFORM *)mr;
1334  info->state.world_transform = lpXfrm->xform;
1335 
1336  if (!IS_WIN9X())
1338 
1339  break;
1340  }
1341 
1342  case EMR_POLYBEZIER:
1343  {
1344  const EMRPOLYBEZIER *lpPolyBez = (const EMRPOLYBEZIER *)mr;
1345  PolyBezier(hdc, (const POINT*)lpPolyBez->aptl, (UINT)lpPolyBez->cptl);
1346  break;
1347  }
1348 
1349  case EMR_POLYGON:
1350  {
1351  const EMRPOLYGON *lpPoly = (const EMRPOLYGON *)mr;
1352  Polygon( hdc, (const POINT*)lpPoly->aptl, (UINT)lpPoly->cptl );
1353  break;
1354  }
1355 
1356  case EMR_POLYLINE:
1357  {
1358  const EMRPOLYLINE *lpPolyLine = (const EMRPOLYLINE *)mr;
1359  Polyline(hdc, (const POINT*)lpPolyLine->aptl, (UINT)lpPolyLine->cptl);
1360  break;
1361  }
1362 
1363  case EMR_POLYBEZIERTO:
1364  {
1365  const EMRPOLYBEZIERTO *lpPolyBezierTo = (const EMRPOLYBEZIERTO *)mr;
1366  PolyBezierTo( hdc, (const POINT*)lpPolyBezierTo->aptl,
1367  (UINT)lpPolyBezierTo->cptl );
1368  break;
1369  }
1370 
1371  case EMR_POLYLINETO:
1372  {
1373  const EMRPOLYLINETO *lpPolyLineTo = (const EMRPOLYLINETO *)mr;
1374  PolylineTo( hdc, (const POINT*)lpPolyLineTo->aptl,
1375  (UINT)lpPolyLineTo->cptl );
1376  break;
1377  }
1378 
1379  case EMR_POLYPOLYLINE:
1380  {
1381  const EMRPOLYPOLYLINE *pPolyPolyline = (const EMRPOLYPOLYLINE *)mr;
1382  /* NB Points at pPolyPolyline->aPolyCounts + pPolyPolyline->nPolys */
1383 
1384  PolyPolyline(hdc, (const POINT*)(pPolyPolyline->aPolyCounts +
1385  pPolyPolyline->nPolys),
1386  pPolyPolyline->aPolyCounts,
1387  pPolyPolyline->nPolys );
1388 
1389  break;
1390  }
1391 
1392  case EMR_POLYPOLYGON:
1393  {
1394  const EMRPOLYPOLYGON *pPolyPolygon = (const EMRPOLYPOLYGON *)mr;
1395 
1396  /* NB Points at pPolyPolygon->aPolyCounts + pPolyPolygon->nPolys */
1397 
1398  PolyPolygon(hdc, (const POINT*)(pPolyPolygon->aPolyCounts +
1399  pPolyPolygon->nPolys),
1400  (const INT*)pPolyPolygon->aPolyCounts, pPolyPolygon->nPolys );
1401  break;
1402  }
1403 
1404  case EMR_SETBRUSHORGEX:
1405  {
1406  const EMRSETBRUSHORGEX *lpSetBrushOrgEx = (const EMRSETBRUSHORGEX *)mr;
1407 
1408  SetBrushOrgEx( hdc,
1409  (INT)lpSetBrushOrgEx->ptlOrigin.x,
1410  (INT)lpSetBrushOrgEx->ptlOrigin.y,
1411  NULL );
1412 
1413  break;
1414  }
1415 
1416  case EMR_SETPIXELV:
1417  {
1418  const EMRSETPIXELV *lpSetPixelV = (const EMRSETPIXELV *)mr;
1419 
1420  SetPixelV( hdc,
1421  (INT)lpSetPixelV->ptlPixel.x,
1422  (INT)lpSetPixelV->ptlPixel.y,
1423  lpSetPixelV->crColor );
1424 
1425  break;
1426  }
1427 
1428  case EMR_SETMAPPERFLAGS:
1429  {
1430  const EMRSETMAPPERFLAGS *lpSetMapperFlags = (const EMRSETMAPPERFLAGS *)mr;
1431 
1432  SetMapperFlags( hdc, lpSetMapperFlags->dwFlags );
1433 
1434  break;
1435  }
1436 
1438  {
1439  const EMRSETCOLORADJUSTMENT *lpSetColorAdjust = (const EMRSETCOLORADJUSTMENT *)mr;
1440 
1441  SetColorAdjustment( hdc, &lpSetColorAdjust->ColorAdjustment );
1442 
1443  break;
1444  }
1445 
1446  case EMR_OFFSETCLIPRGN:
1447  {
1448  const EMROFFSETCLIPRGN *lpOffsetClipRgn = (const EMROFFSETCLIPRGN *)mr;
1449 
1450  OffsetClipRgn( hdc,
1451  (INT)lpOffsetClipRgn->ptlOffset.x,
1452  (INT)lpOffsetClipRgn->ptlOffset.y );
1453  FIXME("OffsetClipRgn\n");
1454 
1455  break;
1456  }
1457 
1458  case EMR_EXCLUDECLIPRECT:
1459  {
1460  const EMREXCLUDECLIPRECT *lpExcludeClipRect = (const EMREXCLUDECLIPRECT *)mr;
1461 
1463  lpExcludeClipRect->rclClip.left,
1464  lpExcludeClipRect->rclClip.top,
1465  lpExcludeClipRect->rclClip.right,
1466  lpExcludeClipRect->rclClip.bottom );
1467  FIXME("ExcludeClipRect\n");
1468 
1469  break;
1470  }
1471 
1473  {
1474  const EMRSCALEVIEWPORTEXTEX *lpScaleViewportExtEx = (const EMRSCALEVIEWPORTEXTEX *)mr;
1475 
1476  if ((info->state.mode != MM_ISOTROPIC) && (info->state.mode != MM_ANISOTROPIC))
1477  break;
1478  if (!lpScaleViewportExtEx->xNum || !lpScaleViewportExtEx->xDenom ||
1479  !lpScaleViewportExtEx->yNum || !lpScaleViewportExtEx->yDenom)
1480  break;
1481  info->state.vportExtX = MulDiv(info->state.vportExtX, lpScaleViewportExtEx->xNum,
1482  lpScaleViewportExtEx->xDenom);
1483  info->state.vportExtY = MulDiv(info->state.vportExtY, lpScaleViewportExtEx->yNum,
1484  lpScaleViewportExtEx->yDenom);
1485  if (info->state.vportExtX == 0) info->state.vportExtX = 1;
1486  if (info->state.vportExtY == 0) info->state.vportExtY = 1;
1487  if (info->state.mode == MM_ISOTROPIC)
1489 
1490  TRACE("EMRSCALEVIEWPORTEXTEX %d/%d %d/%d\n",
1491  lpScaleViewportExtEx->xNum,lpScaleViewportExtEx->xDenom,
1492  lpScaleViewportExtEx->yNum,lpScaleViewportExtEx->yDenom);
1493 
1494  if (!IS_WIN9X())
1496 
1497  break;
1498  }
1499 
1500  case EMR_SCALEWINDOWEXTEX:
1501  {
1502  const EMRSCALEWINDOWEXTEX *lpScaleWindowExtEx = (const EMRSCALEWINDOWEXTEX *)mr;
1503 
1504  if ((info->state.mode != MM_ISOTROPIC) && (info->state.mode != MM_ANISOTROPIC))
1505  break;
1506  if (!lpScaleWindowExtEx->xNum || !lpScaleWindowExtEx->xDenom ||
1507  !lpScaleWindowExtEx->yNum || !lpScaleWindowExtEx->yDenom)
1508  break;
1509  info->state.wndExtX = MulDiv(info->state.wndExtX, lpScaleWindowExtEx->xNum,
1510  lpScaleWindowExtEx->xDenom);
1511  info->state.wndExtY = MulDiv(info->state.wndExtY, lpScaleWindowExtEx->yNum,
1512  lpScaleWindowExtEx->yDenom);
1513  if (info->state.wndExtX == 0) info->state.wndExtX = 1;
1514  if (info->state.wndExtY == 0) info->state.wndExtY = 1;
1515  if (info->state.mode == MM_ISOTROPIC)
1517 
1518  TRACE("EMRSCALEWINDOWEXTEX %d/%d %d/%d\n",
1519  lpScaleWindowExtEx->xNum,lpScaleWindowExtEx->xDenom,
1520  lpScaleWindowExtEx->yNum,lpScaleWindowExtEx->yDenom);
1521 
1522  if (!IS_WIN9X())
1524 
1525  break;
1526  }
1527 
1529  {
1530  const EMRMODIFYWORLDTRANSFORM *lpModifyWorldTrans = (const EMRMODIFYWORLDTRANSFORM *)mr;
1531 
1532  switch(lpModifyWorldTrans->iMode) {
1533  case MWT_IDENTITY:
1534  info->state.world_transform.eM11 = info->state.world_transform.eM22 = 1;
1535  info->state.world_transform.eM12 = info->state.world_transform.eM21 = 0;
1536  info->state.world_transform.eDx = info->state.world_transform.eDy = 0;
1537  if (!IS_WIN9X())
1539  break;
1540  case MWT_LEFTMULTIPLY:
1541  CombineTransform(&info->state.world_transform, &lpModifyWorldTrans->xform,
1542  &info->state.world_transform);
1543  if (!IS_WIN9X())
1544  ModifyWorldTransform(hdc, &lpModifyWorldTrans->xform, MWT_LEFTMULTIPLY);
1545  break;
1546  case MWT_RIGHTMULTIPLY:
1547  CombineTransform(&info->state.world_transform, &info->state.world_transform,
1548  &lpModifyWorldTrans->xform);
1549  if (!IS_WIN9X())
1551  break;
1552  default:
1553  FIXME("Unknown imode %d\n", lpModifyWorldTrans->iMode);
1554  break;
1555  }
1556  break;
1557  }
1558 
1559  case EMR_ANGLEARC:
1560  {
1561  const EMRANGLEARC *lpAngleArc = (const EMRANGLEARC *)mr;
1562 
1563  AngleArc( hdc,
1564  (INT)lpAngleArc->ptlCenter.x, (INT)lpAngleArc->ptlCenter.y,
1565  lpAngleArc->nRadius, lpAngleArc->eStartAngle,
1566  lpAngleArc->eSweepAngle );
1567 
1568  break;
1569  }
1570 
1571  case EMR_ROUNDRECT:
1572  {
1573  const EMRROUNDRECT *lpRoundRect = (const EMRROUNDRECT *)mr;
1574 
1575  RoundRect( hdc,
1576  lpRoundRect->rclBox.left,
1577  lpRoundRect->rclBox.top,
1578  lpRoundRect->rclBox.right,
1579  lpRoundRect->rclBox.bottom,
1580  lpRoundRect->szlCorner.cx,
1581  lpRoundRect->szlCorner.cy );
1582 
1583  break;
1584  }
1585 
1586  case EMR_ARC:
1587  {
1588  const EMRARC *lpArc = (const EMRARC *)mr;
1589 
1590  Arc( hdc,
1591  (INT)lpArc->rclBox.left,
1592  (INT)lpArc->rclBox.top,
1593  (INT)lpArc->rclBox.right,
1594  (INT)lpArc->rclBox.bottom,
1595  (INT)lpArc->ptlStart.x,
1596  (INT)lpArc->ptlStart.y,
1597  (INT)lpArc->ptlEnd.x,
1598  (INT)lpArc->ptlEnd.y );
1599 
1600  break;
1601  }
1602 
1603  case EMR_CHORD:
1604  {
1605  const EMRCHORD *lpChord = (const EMRCHORD *)mr;
1606 
1607  Chord( hdc,
1608  (INT)lpChord->rclBox.left,
1609  (INT)lpChord->rclBox.top,
1610  (INT)lpChord->rclBox.right,
1611  (INT)lpChord->rclBox.bottom,
1612  (INT)lpChord->ptlStart.x,
1613  (INT)lpChord->ptlStart.y,
1614  (INT)lpChord->ptlEnd.x,
1615  (INT)lpChord->ptlEnd.y );
1616 
1617  break;
1618  }
1619 
1620  case EMR_PIE:
1621  {
1622  const EMRPIE *lpPie = (const EMRPIE *)mr;
1623 
1624  Pie( hdc,
1625  (INT)lpPie->rclBox.left,
1626  (INT)lpPie->rclBox.top,
1627  (INT)lpPie->rclBox.right,
1628  (INT)lpPie->rclBox.bottom,
1629  (INT)lpPie->ptlStart.x,
1630  (INT)lpPie->ptlStart.y,
1631  (INT)lpPie->ptlEnd.x,
1632  (INT)lpPie->ptlEnd.y );
1633 
1634  break;
1635  }
1636 
1637  case EMR_ARCTO:
1638  {
1639  const EMRARC *lpArcTo = (const EMRARC *)mr;
1640 
1641  ArcTo( hdc,
1642  (INT)lpArcTo->rclBox.left,
1643  (INT)lpArcTo->rclBox.top,
1644  (INT)lpArcTo->rclBox.right,
1645  (INT)lpArcTo->rclBox.bottom,
1646  (INT)lpArcTo->ptlStart.x,
1647  (INT)lpArcTo->ptlStart.y,
1648  (INT)lpArcTo->ptlEnd.x,
1649  (INT)lpArcTo->ptlEnd.y );
1650 
1651  break;
1652  }
1653 
1654  case EMR_EXTFLOODFILL:
1655  {
1656  const EMREXTFLOODFILL *lpExtFloodFill = (const EMREXTFLOODFILL *)mr;
1657 
1658  ExtFloodFill( hdc,
1659  (INT)lpExtFloodFill->ptlStart.x,
1660  (INT)lpExtFloodFill->ptlStart.y,
1661  lpExtFloodFill->crColor,
1662  (UINT)lpExtFloodFill->iMode );
1663 
1664  break;
1665  }
1666 
1667  case EMR_POLYDRAW:
1668  {
1669  const EMRPOLYDRAW *lpPolyDraw = (const EMRPOLYDRAW *)mr;
1670  PolyDraw( hdc,
1671  (const POINT*)lpPolyDraw->aptl,
1672  lpPolyDraw->abTypes,
1673  (INT)lpPolyDraw->cptl );
1674 
1675  break;
1676  }
1677 
1678  case EMR_SETARCDIRECTION:
1679  {
1680  const EMRSETARCDIRECTION *lpSetArcDirection = (const EMRSETARCDIRECTION *)mr;
1681  SetArcDirection( hdc, (INT)lpSetArcDirection->iArcDirection );
1682  break;
1683  }
1684 
1685  case EMR_SETMITERLIMIT:
1686  {
1687  const EMRSETMITERLIMIT *lpSetMiterLimit = (const EMRSETMITERLIMIT *)mr;
1688  SetMiterLimit( hdc, lpSetMiterLimit->eMiterLimit, NULL );
1689  break;
1690  }
1691 
1692  case EMR_BEGINPATH:
1693  {
1694  BeginPath( hdc );
1695  break;
1696  }
1697 
1698  case EMR_ENDPATH:
1699  {
1700  EndPath( hdc );
1701  break;
1702  }
1703 
1704  case EMR_CLOSEFIGURE:
1705  {
1706  CloseFigure( hdc );
1707  break;
1708  }
1709 
1710  case EMR_FILLPATH:
1711  {
1712  /*const EMRFILLPATH lpFillPath = (const EMRFILLPATH *)mr;*/
1713  FillPath( hdc );
1714  break;
1715  }
1716 
1717  case EMR_STROKEANDFILLPATH:
1718  {
1719  /*const EMRSTROKEANDFILLPATH lpStrokeAndFillPath = (const EMRSTROKEANDFILLPATH *)mr;*/
1721  break;
1722  }
1723 
1724  case EMR_STROKEPATH:
1725  {
1726  /*const EMRSTROKEPATH lpStrokePath = (const EMRSTROKEPATH *)mr;*/
1727  StrokePath( hdc );
1728  break;
1729  }
1730 
1731  case EMR_FLATTENPATH:
1732  {
1733  FlattenPath( hdc );
1734  break;
1735  }
1736 
1737  case EMR_WIDENPATH:
1738  {
1739  WidenPath( hdc );
1740  break;
1741  }
1742 
1743  case EMR_SELECTCLIPPATH:
1744  {
1745  const EMRSELECTCLIPPATH *lpSelectClipPath = (const EMRSELECTCLIPPATH *)mr;
1746  SelectClipPath( hdc, (INT)lpSelectClipPath->iMode );
1747  break;
1748  }
1749 
1750  case EMR_ABORTPATH:
1751  {
1752  AbortPath( hdc );
1753  break;
1754  }
1755 
1756  case EMR_CREATECOLORSPACE:
1757  {
1758  PEMRCREATECOLORSPACE lpCreateColorSpace = (PEMRCREATECOLORSPACE)mr;
1759  (handletable->objectHandle)[lpCreateColorSpace->ihCS] =
1760  CreateColorSpaceA( &lpCreateColorSpace->lcs );
1761  break;
1762  }
1763 
1764  case EMR_SETCOLORSPACE:
1765  {
1766  const EMRSETCOLORSPACE *lpSetColorSpace = (const EMRSETCOLORSPACE *)mr;
1767  SetColorSpace( hdc,
1768  (handletable->objectHandle)[lpSetColorSpace->ihCS] );
1769  break;
1770  }
1771 
1772  case EMR_DELETECOLORSPACE:
1773  {
1774  const EMRDELETECOLORSPACE *lpDeleteColorSpace = (const EMRDELETECOLORSPACE *)mr;
1775  DeleteColorSpace( (handletable->objectHandle)[lpDeleteColorSpace->ihCS] );
1776  break;
1777  }
1778 
1779  case EMR_SETICMMODE:
1780  {
1781  const EMRSETICMMODE *lpSetICMMode = (const EMRSETICMMODE *)mr;
1782  SetICMMode( hdc, (INT)lpSetICMMode->iMode );
1783  break;
1784  }
1785 
1786  case EMR_PIXELFORMAT:
1787  {
1788  INT iPixelFormat;
1789  const EMRPIXELFORMAT *lpPixelFormat = (const EMRPIXELFORMAT *)mr;
1790 
1791  iPixelFormat = ChoosePixelFormat( hdc, &lpPixelFormat->pfd );
1792  SetPixelFormat( hdc, iPixelFormat, &lpPixelFormat->pfd );
1793 
1794  break;
1795  }
1796 
1797  case EMR_SETPALETTEENTRIES:
1798  {
1799  const EMRSETPALETTEENTRIES *lpSetPaletteEntries = (const EMRSETPALETTEENTRIES *)mr;
1800 
1801  SetPaletteEntries( (handletable->objectHandle)[lpSetPaletteEntries->ihPal],
1802  (UINT)lpSetPaletteEntries->iStart,
1803  (UINT)lpSetPaletteEntries->cEntries,
1804  lpSetPaletteEntries->aPalEntries );
1805 
1806  break;
1807  }
1808 
1809  case EMR_RESIZEPALETTE:
1810  {
1811  const EMRRESIZEPALETTE *lpResizePalette = (const EMRRESIZEPALETTE *)mr;
1812 
1813  ResizePalette( (handletable->objectHandle)[lpResizePalette->ihPal],
1814  (UINT)lpResizePalette->cEntries );
1815 
1816  break;
1817  }
1818 
1820  {
1821  const EMRCREATEDIBPATTERNBRUSHPT *lpCreate = (const EMRCREATEDIBPATTERNBRUSHPT *)mr;
1822  LPVOID lpPackedStruct;
1823 
1824  /* Check that offsets and data are contained within the record
1825  * (including checking for wrap-arounds).
1826  */
1827  if ( lpCreate->offBmi + lpCreate->cbBmi > mr->nSize
1828  || lpCreate->offBits + lpCreate->cbBits > mr->nSize
1829  || lpCreate->offBmi + lpCreate->cbBmi < lpCreate->offBmi
1830  || lpCreate->offBits + lpCreate->cbBits < lpCreate->offBits )
1831  {
1832  ERR("Invalid EMR_CREATEDIBPATTERNBRUSHPT record\n");
1833  break;
1834  }
1835 
1836  /* This is a BITMAPINFO struct followed directly by bitmap bits */
1837  lpPackedStruct = HeapAlloc( GetProcessHeap(), 0,
1838  lpCreate->cbBmi + lpCreate->cbBits );
1839  if(!lpPackedStruct)
1840  {
1842  break;
1843  }
1844 
1845  /* Now pack this structure */
1846  memcpy( lpPackedStruct,
1847  ((const BYTE *)lpCreate) + lpCreate->offBmi,
1848  lpCreate->cbBmi );
1849  memcpy( ((BYTE*)lpPackedStruct) + lpCreate->cbBmi,
1850  ((const BYTE *)lpCreate) + lpCreate->offBits,
1851  lpCreate->cbBits );
1852 
1853  (handletable->objectHandle)[lpCreate->ihBrush] =
1854  CreateDIBPatternBrushPt( lpPackedStruct,
1855  (UINT)lpCreate->iUsage );
1856 
1857  HeapFree(GetProcessHeap(), 0, lpPackedStruct);
1858  break;
1859  }
1860 
1861  case EMR_CREATEMONOBRUSH:
1862  {
1863  const EMRCREATEMONOBRUSH *pCreateMonoBrush = (const EMRCREATEMONOBRUSH *)mr;
1864  const BITMAPINFO *pbi = (const BITMAPINFO *)((const BYTE *)mr + pCreateMonoBrush->offBmi);
1865  HBITMAP hBmp;
1866 
1867  /* Need to check if the bitmap is monochrome, and if the
1868  two colors are really black and white */
1869  if (pCreateMonoBrush->iUsage == DIB_PAL_MONO)
1870  {
1871  BITMAP bm;
1872 
1873  /* Undocumented iUsage indicates a mono bitmap with no palette table,
1874  * aligned to 32 rather than 16 bits.
1875  */
1876  bm.bmType = 0;
1877  bm.bmWidth = pbi->bmiHeader.biWidth;
1878  bm.bmHeight = abs(pbi->bmiHeader.biHeight);
1879  bm.bmWidthBytes = 4 * ((pbi->bmiHeader.biWidth + 31) / 32);
1880  bm.bmPlanes = pbi->bmiHeader.biPlanes;
1881  bm.bmBitsPixel = pbi->bmiHeader.biBitCount;
1882  bm.bmBits = (BYTE *)mr + pCreateMonoBrush->offBits;
1883  hBmp = CreateBitmapIndirect(&bm);
1884  }
1885  else if (is_dib_monochrome(pbi))
1886  {
1887  /* Top-down DIBs have a negative height */
1888  LONG height = pbi->bmiHeader.biHeight;
1889 
1890  hBmp = CreateBitmap(pbi->bmiHeader.biWidth, abs(height), 1, 1, NULL);
1891  SetDIBits(hdc, hBmp, 0, pbi->bmiHeader.biHeight,
1892  (const BYTE *)mr + pCreateMonoBrush->offBits, pbi, pCreateMonoBrush->iUsage);
1893  }
1894  else
1895  {
1896  hBmp = CreateDIBitmap(hdc, (const BITMAPINFOHEADER *)pbi, CBM_INIT,
1897  (const BYTE *)mr + pCreateMonoBrush->offBits, pbi, pCreateMonoBrush->iUsage);
1898  }
1899 
1900  (handletable->objectHandle)[pCreateMonoBrush->ihBrush] = CreatePatternBrush(hBmp);
1901 
1902  /* CreatePatternBrush created a copy of the bitmap */
1903  DeleteObject(hBmp);
1904  break;
1905  }
1906 
1907  case EMR_BITBLT:
1908  {
1909  const EMRBITBLT *pBitBlt = (const EMRBITBLT *)mr;
1910 
1911  if(pBitBlt->offBmiSrc == 0) { /* Record is a PatBlt */
1912  PatBlt(hdc, pBitBlt->xDest, pBitBlt->yDest, pBitBlt->cxDest, pBitBlt->cyDest,
1913  pBitBlt->dwRop);
1914  } else { /* BitBlt */
1916  HBRUSH hBrush, hBrushOld;
1917  HBITMAP hBmp = 0, hBmpOld = 0;
1918  const BITMAPINFO *pbi = (const BITMAPINFO *)((const BYTE *)mr + pBitBlt->offBmiSrc);
1919 
1921  SetWorldTransform(hdcSrc, &pBitBlt->xformSrc);
1922 
1923  hBrush = CreateSolidBrush(pBitBlt->crBkColorSrc);
1924  hBrushOld = SelectObject(hdcSrc, hBrush);
1925  PatBlt(hdcSrc, pBitBlt->rclBounds.left, pBitBlt->rclBounds.top,
1926  pBitBlt->rclBounds.right - pBitBlt->rclBounds.left,
1927  pBitBlt->rclBounds.bottom - pBitBlt->rclBounds.top, PATCOPY);
1928  SelectObject(hdcSrc, hBrushOld);
1929  DeleteObject(hBrush);
1930 
1931  hBmp = CreateDIBitmap(hdc, (const BITMAPINFOHEADER *)pbi, CBM_INIT,
1932  (const BYTE *)mr + pBitBlt->offBitsSrc, pbi, pBitBlt->iUsageSrc);
1933  hBmpOld = SelectObject(hdcSrc, hBmp);
1934 
1935  BitBlt(hdc, pBitBlt->xDest, pBitBlt->yDest, pBitBlt->cxDest, pBitBlt->cyDest,
1936  hdcSrc, pBitBlt->xSrc, pBitBlt->ySrc, pBitBlt->dwRop);
1937 
1938  SelectObject(hdcSrc, hBmpOld);
1939  DeleteObject(hBmp);
1940  DeleteDC(hdcSrc);
1941  }
1942  break;
1943  }
1944 
1945  case EMR_STRETCHBLT:
1946  {
1947  const EMRSTRETCHBLT *pStretchBlt = (const EMRSTRETCHBLT *)mr;
1948 
1949  TRACE("EMR_STRETCHBLT: %d, %d %dx%d -> %d, %d %dx%d. rop %08x offBitsSrc %d\n",
1950  pStretchBlt->xSrc, pStretchBlt->ySrc, pStretchBlt->cxSrc, pStretchBlt->cySrc,
1951  pStretchBlt->xDest, pStretchBlt->yDest, pStretchBlt->cxDest, pStretchBlt->cyDest,
1952  pStretchBlt->dwRop, pStretchBlt->offBitsSrc);
1953 
1954  if(pStretchBlt->offBmiSrc == 0) { /* Record is a PatBlt */
1955  PatBlt(hdc, pStretchBlt->xDest, pStretchBlt->yDest, pStretchBlt->cxDest, pStretchBlt->cyDest,
1956  pStretchBlt->dwRop);
1957  } else { /* StretchBlt */
1959  HBRUSH hBrush, hBrushOld;
1960  HBITMAP hBmp = 0, hBmpOld = 0;
1961  const BITMAPINFO *pbi = (const BITMAPINFO *)((const BYTE *)mr + pStretchBlt->offBmiSrc);
1962 
1964  SetWorldTransform(hdcSrc, &pStretchBlt->xformSrc);
1965 
1966  hBrush = CreateSolidBrush(pStretchBlt->crBkColorSrc);
1967  hBrushOld = SelectObject(hdcSrc, hBrush);
1968  PatBlt(hdcSrc, pStretchBlt->rclBounds.left, pStretchBlt->rclBounds.top,
1969  pStretchBlt->rclBounds.right - pStretchBlt->rclBounds.left,
1970  pStretchBlt->rclBounds.bottom - pStretchBlt->rclBounds.top, PATCOPY);
1971  SelectObject(hdcSrc, hBrushOld);
1972  DeleteObject(hBrush);
1973 
1974  hBmp = CreateDIBitmap(hdc, (const BITMAPINFOHEADER *)pbi, CBM_INIT,
1975  (const BYTE *)mr + pStretchBlt->offBitsSrc, pbi, pStretchBlt->iUsageSrc);
1976  hBmpOld = SelectObject(hdcSrc, hBmp);
1977 
1978  StretchBlt(hdc, pStretchBlt->xDest, pStretchBlt->yDest, pStretchBlt->cxDest, pStretchBlt->cyDest,
1979  hdcSrc, pStretchBlt->xSrc, pStretchBlt->ySrc, pStretchBlt->cxSrc, pStretchBlt->cySrc,
1980  pStretchBlt->dwRop);
1981 
1982  SelectObject(hdcSrc, hBmpOld);
1983  DeleteObject(hBmp);
1984  DeleteDC(hdcSrc);
1985  }
1986  break;
1987  }
1988 
1989  case EMR_ALPHABLEND:
1990  {
1991  const EMRALPHABLEND *pAlphaBlend = (const EMRALPHABLEND *)mr;
1992 
1993  TRACE("EMR_ALPHABLEND: %d, %d %dx%d -> %d, %d %dx%d. blendfn %08x offBitsSrc %d\n",
1994  pAlphaBlend->xSrc, pAlphaBlend->ySrc, pAlphaBlend->cxSrc, pAlphaBlend->cySrc,
1995  pAlphaBlend->xDest, pAlphaBlend->yDest, pAlphaBlend->cxDest, pAlphaBlend->cyDest,
1996  pAlphaBlend->dwRop, pAlphaBlend->offBitsSrc);
1997 
1998  if(pAlphaBlend->offBmiSrc == 0) {
1999  FIXME("EMR_ALPHABLEND: offBmiSrc == 0\n");
2000  } else {
2002  HBITMAP hBmp = 0, hBmpOld = 0;
2003  const BITMAPINFO *pbi = (const BITMAPINFO *)((const BYTE *)mr + pAlphaBlend->offBmiSrc);
2004  void *bits;
2005 
2007  SetWorldTransform(hdcSrc, &pAlphaBlend->xformSrc);
2008 
2009  hBmp = CreateDIBSection(hdc, pbi, pAlphaBlend->iUsageSrc, &bits, NULL, 0);
2010  memcpy(bits, (const BYTE *)mr + pAlphaBlend->offBitsSrc, pAlphaBlend->cbBitsSrc);
2011  hBmpOld = SelectObject(hdcSrc, hBmp);
2012 
2013  GdiAlphaBlend(hdc, pAlphaBlend->xDest, pAlphaBlend->yDest, pAlphaBlend->cxDest, pAlphaBlend->cyDest,
2014  hdcSrc, pAlphaBlend->xSrc, pAlphaBlend->ySrc, pAlphaBlend->cxSrc, pAlphaBlend->cySrc,
2015  *(BLENDFUNCTION *)&pAlphaBlend->dwRop);
2016 
2017  SelectObject(hdcSrc, hBmpOld);
2018  DeleteObject(hBmp);
2019  DeleteDC(hdcSrc);
2020  }
2021  break;
2022  }
2023 
2024  case EMR_MASKBLT:
2025  {
2026  const EMRMASKBLT *pMaskBlt = (const EMRMASKBLT *)mr;
2028  HBRUSH hBrush, hBrushOld;
2029  HBITMAP hBmp, hBmpOld, hBmpMask;
2030  const BITMAPINFO *pbi;
2031 
2033  SetWorldTransform(hdcSrc, &pMaskBlt->xformSrc);
2034 
2035  hBrush = CreateSolidBrush(pMaskBlt->crBkColorSrc);
2036  hBrushOld = SelectObject(hdcSrc, hBrush);
2037  PatBlt(hdcSrc, pMaskBlt->rclBounds.left, pMaskBlt->rclBounds.top,
2038  pMaskBlt->rclBounds.right - pMaskBlt->rclBounds.left,
2039  pMaskBlt->rclBounds.bottom - pMaskBlt->rclBounds.top, PATCOPY);
2040  SelectObject(hdcSrc, hBrushOld);
2041  DeleteObject(hBrush);
2042 
2043  pbi = (const BITMAPINFO *)((const BYTE *)mr + pMaskBlt->offBmiMask);
2044  hBmpMask = CreateBitmap(pbi->bmiHeader.biWidth, pbi->bmiHeader.biHeight,
2045  1, 1, NULL);
2046  SetDIBits(hdc, hBmpMask, 0, pbi->bmiHeader.biHeight,
2047  (const BYTE *)mr + pMaskBlt->offBitsMask, pbi, pMaskBlt->iUsageMask);
2048 
2049  pbi = (const BITMAPINFO *)((const BYTE *)mr + pMaskBlt->offBmiSrc);
2050  hBmp = CreateDIBitmap(hdc, (const BITMAPINFOHEADER *)pbi, CBM_INIT,
2051  (const BYTE *)mr + pMaskBlt->offBitsSrc, pbi, pMaskBlt->iUsageSrc);
2052  hBmpOld = SelectObject(hdcSrc, hBmp);
2053  MaskBlt(hdc,
2054  pMaskBlt->xDest,
2055  pMaskBlt->yDest,
2056  pMaskBlt->cxDest,
2057  pMaskBlt->cyDest,
2058  hdcSrc,
2059  pMaskBlt->xSrc,
2060  pMaskBlt->ySrc,
2061  hBmpMask,
2062  pMaskBlt->xMask,
2063  pMaskBlt->yMask,
2064  pMaskBlt->dwRop);
2065  SelectObject(hdcSrc, hBmpOld);
2066  DeleteObject(hBmp);
2067  DeleteObject(hBmpMask);
2068  DeleteDC(hdcSrc);
2069  break;
2070  }
2071 
2072  case EMR_PLGBLT:
2073  {
2074  const EMRPLGBLT *pPlgBlt = (const EMRPLGBLT *)mr;
2076  HBRUSH hBrush, hBrushOld;
2077  HBITMAP hBmp, hBmpOld, hBmpMask;
2078  const BITMAPINFO *pbi;
2079  POINT pts[3];
2080 
2082  SetWorldTransform(hdcSrc, &pPlgBlt->xformSrc);
2083 
2084  pts[0].x = pPlgBlt->aptlDest[0].x; pts[0].y = pPlgBlt->aptlDest[0].y;
2085  pts[1].x = pPlgBlt->aptlDest[1].x; pts[1].y = pPlgBlt->aptlDest[1].y;
2086  pts[2].x = pPlgBlt->aptlDest[2].x; pts[2].y = pPlgBlt->aptlDest[2].y;
2087 
2088  hBrush = CreateSolidBrush(pPlgBlt->crBkColorSrc);
2089  hBrushOld = SelectObject(hdcSrc, hBrush);
2090  PatBlt(hdcSrc, pPlgBlt->rclBounds.left, pPlgBlt->rclBounds.top,
2091  pPlgBlt->rclBounds.right - pPlgBlt->rclBounds.left,
2092  pPlgBlt->rclBounds.bottom - pPlgBlt->rclBounds.top, PATCOPY);
2093  SelectObject(hdcSrc, hBrushOld);
2094  DeleteObject(hBrush);
2095 
2096  pbi = (const BITMAPINFO *)((const BYTE *)mr + pPlgBlt->offBmiMask);
2097  hBmpMask = CreateBitmap(pbi->bmiHeader.biWidth, pbi->bmiHeader.biHeight,
2098  1, 1, NULL);
2099  SetDIBits(hdc, hBmpMask, 0, pbi->bmiHeader.biHeight,
2100  (const BYTE *)mr + pPlgBlt->offBitsMask, pbi, pPlgBlt->iUsageMask);
2101 
2102  pbi = (const BITMAPINFO *)((const BYTE *)mr + pPlgBlt->offBmiSrc);
2103  hBmp = CreateDIBitmap(hdc, (const BITMAPINFOHEADER *)pbi, CBM_INIT,
2104  (const BYTE *)mr + pPlgBlt->offBitsSrc, pbi, pPlgBlt->iUsageSrc);
2105  hBmpOld = SelectObject(hdcSrc, hBmp);
2106  PlgBlt(hdc,
2107  pts,
2108  hdcSrc,
2109  pPlgBlt->xSrc,
2110  pPlgBlt->ySrc,
2111  pPlgBlt->cxSrc,
2112  pPlgBlt->cySrc,
2113  hBmpMask,
2114  pPlgBlt->xMask,
2115  pPlgBlt->yMask);
2116  SelectObject(hdcSrc, hBmpOld);
2117  DeleteObject(hBmp);
2118  DeleteObject(hBmpMask);
2119  DeleteDC(hdcSrc);
2120  break;
2121  }
2122 
2123  case EMR_SETDIBITSTODEVICE:
2124  {
2125  const EMRSETDIBITSTODEVICE *pSetDIBitsToDevice = (const EMRSETDIBITSTODEVICE *)mr;
2126 
2128  pSetDIBitsToDevice->xDest,
2129  pSetDIBitsToDevice->yDest,
2130  pSetDIBitsToDevice->cxSrc,
2131  pSetDIBitsToDevice->cySrc,
2132  pSetDIBitsToDevice->xSrc,
2133  pSetDIBitsToDevice->ySrc,
2134  pSetDIBitsToDevice->iStartScan,
2135  pSetDIBitsToDevice->cScans,
2136  (const BYTE *)mr + pSetDIBitsToDevice->offBitsSrc,
2137  (const BITMAPINFO *)((const BYTE *)mr + pSetDIBitsToDevice->offBmiSrc),
2138  pSetDIBitsToDevice->iUsageSrc);
2139  break;
2140  }
2141 
2142  case EMR_POLYTEXTOUTA:
2143  {
2144  const EMRPOLYTEXTOUTA *pPolyTextOutA = (const EMRPOLYTEXTOUTA *)mr;
2145  POLYTEXTA *polytextA = HeapAlloc(GetProcessHeap(), 0, pPolyTextOutA->cStrings * sizeof(POLYTEXTA));
2146  LONG i;
2147  XFORM xform, xformOld;
2148  int gModeOld;
2149 
2150  gModeOld = SetGraphicsMode(hdc, pPolyTextOutA->iGraphicsMode);
2151  GetWorldTransform(hdc, &xformOld);
2152 
2153  xform.eM11 = pPolyTextOutA->exScale;
2154  xform.eM12 = 0.0;
2155  xform.eM21 = 0.0;
2156  xform.eM22 = pPolyTextOutA->eyScale;
2157  xform.eDx = 0.0;
2158  xform.eDy = 0.0;
2159  SetWorldTransform(hdc, &xform);
2160 
2161  /* Set up POLYTEXTA structures */
2162  for(i = 0; i < pPolyTextOutA->cStrings; i++)
2163  {
2164  polytextA[i].x = pPolyTextOutA->aemrtext[i].ptlReference.x;
2165  polytextA[i].y = pPolyTextOutA->aemrtext[i].ptlReference.y;
2166  polytextA[i].n = pPolyTextOutA->aemrtext[i].nChars;
2167  polytextA[i].lpstr = (LPCSTR)((const BYTE *)mr + pPolyTextOutA->aemrtext[i].offString);
2168  polytextA[i].uiFlags = pPolyTextOutA->aemrtext[i].fOptions;
2169  polytextA[i].rcl.left = pPolyTextOutA->aemrtext[i].rcl.left;
2170  polytextA[i].rcl.right = pPolyTextOutA->aemrtext[i].rcl.right;
2171  polytextA[i].rcl.top = pPolyTextOutA->aemrtext[i].rcl.top;
2172  polytextA[i].rcl.bottom = pPolyTextOutA->aemrtext[i].rcl.bottom;
2173  polytextA[i].pdx = (int *)((BYTE *)mr + pPolyTextOutA->aemrtext[i].offDx);
2174  }
2175  PolyTextOutA(hdc, polytextA, pPolyTextOutA->cStrings);
2176  HeapFree(GetProcessHeap(), 0, polytextA);
2177 
2178  SetWorldTransform(hdc, &xformOld);
2179  SetGraphicsMode(hdc, gModeOld);
2180  break;
2181  }
2182 
2183  case EMR_POLYTEXTOUTW:
2184  {
2185  const EMRPOLYTEXTOUTW *pPolyTextOutW = (const EMRPOLYTEXTOUTW *)mr;
2186  POLYTEXTW *polytextW = HeapAlloc(GetProcessHeap(), 0, pPolyTextOutW->cStrings * sizeof(POLYTEXTW));
2187  LONG i;
2188  XFORM xform, xformOld;
2189  int gModeOld;
2190 
2191  gModeOld = SetGraphicsMode(hdc, pPolyTextOutW->iGraphicsMode);
2192  GetWorldTransform(hdc, &xformOld);
2193 
2194  xform.eM11 = pPolyTextOutW->exScale;
2195  xform.eM12 = 0.0;
2196  xform.eM21 = 0.0;
2197  xform.eM22 = pPolyTextOutW->eyScale;
2198  xform.eDx = 0.0;
2199  xform.eDy = 0.0;
2200  SetWorldTransform(hdc, &xform);
2201 
2202  /* Set up POLYTEXTW structures */
2203  for(i = 0; i < pPolyTextOutW->cStrings; i++)
2204  {
2205  polytextW[i].x = pPolyTextOutW->aemrtext[i].ptlReference.x;
2206  polytextW[i].y = pPolyTextOutW->aemrtext[i].ptlReference.y;
2207  polytextW[i].n = pPolyTextOutW->aemrtext[i].nChars;
2208  polytextW[i].lpstr = (LPCWSTR)((const BYTE *)mr + pPolyTextOutW->aemrtext[i].offString);
2209  polytextW[i].uiFlags = pPolyTextOutW->aemrtext[i].fOptions;
2210  polytextW[i].rcl.left = pPolyTextOutW->aemrtext[i].rcl.left;
2211  polytextW[i].rcl.right = pPolyTextOutW->aemrtext[i].rcl.right;
2212  polytextW[i].rcl.top = pPolyTextOutW->aemrtext[i].rcl.top;
2213  polytextW[i].rcl.bottom = pPolyTextOutW->aemrtext[i].rcl.bottom;
2214  polytextW[i].pdx = (int *)((BYTE *)mr + pPolyTextOutW->aemrtext[i].offDx);
2215  }
2216  PolyTextOutW(hdc, polytextW, pPolyTextOutW->cStrings);
2217  HeapFree(GetProcessHeap(), 0, polytextW);
2218 
2219  SetWorldTransform(hdc, &xformOld);
2220  SetGraphicsMode(hdc, gModeOld);
2221  break;
2222  }
2223 
2224  case EMR_FILLRGN:
2225  {
2226  const EMRFILLRGN *pFillRgn = (const EMRFILLRGN *)mr;
2227  HRGN hRgn = ExtCreateRegion(NULL, pFillRgn->cbRgnData, (const RGNDATA *)pFillRgn->RgnData);
2228  FillRgn(hdc,
2229  hRgn,
2230  (handletable->objectHandle)[pFillRgn->ihBrush]);
2231  DeleteObject(hRgn);
2232  break;
2233  }
2234 
2235  case EMR_FRAMERGN:
2236  {
2237  const EMRFRAMERGN *pFrameRgn = (const EMRFRAMERGN *)mr;
2238  HRGN hRgn = ExtCreateRegion(NULL, pFrameRgn->cbRgnData, (const RGNDATA *)pFrameRgn->RgnData);
2239  FrameRgn(hdc,
2240  hRgn,
2241  (handletable->objectHandle)[pFrameRgn->ihBrush],
2242  pFrameRgn->szlStroke.cx,
2243  pFrameRgn->szlStroke.cy);
2244  DeleteObject(hRgn);
2245  break;
2246  }
2247 
2248  case EMR_INVERTRGN:
2249  {
2250  const EMRINVERTRGN *pInvertRgn = (const EMRINVERTRGN *)mr;
2251  HRGN hRgn = ExtCreateRegion(NULL, pInvertRgn->cbRgnData, (const RGNDATA *)pInvertRgn->RgnData);
2252  InvertRgn(hdc, hRgn);
2253  DeleteObject(hRgn);
2254  break;
2255  }
2256 
2257  case EMR_PAINTRGN:
2258  {
2259  const EMRPAINTRGN *pPaintRgn = (const EMRPAINTRGN *)mr;
2260  HRGN hRgn = ExtCreateRegion(NULL, pPaintRgn->cbRgnData, (const RGNDATA *)pPaintRgn->RgnData);
2261  PaintRgn(hdc, hRgn);
2262  DeleteObject(hRgn);
2263  break;
2264  }
2265 
2266  case EMR_SETTEXTJUSTIFICATION:
2267  {
2268  const EMRSETTEXTJUSTIFICATION *pSetTextJust = (const EMRSETTEXTJUSTIFICATION *)mr;
2269  SetTextJustification(hdc, pSetTextJust->nBreakExtra, pSetTextJust->nBreakCount);
2270  break;
2271  }
2272 
2273  case EMR_SETLAYOUT:
2274  {
2275  const EMRSETLAYOUT *pSetLayout = (const EMRSETLAYOUT *)mr;
2276  SetLayout(hdc, pSetLayout->iMode);
2277  break;
2278  }
2279 
2280  case EMR_GRADIENTFILL:
2281  {
2282  EMRGRADIENTFILL *grad = (EMRGRADIENTFILL *)mr;
2283  GdiGradientFill( hdc, grad->Ver, grad->nVer, grad->Ver + grad->nVer,
2284  grad->nTri, grad->ulMode );
2285  break;
2286  }
2287 
2288  case EMR_DRAWESCAPE:
2289  {
2290  PEMRESCAPE pemr = (PEMRESCAPE)mr;
2291  DrawEscape( hdc, pemr->iEsc, pemr->cjIn, (LPCSTR)pemr->Data );
2292  break;
2293  }
2294 
2295  case EMR_EXTESCAPE:
2296  {
2297  PEMRESCAPE pemr = (PEMRESCAPE)mr;
2298  ExtEscape( hdc, pemr->iEsc, pemr->cjIn, (LPCSTR)pemr->Data, 0, NULL );
2299  break;
2300  }
2301 
2302  case EMR_NAMEDESCAPE:
2303  {
2304  PEMRNAMEDESCAPE pemr = (PEMRNAMEDESCAPE)mr;
2305  INT rounded_size = (pemr->cjIn+3) & ~3;
2306  NamedEscape( hdc, (PWCHAR)&pemr->Data[rounded_size], pemr->iEsc, pemr->cjIn, (LPSTR)pemr->Data, 0, NULL );
2307  break;
2308  }
2309 
2310  case EMR_GLSRECORD:
2311  case EMR_GLSBOUNDEDRECORD:
2312  case EMR_STARTDOC:
2313  case EMR_SMALLTEXTOUT:
2314  case EMR_FORCEUFIMAPPING:
2315  case EMR_COLORCORRECTPALETTE:
2316  case EMR_SETICMPROFILEA:
2317  case EMR_SETICMPROFILEW:
2318  case EMR_TRANSPARENTBLT:
2319  case EMR_SETLINKEDUFI:
2320  case EMR_COLORMATCHTOTARGETW:
2321  case EMR_CREATECOLORSPACEW:
2322 
2323  default:
2324  /* From docs: If PlayEnhMetaFileRecord doesn't recognize a
2325  record then ignore and return TRUE. */
2326  FIXME("type %d is unimplemented\n", type);
2327  break;
2328  }
2329  tmprc.left = tmprc.top = 0;
2330  tmprc.right = tmprc.bottom = 1000;
2331  LPtoDP(hdc, (POINT*)&tmprc, 2);
2332  TRACE("L:0,0 - 1000,1000 -> D:%s\n", wine_dbgstr_rect(&tmprc));
2333 
2334  return TRUE;
2335 }
2336 
2337 /*****************************************************************************
2338  *
2339  * EnumEnhMetaFile (GDI32.@)
2340  *
2341  * Walk an enhanced metafile, calling a user-specified function _EnhMetaFunc_
2342  * for each
2343  * record. Returns when either every record has been used or
2344  * when _EnhMetaFunc_ returns FALSE.
2345  *
2346  *
2347  * RETURNS
2348  * TRUE if every record is used, FALSE if any invocation of _EnhMetaFunc_
2349  * returns FALSE.
2350  *
2351  * BUGS
2352  * Ignores rect.
2353  *
2354  * NOTES
2355  * This function behaves differently in Win9x and WinNT.
2356  *
2357  * In WinNT, the DC's world transform is updated as the EMF changes
2358  * the Window/Viewport Extent and Origin or its world transform.
2359  * The actual Window/Viewport Extent and Origin are left untouched.
2360  *
2361  * In Win9x, the DC is left untouched, and PlayEnhMetaFileRecord
2362  * updates the scaling itself but only just before a record that
2363  * writes anything to the DC.
2364  *
2365  * I'm not sure where the data (enum_emh_data) is stored in either
2366  * version. For this implementation, it is stored before the handle
2367  * table, but it could be stored in the DC, in the EMF handle or in
2368  * TLS.
2369  * MJM 5 Oct 2002
2370  */
2372  HDC hdc, /* [in] device context to pass to _EnhMetaFunc_ */
2373  HENHMETAFILE hmf, /* [in] EMF to walk */
2374  ENHMFENUMPROC callback, /* [in] callback function */
2375  LPVOID data, /* [in] optional data for callback function */
2376  const RECT *lpRect /* [in] bounding rectangle for rendered metafile */
2377  )
2378 {
2379  BOOL ret;
2380  ENHMETAHEADER *emh;
2381  ENHMETARECORD *emr;
2382  DWORD offset;
2383  UINT i;
2384  HANDLETABLE *ht;
2385  INT savedMode = 0;
2386  XFORM savedXform;
2387  HPEN hPen = NULL;
2388  HBRUSH hBrush = NULL;
2389  HFONT hFont = NULL;
2390  HRGN hRgn = NULL;
2392  SIZE vp_size, win_size;
2393  POINT vp_org, win_org;
2394  INT mapMode = MM_TEXT, old_align = 0, old_rop2 = 0, old_arcdir = 0, old_polyfill = 0, old_stretchblt = 0;
2395  COLORREF old_text_color = 0, old_bk_color = 0;
2396 
2397  if(!lpRect && hdc)
2398  {
2400  return FALSE;
2401  }
2402 
2403  emh = EMF_GetEnhMetaHeader(hmf);
2404  if(!emh) {
2406  return FALSE;
2407  }
2408 
2409  info = HeapAlloc( GetProcessHeap(), 0,
2410  sizeof (enum_emh_data) + sizeof(HANDLETABLE) * emh->nHandles );
2411  if(!info)
2412  {
2414  return FALSE;
2415  }
2416  info->state.mode = MM_TEXT;
2417  info->state.wndOrgX = 0;
2418  info->state.wndOrgY = 0;
2419  info->state.wndExtX = 1;
2420  info->state.wndExtY = 1;
2421  info->state.vportOrgX = 0;
2422  info->state.vportOrgY = 0;
2423  info->state.vportExtX = 1;
2424  info->state.vportExtY = 1;
2425  info->state.world_transform.eM11 = info->state.world_transform.eM22 = 1;
2426  info->state.world_transform.eM12 = info->state.world_transform.eM21 = 0;
2427  info->state.world_transform.eDx = info->state.world_transform.eDy = 0;
2428 
2429  info->state.next = NULL;
2430  info->save_level = 0;
2431  info->saved_state = NULL;
2432  info->init_transform = info->state.world_transform;
2433 
2434  ht = (HANDLETABLE*) &info[1];
2435  ht->objectHandle[0] = hmf;
2436  for(i = 1; i < emh->nHandles; i++)
2437  ht->objectHandle[i] = NULL;
2438 
2439  if(hdc && !is_meta_dc( hdc ))
2440  {
2441  savedMode = SetGraphicsMode(hdc, GM_ADVANCED);
2442  GetWorldTransform(hdc, &savedXform);
2443  GetViewportExtEx(hdc, &vp_size);
2444  GetWindowExtEx(hdc, &win_size);
2445  GetViewportOrgEx(hdc, &vp_org);
2446  GetWindowOrgEx(hdc, &win_org);
2447  mapMode = GetMapMode(hdc);
2448 
2449  /* save DC */
2450  hPen = GetCurrentObject(hdc, OBJ_PEN);
2451  hBrush = GetCurrentObject(hdc, OBJ_BRUSH);
2453 
2454  hRgn = CreateRectRgn(0, 0, 0, 0);
2455  if (!GetClipRgn(hdc, hRgn))
2456  {
2457  DeleteObject(hRgn);
2458  hRgn = 0;
2459  }
2460 
2461  old_text_color = SetTextColor(hdc, RGB(0,0,0));
2462  old_bk_color = SetBkColor(hdc, RGB(0xff, 0xff, 0xff));
2463  old_align = SetTextAlign(hdc, 0);
2464  old_rop2 = SetROP2(hdc, R2_COPYPEN);
2465  old_arcdir = SetArcDirection(hdc, AD_COUNTERCLOCKWISE);
2466  old_polyfill = SetPolyFillMode(hdc, ALTERNATE);
2467  old_stretchblt = SetStretchBltMode(hdc, BLACKONWHITE);
2468 
2469  if (!IS_WIN9X() )
2470  {
2471  /* WinNT combines the vp/win ext/org info into a transform */
2472  double xscale, yscale;
2473  xscale = (double)vp_size.cx / (double)win_size.cx;
2474  yscale = (double)vp_size.cy / (double)win_size.cy;
2475  info->init_transform.eM11 = xscale;
2476  info->init_transform.eM12 = 0.0;
2477  info->init_transform.eM21 = 0.0;
2478  info->init_transform.eM22 = yscale;
2479  info->init_transform.eDx = (double)vp_org.x - xscale * (double)win_org.x;
2480  info->init_transform.eDy = (double)vp_org.y - yscale * (double)win_org.y;
2481 
2482  CombineTransform(&info->init_transform, &savedXform, &info->init_transform);
2483  }
2484 
2485  if ( lpRect && WIDTH(emh->rclFrame) && HEIGHT(emh->rclFrame) )
2486  {
2487  double xSrcPixSize, ySrcPixSize, xscale, yscale;
2488  XFORM xform;
2489 
2490  TRACE("rect: %s. rclFrame: (%d,%d)-(%d,%d)\n", wine_dbgstr_rect(lpRect),
2491  emh->rclFrame.left, emh->rclFrame.top, emh->rclFrame.right,
2492  emh->rclFrame.bottom);
2493 
2494  xSrcPixSize = (double) emh->szlMillimeters.cx / emh->szlDevice.cx;
2495  ySrcPixSize = (double) emh->szlMillimeters.cy / emh->szlDevice.cy;
2496  xscale = (double) WIDTH(*lpRect) * 100.0 /
2497  WIDTH(emh->rclFrame) * xSrcPixSize;
2498  yscale = (double) HEIGHT(*lpRect) * 100.0 /
2499  HEIGHT(emh->rclFrame) * ySrcPixSize;
2500  TRACE("xscale = %f, yscale = %f\n", xscale, yscale);
2501 
2502  xform.eM11 = xscale;
2503  xform.eM12 = 0;
2504  xform.eM21 = 0;
2505  xform.eM22 = yscale;
2506  xform.eDx = (double) lpRect->left - (double) WIDTH(*lpRect) / WIDTH(emh->rclFrame) * emh->rclFrame.left;
2507  xform.eDy = (double) lpRect->top - (double) HEIGHT(*lpRect) / HEIGHT(emh->rclFrame) * emh->rclFrame.top;
2508 
2509  CombineTransform(&info->init_transform, &xform, &info->init_transform);
2510  }
2511 
2512  /* WinNT resets the current vp/win org/ext */
2513  if ( !IS_WIN9X() )
2514  {
2516  SetWindowOrgEx(hdc, 0, 0, NULL);
2517  SetViewportOrgEx(hdc, 0, 0, NULL);
2519  }
2520  }
2521 
2522  ret = TRUE;
2523  offset = 0;
2524  while(ret && offset < emh->nBytes)
2525  {
2526  emr = (ENHMETARECORD *)((char *)emh + offset);
2527 
2528  if (offset + 8 > emh->nBytes ||
2529  offset > offset + emr->nSize ||
2530  offset + emr->nSize > emh->nBytes)
2531  {
2532  WARN("record truncated\n");
2533  break;
2534  }
2535 
2536  /* In Win9x mode we update the xform if the record will produce output */
2537  if (hdc && IS_WIN9X() && emr_produces_output(emr->iType))
2539 
2540  TRACE("Calling EnumFunc with record %s, size %d\n", get_emr_name(emr->iType), emr->nSize);
2541  ret = (*callback)(hdc, ht, emr, emh->nHandles, (LPARAM)data);
2542  offset += emr->nSize;
2543  }
2544 
2545  if (hdc && !is_meta_dc( hdc ))
2546  {
2547  SetStretchBltMode(hdc, old_stretchblt);
2548  SetPolyFillMode(hdc, old_polyfill);
2549  SetArcDirection(hdc, old_arcdir);
2550  SetROP2(hdc, old_rop2);
2551  SetTextAlign(hdc, old_align);
2552  SetBkColor(hdc, old_bk_color);
2553  SetTextColor(hdc, old_text_color);
2554 
2555  /* restore DC */
2556  SelectObject(hdc, hBrush);
2557  SelectObject(hdc, hPen);
2560  DeleteObject(hRgn);
2561 
2562  SetWorldTransform(hdc, &savedXform);
2563  if (savedMode)
2564  SetGraphicsMode(hdc, savedMode);
2565  SetMapMode(hdc, mapMode);
2566  SetWindowOrgEx(hdc, win_org.x, win_org.y, NULL);
2567  SetWindowExtEx(hdc, win_size.cx, win_size.cy, NULL);
2568  SetViewportOrgEx(hdc, vp_org.x, vp_org.y, NULL);
2569  SetViewportExtEx(hdc, vp_size.cx, vp_size.cy, NULL);
2570  }
2571 
2572  for(i = 1; i < emh->nHandles; i++) /* Don't delete element 0 (hmf) */
2573  if( (ht->objectHandle)[i] )
2574  DeleteObject( (ht->objectHandle)[i] );
2575 
2576  while (info->saved_state)
2577  {
2578  EMF_dc_state *state = info->saved_state;
2579  info->saved_state = info->saved_state->next;
2580  HeapFree( GetProcessHeap(), 0, state );
2581  }
2582  HeapFree( GetProcessHeap(), 0, info );
2583  return ret;
2584 }
2585 
2587  const ENHMETARECORD *emr,
2589 {
2590  return PlayEnhMetaFileRecord(hdc, ht, emr, handles);
2591 }
2592 
2593 /**************************************************************************
2594  * PlayEnhMetaFile (GDI32.@)
2595  *
2596  * Renders an enhanced metafile into a specified rectangle *lpRect
2597  * in device context hdc.
2598  *
2599  * RETURNS
2600  * Success: TRUE
2601  * Failure: FALSE
2602  */
2604  HDC hdc, /* [in] DC to render into */
2605  HENHMETAFILE hmf, /* [in] metafile to render */
2606  const RECT *lpRect /* [in] rectangle to place metafile inside */
2607  )
2608 {
2609  return EnumEnhMetaFile(hdc, hmf, EMF_PlayEnhMetaFileCallback, NULL, lpRect);
2610 }
2611 
2612 /*****************************************************************************
2613  * DeleteEnhMetaFile (GDI32.@)
2614  *
2615  * Deletes an enhanced metafile and frees the associated storage.
2616  */
2617 BOOL WINAPI DeleteEnhMetaFile(HENHMETAFILE hmf)
2618 {
2619  return EMF_Delete_HENHMETAFILE( hmf );
2620 }
2621 
2622 /*****************************************************************************
2623  * CopyEnhMetaFileA (GDI32.@)
2624  *
2625  * Duplicate an enhanced metafile.
2626  *
2627  *
2628  */
2630  HENHMETAFILE hmfSrc,
2631  LPCSTR file)
2632 {
2633  ENHMETAHEADER *emrSrc = EMF_GetEnhMetaHeader( hmfSrc ), *emrDst;
2634  HENHMETAFILE hmfDst;
2635 
2636  if(!emrSrc) return FALSE;
2637  if (!file) {
2638  emrDst = HeapAlloc( GetProcessHeap(), 0, emrSrc->nBytes );
2639  memcpy( emrDst, emrSrc, emrSrc->nBytes );
2640  hmfDst = EMF_Create_HENHMETAFILE( emrDst, emrSrc->nBytes, FALSE );
2641  if (!hmfDst)
2642  HeapFree( GetProcessHeap(), 0, emrDst );
2643  } else {
2644  HANDLE hFile;
2645  DWORD w;
2647  NULL, CREATE_ALWAYS, 0, 0);
2648  WriteFile( hFile, emrSrc, emrSrc->nBytes, &w, NULL);
2649  CloseHandle( hFile );
2650  /* Reopen file for reading only, so that apps can share
2651  read access to the file while hmf is still valid */
2653  NULL, OPEN_EXISTING, 0, 0);
2654  if(hFile == INVALID_HANDLE_VALUE) {
2655  ERR("Can't reopen emf for reading\n");
2656  return 0;
2657  }
2658  hmfDst = EMF_GetEnhMetaFile( hFile );
2659  CloseHandle( hFile );
2660  }
2661  return hmfDst;
2662 }
2663 
2664 /*****************************************************************************
2665  * CopyEnhMetaFileW (GDI32.@)
2666  *
2667  * See CopyEnhMetaFileA.
2668  *
2669  *
2670  */
2672  HENHMETAFILE hmfSrc,
2673  LPCWSTR file)
2674 {
2675  ENHMETAHEADER *emrSrc = EMF_GetEnhMetaHeader( hmfSrc ), *emrDst;
2676  HENHMETAFILE hmfDst;
2677 
2678  if(!emrSrc) return FALSE;
2679  if (!file) {
2680  emrDst = HeapAlloc( GetProcessHeap(), 0, emrSrc->nBytes );
2681  memcpy( emrDst, emrSrc, emrSrc->nBytes );
2682  hmfDst = EMF_Create_HENHMETAFILE( emrDst, emrSrc->nBytes, FALSE );
2683  if (!hmfDst)
2684  HeapFree( GetProcessHeap(), 0, emrDst );
2685  } else {
2686  HANDLE hFile;
2687  DWORD w;
2689  NULL, CREATE_ALWAYS, 0, 0);
2690  WriteFile( hFile, emrSrc, emrSrc->nBytes, &w, NULL);
2691  CloseHandle( hFile );
2692  /* Reopen file for reading only, so that apps can share
2693  read access to the file while hmf is still valid */
2695  NULL, OPEN_EXISTING, 0, 0);
2696  if(hFile == INVALID_HANDLE_VALUE) {
2697  ERR("Can't reopen emf for reading\n");
2698  return 0;
2699  }
2700  hmfDst = EMF_GetEnhMetaFile( hFile );
2701  CloseHandle( hFile );
2702  }
2703  return hmfDst;
2704 }
2705 
2706 
2707 /* Struct to be used to be passed in the LPVOID parameter for cbEnhPaletteCopy */
2708 typedef struct tagEMF_PaletteCopy
2709 {
2712 } EMF_PaletteCopy;
2713 
2714 /***************************************************************
2715  * Find the EMR_EOF record and then use it to find the
2716  * palette entries for this enhanced metafile.
2717  * The lpData is actually a pointer to an EMF_PaletteCopy struct
2718  * which contains the max number of elements to copy and where
2719  * to copy them to.
2720  *
2721  * NOTE: To be used by GetEnhMetaFilePaletteEntries only!
2722  */
2724  HANDLETABLE *b,
2725  const ENHMETARECORD *lpEMR,
2726  INT c,
2727  LPARAM lpData )
2728 {
2729 
2730  if ( lpEMR->iType == EMR_EOF )
2731  {
2732  const EMREOF *lpEof = (const EMREOF *)lpEMR;
2733  EMF_PaletteCopy* info = (EMF_PaletteCopy*)lpData;
2734  DWORD dwNumPalToCopy = min( lpEof->nPalEntries, info->cEntries );
2735 
2736  TRACE( "copying 0x%08x palettes\n", dwNumPalToCopy );
2737 
2738  memcpy( info->lpPe, (LPCSTR)lpEof + lpEof->offPalEntries,
2739  sizeof( *(info->lpPe) ) * dwNumPalToCopy );
2740 
2741  /* Update the passed data as a return code */
2742  info->lpPe = NULL; /* Palettes were copied! */
2743  info->cEntries = dwNumPalToCopy;
2744 
2745  return FALSE; /* That's all we need */
2746  }
2747 
2748  return TRUE;
2749 }
2750 
2751 /*****************************************************************************
2752  * GetEnhMetaFilePaletteEntries (GDI32.@)
2753  *
2754  * Copy the palette and report size
2755  *
2756  * BUGS: Error codes (SetLastError) are not set on failures
2757  */
2759  UINT cEntries,
2760  LPPALETTEENTRY lpPe )
2761 {
2762  ENHMETAHEADER* enhHeader = EMF_GetEnhMetaHeader( hEmf );
2763  EMF_PaletteCopy infoForCallBack;
2764 
2765  TRACE( "(%p,%d,%p)\n", hEmf, cEntries, lpPe );
2766 
2767  if (!enhHeader) return 0;
2768 
2769  /* First check if there are any palettes associated with
2770  this metafile. */
2771  if ( enhHeader->nPalEntries == 0 ) return 0;
2772 
2773  /* Is the user requesting the number of palettes? */
2774  if ( lpPe == NULL ) return enhHeader->nPalEntries;
2775 
2776  /* Copy cEntries worth of PALETTEENTRY structs into the buffer */
2777  infoForCallBack.cEntries = cEntries;
2778  infoForCallBack.lpPe = lpPe;
2779 
2780  if ( !EnumEnhMetaFile( 0, hEmf, cbEnhPaletteCopy,
2781  &infoForCallBack, 0 ) )
2782  return GDI_ERROR;
2783 
2784  /* Verify that the callback executed correctly */
2785  if ( infoForCallBack.lpPe != NULL )
2786  {
2787  /* Callback proc had error! */
2788  ERR( "cbEnhPaletteCopy didn't execute correctly\n" );
2789  return GDI_ERROR;
2790  }
2791 
2792  return infoForCallBack.cEntries;
2793 }
2794 
2795 /******************************************************************
2796  * extract_emf_from_comment
2797  *
2798  * If the WMF was created by GetWinMetaFileBits, then extract the
2799  * original EMF that is stored in MFCOMMENT chunks.
2800  */
2801 static HENHMETAFILE extract_emf_from_comment( const BYTE *buf, UINT mf_size )
2802 {
2803  METAHEADER *mh = (METAHEADER *)buf;
2804  METARECORD *mr;
2806  WORD checksum = 0;
2807  DWORD size = 0, remaining, chunks;
2808  BYTE *emf_bits = NULL, *ptr;
2809  UINT offset;
2810  HENHMETAFILE emf = NULL;
2811 
2812  if (mf_size < sizeof(*mh)) return NULL;
2813 
2814  for (offset = mh->mtHeaderSize * 2; offset < mf_size; offset += (mr->rdSize * 2))
2815  {
2816  mr = (METARECORD *)((char *)mh + offset);
2817  chunk = (emf_in_wmf_comment *)(mr->rdParm + 2);
2818 
2819  if (mr->rdFunction != META_ESCAPE || mr->rdParm[0] != MFCOMMENT) goto done;
2820  if (chunk->magic != WMFC_MAGIC) goto done;
2821 
2822  if (!emf_bits)
2823  {
2824  size = remaining = chunk->emf_size;
2825  chunks = chunk->num_chunks;
2826  emf_bits = ptr = HeapAlloc( GetProcessHeap(), 0, size );
2827  if (!emf_bits) goto done;
2828  }
2829  if (chunk->chunk_size > remaining) goto done;
2830  remaining -= chunk->chunk_size;
2831  if (chunk->remaining_size != remaining) goto done;
2832  memcpy( ptr, chunk->emf_data, chunk->chunk_size );
2833  ptr += chunk->chunk_size;
2834  if (--chunks == 0) break;
2835  }
2836 
2837  for (offset = 0; offset < mf_size / 2; offset++)
2838  checksum += *((WORD *)buf + offset);
2839  if (checksum) goto done;
2840 
2841  emf = SetEnhMetaFileBits( size, emf_bits );
2842 
2843 done:
2844  HeapFree( GetProcessHeap(), 0, emf_bits );
2845  return emf;
2846 }
2847 
2848 typedef struct wmf_in_emf_comment
2849 {
2857 
2858 /******************************************************************
2859  * SetWinMetaFileBits (GDI32.@)
2860  *
2861  * Translate from old style to new style.
2862  *
2863  */
2864 HENHMETAFILE WINAPI SetWinMetaFileBits(UINT cbBuffer, const BYTE *lpbBuffer, HDC hdcRef,
2865  const METAFILEPICT *lpmfp)
2866 {
2867  static const WCHAR szDisplayW[] = { 'D','I','S','P','L','A','Y','\0' };
2868  HMETAFILE hmf = NULL;
2869  HENHMETAFILE ret = NULL;
2870  HDC hdc = NULL, hdcdisp = NULL;
2871  RECT rc, *prcFrame = NULL;
2872  LONG mm, xExt, yExt;
2873  INT horzsize, vertsize, horzres, vertres;
2874 
2875  TRACE("(%d, %p, %p, %p)\n", cbBuffer, lpbBuffer, hdcRef, lpmfp);
2876 
2877  hmf = SetMetaFileBitsEx(cbBuffer, lpbBuffer);
2878  if(!hmf)
2879  {
2880  WARN("SetMetaFileBitsEx failed\n");
2881  return NULL;
2882  }
2883 
2884  ret = extract_emf_from_comment( lpbBuffer, cbBuffer );
2885  if (ret) return ret;
2886 
2887  if(!hdcRef)
2888  hdcRef = hdcdisp = CreateDCW(szDisplayW, NULL, NULL, NULL);
2889 
2890  if (lpmfp)
2891  {
2892  TRACE("mm = %d %dx%d\n", lpmfp->mm, lpmfp->xExt, lpmfp->yExt);
2893 
2894  mm = lpmfp->mm;
2895  xExt = lpmfp->xExt;
2896  yExt = lpmfp->yExt;
2897  }
2898  else
2899  {
2900  TRACE("lpmfp == NULL\n");
2901 
2902  /* Use the whole device surface */
2903  mm = MM_ANISOTROPIC;
2904  xExt = 0;
2905  yExt = 0;
2906  }
2907 
2908  if (mm == MM_ISOTROPIC || mm == MM_ANISOTROPIC)
2909  {
2910  if (xExt < 0 || yExt < 0)
2911  {
2912  /* Use the whole device surface */
2913  xExt = 0;
2914  yExt = 0;
2915  }
2916 
2917  /* Use the x and y extents as the frame box */
2918  if (xExt && yExt)
2919  {
2920  rc.left = rc.top = 0;
2921  rc.right = xExt;
2922  rc.bottom = yExt;
2923  prcFrame = &rc;
2924  }
2925  }
2926 
2927  if(!(hdc = CreateEnhMetaFileW(hdcRef, NULL, prcFrame, NULL)))
2928  {
2929  ERR("CreateEnhMetaFile failed\n");
2930  goto end;
2931  }
2932 
2933  /*
2934  * Write the original METAFILE into the enhanced metafile.
2935  * It is encapsulated in a GDICOMMENT_WINDOWS_METAFILE record.
2936  */
2937  if (mm != MM_TEXT)
2938  {
2939  wmf_in_emf_comment *mfcomment;
2940  UINT mfcomment_size;
2941 
2942  mfcomment_size = sizeof (*mfcomment) + cbBuffer;
2943  mfcomment = HeapAlloc(GetProcessHeap(), 0, mfcomment_size);
2944  if (mfcomment)
2945  {
2946  mfcomment->ident = GDICOMMENT_IDENTIFIER;
2948  mfcomment->nVersion = 0x00000300;
2949  mfcomment->nChecksum = 0; /* FIXME */
2950  mfcomment->fFlags = 0;
2951  mfcomment->cbWinMetaFile = cbBuffer;
2952  memcpy(&mfcomment[1], lpbBuffer, cbBuffer);
2953  GdiComment(hdc, mfcomment_size, (BYTE*) mfcomment);
2954  HeapFree(GetProcessHeap(), 0, mfcomment);
2955  }
2956  SetMapMode(hdc, mm);
2957  }
2958 
2959 
2960  horzsize = GetDeviceCaps(hdcRef, HORZSIZE);
2961  vertsize = GetDeviceCaps(hdcRef, VERTSIZE);
2962  horzres = GetDeviceCaps(hdcRef, HORZRES);
2963  vertres = GetDeviceCaps(hdcRef, VERTRES);
2964 
2965  if (!xExt || !yExt)
2966  {
2967  /* Use the whole device surface */
2968  xExt = horzres;
2969  yExt = vertres;
2970  }
2971  else
2972  {
2973  xExt = MulDiv(xExt, horzres, 100 * horzsize);
2974  yExt = MulDiv(yExt, vertres, 100 * vertsize);
2975  }
2976 
2977  /* set the initial viewport:window ratio as 1:1 */
2978  SetViewportExtEx(hdc, xExt, yExt, NULL);
2979  SetWindowExtEx(hdc, xExt, yExt, NULL);
2980 
2981  PlayMetaFile(hdc, hmf);
2982 
2984 end:
2985  if (hdcdisp) DeleteDC(hdcdisp);
2986  DeleteMetaFile(hmf);
2987  return ret;
2988 }
DWORD WINAPI SetMapperFlags(_In_ HDC, _In_ DWORD)
HGDIOBJ WINAPI GetStockObject(_In_ int)
#define MM_ISOTROPIC
Definition: wingdi.h:870
DWORD WINAPI SetLayout(_In_ HDC hdc, _In_ DWORD dwLayout)
Definition: coord.c:780
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define EMR_SETPOLYFILLMODE
Definition: wingdi.h:93
COLORREF elpColor
Definition: wingdi.h:1945
BYTE Data[1]
Definition: gdi_private.h:89
BOOL WINAPI ExtTextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_ UINT options, _In_opt_ const RECT *lprect, _In_reads_opt_(c) LPCWSTR lpString, _In_ UINT c, _In_reads_opt_(c) const INT *lpDx)
BOOL WINAPI PolyDraw(_In_ HDC hdc, _In_reads_(cpt) const POINT *apt, _In_reads_(cpt) const BYTE *aj, _In_ int cpt)
COLORREF crBkColorSrc
Definition: wingdi.h:2079
#define abs(i)
Definition: fconv.c:206
COLORREF crColor
Definition: wingdi.h:2222
RECTL rclBounds
Definition: wingdi.h:2038
HMETAFILE WINAPI SetMetaFileBitsEx(_In_ UINT cbBuffer, _In_reads_bytes_(cbBuffer) CONST BYTE *lpData)
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
#define EMR_SETMAPMODE
Definition: wingdi.h:91
struct _RGNDATAHEADER RGNDATAHEADER
#define EMR_ROUNDRECT
Definition: wingdi.h:118
int WINAPI StretchDIBits(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_opt_ const VOID *, _In_ const BITMAPINFO *, _In_ UINT, _In_ DWORD)
static CRITICAL_SECTION_DEBUG critsect_debug
Definition: enhmetafile.c:53
GLint level
Definition: gl.h:1546
DWORD offBmiSrc
Definition: wingdi.h:2269
DWORD offPalEntries
Definition: wingdi.h:1861
#define EMR_SETARCDIRECTION
Definition: wingdi.h:131
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
ENHMETAHEADER * emh
Definition: enhmetafile.c:63
#define HORZRES
Definition: wingdi.h:716
BOOL WINAPI SetViewportOrgEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
Definition: coord.c:655
#define EMR_SETMITERLIMIT
Definition: wingdi.h:132
#define EMR_POLYBEZIERTO16
Definition: wingdi.h:161
DWORD iUsageSrc
Definition: wingdi.h:1740
DWORD iUsageMask
Definition: wingdi.h:2055
BOOL WINAPI GdiAlphaBlend(HDC hdcDst, int xDst, int yDst, int widthDst, int heightDst, HDC hdcSrc, int xSrc, int ySrc, int widthSrc, int heightSrc, BLENDFUNCTION blendFunction)
POINTL ptlCenter
Definition: wingdi.h:1709
#define EMR_POLYLINE
Definition: wingdi.h:78
LPPALETTEENTRY lpPe
Definition: enhmetafile.c:2711
#define CloseHandle
Definition: compat.h:598
BOOL WINAPI SetWindowExtEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPSIZE)
int WINAPI FillRgn(_In_ HDC, _In_ HRGN, _In_ HBRUSH)
Definition: painting.c:183
UINT n
Definition: wingdi.h:2563
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
LPCWSTR lpstr
Definition: wingdi.h:2564
SIZEL szlDevice
Definition: wingdi.h:2333
HBITMAP WINAPI CreateBitmapIndirect(_In_ const BITMAP *pbm)
POINTL ptlReference
Definition: wingdi.h:1972
HCOLORSPACE WINAPI SetColorSpace(_In_ HDC, _In_ HCOLORSPACE)
#define EMR_ARCTO
Definition: wingdi.h:129
static struct object_header ** handles
Definition: handle.c:45
long y
Definition: polytest.cpp:48
#define MapViewOfFile
Definition: compat.h:604
#define DWORD_PTR
Definition: treelist.c:76
#define WideCharToMultiByte
Definition: compat.h:111
DWORD elpWidth
Definition: wingdi.h:1943
BOOL WINAPI PaintRgn(_In_ HDC, _In_ HRGN)
Definition: painting.c:250
DWORD iGraphicsMode
Definition: wingdi.h:1982
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
BOOL Polygon(CONST PPOINT UnsafePoints, int Count, int polyFillMode)
Definition: polytest.cpp:730
ULONG lbHatch
Definition: wingdi.h:1755
#define RGB(r, g, b)
Definition: precomp.h:62
LONG cxDest
Definition: wingdi.h:2041
HGDIOBJ alloc_gdi_handle(void *obj, WORD type, const struct gdi_obj_funcs *funcs) DECLSPEC_HIDDEN
#define EMR_POLYLINE16
Definition: wingdi.h:160
long x
Definition: polytest.cpp:48
UINT lbStyle
Definition: wingdi.h:1747
BOOL WINAPI LPtoDP(_In_ HDC hdc, _Inout_updates_(c) LPPOINT lppt, _In_ int c)
BOOL WINAPI Rectangle(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
BOOL WINAPI GetWindowOrgEx(_In_ HDC, _Out_ LPPOINT)
Definition: coord.c:439
DWORD iGraphicsMode
Definition: wingdi.h:2138
#define TRUE
Definition: types.h:120
#define EMR_STROKEANDFILLPATH
Definition: wingdi.h:137
#define pt(x, y)
Definition: drawing.c:79
static CRITICAL_SECTION enhmetafile_cs
Definition: enhmetafile.c:52
SIZEL szlMillimeters
Definition: wingdi.h:2334
LONG yMask
Definition: wingdi.h:2054
#define CP_ACP
Definition: compat.h:109
LONG cxSrc
Definition: wingdi.h:2076
#define EMR_EXCLUDECLIPRECT
Definition: wingdi.h:103
DWORD iUsageSrc
Definition: wingdi.h:2248
#define EMR_STRETCHDIBITS
Definition: wingdi.h:154
DWORD ihBrush
Definition: wingdi.h:1995
ULONG_PTR lbHatch
Definition: wingdi.h:1749
#define EMR_LINETO
Definition: wingdi.h:128
DWORD aPolyCounts[1]
Definition: wingdi.h:2124
#define EMR_WIDENPATH
Definition: wingdi.h:140
#define WARN(fmt,...)
Definition: debug.h:112
BOOL WINAPI EndPath(_In_ HDC)
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define EMR_STROKEPATH
Definition: wingdi.h:138
XFORM xformSrc
Definition: wingdi.h:2266
#define HEIGHT(rect)
Definition: enhmetafile.c:555
BOOL WINAPI PlayEnhMetaFileRecord(HDC hdc, LPHANDLETABLE handletable, const ENHMETARECORD *mr, UINT handles)
Definition: enhmetafile.c:777
#define EMR_CREATECOLORSPACE
Definition: wingdi.h:172
DWORD cptl
Definition: wingdi.h:2110
BOOL WINAPI SetMiterLimit(_In_ HDC, _In_ FLOAT, _Out_opt_ PFLOAT)
POINTL aptl[1]
Definition: wingdi.h:2097
#define EMR_POLYLINETO16
Definition: wingdi.h:162
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:35
#define MWT_LEFTMULTIPLY
Definition: wingdi.h:945
POINTL ptlStart
Definition: wingdi.h:1717
#define EMR_PIXELFORMAT
Definition: wingdi.h:177
int * pdx
Definition: wingdi.h:2558
BOOL WINAPI SelectClipPath(_In_ HDC, _In_ int)
LONG top
Definition: windef.h:307
XFORM xformSrc
Definition: wingdi.h:2046
long bottom
Definition: polytest.cpp:53
static BOOL emr_produces_output(int type)
Definition: enhmetafile.c:703
INT WINAPI NamedEscape(HDC hdc, PWCHAR pDriver, INT iEsc, INT cjIn, LPSTR pjIn, INT cjOut, LPSTR pjOut)
Definition: misc.c:229
DWORD aPolyCounts[1]
Definition: wingdi.h:2132
#define EMR_DELETECOLORSPACE
Definition: wingdi.h:174
static INT CALLBACK cbEnhPaletteCopy(HDC a, HANDLETABLE *b, const ENHMETARECORD *lpEMR, INT c, LPARAM lpData)
Definition: enhmetafile.c:2723
static HRGN hRgn
Definition: mapping.c:33
DWORD offBmiSrc
Definition: wingdi.h:2081
LONG cxDest
Definition: wingdi.h:1733
int WINAPI IntersectClipRect(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define EMR_ENDPATH
Definition: wingdi.h:134
#define EMR_POLYLINETO
Definition: wingdi.h:80
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
#define WMFC_MAGIC
Definition: gdi_private.h:186
WORD rdFunction
Definition: wingdi.h:2346
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
BOOL WINAPI Chord(_In_ HDC hdc, _In_ INT xLeft, _In_ INT yTop, _In_ INT xRight, _In_ INT yBottom, _In_ INT xRadial1, _In_ INT yRadial1, _In_ INT xRadial2, _In_ INT yRadial2)
Definition: arc.c:119
BOOL WINAPI LineTo(_In_ HDC, _In_ int, _In_ int)
BYTE Data[1]
Definition: wingdi.h:2024
#define EMR_SETPALETTEENTRIES
Definition: wingdi.h:124
#define EMR_PAINTRGN
Definition: wingdi.h:147
DWORD iUsageMask
Definition: wingdi.h:2087
#define EMR_MOVETOEX
Definition: wingdi.h:101
UINT WINAPI GetEnhMetaFileHeader(HENHMETAFILE hmf, UINT bufsize, LPENHMETAHEADER buf)
Definition: enhmetafile.c:417
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
UINT uiFlags
Definition: wingdi.h:2565
#define EMR_CREATEPALETTE
Definition: wingdi.h:123
#define EMR_STRETCHBLT
Definition: wingdi.h:150
PALETTEENTRY aPalEntries[1]
Definition: wingdi.h:2217
FLOAT eSweepAngle
Definition: wingdi.h:1712
#define EMR_ABORTPATH
Definition: wingdi.h:142
#define R2_COPYPEN
Definition: wingdi.h:339
uint16_t * PWCHAR
Definition: typedefs.h:56
HDC WINAPI CreateEnhMetaFileW(_In_opt_ HDC, _In_opt_ LPCWSTR, _In_opt_ LPCRECT, _In_opt_ LPCWSTR)
LONG left
Definition: windef.h:306
UINT WINAPI GetEnhMetaFilePaletteEntries(HENHMETAFILE hEmf, UINT cEntries, LPPALETTEENTRY lpPe)
Definition: enhmetafile.c:2758
static HDC hdcSrc
Definition: xlate.c:32
#define EMR_SETBRUSHORGEX
Definition: wingdi.h:87
UINT WINAPI SetTextAlign(_In_ HDC, _In_ UINT)
Definition: text.c:876
DWORD offDescription
Definition: wingdi.h:2331
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
BOOL WINAPI PolylineTo(_In_ HDC hdc, _In_reads_(cpt) const POINT *apt, _In_ DWORD cpt)
Definition: painting.c:354
#define EMR_SETTEXTCOLOR
Definition: wingdi.h:98
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
XFORM init_transform
Definition: enhmetafile.c:545
#define EMR_EXTCREATEFONTINDIRECTW
Definition: wingdi.h:155
char * LPSTR
Definition: xmlstorage.h:182
#define MFCOMMENT
Definition: wingdi.h:1008
#define EMR_SETTEXTALIGN
Definition: wingdi.h:96
LONG right
Definition: windef.h:308
BOOL WINAPI PolyTextOutW(_In_ HDC hdc, _In_reads_(nstrings) const POLYTEXTW *ppt, _In_ int nstrings)
struct wmf_in_emf_comment wmf_in_emf_comment
static void EMF_FixIsotropic(HDC hdc, enum_emh_data *info)
Definition: enhmetafile.c:673
#define EMR_SELECTPALETTE
Definition: wingdi.h:122
#define EMR_POLYDRAW
Definition: wingdi.h:130
#define ENUM_GET_PRIVATE_DATA(ht)
Definition: enhmetafile.c:551
ULONG_PTR elpHatch
Definition: wingdi.h:1946
BOOL WINAPI DeleteColorSpace(_In_ HCOLORSPACE)
HGDIOBJ objectHandle[1]
Definition: wingdi.h:2355
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
int32_t INT
Definition: typedefs.h:58
DWORD offBitsSrc
Definition: wingdi.h:2051
DWORD rdSize
Definition: wingdi.h:2345
BOOL WINAPI PolyTextOutA(_In_ HDC hdc, _In_reads_(nstrings) const POLYTEXTA *ppt, _In_ int nstrings)
BOOL WINAPI StretchBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_opt_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD)
LONG cySrc
Definition: wingdi.h:2077
#define EMR_SETCOLORSPACE
Definition: wingdi.h:173
#define EMR_SELECTOBJECT
Definition: wingdi.h:111
BOOL WINAPI SetPixelFormat(_In_ HDC, _In_ int, _In_ const PIXELFORMATDESCRIPTOR *)
HFONT hFont
Definition: main.c:53
#define FILE_SHARE_READ
Definition: compat.h:136
BOOL WINAPI SetWorldTransform(_In_ HDC, _In_ const XFORM *)
POINTL ptlPixel
Definition: wingdi.h:2221
LOGPEN lopn
Definition: wingdi.h:1852
DWORD elpNumEntries
Definition: wingdi.h:1947
#define AD_COUNTERCLOCKWISE
Definition: wingdi.h:667
LONG y
Definition: windef.h:330
#define EMR_SETVIEWPORTORGEX
Definition: wingdi.h:86
EMF_dc_state state
Definition: enhmetafile.c:546
BYTE RgnData[1]
Definition: wingdi.h:1996
struct tagRECT RECT
#define OBJ_PEN
Definition: objidl.idl:1409
#define EMR_PLGBLT
Definition: wingdi.h:152
int(CALLBACK * ENHMFENUMPROC)(_In_ HDC hdc, _In_reads_(nHandles) HANDLETABLE FAR *lpht, _In_ CONST ENHMETARECORD *lpmr, _In_ int nHandles, _In_opt_ LPARAM data)
Definition: wingdi.h:2922
#define EMR_REALIZEPALETTE
Definition: wingdi.h:126
#define CBM_INIT
Definition: wingdi.h:365
COLORREF WINAPI SetBkColor(_In_ HDC, _In_ COLORREF)
Definition: dc.c:999
static void EMF_RestoreDC(enum_emh_data *info, INT level)
Definition: enhmetafile.c:582
void GDI_ReleaseObj(HGDIOBJ) DECLSPEC_HIDDEN
Definition: rosglue.c:100
#define EMR_SETSTRETCHBLTMODE
Definition: wingdi.h:95
BOOL WINAPI PatBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD)
LOGFONTW elfLogFont
Definition: wingdi.h:1925
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
BOOL WINAPI MoveToEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
int WINAPI ExtSelectClipRgn(_In_ HDC, _In_opt_ HRGN, _In_ int)
long right
Definition: polytest.cpp:53
DWORD cbRgnData
Definition: wingdi.h:1994
static BOOL EMF_Delete_HENHMETAFILE(HENHMETAFILE hmf)
Definition: enhmetafile.c:295
int WINAPI SetBkMode(_In_ HDC, _In_ int)
Definition: dc.c:1056
static HENHMETAFILE extract_emf_from_comment(const BYTE *buf, UINT mf_size)
Definition: enhmetafile.c:2801
RECTL rclBox
Definition: wingdi.h:1856
BOOL WINAPI PlgBlt(_In_ HDC hdcDest, _In_reads_(3) const POINT *lpPoint, _In_ HDC hdcSrc, _In_ int xSrc, _In_ int ySrc, _In_ int width, _In_ int height, _In_opt_ HBITMAP hbmMask, _In_ int xMask, _In_ int yMask)
DWORD ihBrush
Definition: wingdi.h:2017
BOOL WINAPI ResizePalette(_In_ HPALETTE, _In_ UINT)
#define ALTERNATE
Definition: constants.h:278
BOOL WINAPI PolyBezierTo(_In_ HDC hdc, _In_reads_(cpt) const POINT *apt, _In_ DWORD cpt)
Definition: painting.c:281
unsigned char * LPBYTE
Definition: typedefs.h:53
#define OBJ_ENHMETAFILE
Definition: objidl.idl:1421
#define FALSE
Definition: types.h:117
#define EMR_EOF
Definition: wingdi.h:88
#define EMR_INTERSECTCLIPRECT
Definition: wingdi.h:104
static const char * get_emr_name(DWORD type)
Definition: enhmetafile.c:199
#define GDICOMMENT_IDENTIFIER
Definition: wingdi.h:666
BOOL WINAPI RoundRect(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int)
DWORD elpStyleEntry[1]
Definition: wingdi.h:1948
unsigned int BOOL
Definition: ntddk_ex.h:94
LONG xSrc
Definition: wingdi.h:2074
long LONG
Definition: pedump.c:60
EXTLOGPEN elp
Definition: wingdi.h:1957
int WINAPI SetMapMode(_In_ HDC, _In_ int)
BOOL WINAPI Arc(_In_ HDC hdc, _In_ INT xLeft, _In_ INT yTop, _In_ INT xRight, _In_ INT yBottom, _In_ INT xStartArc, _In_ INT yStartArc, _In_ INT xEndArc, _In_ INT yEndArc)
Definition: arc.c:5
int WINAPI SetROP2(_In_ HDC, _In_ int)
Definition: dc.c:1107
int WINAPI OffsetClipRgn(_In_ HDC, _In_ int, _In_ int)
FLOAT eDx
Definition: wingdi.h:1725
#define GENERIC_WRITE
Definition: nt_native.h:90
long top
Definition: polytest.cpp:53
#define EMR_SETICMMODE
Definition: wingdi.h:171
#define debugstr_w
Definition: kernel32.h:32
BOOL WINAPI StrokeAndFillPath(_In_ HDC)
#define EMR_RESTOREDC
Definition: wingdi.h:108
RECTL rcl
Definition: wingdi.h:1976
#define FIXME(fmt,...)
Definition: debug.h:111
static PVOID ptr
Definition: dispmode.c:27
struct tagEMRESCAPE * PEMRNAMEDESCAPE
DWORD elpPenStyle
Definition: wingdi.h:1942
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
HENHMETAFILE WINAPI GetEnhMetaFileW(LPCWSTR lpszMetaFile)
Definition: enhmetafile.c:389
LOGPALETTE lgpl
Definition: wingdi.h:1842
DWORD type
Definition: enhmetafile.c:68
XFORM xformSrc
Definition: wingdi.h:1738
#define EMR_EXTCREATEPEN
Definition: wingdi.h:168
FLOAT eM21
Definition: wingdi.h:1723
POINTS apts[1]
Definition: wingdi.h:2104
HPALETTE WINAPI SelectPalette(_In_ HDC, _In_ HPALETTE, _In_ BOOL)
UINT WINAPI GetEnhMetaFileDescriptionA(HENHMETAFILE hmf, UINT size, LPSTR buf)
Definition: enhmetafile.c:441
HENHMETAFILE WINAPI CopyEnhMetaFileA(HENHMETAFILE hmfSrc, LPCSTR file)
Definition: enhmetafile.c:2629
HFONT WINAPI CreateFontIndirectW(_In_ const LOGFONTW *)
BOOL WINAPI StrokePath(_In_ HDC)
POINTL ptl
Definition: wingdi.h:2034
DWORD offBitsSrc
Definition: wingdi.h:2271
FLOAT eM12
Definition: wingdi.h:1722
LONG cx
Definition: windef.h:334
#define EMR_GLSRECORD
Definition: wingdi.h:175
#define EMR_POLYPOLYLINE
Definition: wingdi.h:81
LONG_PTR LPARAM
Definition: windef.h:208
BOOL WINAPI SetBrushOrgEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
_Inout_ PERBANDINFO * pbi
Definition: winddi.h:3917
SHORT x
Definition: windef.h:342
LONG cyDest
Definition: wingdi.h:1734
#define EMR_EXTTEXTOUTW
Definition: wingdi.h:157
EMF_dc_state * saved_state
Definition: enhmetafile.c:548
HENHMETAFILE WINAPI SetWinMetaFileBits(UINT cbBuffer, const BYTE *lpbBuffer, HDC hdcRef, const METAFILEPICT *lpmfp)
Definition: enhmetafile.c:2864
#define FILE_MAP_READ
Definition: compat.h:635
BOOL WINAPI CombineTransform(_Out_ LPXFORM pxformResult, _In_ const XFORM *pxform1, _In_ const XFORM *pxform2)
Definition: coord.c:64
LONG xMask
Definition: wingdi.h:2085
const char * LPCSTR
Definition: xmlstorage.h:183
#define EMR_SETMAPPERFLAGS
Definition: wingdi.h:90
#define EMR_FRAMERGN
Definition: wingdi.h:145
DWORD nRadius
Definition: wingdi.h:1710
#define EMR_SETMETARGN
Definition: wingdi.h:102
HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, DWORD filesize, BOOL on_disk)
Definition: enhmetafile.c:259
int WINAPI SetArcDirection(_In_ HDC, _In_ int)
long left
Definition: polytest.cpp:53
COLORREF lbColor
Definition: wingdi.h:1754
#define OPEN_EXISTING
Definition: compat.h:634
DWORD nPalEntries
Definition: wingdi.h:1860
#define EMR_INVERTRGN
Definition: wingdi.h:146
COLORREF crColor
Definition: wingdi.h:2181
#define EMR_RECTANGLE
Definition: wingdi.h:117
DWORD iUsageSrc
Definition: wingdi.h:2048
DWORD dSignature
Definition: wingdi.h:2324
BOOL WINAPI SetColorAdjustment(_In_ HDC, _In_ const COLORADJUSTMENT *)
HRGN WINAPI CreateRectRgn(_In_ int, _In_ int, _In_ int, _In_ int)
#define EMR_GDICOMMENT
Definition: wingdi.h:143
#define EMR_MODIFYWORLDTRANSFORM
Definition: wingdi.h:110
HBRUSH WINAPI CreatePatternBrush(_In_ HBITMAP)
static HENHMETAFILE EMF_GetEnhMetaFile(HANDLE hFile)
Definition: enhmetafile.c:341
#define EMR_CREATEDIBPATTERNBRUSHPT
Definition: wingdi.h:167
struct EMF_dc_state * next
Definition: enhmetafile.c:540
#define EMR_SETROP2
Definition: wingdi.h:94
DWORD offDx
Definition: wingdi.h:1977
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define TRACE(s)
Definition: solgame.cpp:4
UINT WINAPI GetEnhMetaFileDescriptionW(HENHMETAFILE hmf, UINT size, LPWSTR buf)
Definition: enhmetafile.c:473
BOOL WINAPI GetWorldTransform(_In_ HDC, _Out_ LPXFORM)
Definition: coord.c:278
BOOL WINAPI PolyPolygon(_In_ HDC hdc, _In_ const POINT *apt, _In_reads_(csz) const INT *asz, _In_ int csz)
GLsizeiptr size
Definition: glext.h:5919
RECTL rclFrame
Definition: wingdi.h:2323
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define META_ESCAPE
Definition: wingdi.h:248
HENHMETAFILE WINAPI GetEnhMetaFileA(LPCSTR lpszMetaFile)
Definition: enhmetafile.c:368
ULONG RGBQUAD
Definition: precomp.h:50
HCOLORSPACE WINAPI CreateColorSpaceA(_In_ LPLOGCOLORSPACEA pLogColorSpace)
BOOL WINAPI SetTextJustification(_In_ HDC, _In_ int, _In_ int)
Definition: cmds.c:130
BOOL WINAPI GetViewportExtEx(_In_ HDC, _Out_ LPSIZE)
Definition: coord.c:351
BOOL WINAPI Pie(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int)
#define EMR_SETPIXELV
Definition: wingdi.h:89
__wchar_t WCHAR
Definition: xmlstorage.h:180
RECT rcl
Definition: wingdi.h:2566
int WINAPI SetPolyFillMode(_In_ HDC, _In_ int)
Definition: dc.c:1167
GLintptr offset
Definition: glext.h:5920
DWORD COLORREF
Definition: windef.h:300
BOOL WINAPI ModifyWorldTransform(_In_ HDC, _In_opt_ const XFORM *, _In_ DWORD)
HPALETTE WINAPI CreatePalette(_In_reads_(_Inexpressible_(2 *sizeof(WORD)+plpal->palNumEntries *sizeof(PALETTEENTRY))) const LOGPALETTE *)
#define EMR_BITBLT
Definition: wingdi.h:149
BOOL WINAPI GetWindowExtEx(_In_ HDC, _Out_ LPSIZE)
Definition: coord.c:411
BOOL WINAPI WidenPath(_In_ HDC)
HENHMETAFILE WINAPI SetEnhMetaFileBits(UINT bufsize, const BYTE *buf)
Definition: enhmetafile.c:494
#define EMR_ELLIPSE
Definition: wingdi.h:116
DWORD offBitsMask
Definition: wingdi.h:2058
DWORD iUsageSrc
Definition: wingdi.h:2268
COLORREF lbColor
Definition: wingdi.h:1748
#define EMR_SETLINKEDUFI
Definition: gdi_private.h:193
#define WINAPI
Definition: msvc.h:6
const GLubyte * c
Definition: glext.h:8905
const char * wine_dbgstr_rect(const RECT *rect)
struct enum_emh_data enum_emh_data
COLORREF crBkColorSrc
Definition: wingdi.h:1739
int WINAPI ChoosePixelFormat(_In_ HDC hdc, _In_ const PIXELFORMATDESCRIPTOR *ppfd)
BOOL WINAPI GdiComment(_In_ HDC hdc, _In_ UINT nSize, _In_reads_bytes_(nSize) const BYTE *lpData)
WORD mtHeaderSize
Definition: wingdi.h:2311
LONG xSrc
Definition: wingdi.h:1736
unsigned short WORD
Definition: ntddk_ex.h:93
#define MM_LOMETRIC
Definition: wingdi.h:872
BOOL WINAPI GetViewportOrgEx(_In_ HDC, _Out_ LPPOINT)
Definition: coord.c:383
DWORD dwRop
Definition: wingdi.h:2043
unsigned long DWORD
Definition: ntddk_ex.h:95
#define EMR_SCALEWINDOWEXTEX
Definition: wingdi.h:106
DWORD offBitsSrc
Definition: wingdi.h:2083
LONG x
Definition: windef.h:329
#define EMR_FILLRGN
Definition: wingdi.h:144
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
LONG cyDest
Definition: wingdi.h:2042
#define SetLastError(x)
Definition: compat.h:611
int WINAPI SetMetaRgn(_In_ HDC)
#define EMR_CREATEBRUSHINDIRECT
Definition: wingdi.h:113
#define EMR_SELECTCLIPPATH
Definition: wingdi.h:141
#define OBJ_FONT
Definition: objidl.idl:1414
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
HENHMETAFILE WINAPI CloseEnhMetaFile(_In_ HDC hdc)
#define MM_LOENGLISH
Definition: wingdi.h:871
RECTL rclBounds
Definition: wingdi.h:2238
#define EMR_POLYGON
Definition: wingdi.h:77
#define EMR_POLYBEZIER16
Definition: wingdi.h:158
LONG yDest
Definition: wingdi.h:2040
_In_ UINT _In_ UINT cEntries
Definition: wingdi.h:3620
GLuint GLuint end
Definition: gl.h:1545
struct _test_info info[]
Definition: SetCursorPos.c:19
COLORADJUSTMENT ColorAdjustment
Definition: wingdi.h:2185
BYTE abTypes[1]
Definition: wingdi.h:2098
#define X(p)
HBITMAP WINAPI CreateDIBitmap(_In_ HDC hdc, _In_opt_ const BITMAPINFOHEADER *pbmih, _In_ DWORD fdwInit, _In_opt_ const VOID *pvInit, _In_opt_ const BITMAPINFO *pbmi, _In_ UINT uUsage)
BYTE RgnData[1]
Definition: wingdi.h:2019
#define EMR_PIE
Definition: wingdi.h:121
POINTL ptlEnd
Definition: wingdi.h:1718
int ret
static const unsigned char enhmetafile[]
Definition: olepicture.c:149
FLOAT eM11
Definition: wingdi.h:1721
#define EMR_DELETEOBJECT
Definition: wingdi.h:114
COLORREF crBkColorSrc
Definition: wingdi.h:2247
#define EMR_CREATEPEN
Definition: wingdi.h:112
#define EMR_FILLPATH
Definition: wingdi.h:136
#define EMR_CHORD
Definition: wingdi.h:120
RECTL rclBox
Definition: wingdi.h:2155
HDC hdc
Definition: main.c:9
#define MM_ANISOTROPIC
Definition: wingdi.h:867
#define EMR_HEADER
Definition: wingdi.h:75
static const struct emr_name emr_names[]
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
HENHMETAFILE WINAPI CopyEnhMetaFileW(HENHMETAFILE hmfSrc, LPCWSTR file)
Definition: enhmetafile.c:2671
static int state
Definition: maze.c:121
#define MM_TWIPS
Definition: wingdi.h:874
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
LONG yDest
Definition: wingdi.h:1732
int WINAPI GetMapMode(_In_ HDC)
Definition: coord.c:114
#define GENERIC_READ
Definition: compat.h:135
static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum)
Definition: fdi.c:353
LIST_ENTRY ProcessLocksList
Definition: winbase.h:877
_In_ HANDLE hFile
Definition: mswsock.h:90
Definition: emfdc.c:44
UINT lbStyle
Definition: wingdi.h:1753
WORD rdParm[1]
Definition: wingdi.h:2347
HPEN WINAPI CreatePenIndirect(_In_ const LOGPEN *)
unsigned char BYTE
Definition: xxhash.c:193
UINT n
Definition: wingdi.h:2554
#define ENHMETA_SIGNATURE
Definition: wingdi.h:204
DWORD offBmiSrc
Definition: wingdi.h:2049
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
BOOL WINAPI PolyPolyline(_In_ HDC hdc, _In_ const POINT *apt, _In_reads_(csz) const DWORD *asz, _In_ DWORD csz)
HBRUSH WINAPI CreateBrushIndirect(_In_ const LOGBRUSH *plb)
#define EMR_POLYBEZIER
Definition: wingdi.h:76
#define WIDTH(rect)
Definition: enhmetafile.c:554
int WINAPI SetStretchBltMode(_In_ HDC, _In_ int)
Definition: dc.c:1366
#define EMR_SCALEVIEWPORTEXTEX
Definition: wingdi.h:105
DWORD cbBitsSrc
Definition: wingdi.h:2272
#define EMR_SETWINDOWEXTEX
Definition: wingdi.h:83
DWORD dwRop
Definition: wingdi.h:1735
#define EMR_SETBKMODE
Definition: wingdi.h:92
#define PATCOPY
Definition: wingdi.h:335
#define HORZSIZE
Definition: wingdi.h:714
#define RGN_COPY
Definition: wingdi.h:357
_Check_return_ _CRT_JIT_INTRINSIC double __cdecl fabs(_In_ double x)
#define ERROR_INVALID_DATA
Definition: winerror.h:116
DWORD nChars
Definition: wingdi.h:1973
#define EMR_ANGLEARC
Definition: wingdi.h:115
LONG xMask
Definition: wingdi.h:2053
struct tagEMRCREATECOLORSPACE * PEMRCREATECOLORSPACE
PIXELFORMATDESCRIPTOR pfd
Definition: wingdi.h:2601
DWORD cptl
Definition: wingdi.h:2096
#define EMR_EXTFLOODFILL
Definition: wingdi.h:127
#define ERR(fmt,...)
Definition: debug.h:110
DWORD offBitsMask
Definition: wingdi.h:2090
RECTL rclBounds
Definition: wingdi.h:1730
XFORM xformSrc
Definition: wingdi.h:2246
#define EMR_ARC
Definition: wingdi.h:119
BYTE RgnData[1]
Definition: wingdi.h:2030
DWORD offBmiSrc
Definition: wingdi.h:1741
#define EMR_CLOSEFIGURE
Definition: wingdi.h:135
RECTL rclBounds
Definition: wingdi.h:2072
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:911
SHORT y
Definition: windef.h:343
EMRTEXT aemrtext[1]
Definition: wingdi.h:2142
HRGN WINAPI ExtCreateRegion(_In_opt_ const XFORM *lpx, _In_ DWORD nCount, _In_reads_bytes_(nCount) const RGNDATA *lpData)
LONG ySrc
Definition: wingdi.h:1737
#define CREATE_ALWAYS
Definition: disk.h:72
#define VERTSIZE
Definition: wingdi.h:715
static ENHMETAHEADER * EMF_GetEnhMetaHeader(HENHMETAFILE hmf)
Definition: enhmetafile.c:320
#define EMR_EXTTEXTOUTA
Definition: wingdi.h:156
#define EMR_SETCOLORADJUSTMENT
Definition: wingdi.h:97
LONG ySrc
Definition: wingdi.h:2075
int WINAPI SetDIBitsToDevice(_In_ HDC, _In_ int, _In_ int, _In_ DWORD, _In_ DWORD, _In_ int, _In_ int, _In_ UINT, _In_ UINT, _In_ CONST VOID *, _In_ CONST BITMAPINFO *, _In_ UINT)
static INT CALLBACK EMF_PlayEnhMetaFileCallback(HDC hdc, HANDLETABLE *ht, const ENHMETARECORD *emr, INT handles, LPARAM data)
Definition: enhmetafile.c:2586
#define EMR_POLYTEXTOUTA
Definition: wingdi.h:169
#define EMR_POLYTEXTOUTW
Definition: wingdi.h:170
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
UINT elpBrushStyle
Definition: wingdi.h:1944
#define EMR_POLYPOLYGON16
Definition: wingdi.h:164
_In_ ULONG _In_ ULONG rgb
Definition: winddi.h:3520
BOOL WINAPI DeleteDC(_In_ HDC)
#define OBJ_BRUSH
Definition: objidl.idl:1410
SIZEL szlStroke
Definition: wingdi.h:2018
BOOL WINAPI Ellipse(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
int WINAPI ExcludeClipRect(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
#define EMR_FLATTENPATH
Definition: wingdi.h:139
DWORD cbRgnData
Definition: wingdi.h:2029
DWORD fOptions
Definition: wingdi.h:1975
POINTL aptl[1]
Definition: wingdi.h:2111
static BOOL is_meta_dc(HDC hdc)
Definition: gdi_private.h:135
LONG xDest
Definition: wingdi.h:2039
HBITMAP WINAPI CreateDIBSection(HDC hDC, CONST BITMAPINFO *BitmapInfo, UINT Usage, VOID **Bits, HANDLE hSection, DWORD dwOffset)
Definition: bitmap.c:199
Definition: bl.h:1331
_In_ LONG iPixelFormat
Definition: winddi.h:3488
UINT WINAPI GetEnhMetaFileBits(HENHMETAFILE hmf, UINT bufsize, LPBYTE buf)
Definition: enhmetafile.c:509
UINT WINAPI SetPaletteEntries(_In_ HPALETTE hpal, _In_ UINT iStart, _In_ UINT cEntries, _In_reads_(cEntries) CONST PALETTEENTRY *pPalEntries)
static const struct newhuff ht[]
Definition: huffman.h:296
struct EMF_dc_state EMF_dc_state
FLOAT eM22
Definition: wingdi.h:1724
RECT rcl
Definition: wingdi.h:2557
#define min(a, b)
Definition: monoChain.cc:55
FLOAT eDy
Definition: wingdi.h:1726
BOOL WINAPI GdiGradientFill(HDC hdc, TRIVERTEX *vert_array, ULONG nvert, void *grad_array, ULONG ngrad, ULONG mode)
unsigned int UINT
Definition: ndis.h:50
COLORREF crColor
Definition: wingdi.h:1962
int WINAPI SaveDC(_In_ HDC)
#define NULL
Definition: types.h:112
DWORD offString
Definition: wingdi.h:1974
HBRUSH WINAPI CreateSolidBrush(_In_ COLORREF)
#define DIB_PAL_MONO
Definition: gdi_private.h:196
#define PAGE_READONLY
Definition: compat.h:138
#define VERTRES
Definition: wingdi.h:717
static void EMF_SaveDC(enum_emh_data *info)
Definition: enhmetafile.c:599
BOOL WINAPI InvertRgn(_In_ HDC, _In_ HRGN)
Definition: painting.c:229
RGNDATAHEADER rdh
Definition: axextend.idl:399
#define MM_HIMETRIC
Definition: wingdi.h:869
GLint dx
Definition: linetemp.h:97
BOOL WINAPI ExtTextOutA(_In_ HDC hdc, _In_ int x, _In_ int y, _In_ UINT options, _In_opt_ const RECT *lprect, _In_reads_opt_(c) LPCSTR lpString, _In_ UINT c, _In_reads_opt_(c) const INT *lpDx)
BOOL WINAPI PolyBezier(_In_ HDC hdc, _In_reads_(cpt) const POINT *apt, _In_ DWORD cpt)
Definition: painting.c:263
const char * name
Definition: enhmetafile.c:69
BOOL WINAPI AbortPath(_In_ HDC hdc)
HDC WINAPI CreateDCW(_In_opt_ LPCWSTR pszDriver, _In_opt_ LPCWSTR pszDevice, _In_opt_ LPCWSTR psz, _In_opt_ const DEVMODEW *pdmInit)
#define CreateFileW
Definition: compat.h:600
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
#define MWT_IDENTITY
Definition: wingdi.h:944
LPCSTR lpstr
Definition: wingdi.h:2555
#define EMR_POLYPOLYGON
Definition: wingdi.h:82
#define EMR_GLSBOUNDEDRECORD
Definition: wingdi.h:176
BOOL WINAPI BeginPath(_In_ HDC hdc)
#define MM_TEXT
Definition: wingdi.h:873
BOOL WINAPI EnumEnhMetaFile(HDC hdc, HENHMETAFILE hmf, ENHMFENUMPROC callback, LPVOID data, const RECT *lpRect)
Definition: enhmetafile.c:2371
COLORREF crBkColorSrc
Definition: wingdi.h:2047
DWORD offBmiSrc
Definition: wingdi.h:2249
TRIVERTEX Ver[1]
Definition: wingdi.h:2797
RECTL rclBox
Definition: wingdi.h:1716
BOOL WINAPI Polyline(_In_ HDC hdc, _In_reads_(cpt) const POINT *apt, _In_ int cpt)
XFORM world_transform
Definition: enhmetafile.c:531
int WINAPI SetICMMode(_In_ HDC, _In_ int)
BOOL WINAPI FlattenPath(_In_ HDC)
static void EMF_Update_MF_Xform(HDC hdc, const enum_emh_data *info)
Definition: enhmetafile.c:559
int WINAPI DrawEscape(_In_ HDC hdc, _In_ int iEscape, _In_ int cjIn, _In_reads_bytes_opt_(cjIn) LPCSTR lpIn)
DWORD offBmiMask
Definition: wingdi.h:2056
#define EMR_SETBKCOLOR
Definition: wingdi.h:99
#define EMR_BEGINPATH
Definition: wingdi.h:133
#define EMR_SETWORLDTRANSFORM
Definition: wingdi.h:109
DWORD nDescription
Definition: wingdi.h:2330
BOOL WINAPI SetWindowOrgEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
Definition: coord.c:532
XFORM xformSrc
Definition: wingdi.h:2078
#define EMR_MASKBLT
Definition: wingdi.h:151
void * free_gdi_handle(HGDIOBJ handle) DECLSPEC_HIDDEN
Definition: rosglue.c:59
DWORD offBitsSrc
Definition: wingdi.h:2251
LONG bottom
Definition: windef.h:309
BOOL WINAPI DeleteMetaFile(_In_ HMETAFILE)
LONG xDest
Definition: wingdi.h:1731
void * GDI_GetObjPtr(HGDIOBJ, WORD) DECLSPEC_HIDDEN
Definition: rosglue.c:66
BOOL WINAPI MaskBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ HDC, _In_ int, _In_ int, _In_ HBITMAP, _In_ int, _In_ int, _In_ DWORD)
#define EMR_SETVIEWPORTEXTEX
Definition: wingdi.h:85
HPEN WINAPI ExtCreatePen(_In_ DWORD iPenStyle, _In_ DWORD cWidth, _In_ const LOGBRUSH *plbrush, _In_ DWORD cStyle, _In_reads_opt_(cStyle) const DWORD *pstyle)
#define EMR_POLYGON16
Definition: wingdi.h:159
#define EMR_POLYDRAW16
Definition: wingdi.h:165
int WINAPI GetClipRgn(_In_ HDC, _In_ HRGN)
static void EMF_SetMapMode(HDC hdc, enum_emh_data *info)
Definition: enhmetafile.c:612
DWORD cbRgnData
Definition: wingdi.h:2016
static HBITMAP
Definition: button.c:44
LONG iRelative
Definition: wingdi.h:2151
#define EMR_POLYPOLYLINE16
Definition: wingdi.h:163
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
static IPrintDialogCallback callback
Definition: printdlg.c:326
FLOAT eStartAngle
Definition: wingdi.h:1711
#define EMR_SETDIBITSTODEVICE
Definition: wingdi.h:153
#define EMR_SETWINDOWORGEX
Definition: wingdi.h:84
DWORD iUsageSrc
Definition: wingdi.h:2080
BOOL WINAPI SetViewportExtEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPSIZE)
Definition: coord.c:465
#define GDICOMMENT_WINDOWS_METAFILE
Definition: wingdi.h:662
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:599
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
BOOL WINAPI SetPixelV(_In_ HDC, _In_ int, _In_ int, _In_ COLORREF)
BOOL WINAPI FillPath(_In_ HDC)
WCHAR * LPWSTR
Definition: xmlstorage.h:184
_Check_return_ _CRTIMP double __cdecl floor(_In_ double x)
#define IS_WIN9X()
Definition: enhmetafile.c:557
DWORD nPalEntries
Definition: wingdi.h:2332
int * pdx
Definition: wingdi.h:2567
DWORD offBmiMask
Definition: wingdi.h:2088
struct tagEMRESCAPE * PEMRESCAPE
static BOOL is_dib_monochrome(const BITMAPINFO *info)
Definition: enhmetafile.c:220
#define UnmapViewOfFile
Definition: compat.h:605
#define GDI_ERROR
Definition: wingdi.h:1309
LOGCOLORSPACEA lcs
Definition: wingdi.h:1799
LONG yMask
Definition: wingdi.h:2086
int WINAPI SetGraphicsMode(_In_ HDC, _In_ int)
Definition: dc.c:1226
HBRUSH WINAPI CreateDIBPatternBrushPt(_In_ const VOID *pvPackedDIB, _In_ UINT uUsage)
POINTS apts[1]
Definition: wingdi.h:2117
BOOL WINAPI RestoreDC(_In_ HDC, _In_ int)
#define EMR_RESIZEPALETTE
Definition: wingdi.h:125
LONG cy
Definition: windef.h:335
BOOL WINAPI CloseFigure(_In_ HDC hdc)
int WINAPI SetDIBits(_In_opt_ HDC, _In_ HBITMAP, _In_ UINT, _In_ UINT, _In_ CONST VOID *, _In_ CONST BITMAPINFO *, _In_ UINT)
POINTL aptlDest[3]
Definition: wingdi.h:2073
BOOL WINAPI FrameRgn(_In_ HDC, _In_ HRGN, _In_ HBRUSH, _In_ int, _In_ int)
#define MM_HIENGLISH
Definition: wingdi.h:868
#define HeapFree(x, y, z)
Definition: compat.h:594
UINT WINAPI RealizePalette(_In_ HDC)
Definition: palette.c:138
#define EMR_EXTSELECTCLIPRGN
Definition: wingdi.h:148
BOOL WINAPI PlayMetaFile(_In_ HDC, _In_ HMETAFILE)
DWORD offBitsSrc
Definition: wingdi.h:1743