ReactOS  0.4.15-dev-3442-gc05a45e
emfdc.c
Go to the documentation of this file.
1 /*
2  * Enhanced MetaFile recording functions
3  *
4  * Copyright 1999 Huw D M Davies
5  * Copyright 2016 Alexandre Julliard
6  * Copyright 2021 Jacek Caban for CodeWeavers
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 #include "config.h"
23 
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <assert.h>
28 #include "windef.h"
29 #include "winbase.h"
30 #include "wingdi.h"
31 #include "winnls.h"
32 #include "winerror.h"
33 #include "gdi_private.h"
34 #include "wine/wingdi16.h"
35 #include "wine/debug.h"
36 #ifdef __REACTOS__
37 #include "wine/winternl.h"
38 #else
39 #include "winternl.h"
40 #endif
41 
43 
44 struct emf
45 {
51  HBRUSH dc_brush;
52  HPEN dc_pen;
54 };
55 
56 #define HANDLE_LIST_INC 20
57 static const RECTL empty_bounds = { 0, 0, -1, -1 };
58 
59 static BOOL emfdc_record( struct emf *emf, EMR *emr )
60 {
61  DWORD len, size;
62  ENHMETAHEADER *emh;
63 
64  TRACE( "record %d, size %d\n", emr->iType, emr->nSize );
65 
66  assert( !(emr->nSize & 3) );
67 
68  emf->emh->nBytes += emr->nSize;
69  emf->emh->nRecords++;
70 
71  size = HeapSize( GetProcessHeap(), 0, emf->emh );
72  len = emf->emh->nBytes;
73  if (len > size)
74  {
75  size += (size / 2) + emr->nSize;
76  emh = HeapReAlloc( GetProcessHeap(), 0, emf->emh, size );
77  if (!emh) return FALSE;
78  emf->emh = emh;
79  }
80  memcpy( (char *)emf->emh + emf->emh->nBytes - emr->nSize, emr, emr->nSize );
81  return TRUE;
82 }
83 
84 static void emfdc_update_bounds( struct emf *emf, RECTL *rect )
85 {
86  RECTL *bounds = &emf->dc_attr->emf_bounds;
87  RECTL vport_rect = *rect;
88 
89  LPtoDP( emf->dc_attr->hdc, (POINT *)&vport_rect, 2 );
90 
91  /* The coordinate systems may be mirrored
92  (LPtoDP handles points, not rectangles) */
93  if (vport_rect.left > vport_rect.right)
94  {
95  LONG temp = vport_rect.right;
96  vport_rect.right = vport_rect.left;
97  vport_rect.left = temp;
98  }
99  if (vport_rect.top > vport_rect.bottom)
100  {
101  LONG temp = vport_rect.bottom;
102  vport_rect.bottom = vport_rect.top;
103  vport_rect.top = temp;
104  }
105 
106  if (bounds->left > bounds->right)
107  {
108  /* first bounding rectangle */
109  *bounds = vport_rect;
110  }
111  else
112  {
113  bounds->left = min(bounds->left, vport_rect.left);
114  bounds->top = min(bounds->top, vport_rect.top);
115  bounds->right = max(bounds->right, vport_rect.right);
116  bounds->bottom = max(bounds->bottom, vport_rect.bottom);
117  }
118 }
119 
121 {
122  HBITMAP blit_bitmap;
123  HDC blit_dc;
124  UINT info_size, bpp;
125  DIBSECTION dib;
126 
127  if (!(info_size = GetObjectW( *bitmap, sizeof(dib), &dib ))) return 0;
128 
129  if (info_size == sizeof(dib))
130  {
131  blit_dc = *hdc;
132  blit_bitmap = *bitmap;
133  }
134  else
135  {
136  unsigned char dib_info_buffer[FIELD_OFFSET(BITMAPINFO, bmiColors)
137  + 256*RTL_FIELD_SIZE(BITMAPINFO, bmiColors)];
138  BITMAPINFO *dib_info = (BITMAPINFO *)dib_info_buffer;
139  BITMAP bmp = dib.dsBm;
140  HPALETTE palette;
141  void *bits;
142 
143  assert( info_size == sizeof(BITMAP) );
144 
145  dib_info->bmiHeader.biSize = sizeof(dib_info->bmiHeader);
146  dib_info->bmiHeader.biWidth = bmp.bmWidth;
147  dib_info->bmiHeader.biHeight = bmp.bmHeight;
148  dib_info->bmiHeader.biPlanes = 1;
149  dib_info->bmiHeader.biBitCount = bmp.bmBitsPixel;
150  dib_info->bmiHeader.biCompression = BI_RGB;
151  dib_info->bmiHeader.biSizeImage = 0;
152  dib_info->bmiHeader.biXPelsPerMeter = 0;
153  dib_info->bmiHeader.biYPelsPerMeter = 0;
154  dib_info->bmiHeader.biClrUsed = 0;
155  dib_info->bmiHeader.biClrImportant = 0;
156  switch (dib_info->bmiHeader.biBitCount)
157  {
158  case 16:
159  ((DWORD *)dib_info->bmiColors)[0] = 0xf800;
160  ((DWORD *)dib_info->bmiColors)[1] = 0x07e0;
161  ((DWORD *)dib_info->bmiColors)[2] = 0x001f;
162  break;
163  case 32:
164  ((DWORD *)dib_info->bmiColors)[0] = 0xff0000;
165  ((DWORD *)dib_info->bmiColors)[1] = 0x00ff00;
166  ((DWORD *)dib_info->bmiColors)[2] = 0x0000ff;
167  break;
168  default:
169  if (dib_info->bmiHeader.biBitCount > 8) break;
170  if (!(palette = GetCurrentObject( *hdc, OBJ_PAL ))) return FALSE;
171  if (!GetPaletteEntries( palette, 0, 256, (PALETTEENTRY *)dib_info->bmiColors ))
172  return FALSE;
173  }
174 
175  if (!(blit_dc = /*NtGdi*/CreateCompatibleDC( *hdc ))) return FALSE;
176  if (!(blit_bitmap = CreateDIBSection( blit_dc, dib_info, DIB_RGB_COLORS, &bits, NULL, 0 )))
177  goto err;
178  if (!SelectObject( blit_dc, blit_bitmap )) goto err;
179  if (!BitBlt( blit_dc, 0, 0, bmp.bmWidth, bmp.bmHeight, *hdc, 0, 0, SRCCOPY ))
180  goto err;
181  }
182  if (!GetDIBits( blit_dc, blit_bitmap, 0, INT_MAX, NULL, info, DIB_RGB_COLORS ))
183  goto err;
184 
185  bpp = info->bmiHeader.biBitCount;
186  if (bpp <= 8)
187  return sizeof(BITMAPINFOHEADER) + (1L << bpp) * sizeof(RGBQUAD);
188  else if (bpp == 16 || bpp == 32)
189  return sizeof(BITMAPINFOHEADER) + 3 * sizeof(RGBQUAD);
190 
191  return sizeof(BITMAPINFOHEADER);
192 
193 err:
194  if (blit_dc && blit_dc != *hdc) DeleteDC( blit_dc );
195  if (blit_bitmap && blit_bitmap != *bitmap) DeleteObject( blit_bitmap );
196  return 0;
197 }
198 
200 {
201  UINT index;
202 
203  for (index = 0; index < emf->handles_size; index++)
204  if (emf->handles[index] == 0) break;
205 
206  if (index == emf->handles_size)
207  {
210  emf->handles,
211  emf->handles_size * sizeof(emf->handles[0]) );
212  }
214 
215  emf->cur_handles++;
216  if (emf->cur_handles > emf->emh->nHandles)
217  emf->emh->nHandles++;
218 
219  return index + 1; /* index 0 is reserved for the hmf, so we increment everything by 1 */
220 }
221 
223 {
224  UINT index;
225 
226  for (index = 0; index < emf->handles_size; index++)
227  if (emf->handles[index] == obj) return index + 1;
228 
229  return 0;
230 }
231 
233 {
234  WINEDC *dc_attr = get_dc_ptr( hdc );
235  struct emf *emf = dc_attr->emf;
236  EMRDELETEOBJECT emr;
237  UINT index;
238 
239  if(!(index = emfdc_find_object( emf, obj ))) return;
240 
241  emr.emr.iType = EMR_DELETEOBJECT;
242  emr.emr.nSize = sizeof(emr);
243  emr.ihObject = index;
244 
245  emfdc_record( emf, &emr.emr );
246 
247  emf->handles[index - 1] = 0;
248  emf->cur_handles--;
249 }
250 
251 static DWORD emfdc_create_brush( struct emf *emf, HBRUSH brush )
252 {
253  DWORD index = 0;
254  LOGBRUSH logbrush;
255 
256  if (!GetObjectA( brush, sizeof(logbrush), &logbrush )) return 0;
257 
258  switch (logbrush.lbStyle) {
259  case BS_SOLID:
260  case BS_HATCHED:
261  case BS_NULL:
262  {
265  emr.emr.nSize = sizeof(emr);
266  emr.ihBrush = index = emfdc_add_handle( emf, brush );
267  emr.lb.lbStyle = logbrush.lbStyle;
268  emr.lb.lbColor = logbrush.lbColor;
269  emr.lb.lbHatch = logbrush.lbHatch;
270 
271  if(!emfdc_record( emf, &emr.emr ))
272  index = 0;
273  }
274  break;
275  case BS_PATTERN:
276  case BS_DIBPATTERN:
277  {
278  unsigned char buffer[FIELD_OFFSET(BITMAPINFO, bmiColors)
279  + 256*RTL_FIELD_SIZE(BITMAPINFO, bmiColors)];
282  DWORD info_size;
283  UINT usage;
284 
285  if (!get_brush_bitmap_info( brush, info, NULL, &usage )) break;
286  info_size = get_dib_info_size( info, usage );
287 
288  emr = HeapAlloc( GetProcessHeap(), 0,
289  sizeof(EMRCREATEDIBPATTERNBRUSHPT) + sizeof(DWORD) +
290  info_size+info->bmiHeader.biSizeImage );
291  if(!emr) break;
292 
293  /* FIXME: There is an extra DWORD written by native before the BMI.
294  * Not sure what it's meant to contain.
295  */
296  emr->offBmi = sizeof( EMRCREATEDIBPATTERNBRUSHPT ) + sizeof(DWORD);
297  *(DWORD *)(emr + 1) = 0x20000000;
298 
299  if (logbrush.lbStyle == BS_PATTERN && info->bmiHeader.biBitCount == 1)
300  {
301  /* Presumably to reduce the size of the written EMF, MS supports an
302  * undocumented iUsage value of 2, indicating a mono bitmap without the
303  * 8 byte 2 entry black/white palette. Stupidly, they could have saved
304  * over 20 bytes more by also ignoring the BITMAPINFO fields that are
305  * irrelevant/constant for monochrome bitmaps.
306  * FIXME: It may be that the DIB functions themselves accept this value.
307  */
310  emr->cbBmi = sizeof( BITMAPINFOHEADER );
311  }
312  else
313  {
315  emr->cbBmi = info_size;
316  }
317  emr->ihBrush = index = emfdc_add_handle( emf, brush );
318  emr->iUsage = usage;
319  emr->offBits = emr->offBmi + emr->cbBmi;
320  emr->cbBits = info->bmiHeader.biSizeImage;
321  emr->emr.nSize = emr->offBits + emr->cbBits;
322 
323  if (info->bmiHeader.biClrUsed == 1 << info->bmiHeader.biBitCount)
324  info->bmiHeader.biClrUsed = 0;
325  memcpy( (BYTE *)emr + emr->offBmi, info, emr->cbBmi );
326  get_brush_bitmap_info( brush, NULL, (char *)emr + emr->offBits, NULL );
327 
328  if (!emfdc_record( emf, &emr->emr )) index = 0;
329  HeapFree( GetProcessHeap(), 0, emr );
330  }
331  break;
332 
333  default:
334  FIXME("Unknown style %x\n", logbrush.lbStyle);
335  break;
336  }
337 
338  return index;
339 }
340 
341 static BOOL emfdc_select_brush( WINEDC *dc_attr, HBRUSH brush )
342 {
343  struct emf *emf = dc_attr->emf;
344  EMRSELECTOBJECT emr;
345  DWORD index = 0;
346  int i;
347 
348  /* If the object is a stock brush object, do not need to create it.
349  * See definitions in wingdi.h for range of stock brushes.
350  * We do however have to handle setting the higher order bit to
351  * designate that this is a stock object.
352  */
353  for (i = WHITE_BRUSH; i <= DC_BRUSH; i++)
354  {
355  if (brush == GetStockObject(i))
356  {
357  index = i | 0x80000000;
358  break;
359  }
360  }
361 
362  if (!index && !(index = emfdc_find_object( emf, brush )))
363  {
364  if (!(index = emfdc_create_brush( emf, brush ))) return 0;
365  GDI_hdc_using_object( brush, dc_attr->hdc);//, emfdc_delete_object );
366  }
367 
368  emr.emr.iType = EMR_SELECTOBJECT;
369  emr.emr.nSize = sizeof(emr);
370  emr.ihObject = index;
371  return emfdc_record( emf, &emr.emr );
372 }
373 
375 {
376  DWORD index = 0;
378  int i;
379 
380  if (!GetObjectW( font, sizeof(emr.elfw.elfLogFont), &emr.elfw.elfLogFont )) return FALSE;
381 
383  emr.emr.nSize = (sizeof(emr) + 3) / 4 * 4;
384  emr.ihFont = index = emfdc_add_handle( emf, font );
385  emr.elfw.elfFullName[0] = '\0';
386  emr.elfw.elfStyle[0] = '\0';
387  emr.elfw.elfVersion = 0;
388  emr.elfw.elfStyleSize = 0;
389  emr.elfw.elfMatch = 0;
390  emr.elfw.elfReserved = 0;
391  for (i = 0; i < ELF_VENDOR_SIZE; i++)
392  emr.elfw.elfVendorId[i] = 0;
404 
405  return emfdc_record( emf, &emr.emr ) ? index : 0;
406 }
407 
409 {
410  struct emf *emf = dc_attr->emf;
411  EMRSELECTOBJECT emr;
412  DWORD index;
413  int i;
414 
415  /* If the object is a stock font object, do not need to create it.
416  * See definitions in wingdi.h for range of stock fonts.
417  * We do however have to handle setting the higher order bit to
418  * designate that this is a stock object.
419  */
420 
421  for (i = OEM_FIXED_FONT; i <= DEFAULT_GUI_FONT; i++)
422  {
423  if (i != DEFAULT_PALETTE && font == GetStockObject(i))
424  {
425  index = i | 0x80000000;
426  goto found;
427  }
428  }
429 
430  if (!(index = emfdc_find_object( emf, font )))
431  {
432  if (!(index = emfdc_create_font( emf, font ))) return FALSE;
433  GDI_hdc_using_object( font, dc_attr->hdc);//, emfdc_delete_object );
434  }
435 
436  found:
437  emr.emr.iType = EMR_SELECTOBJECT;
438  emr.emr.nSize = sizeof(emr);
439  emr.ihObject = index;
440  return emfdc_record( emf, &emr.emr );
441 }
442 
443 static DWORD emfdc_create_pen( struct emf *emf, HPEN hPen )
444 {
445  EMRCREATEPEN emr;
446  DWORD index = 0;
447 
448  if (!GetObjectW( hPen, sizeof(emr.lopn), &emr.lopn ))
449  {
450  /* must be an extended pen */
451  EXTLOGPEN *elp;
452  INT size = GetObjectW( hPen, 0, NULL );
453 
454  if (!size) return 0;
455 
456  elp = HeapAlloc( GetProcessHeap(), 0, size );
457 
458  GetObjectW( hPen, size, elp );
459  /* FIXME: add support for user style pens */
460  emr.lopn.lopnStyle = elp->elpPenStyle;
461  emr.lopn.lopnWidth.x = elp->elpWidth;
462  emr.lopn.lopnWidth.y = 0;
463  emr.lopn.lopnColor = elp->elpColor;
464 
465  HeapFree( GetProcessHeap(), 0, elp );
466  }
467 
468  emr.emr.iType = EMR_CREATEPEN;
469  emr.emr.nSize = sizeof(emr);
470  emr.ihPen = index = emfdc_add_handle( emf, hPen );
471  return emfdc_record( emf, &emr.emr ) ? index : 0;
472 }
473 
474 static BOOL emfdc_select_pen( WINEDC *dc_attr, HPEN pen )
475 {
476  struct emf *emf = dc_attr->emf;
477  EMRSELECTOBJECT emr;
478  DWORD index = 0;
479  int i;
480 
481  /* If the object is a stock pen object, do not need to create it.
482  * See definitions in wingdi.h for range of stock pens.
483  * We do however have to handle setting the higher order bit to
484  * designate that this is a stock object.
485  */
486 
487  for (i = WHITE_PEN; i <= DC_PEN; i++)
488  {
489  if (pen == GetStockObject(i))
490  {
491  index = i | 0x80000000;
492  break;
493  }
494  }
495  if (!index && !(index = emfdc_find_object( emf, pen )))
496  {
497  if (!(index = emfdc_create_pen( emf, pen ))) return FALSE;
498  GDI_hdc_using_object( pen, dc_attr->hdc);//, emfdc_delete_object );
499  }
500 
501  emr.emr.iType = EMR_SELECTOBJECT;
502  emr.emr.nSize = sizeof(emr);
503  emr.ihObject = index;
504  return emfdc_record( emf, &emr.emr );
505 }
506 
507 static DWORD emfdc_create_palette( struct emf *emf, HPALETTE hPal )
508 {
509  WORD i;
510  struct {
512  PALETTEENTRY entry[255];
513  } pal;
514 
515  memset( &pal, 0, sizeof(pal) );
516 
517  if (!GetObjectW( hPal, sizeof(pal.hdr.lgpl) + sizeof(pal.entry), &pal.hdr.lgpl ))
518  return 0;
519 
520  for (i = 0; i < pal.hdr.lgpl.palNumEntries; i++)
521  pal.hdr.lgpl.palPalEntry[i].peFlags = 0;
522 
523  pal.hdr.emr.iType = EMR_CREATEPALETTE;
524  pal.hdr.emr.nSize = sizeof(pal.hdr) + pal.hdr.lgpl.palNumEntries * sizeof(PALETTEENTRY);
525  pal.hdr.ihPal = emfdc_add_handle( emf, hPal );
526 
527  if (!emfdc_record( emf, &pal.hdr.emr ))
528  pal.hdr.ihPal = 0;
529  return pal.hdr.ihPal;
530 }
531 
532 BOOL EMFDC_SelectPalette( WINEDC *dc_attr, HPALETTE palette )
533 {
534  struct emf *emf = dc_attr->emf;
535  EMRSELECTPALETTE emr;
536  DWORD index = 0;
537 
539  {
540  index = DEFAULT_PALETTE | 0x80000000;
541  }
542  else if (!(index = emfdc_find_object( emf, palette )))
543  {
544  if (!(index = emfdc_create_palette( emf, palette ))) return 0;
545  GDI_hdc_using_object( palette, dc_attr->hdc);//, emfdc_delete_object );
546  }
547 
549  emr.emr.nSize = sizeof(emr);
550  emr.ihPal = index;
551  return emfdc_record( emf, &emr.emr );
552 }
553 
555 {
556  switch (GDI_HANDLE_GET_TYPE( obj ))
557  {
559  return emfdc_select_brush( dc_attr, obj );
561  return emfdc_select_font( dc_attr, obj );
564  return emfdc_select_pen( dc_attr, obj );
565  default:
566  return TRUE;
567  }
568 }
569 
570 /* determine if we can use 16-bit points to store all the input points */
571 static BOOL can_use_short_points( const POINT *pts, UINT count )
572 {
573  UINT i;
574 
575  for (i = 0; i < count; i++)
576  if (((pts[i].x + 0x8000) & ~0xffff) || ((pts[i].y + 0x8000) & ~0xffff))
577  return FALSE;
578  return TRUE;
579 }
580 
581 /* store points in either long or short format; return a pointer to the end of the stored data */
582 static void *store_points( POINTL *dest, const POINT *pts, UINT count, BOOL short_points )
583 {
584  if (short_points)
585  {
586  UINT i;
587  POINTS *dest_short = (POINTS *)dest;
588 
589  for (i = 0; i < count; i++)
590  {
591  dest_short[i].x = pts[i].x;
592  dest_short[i].y = pts[i].y;
593  }
594  return dest_short + count;
595  }
596  else
597  {
598  memcpy( dest, pts, count * sizeof(*dest) );
599  return dest + count;
600  }
601 }
602 
603 /* compute the bounds of an array of points, optionally including the current position */
604 static void get_points_bounds( RECTL *bounds, const POINT *pts, UINT count, WINEDC *dc_attr )
605 {
606  UINT i;
607 
608  if (dc_attr)
609  {
610  POINT cur_pos;
611  GetCurrentPositionEx(dc_attr->hdc, &cur_pos);
612  bounds->left = bounds->right = cur_pos.x;
613  bounds->top = bounds->bottom = cur_pos.y;
614  }
615  else if (count)
616  {
617  bounds->left = bounds->right = pts[0].x;
618  bounds->top = bounds->bottom = pts[0].y;
619  }
620  else *bounds = empty_bounds;
621 
622  for (i = 0; i < count; i++)
623  {
624  bounds->left = min( bounds->left, pts[i].x );
625  bounds->right = max( bounds->right, pts[i].x );
626  bounds->top = min( bounds->top, pts[i].y );
627  bounds->bottom = max( bounds->bottom, pts[i].y );
628  }
629 }
630 
631 /* helper for path stroke and fill functions */
632 #ifdef __REACTOS__
633 static BOOL emfdrv_stroke_and_fill_path( struct emf *emf, INT type )
634 {
636  LPPOINT Points;
637  LPBYTE Types;
638  INT nSize;
639 
640  emr.emr.iType = type;
641  emr.emr.nSize = sizeof(emr);
642 
643  nSize = GetPath(emf->dc_attr->hdc, NULL, NULL, 0);
644  if (nSize != -1)
645  {
646  Points = HeapAlloc( GetProcessHeap(), 0, nSize*sizeof(POINT) );
647  Types = HeapAlloc( GetProcessHeap(), 0, nSize*sizeof(BYTE) );
648 
649  GetPath(emf->dc_attr->hdc, Points, Types, nSize);
650  get_points_bounds( &emr.rclBounds, Points, nSize, 0 );
651 
652  HeapFree( GetProcessHeap(), 0, Points );
653  HeapFree( GetProcessHeap(), 0, Types );
654 
655  TRACE("GetBounds l %d t %d r %d b %d\n",emr.rclBounds.left, emr.rclBounds.top, emr.rclBounds.right, emr.rclBounds.bottom);
656  }
657  else emr.rclBounds = empty_bounds;
658 
659  if (!emfdc_record( emf, &emr.emr )) return FALSE;
660  if (nSize == -1 ) return FALSE;
662  return TRUE;
663 }
664 #else
666 {
668  HRGN region;
669 
670  emr.emr.iType = type;
671  emr.emr.nSize = sizeof(emr);
672  emr.rclBounds = empty_bounds;
673 
674  if ((region = NtGdiPathToRegion( emf->dc_attr->hdc ))) // WTF are you doing? This removes path!!!
675  {
676  NtGdiGetRgnBox( region, (RECT *)&emr.rclBounds );
677  DeleteObject( region );
678  }
679  if (!emfdc_record( emf, &emr.emr )) return FALSE;
680  if (!region) return FALSE;
682  return TRUE;
683 }
684 #endif
686 {
687  struct emf *emf = dc_attr->emf;
688  EMRMOVETOEX emr;
689 
690  emr.emr.iType = EMR_MOVETOEX;
691  emr.emr.nSize = sizeof(emr);
692  emr.ptl.x = x;
693  emr.ptl.y = y;
694  return emfdc_record( emf, &emr.emr );
695 }
696 
698 {
699  EMRLINETO emr;
700  BOOL Ret;
701 
702  emr.emr.iType = EMR_LINETO;
703  emr.emr.nSize = sizeof(emr);
704  emr.ptl.x = x;
705  emr.ptl.y = y;
706  Ret = emfdc_record( dc_attr->emf, &emr.emr );
707  EMFDRV_LineTo( dc_attr, x, y );
708  return Ret;
709 }
710 
712  INT xstart, INT ystart, INT xend, INT yend, DWORD type )
713 {
714  struct emf *emf = dc_attr->emf;
715  EMRARC emr;
716  INT temp;
717  BOOL Ret;
718 
719  if (left == right || top == bottom) return FALSE;
720 
721  if (left > right) { temp = left; left = right; right = temp; }
722  if (top > bottom) { temp = top; top = bottom; bottom = temp; }
723 
725  {
726  right--;
727  bottom--;
728  }
729 
730  emr.emr.iType = type;
731  emr.emr.nSize = sizeof(emr);
732  emr.rclBox.left = left;
733  emr.rclBox.top = top;
734  emr.rclBox.right = right;
735  emr.rclBox.bottom = bottom;
736  emr.ptlStart.x = xstart;
737  emr.ptlStart.y = ystart;
738  emr.ptlEnd.x = xend;
739  emr.ptlEnd.y = yend;
740  Ret = emfdc_record( emf, &emr.emr );
741  EMFDRV_ArcChordPie( dc_attr, left, top, right, bottom, xstart, ystart, xend, yend, type );
742  return Ret;
743 }
744 
746 {
747  EMRANGLEARC emr;
748 
749  emr.emr.iType = EMR_ANGLEARC;
750  emr.emr.nSize = sizeof( emr );
751  emr.ptlCenter.x = x;
752  emr.ptlCenter.y = y;
753  emr.nRadius = radius;
754  emr.eStartAngle = start;
755  emr.eSweepAngle = sweep;
756  return emfdc_record( dc_attr->emf, &emr.emr );
757 }
758 
760 {
761  struct emf *emf = dc_attr->emf;
762  EMRELLIPSE emr;
763  BOOL Ret;
764 
765  if (left == right || top == bottom) return FALSE;
766 
767  emr.emr.iType = EMR_ELLIPSE;
768  emr.emr.nSize = sizeof(emr);
769  emr.rclBox.left = min( left, right );
770  emr.rclBox.top = min( top, bottom );
771  emr.rclBox.right = max( left, right );
772  emr.rclBox.bottom = max( top, bottom );
774  {
775  emr.rclBox.right--;
776  emr.rclBox.bottom--;
777  }
778  Ret = emfdc_record( emf, &emr.emr );
780  return Ret;
781 }
782 
784 {
785  struct emf *emf = dc_attr->emf;
786  EMRRECTANGLE emr;
787  BOOL Ret;
788 
789  if(left == right || top == bottom) return FALSE;
790 
791  emr.emr.iType = EMR_RECTANGLE;
792  emr.emr.nSize = sizeof(emr);
793  emr.rclBox.left = min( left, right );
794  emr.rclBox.top = min( top, bottom );
795  emr.rclBox.right = max( left, right );
796  emr.rclBox.bottom = max( top, bottom );
798  {
799  emr.rclBox.right--;
800  emr.rclBox.bottom--;
801  }
802  Ret = emfdc_record( emf, &emr.emr );
804  return Ret;
805 }
806 
808  INT bottom, INT ell_width, INT ell_height )
809 {
810  struct emf *emf = dc_attr->emf;
811  EMRROUNDRECT emr;
812  BOOL Ret;
813 
814  if (left == right || top == bottom) return FALSE;
815 
816  emr.emr.iType = EMR_ROUNDRECT;
817  emr.emr.nSize = sizeof(emr);
818  emr.rclBox.left = min( left, right );
819  emr.rclBox.top = min( top, bottom );
820  emr.rclBox.right = max( left, right );
821  emr.rclBox.bottom = max( top, bottom );
822  emr.szlCorner.cx = ell_width;
823  emr.szlCorner.cy = ell_height;
825  {
826  emr.rclBox.right--;
827  emr.rclBox.bottom--;
828  }
829  Ret = emfdc_record( emf, &emr.emr );
830  EMFDRV_RoundRect( dc_attr, left, top, right, bottom, ell_width, ell_height );
831  return Ret;
832 }
833 
835 {
836  EMRSETPIXELV emr;
837  BOOL Ret;
838 
839  emr.emr.iType = EMR_SETPIXELV;
840  emr.emr.nSize = sizeof(emr);
841  emr.ptlPixel.x = x;
842  emr.ptlPixel.y = y;
843  emr.crColor = color;
844  Ret = emfdc_record( dc_attr->emf, &emr.emr );
846  return Ret;
847 }
848 
850 {
851  struct emf *emf = dc_attr->emf;
852  EMRPOLYLINE *emr;
853  DWORD size;
854  BOOL ret, use_small_emr = can_use_short_points( points, count );
855 
856  size = use_small_emr ? (DWORD)offsetof( EMRPOLYLINE16, apts[count] ) : (DWORD)offsetof( EMRPOLYLINE, aptl[count] );
857 
858  emr = HeapAlloc( GetProcessHeap(), 0, size );
859  emr->emr.iType = use_small_emr ? type + EMR_POLYLINE16 - EMR_POLYLINE : type;
860  emr->emr.nSize = size;
861  emr->cptl = count;
862 
863  store_points( emr->aptl, points, count, use_small_emr );
864 
865  if (!emf->path)
867  (type == EMR_POLYBEZIERTO || type == EMR_POLYLINETO) ? dc_attr : 0 );
868  else
869  emr->rclBounds = empty_bounds;
870 
871  ret = emfdc_record( emf, &emr->emr );
872  if (ret && !emf->path) emfdc_update_bounds( emf, &emr->rclBounds );
873  HeapFree( GetProcessHeap(), 0, emr );
874  return ret;
875 }
876 
878 {
880 }
881 
883 {
885 }
886 
888 {
889  if(count < 2) return FALSE;
891 }
892 
894 {
896 }
897 
899 {
901 }
902 
903 static BOOL emfdc_poly_polylinegon( struct emf *emf, const POINT *pt, const INT *counts,
904  UINT polys, DWORD type)
905 {
906  EMRPOLYPOLYLINE *emr;
907  DWORD cptl = 0, poly, size;
908  BOOL ret, use_small_emr, bounds_valid = TRUE;
909 
910  for(poly = 0; poly < polys; poly++) {
911  cptl += counts[poly];
912  if(counts[poly] < 2) bounds_valid = FALSE;
913  }
914  if(!cptl) bounds_valid = FALSE;
915  use_small_emr = can_use_short_points( pt, cptl );
916 
917  size = FIELD_OFFSET(EMRPOLYPOLYLINE, aPolyCounts[polys]);
918  if(use_small_emr)
919  size += cptl * sizeof(POINTS);
920  else
921  size += cptl * sizeof(POINTL);
922 
923  emr = HeapAlloc( GetProcessHeap(), 0, size );
924 
925  emr->emr.iType = type;
926  if(use_small_emr) emr->emr.iType += EMR_POLYPOLYLINE16 - EMR_POLYPOLYLINE;
927 
928  emr->emr.nSize = size;
929  if(bounds_valid && !emf->path)
930  get_points_bounds( &emr->rclBounds, pt, cptl, 0 );
931  else
932  emr->rclBounds = empty_bounds;
933  emr->nPolys = polys;
934  emr->cptl = cptl;
935 
936  if(polys)
937  {
938  memcpy( emr->aPolyCounts, counts, polys * sizeof(DWORD) );
939  store_points( (POINTL *)(emr->aPolyCounts + polys), pt, cptl, use_small_emr );
940  }
941 
942  ret = emfdc_record( emf, &emr->emr );
943  if(ret && !bounds_valid)
944  {
945  ret = FALSE;
947  }
948  if(ret && !emf->path)
949  emfdc_update_bounds( emf, &emr->rclBounds );
950  HeapFree( GetProcessHeap(), 0, emr );
951  return ret;
952 }
953 
954 BOOL EMFDC_PolyPolyline( WINEDC *dc_attr, const POINT *pt, const DWORD *counts, DWORD polys)
955 {
956  return emfdc_poly_polylinegon( dc_attr->emf, pt, (const INT *)counts, polys, EMR_POLYPOLYLINE );
957 }
958 
959 BOOL EMFDC_PolyPolygon( WINEDC *dc_attr, const POINT *pt, const INT *counts, UINT polys )
960 {
961  return emfdc_poly_polylinegon( dc_attr->emf, pt, counts, polys, EMR_POLYPOLYGON );
962 }
963 
965 {
966  struct emf *emf = dc_attr->emf;
967  EMRPOLYDRAW *emr;
968  BOOL ret;
969  BYTE *types_dest;
970  BOOL use_small_emr = can_use_short_points( pts, count );
971  DWORD size;
972 
973  size = use_small_emr ? (DWORD)offsetof( EMRPOLYDRAW16, apts[count] )
974  : (DWORD)offsetof( EMRPOLYDRAW, aptl[count] );
975  size += (count + 3) & ~3;
976 
977  if (!(emr = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
978 
979  emr->emr.iType = use_small_emr ? EMR_POLYDRAW16 : EMR_POLYDRAW;
980  emr->emr.nSize = size;
981  emr->cptl = count;
982 
983  types_dest = store_points( emr->aptl, pts, count, use_small_emr );
984  memcpy( types_dest, types, count );
985  if (count & 3) memset( types_dest + count, 0, 4 - (count & 3) );
986 
987  if (!emf->path)
988  get_points_bounds( &emr->rclBounds, pts, count, 0 );
989  else
990  emr->rclBounds = empty_bounds;
991 
992  ret = emfdc_record( emf, &emr->emr );
993  if (ret && !emf->path) emfdc_update_bounds( emf, &emr->rclBounds );
994  HeapFree( GetProcessHeap(), 0, emr );
995  return ret;
996 }
997 
999 {
1000  EMREXTFLOODFILL emr;
1001 
1002  emr.emr.iType = EMR_EXTFLOODFILL;
1003  emr.emr.nSize = sizeof(emr);
1004  emr.ptlStart.x = x;
1005  emr.ptlStart.y = y;
1006  emr.crColor = color;
1007  emr.iMode = fill_type;
1008  return emfdc_record( dc_attr->emf, &emr.emr );
1009 }
1010 
1012 {
1013  struct emf *emf = dc_attr->emf;
1014  EMRFILLRGN *emr;
1015  DWORD size, rgnsize, index;
1016  BOOL ret;
1017 
1018  if (!(index = emfdc_create_brush( emf, hbrush ))) return FALSE;
1019 
1020  rgnsize = /*NtGdi*/GetRegionData( hrgn, 0, NULL );
1021  size = rgnsize + offsetof(EMRFILLRGN,RgnData);
1022  emr = HeapAlloc( GetProcessHeap(), 0, size );
1023 
1024  /*NtGdi*/GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
1025 
1026  emr->emr.iType = EMR_FILLRGN;
1027  emr->emr.nSize = size;
1028  emr->rclBounds.left = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.left;
1029  emr->rclBounds.top = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.top;
1030  emr->rclBounds.right = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.right - 1;
1031  emr->rclBounds.bottom = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.bottom - 1;
1032  emr->cbRgnData = rgnsize;
1033  emr->ihBrush = index;
1034 
1035  ret = emfdc_record( emf, &emr->emr );
1036  if (ret) emfdc_update_bounds( emf, &emr->rclBounds );
1037  HeapFree( GetProcessHeap(), 0, emr );
1038  return ret;
1039 }
1040 
1042 {
1043  struct emf *emf = dc_attr->emf;
1044  EMRFRAMERGN *emr;
1045  DWORD size, rgnsize, index;
1046  BOOL ret;
1047 
1049  if(!index) return FALSE;
1050 
1051  rgnsize = /*NtGdi*/GetRegionData( hrgn, 0, NULL );
1052  size = rgnsize + offsetof(EMRFRAMERGN,RgnData);
1053  emr = HeapAlloc( GetProcessHeap(), 0, size );
1054 
1055  /*NtGdi*/GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
1056 
1057  emr->emr.iType = EMR_FRAMERGN;
1058  emr->emr.nSize = size;
1059  emr->rclBounds.left = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.left;
1060  emr->rclBounds.top = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.top;
1061  emr->rclBounds.right = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.right - 1;
1062  emr->rclBounds.bottom = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.bottom - 1;
1063  emr->cbRgnData = rgnsize;
1064  emr->ihBrush = index;
1065  emr->szlStroke.cx = width;
1066  emr->szlStroke.cy = height;
1067 
1068  ret = emfdc_record( emf, &emr->emr );
1069  if (ret) emfdc_update_bounds( emf, &emr->rclBounds );
1070  HeapFree( GetProcessHeap(), 0, emr );
1071  return ret;
1072 }
1073 
1075 {
1076  EMRINVERTRGN *emr;
1077  DWORD size, rgnsize;
1078  BOOL ret;
1079 
1080  rgnsize = /*NtGdi*/GetRegionData( hrgn, 0, NULL );
1081  size = rgnsize + offsetof(EMRINVERTRGN,RgnData);
1082  emr = HeapAlloc( GetProcessHeap(), 0, size );
1083 
1084  /*NtGdi*/GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
1085 
1086  emr->emr.iType = iType;
1087  emr->emr.nSize = size;
1088  emr->rclBounds.left = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.left;
1089  emr->rclBounds.top = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.top;
1090  emr->rclBounds.right = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.right - 1;
1091  emr->rclBounds.bottom = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.bottom - 1;
1092  emr->cbRgnData = rgnsize;
1093 
1094  ret = emfdc_record( emf, &emr->emr );
1095  if (ret) emfdc_update_bounds( emf, &emr->rclBounds );
1096  HeapFree( GetProcessHeap(), 0, emr );
1097  return ret;
1098 }
1099 
1101 {
1103 }
1104 
1106 {
1108 }
1109 
1111  const WCHAR *str, UINT count, const INT *dx )
1112 {
1113  struct emf *emf = dc_attr->emf;
1114  FLOAT ex_scale, ey_scale;
1115  EMREXTTEXTOUTW *emr;
1116  int text_height = 0;
1117  int text_width = 0;
1118  TEXTMETRICW tm;
1119  DWORD size;
1120  BOOL ret;
1121 
1122  if (count > INT_MAX) return FALSE;
1123 
1124  size = sizeof(*emr) + ((count+1) & ~1) * sizeof(WCHAR) + count * sizeof(INT);
1125 
1126  TRACE( "%s %s count %d size = %d\n", debugstr_wn(str, count),
1129 
1131  {
1132  const INT horzSize = GetDeviceCaps( dc_attr->hdc, HORZSIZE );
1133  const INT horzRes = GetDeviceCaps( dc_attr->hdc, HORZRES );
1134  const INT vertSize = GetDeviceCaps( dc_attr->hdc, VERTSIZE );
1135  const INT vertRes = GetDeviceCaps( dc_attr->hdc, VERTRES );
1136  SIZE wndext, vportext;
1137 
1138  GetViewportExtEx( dc_attr->hdc, &vportext );
1139  GetWindowExtEx( dc_attr->hdc, &wndext );
1140  ex_scale = 100.0 * ((FLOAT)horzSize / (FLOAT)horzRes) /
1141  ((FLOAT)wndext.cx / (FLOAT)vportext.cx);
1142  ey_scale = 100.0 * ((FLOAT)vertSize / (FLOAT)vertRes) /
1143  ((FLOAT)wndext.cy / (FLOAT)vportext.cy);
1144  }
1145  else
1146  {
1147  ex_scale = 0.0;
1148  ey_scale = 0.0;
1149  }
1150 
1151  emr->emr.iType = EMR_EXTTEXTOUTW;
1152  emr->emr.nSize = size;
1154  emr->exScale = ex_scale;
1155  emr->eyScale = ey_scale;
1156  emr->emrtext.ptlReference.x = x;
1157  emr->emrtext.ptlReference.y = y;
1158  emr->emrtext.nChars = count;
1159  emr->emrtext.offString = sizeof(*emr);
1160  memcpy( (char*)emr + emr->emrtext.offString, str, count * sizeof(WCHAR) );
1161  emr->emrtext.fOptions = flags;
1162  if (!rect)
1163  {
1164  emr->emrtext.rcl.left = emr->emrtext.rcl.top = 0;
1165  emr->emrtext.rcl.right = emr->emrtext.rcl.bottom = -1;
1166  }
1167  else
1168  {
1169  emr->emrtext.rcl.left = rect->left;
1170  emr->emrtext.rcl.top = rect->top;
1171  emr->emrtext.rcl.right = rect->right;
1172  emr->emrtext.rcl.bottom = rect->bottom;
1173  }
1174 
1175  emr->emrtext.offDx = emr->emrtext.offString + ((count+1) & ~1) * sizeof(WCHAR);
1176  if (dx)
1177  {
1178  UINT i;
1179  SIZE str_size;
1180  memcpy( (char*)emr + emr->emrtext.offDx, dx, count * sizeof(INT) );
1181  for (i = 0; i < count; i++) text_width += dx[i];
1182  if (GetTextExtentPoint32W( dc_attr->hdc, str, count, &str_size ))
1183  text_height = str_size.cy;
1184  }
1185  else
1186  {
1187  UINT i;
1188  INT *emf_dx = (INT *)((char*)emr + emr->emrtext.offDx);
1189  SIZE charSize;
1190  for (i = 0; i < count; i++)
1191  {
1192  if (GetTextExtentPoint32W( dc_attr->hdc, str + i, 1, &charSize ))
1193  {
1194  emf_dx[i] = charSize.cx;
1195  text_width += charSize.cx;
1196  text_height = max( text_height, charSize.cy );
1197  }
1198  }
1199  }
1200 
1201  if (emf->path)
1202  {
1203  emr->rclBounds.left = emr->rclBounds.top = 0;
1204  emr->rclBounds.right = emr->rclBounds.bottom = -1;
1205  goto no_bounds;
1206  }
1207 
1208  /* FIXME: handle font escapement */
1209  switch (GetTextAlign(dc_attr->hdc) & (TA_LEFT | TA_RIGHT | TA_CENTER))
1210  {
1211  case TA_CENTER:
1212  emr->rclBounds.left = x - (text_width / 2) - 1;
1213  emr->rclBounds.right = x + (text_width / 2) + 1;
1214  break;
1215 
1216  case TA_RIGHT:
1217  emr->rclBounds.left = x - text_width - 1;
1218  emr->rclBounds.right = x;
1219  break;
1220 
1221  default: /* TA_LEFT */
1222  emr->rclBounds.left = x;
1223  emr->rclBounds.right = x + text_width + 1;
1224  }
1225 
1226  switch (GetTextAlign(dc_attr->hdc) & (TA_TOP | TA_BOTTOM | TA_BASELINE))
1227  {
1228  case TA_BASELINE:
1229  if (!GetTextMetricsW( dc_attr->hdc, &tm )) tm.tmDescent = 0;
1230  /* Play safe here... it's better to have a bounding box */
1231  /* that is too big than too small. */
1232  emr->rclBounds.top = y - text_height - 1;
1233  emr->rclBounds.bottom = y + tm.tmDescent + 1;
1234  break;
1235 
1236  case TA_BOTTOM:
1237  emr->rclBounds.top = y - text_height - 1;
1238  emr->rclBounds.bottom = y;
1239  break;
1240 
1241  default: /* TA_TOP */
1242  emr->rclBounds.top = y;
1243  emr->rclBounds.bottom = y + text_height + 1;
1244  }
1245  emfdc_update_bounds( emf, &emr->rclBounds );
1246 
1247 no_bounds:
1248  ret = emfdc_record( emf, &emr->emr );
1249  HeapFree( GetProcessHeap(), 0, emr );
1250  return ret;
1251 }
1252 
1254  void *grad_array, ULONG ngrad, ULONG mode )
1255 {
1256  EMRGRADIENTFILL *emr;
1257  ULONG i, pt, size, num_pts = ngrad * (mode == GRADIENT_FILL_TRIANGLE ? 3 : 2);
1258  const ULONG *pts = (const ULONG *)grad_array;
1259  BOOL ret;
1260 
1261  size = FIELD_OFFSET(EMRGRADIENTFILL, Ver[nvert]) + num_pts * sizeof(pts[0]);
1262 
1263  emr = HeapAlloc( GetProcessHeap(), 0, size );
1264  if (!emr) return FALSE;
1265 
1266  for (i = 0; i < num_pts; i++)
1267  {
1268  pt = pts[i];
1269 
1270  if (i == 0)
1271  {
1272  emr->rclBounds.left = emr->rclBounds.right = vert_array[pt].x;
1273  emr->rclBounds.top = emr->rclBounds.bottom = vert_array[pt].y;
1274  }
1275  else
1276  {
1277  if (vert_array[pt].x < emr->rclBounds.left)
1278  emr->rclBounds.left = vert_array[pt].x;
1279  else if (vert_array[pt].x > emr->rclBounds.right)
1280  emr->rclBounds.right = vert_array[pt].x;
1281  if (vert_array[pt].y < emr->rclBounds.top)
1282  emr->rclBounds.top = vert_array[pt].y;
1283  else if (vert_array[pt].y > emr->rclBounds.bottom)
1284  emr->rclBounds.bottom = vert_array[pt].y;
1285  }
1286  }
1287  emr->rclBounds.right--;
1288  emr->rclBounds.bottom--;
1289 
1290  emr->emr.iType = EMR_GRADIENTFILL;
1291  emr->emr.nSize = size;
1292  emr->nVer = nvert;
1293  emr->nTri = ngrad;
1294  emr->ulMode = mode;
1295  memcpy( emr->Ver, vert_array, nvert * sizeof(vert_array[0]) );
1296  memcpy( emr->Ver + nvert, pts, num_pts * sizeof(pts[0]) );
1297 
1298  emfdc_update_bounds( dc_attr->emf, &emr->rclBounds );
1299  ret = emfdc_record( dc_attr->emf, &emr->emr );
1300  HeapFree( GetProcessHeap(), 0, emr );
1301  return ret;
1302 }
1303 
1305 {
1307 }
1308 
1310 {
1312 }
1313 
1315 {
1317 }
1318 
1319 /* Generate an EMRBITBLT, EMRSTRETCHBLT or EMRALPHABLEND record depending on the type parameter */
1320 static BOOL emfdrv_stretchblt( struct emf *emf, INT x_dst, INT y_dst, INT width_dst, INT height_dst,
1321  HDC hdc_src, INT x_src, INT y_src, INT width_src, INT height_src,
1322  DWORD rop, DWORD type )
1323 {
1324  BITMAPINFO src_info = {{ sizeof( src_info.bmiHeader ) }};
1325  UINT bmi_size, emr_size, size;
1326  HBITMAP bitmap, blit_bitmap = NULL;
1327  EMRBITBLT *emr = NULL;
1328  BITMAPINFO *bmi;
1329  HDC blit_dc;
1330  BOOL ret = FALSE;
1331 
1332  if (hdc_src && GDI_HANDLE_GET_TYPE(hdc_src) == GDILoObjType_LO_ALTDC_TYPE)
1333  {
1334  WINEDC * pldc = get_dc_ptr(hdc_src);
1335 
1336  if (pldc->iType == LDC_EMFLDC)
1337  {
1338  return FALSE;
1339  }
1340  }
1341 
1342  if (!(bitmap = GetCurrentObject( hdc_src, OBJ_BITMAP ))) return FALSE;
1343 
1344  blit_dc = hdc_src;
1345  blit_bitmap = bitmap;
1346  if (!(bmi_size = get_bitmap_info( &blit_dc, &blit_bitmap, &src_info ))) return FALSE;
1347 
1348  /* EMRSTRETCHBLT and EMRALPHABLEND have the same structure */
1349  emr_size = type == EMR_BITBLT ? sizeof(EMRBITBLT) : sizeof(EMRSTRETCHBLT);
1350  size = emr_size + bmi_size + src_info.bmiHeader.biSizeImage;
1351 
1352  if (!(emr = HeapAlloc(GetProcessHeap(), 0, size))) goto err;
1353 
1354  emr->emr.iType = type;
1355  emr->emr.nSize = size;
1356  emr->rclBounds.left = x_dst;
1357  emr->rclBounds.top = y_dst;
1358  emr->rclBounds.right = x_dst + width_dst - 1;
1359  emr->rclBounds.bottom = y_dst + height_dst - 1;
1360  emr->xDest = x_dst;
1361  emr->yDest = y_dst;
1362  emr->cxDest = width_dst;
1363  emr->cyDest = height_dst;
1364  emr->xSrc = x_src;
1365  emr->ySrc = y_src;
1366  if (type != EMR_BITBLT)
1367  {
1368  EMRSTRETCHBLT *emr_stretchblt = (EMRSTRETCHBLT *)emr;
1369  emr_stretchblt->cxSrc = width_src;
1370  emr_stretchblt->cySrc = height_src;
1371  }
1372  emr->dwRop = rop;
1374  emr->crBkColorSrc = GetBkColor( hdc_src );
1375  emr->iUsageSrc = DIB_RGB_COLORS;
1376  emr->offBmiSrc = emr_size;
1377  emr->cbBmiSrc = bmi_size;
1378  emr->offBitsSrc = emr_size + bmi_size;
1379  emr->cbBitsSrc = src_info.bmiHeader.biSizeImage;
1380 
1381  bmi = (BITMAPINFO *)((BYTE *)emr + emr->offBmiSrc);
1382  bmi->bmiHeader = src_info.bmiHeader;
1383  ret = GetDIBits( blit_dc, blit_bitmap, 0, src_info.bmiHeader.biHeight,
1384  (BYTE *)emr + emr->offBitsSrc, bmi, DIB_RGB_COLORS );
1385 
1386  if (ret)
1387  {
1388  ret = emfdc_record( emf, (EMR *)emr );
1389  if (ret) emfdc_update_bounds( emf, &emr->rclBounds );
1390  }
1391 
1392 err:
1393  HeapFree( GetProcessHeap(), 0, emr );
1394  if (blit_bitmap != bitmap) DeleteObject( blit_bitmap );
1395  if (blit_dc != hdc_src) DeleteDC( blit_dc );
1396  return ret;
1397 }
1398 
1399 BOOL EMFDC_AlphaBlend( WINEDC *dc_attr, INT x_dst, INT y_dst, INT width_dst, INT height_dst,
1400  HDC hdc_src, INT x_src, INT y_src, INT width_src, INT height_src,
1401  BLENDFUNCTION blend_function )
1402 {
1403  return emfdrv_stretchblt( dc_attr->emf, x_dst, y_dst, width_dst, height_dst, hdc_src,
1404  x_src, y_src, width_src, height_src, *(DWORD *)&blend_function,
1405  EMR_ALPHABLEND );
1406 }
1407 
1409 {
1410  struct emf *emf = dc_attr->emf;
1411  EMRBITBLT emr;
1412  BOOL ret;
1413 
1414  emr.emr.iType = EMR_BITBLT;
1415  emr.emr.nSize = sizeof(emr);
1416  emr.rclBounds.left = left;
1417  emr.rclBounds.top = top;
1418  emr.rclBounds.right = left + width - 1;
1419  emr.rclBounds.bottom = top + height - 1;
1420  emr.xDest = left;
1421  emr.yDest = top;
1422  emr.cxDest = width;
1423  emr.cyDest = height;
1424  emr.dwRop = rop;
1425  emr.xSrc = 0;
1426  emr.ySrc = 0;
1427  emr.xformSrc.eM11 = 1.0;
1428  emr.xformSrc.eM12 = 0.0;
1429  emr.xformSrc.eM21 = 0.0;
1430  emr.xformSrc.eM22 = 1.0;
1431  emr.xformSrc.eDx = 0.0;
1432  emr.xformSrc.eDy = 0.0;
1433  emr.crBkColorSrc = 0;
1434  emr.iUsageSrc = 0;
1435  emr.offBmiSrc = 0;
1436  emr.cbBmiSrc = 0;
1437  emr.offBitsSrc = 0;
1438  emr.cbBitsSrc = 0;
1439 
1440  ret = emfdc_record( emf, &emr.emr );
1441  if (ret) emfdc_update_bounds( emf, &emr.rclBounds );
1442  return ret;
1443 }
1444 
1445 static inline BOOL rop_uses_src( DWORD rop )
1446 {
1447  return ((rop >> 2) & 0x330000) != (rop & 0x330000);
1448 }
1449 
1451  HDC hdc_src, INT x_src, INT y_src, DWORD rop )
1452 {
1453  if (!rop_uses_src( rop )) return EMFDC_PatBlt( dc_attr, x_dst, y_dst, width, height, rop );
1454  return emfdrv_stretchblt( dc_attr->emf, x_dst, y_dst, width, height,
1455  hdc_src, x_src, y_src, width, height, rop, EMR_BITBLT );
1456 }
1457 
1458 BOOL EMFDC_StretchBlt( WINEDC *dc_attr, INT x_dst, INT y_dst, INT width_dst, INT height_dst,
1459  HDC hdc_src, INT x_src, INT y_src, INT width_src, INT height_src,
1460  DWORD rop )
1461 {
1462  if (!rop_uses_src( rop )) return EMFDC_PatBlt( dc_attr, x_dst, y_dst, width_dst, height_dst, rop );
1463  return emfdrv_stretchblt( dc_attr->emf, x_dst, y_dst, width_dst, height_dst,
1464  hdc_src, x_src, y_src, width_src,
1465  height_src, rop, EMR_STRETCHBLT );
1466 }
1467 
1468 BOOL EMFDC_TransparentBlt( WINEDC *dc_attr, int x_dst, int y_dst, int width_dst, int height_dst,
1469  HDC hdc_src, int x_src, int y_src, int width_src, int height_src,
1470  UINT color )
1471 {
1472  return emfdrv_stretchblt( dc_attr->emf, x_dst, y_dst, width_dst, height_dst,
1473  hdc_src, x_src, y_src, width_src,
1474  height_src, color, EMR_TRANSPARENTBLT );
1475 }
1476 
1477 BOOL EMFDC_MaskBlt( WINEDC *dc_attr, INT x_dst, INT y_dst, INT width_dst, INT height_dst,
1478  HDC hdc_src, INT x_src, INT y_src, HBITMAP mask,
1479  INT x_mask, INT y_mask, DWORD rop )
1480 {
1481  unsigned char mask_info_buffer[FIELD_OFFSET(BITMAPINFO, bmiColors)
1482  + 256*RTL_FIELD_SIZE(BITMAPINFO, bmiColors)];
1483  BITMAPINFO *mask_bits_info = (BITMAPINFO *)mask_info_buffer;
1484  struct emf *emf = dc_attr->emf;
1485  BITMAPINFO mask_info = {{ sizeof( mask_info.bmiHeader ) }};
1486  BITMAPINFO src_info = {{ sizeof( src_info.bmiHeader ) }};
1487  HBITMAP bitmap, blit_bitmap = NULL, mask_bitmap = NULL;
1488  UINT bmi_size, size, mask_info_size = 0;
1489  EMRMASKBLT *emr = NULL;
1490  BITMAPINFO *bmi;
1491  HDC blit_dc, mask_dc = NULL;
1492  BOOL ret = FALSE;
1493 
1494  if (!rop_uses_src( rop ))
1495  return EMFDC_PatBlt( dc_attr, x_dst, y_dst, width_dst, height_dst, rop );
1496 
1497  if (hdc_src && GDI_HANDLE_GET_TYPE(hdc_src) == GDILoObjType_LO_ALTDC_TYPE)
1498  {
1499  WINEDC * pldc = get_dc_ptr(hdc_src);
1500 
1501  if (pldc->iType == LDC_EMFLDC)
1502  {
1503  return FALSE;
1504  }
1505  }
1506 
1507  if (!(bitmap = GetCurrentObject( hdc_src, OBJ_BITMAP ))) return FALSE;
1508  blit_dc = hdc_src;
1509  blit_bitmap = bitmap;
1510  if (!(bmi_size = get_bitmap_info( &blit_dc, &blit_bitmap, &src_info ))) return FALSE;
1511 
1512  if (mask)
1513  {
1514  mask_dc = hdc_src;
1515  mask_bitmap = mask;
1516  if (!(mask_info_size = get_bitmap_info( &mask_dc, &mask_bitmap, &mask_info ))) goto err;
1517  if (mask_info.bmiHeader.biBitCount == 1)
1518  mask_info_size = sizeof(BITMAPINFOHEADER); /* don't include colors */
1519  }
1520  else mask_info.bmiHeader.biSizeImage = 0;
1521 
1522  size = sizeof(*emr) + bmi_size + src_info.bmiHeader.biSizeImage +
1523  mask_info_size + mask_info.bmiHeader.biSizeImage;
1524 
1525  if (!(emr = HeapAlloc(GetProcessHeap(), 0, size))) goto err;
1526 
1527  emr->emr.iType = EMR_MASKBLT;
1528  emr->emr.nSize = size;
1529  emr->rclBounds.left = x_dst;
1530  emr->rclBounds.top = y_dst;
1531  emr->rclBounds.right = x_dst + width_dst - 1;
1532  emr->rclBounds.bottom = y_dst + height_dst - 1;
1533  emr->xDest = x_dst;
1534  emr->yDest = y_dst;
1535  emr->cxDest = width_dst;
1536  emr->cyDest = height_dst;
1537  emr->dwRop = rop;
1538  emr->xSrc = x_src;
1539  emr->ySrc = y_src;
1541  emr->crBkColorSrc = GetBkColor( hdc_src );
1542  emr->iUsageSrc = DIB_RGB_COLORS;
1543  emr->offBmiSrc = sizeof(*emr);
1544  emr->cbBmiSrc = bmi_size;
1545  emr->offBitsSrc = emr->offBmiSrc + bmi_size;
1546  emr->cbBitsSrc = src_info.bmiHeader.biSizeImage;
1547  emr->xMask = x_mask;
1548  emr->yMask = y_mask;
1549  emr->iUsageMask = DIB_PAL_MONO;
1550  emr->offBmiMask = mask_info_size ? emr->offBitsSrc + emr->cbBitsSrc : 0;
1551  emr->cbBmiMask = mask_info_size;
1552  emr->offBitsMask = emr->offBmiMask + emr->cbBmiMask;
1553  emr->cbBitsMask = mask_info.bmiHeader.biSizeImage;
1554 
1555  bmi = (BITMAPINFO *)((char *)emr + emr->offBmiSrc);
1556  bmi->bmiHeader = src_info.bmiHeader;
1557  ret = GetDIBits( blit_dc, blit_bitmap, 0, src_info.bmiHeader.biHeight,
1558  (char *)emr + emr->offBitsSrc, bmi, DIB_RGB_COLORS );
1559  if (!ret) goto err;
1560 
1561  if (mask_info_size)
1562  {
1563  mask_bits_info->bmiHeader = mask_info.bmiHeader;
1564  ret = GetDIBits( blit_dc, mask_bitmap, 0, mask_info.bmiHeader.biHeight,
1565  (char *)emr + emr->offBitsMask, mask_bits_info, DIB_RGB_COLORS );
1566  if (ret) memcpy( (char *)emr + emr->offBmiMask, mask_bits_info, mask_info_size );
1567  }
1568 
1569  if (ret)
1570  {
1571  ret = emfdc_record( emf, (EMR *)emr );
1572  if (ret) emfdc_update_bounds( emf, &emr->rclBounds );
1573  }
1574 
1575 err:
1576  HeapFree( GetProcessHeap(), 0, emr );
1577  if (mask_bitmap != mask) DeleteObject( mask_bitmap );
1578  if (mask_dc != hdc_src) DeleteObject( mask_dc );
1579  if (blit_bitmap != bitmap) DeleteObject( blit_bitmap );
1580  if (blit_dc != hdc_src) DeleteDC( blit_dc );
1581  return ret;
1582 }
1583 
1584 BOOL EMFDC_PlgBlt( WINEDC *dc_attr, const POINT *points, HDC hdc_src, INT x_src, INT y_src,
1585  INT width, INT height, HBITMAP mask, INT x_mask, INT y_mask )
1586 {
1587  unsigned char mask_info_buffer[FIELD_OFFSET(BITMAPINFO, bmiColors)
1588  + 256*RTL_FIELD_SIZE(BITMAPINFO, bmiColors)];
1589  BITMAPINFO *mask_bits_info = (BITMAPINFO *)mask_info_buffer;
1590  struct emf *emf = dc_attr->emf;
1591  BITMAPINFO mask_info = {{ sizeof( mask_info.bmiHeader ) }};
1592  BITMAPINFO src_info = {{ sizeof( src_info.bmiHeader ) }};
1593  HBITMAP bitmap, blit_bitmap = NULL, mask_bitmap = NULL;
1594  UINT bmi_size, size, mask_info_size = 0;
1595  EMRPLGBLT *emr = NULL;
1596  BITMAPINFO *bmi;
1597  HDC blit_dc, mask_dc = NULL;
1598  int x_min, y_min, x_max, y_max, i;
1599  BOOL ret = FALSE;
1600 
1601  if (hdc_src && GDI_HANDLE_GET_TYPE(hdc_src) == GDILoObjType_LO_ALTDC_TYPE)
1602  {
1603  WINEDC * pldc = get_dc_ptr(hdc_src);
1604 
1605  if (pldc->iType == LDC_EMFLDC)
1606  {
1607  return FALSE;
1608  }
1609  }
1610 
1611  if (!(bitmap = GetCurrentObject( hdc_src, OBJ_BITMAP ))) return FALSE;
1612 
1613  blit_dc = hdc_src;
1614  blit_bitmap = bitmap;
1615  if (!(bmi_size = get_bitmap_info( &blit_dc, &blit_bitmap, &src_info ))) return FALSE;
1616 
1617  if (mask)
1618  {
1619  mask_dc = hdc_src;
1620  mask_bitmap = mask;
1621  if (!(mask_info_size = get_bitmap_info( &mask_dc, &mask_bitmap, &mask_info ))) goto err;
1622  if (mask_info.bmiHeader.biBitCount == 1)
1623  mask_info_size = sizeof(BITMAPINFOHEADER); /* don't include colors */
1624  }
1625  else mask_info.bmiHeader.biSizeImage = 0;
1626 
1627  size = sizeof(*emr) + bmi_size + src_info.bmiHeader.biSizeImage +
1628  mask_info_size + mask_info.bmiHeader.biSizeImage;
1629 
1630  if (!(emr = HeapAlloc(GetProcessHeap(), 0, size))) goto err;
1631 
1632  emr->emr.iType = EMR_PLGBLT;
1633  emr->emr.nSize = size;
1634 
1635  /* FIXME: not exactly what native does */
1636  x_min = x_max = points[1].x + points[2].x - points[0].x;
1637  y_min = y_max = points[1].y + points[2].y - points[0].y;
1638  for (i = 0; i < ARRAYSIZE(emr->aptlDest); i++)
1639  {
1640  x_min = min( x_min, points[i].x );
1641  y_min = min( y_min, points[i].y );
1642  x_max = max( x_max, points[i].x );
1643  y_max = max( y_min, points[i].y );
1644  }
1645  emr->rclBounds.left = x_min;
1646  emr->rclBounds.top = y_min;
1647  emr->rclBounds.right = x_max;
1648  emr->rclBounds.bottom = y_max;
1649  memcpy( emr->aptlDest, points, sizeof(emr->aptlDest) );
1650  emr->xSrc = x_src;
1651  emr->ySrc = y_src;
1652  emr->cxSrc = width;
1653  emr->cySrc = height;
1655  emr->crBkColorSrc = GetBkColor( hdc_src );
1656  emr->iUsageSrc = DIB_RGB_COLORS;
1657  emr->offBmiSrc = sizeof(*emr);
1658  emr->cbBmiSrc = bmi_size;
1659  emr->offBitsSrc = emr->offBmiSrc + bmi_size;
1660  emr->cbBitsSrc = src_info.bmiHeader.biSizeImage;
1661  emr->xMask = x_mask;
1662  emr->yMask = y_mask;
1663  emr->iUsageMask = DIB_PAL_MONO;
1664  emr->offBmiMask = mask_info_size ? emr->offBitsSrc + emr->cbBitsSrc : 0;
1665  emr->cbBmiMask = mask_info_size;
1666  emr->offBitsMask = emr->offBmiMask + emr->cbBmiMask;
1667  emr->cbBitsMask = mask_info.bmiHeader.biSizeImage;
1668 
1669  bmi = (BITMAPINFO *)((char *)emr + emr->offBmiSrc);
1670  bmi->bmiHeader = src_info.bmiHeader;
1671  ret = GetDIBits( blit_dc, blit_bitmap, 0, src_info.bmiHeader.biHeight,
1672  (char *)emr + emr->offBitsSrc, bmi, DIB_RGB_COLORS );
1673  if (!ret) goto err;
1674 
1675  if (mask_info_size)
1676  {
1677  mask_bits_info->bmiHeader = mask_info.bmiHeader;
1678  ret = GetDIBits( blit_dc, mask_bitmap, 0, mask_info.bmiHeader.biHeight,
1679  (char *)emr + emr->offBitsMask, mask_bits_info, DIB_RGB_COLORS );
1680  if (ret) memcpy( (char *)emr + emr->offBmiMask, mask_bits_info, mask_info_size );
1681  }
1682 
1683  if (ret)
1684  {
1685  ret = emfdc_record( emf, (EMR *)emr );
1686  if (ret) emfdc_update_bounds( emf, &emr->rclBounds );
1687  }
1688 
1689 err:
1690  HeapFree( GetProcessHeap(), 0, emr );
1691  if (mask_bitmap != mask) DeleteObject( mask_bitmap );
1692  if (mask_dc != hdc_src) DeleteObject( mask_dc );
1693  if (blit_bitmap != bitmap) DeleteObject( blit_bitmap );
1694  if (blit_dc != hdc_src) DeleteDC( blit_dc );
1695  return ret;
1696 }
1697 
1698 BOOL EMFDC_StretchDIBits( WINEDC *dc_attr, INT x_dst, INT y_dst, INT width_dst, INT height_dst,
1699  INT x_src, INT y_src, INT width_src, INT height_src, const void *bits,
1700  const BITMAPINFO *info, UINT usage, DWORD rop )
1701 {
1702  EMRSTRETCHDIBITS *emr;
1703  BOOL ret;
1704  UINT bmi_size, emr_size;
1705 
1706  /* calculate the size of the colour table */
1707  bmi_size = get_dib_info_size( info, usage );
1708 
1709  emr_size = sizeof (EMRSTRETCHDIBITS) + bmi_size + info->bmiHeader.biSizeImage;
1710  if (!(emr = HeapAlloc(GetProcessHeap(), 0, emr_size ))) return 0;
1711 
1712  /* write a bitmap info header (with colours) to the record */
1713  memcpy( &emr[1], info, bmi_size);
1714 
1715  /* write bitmap bits to the record */
1716  memcpy ( (BYTE *)&emr[1] + bmi_size, bits, info->bmiHeader.biSizeImage );
1717 
1718  /* fill in the EMR header at the front of our piece of memory */
1719  emr->emr.iType = EMR_STRETCHDIBITS;
1720  emr->emr.nSize = emr_size;
1721 
1722  emr->xDest = x_dst;
1723  emr->yDest = y_dst;
1724  emr->cxDest = width_dst;
1725  emr->cyDest = height_dst;
1726  emr->dwRop = rop;
1727  emr->xSrc = x_src;
1728  emr->ySrc = y_src;
1729 
1730  emr->iUsageSrc = usage;
1731  emr->offBmiSrc = sizeof (EMRSTRETCHDIBITS);
1732  emr->cbBmiSrc = bmi_size;
1733  emr->offBitsSrc = emr->offBmiSrc + bmi_size;
1734  emr->cbBitsSrc = info->bmiHeader.biSizeImage;
1735 
1736  emr->cxSrc = width_src;
1737  emr->cySrc = height_src;
1738 
1739  emr->rclBounds.left = x_dst;
1740  emr->rclBounds.top = y_dst;
1741  emr->rclBounds.right = x_dst + width_dst;
1742  emr->rclBounds.bottom = y_dst + height_dst;
1743 
1744  /* save the record we just created */
1745  ret = emfdc_record( dc_attr->emf, &emr->emr );
1746  if (ret) emfdc_update_bounds( dc_attr->emf, &emr->rclBounds );
1747  HeapFree( GetProcessHeap(), 0, emr );
1748  return ret;
1749 }
1750 
1752  INT x_src, INT y_src, UINT startscan, UINT lines,
1753  const void *bits, const BITMAPINFO *info, UINT usage )
1754 {
1755  EMRSETDIBITSTODEVICE *emr;
1756  DWORD bmiSize = get_dib_info_size( info, usage );
1757  DWORD size = sizeof(EMRSETDIBITSTODEVICE) + bmiSize + info->bmiHeader.biSizeImage;
1758  BOOL ret;
1759 
1760  if (!(emr = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
1761 
1763  emr->emr.nSize = size;
1764  emr->rclBounds.left = x_dst;
1765  emr->rclBounds.top = y_dst;
1766  emr->rclBounds.right = x_dst + width - 1;
1767  emr->rclBounds.bottom = y_dst + height - 1;
1768  emr->xDest = x_dst;
1769  emr->yDest = y_dst;
1770  emr->xSrc = x_src;
1771  emr->ySrc = y_src;
1772  emr->cxSrc = width;
1773  emr->cySrc = height;
1774  emr->offBmiSrc = sizeof(EMRSETDIBITSTODEVICE);
1775  emr->cbBmiSrc = bmiSize;
1776  emr->offBitsSrc = sizeof(EMRSETDIBITSTODEVICE) + bmiSize;
1777  emr->cbBitsSrc = info->bmiHeader.biSizeImage;
1778  emr->iUsageSrc = usage;
1779  emr->iStartScan = startscan;
1780  emr->cScans = lines;
1781  memcpy( (BYTE*)emr + emr->offBmiSrc, info, bmiSize );
1782  memcpy( (BYTE*)emr + emr->offBitsSrc, bits, info->bmiHeader.biSizeImage );
1783 
1784  if ((ret = emfdc_record( dc_attr->emf, (EMR*)emr )))
1785  emfdc_update_bounds( dc_attr->emf, &emr->rclBounds );
1786 
1787  HeapFree( GetProcessHeap(), 0, emr );
1788  return ret;
1789 }
1790 
1792 {
1793  struct emf *emf = dc_attr->emf;
1794  EMRSELECTOBJECT emr;
1795  DWORD index;
1796 
1797  if (GetCurrentObject( dc_attr->hdc, OBJ_BRUSH ) != GetStockObject( DC_BRUSH )) return TRUE;
1798 
1799  if (emf->dc_brush) DeleteObject( emf->dc_brush );
1800  if (!(emf->dc_brush = CreateSolidBrush( color ))) return FALSE;
1801  if (!(index = emfdc_create_brush( emf, emf->dc_brush ))) return FALSE;
1802  GDI_hdc_using_object( emf->dc_brush, dc_attr->hdc);//, emfdc_delete_object );
1803  emr.emr.iType = EMR_SELECTOBJECT;
1804  emr.emr.nSize = sizeof(emr);
1805  emr.ihObject = index;
1806  return emfdc_record( emf, &emr.emr );
1807 }
1808 
1810 {
1811  struct emf *emf = dc_attr->emf;
1812  EMRSELECTOBJECT emr;
1813  DWORD index;
1814  LOGPEN logpen = { PS_SOLID, { 0, 0 }, color };
1815 
1816  if (GetCurrentObject( dc_attr->hdc, OBJ_PEN ) != GetStockObject( DC_PEN )) return TRUE;
1817 
1818  if (emf->dc_pen) DeleteObject( emf->dc_pen );
1819  if (!(emf->dc_pen = CreatePenIndirect( &logpen ))) return FALSE;
1820  if (!(index = emfdc_create_pen( emf, emf->dc_pen ))) return FALSE;
1821  GDI_hdc_using_object( emf->dc_pen, dc_attr->hdc);//, emfdc_delete_object );
1822  emr.emr.iType = EMR_SELECTOBJECT;
1823  emr.emr.nSize = sizeof(emr);
1824  emr.ihObject = index;
1825  return emfdc_record( emf, &emr.emr );
1826 }
1827 
1829 {
1830  EMRSAVEDC emr;
1831 
1832  emr.emr.iType = EMR_SAVEDC;
1833  emr.emr.nSize = sizeof(emr);
1834  return emfdc_record( dc_attr->emf, &emr.emr );
1835 }
1836 #define GdiGetEMFRestorDc 5
1838 {
1839  EMRRESTOREDC emr;
1840 
1841  /* The Restore DC function needs the save level to be set correctly.
1842  Note that wine's level is 0 based, while our's is (like win) 1 based. */
1844 
1845  if (abs(level) > dc_attr->save_level || level == 0) return FALSE;
1846 
1847  emr.emr.iType = EMR_RESTOREDC;
1848  emr.emr.nSize = sizeof(emr);
1849  if (level < 0)
1850  emr.iRelative = level;
1851  else
1852  emr.iRelative = level - dc_attr->save_level - 1;
1853  return emfdc_record( dc_attr->emf, &emr.emr );
1854 }
1855 
1857 {
1858  EMRSETTEXTALIGN emr;
1859 
1860  emr.emr.iType = EMR_SETTEXTALIGN;
1861  emr.emr.nSize = sizeof(emr);
1862  emr.iMode = align;
1863  return emfdc_record( dc_attr->emf, &emr.emr );
1864 }
1865 
1867 {
1869 
1870  emr.emr.iType = EMR_SETTEXTJUSTIFICATION;
1871  emr.emr.nSize = sizeof(emr);
1872  emr.nBreakExtra = extra;
1873  emr.nBreakCount = breaks;
1874  return emfdc_record( dc_attr->emf, &emr.emr );
1875 }
1876 
1878 {
1879  EMRSETBKMODE emr;
1880 
1881  emr.emr.iType = EMR_SETBKMODE;
1882  emr.emr.nSize = sizeof(emr);
1883  emr.iMode = mode;
1884  return emfdc_record( dc_attr->emf, &emr.emr );
1885 }
1886 
1888 {
1889  EMRSETBKCOLOR emr;
1890 
1891  emr.emr.iType = EMR_SETBKCOLOR;
1892  emr.emr.nSize = sizeof(emr);
1893  emr.crColor = color;
1894  return emfdc_record( dc_attr->emf, &emr.emr );
1895 }
1896 
1898 {
1899  EMRSETTEXTCOLOR emr;
1900 
1901  emr.emr.iType = EMR_SETTEXTCOLOR;
1902  emr.emr.nSize = sizeof(emr);
1903  emr.crColor = color;
1904  return emfdc_record( dc_attr->emf, &emr.emr );
1905 }
1906 
1908 {
1909  EMRSETROP2 emr;
1910 
1911  emr.emr.iType = EMR_SETROP2;
1912  emr.emr.nSize = sizeof(emr);
1913  emr.iMode = rop;
1914  return emfdc_record( dc_attr->emf, &emr.emr );
1915 }
1916 
1918 {
1919  EMRSETPOLYFILLMODE emr;
1920 
1922  emr.emr.nSize = sizeof(emr);
1923  emr.iMode = mode;
1924  return emfdc_record( dc_attr->emf, &emr.emr );
1925 }
1926 
1928 {
1930 
1932  emr.emr.nSize = sizeof(emr);
1933  emr.iMode = mode;
1934  return emfdc_record( dc_attr->emf, &emr.emr );
1935 }
1936 
1938 {
1939  EMRSETARCDIRECTION emr;
1940 
1942  emr.emr.nSize = sizeof(emr);
1943  emr.iArcDirection = dir;
1944  return emfdc_record( dc_attr->emf, &emr.emr );
1945 }
1946 
1948 {
1949  EMREXCLUDECLIPRECT emr;
1950 
1952  emr.emr.nSize = sizeof(emr);
1953  emr.rclClip.left = left;
1954  emr.rclClip.top = top;
1955  emr.rclClip.right = right;
1956  emr.rclClip.bottom = bottom;
1957  return emfdc_record( dc_attr->emf, &emr.emr );
1958 }
1959 
1961 {
1963 
1965  emr.emr.nSize = sizeof(emr);
1966  emr.rclClip.left = left;
1967  emr.rclClip.top = top;
1968  emr.rclClip.right = right;
1969  emr.rclClip.bottom = bottom;
1970  return emfdc_record( dc_attr->emf, &emr.emr );
1971 }
1972 
1974 {
1975  EMROFFSETCLIPRGN emr;
1976 
1977  emr.emr.iType = EMR_OFFSETCLIPRGN;
1978  emr.emr.nSize = sizeof(emr);
1979  emr.ptlOffset.x = x;
1980  emr.ptlOffset.y = y;
1981  return emfdc_record( dc_attr->emf, &emr.emr );
1982 }
1983 
1985 {
1986  EMREXTSELECTCLIPRGN *emr;
1987  DWORD size, rgnsize;
1988  BOOL ret;
1989 
1990  if (!hrgn)
1991  {
1992  if (mode != RGN_COPY) return ERROR;
1993  rgnsize = 0;
1994  }
1995  else rgnsize = /*NtGdi*/GetRegionData( hrgn, 0, NULL );
1996 
1997  size = rgnsize + offsetof(EMREXTSELECTCLIPRGN,RgnData);
1998  emr = HeapAlloc( GetProcessHeap(), 0, size );
1999  if (rgnsize) /*NtGdi*/GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
2000 
2002  emr->emr.nSize = size;
2003  emr->cbRgnData = rgnsize;
2004  emr->iMode = mode;
2005 
2006  ret = emfdc_record( dc_attr->emf, &emr->emr );
2007  HeapFree( GetProcessHeap(), 0, emr );
2008  return ret;
2009 }
2010 
2012 {
2013  EMRSETMAPMODE emr;
2014 
2015  emr.emr.iType = EMR_SETMAPMODE;
2016  emr.emr.nSize = sizeof(emr);
2017  emr.iMode = mode;
2018  return emfdc_record( dc_attr->emf, &emr.emr );
2019 }
2020 
2022 {
2023  EMRSETVIEWPORTEXTEX emr;
2024 
2026  emr.emr.nSize = sizeof(emr);
2027  emr.szlExtent.cx = cx;
2028  emr.szlExtent.cy = cy;
2029  return emfdc_record( dc_attr->emf, &emr.emr );
2030 }
2031 
2033 {
2034  EMRSETWINDOWEXTEX emr;
2035 
2037  emr.emr.nSize = sizeof(emr);
2038  emr.szlExtent.cx = cx;
2039  emr.szlExtent.cy = cy;
2040  return emfdc_record( dc_attr->emf, &emr.emr );
2041 }
2042 
2044 {
2045  EMRSETVIEWPORTORGEX emr;
2046 
2048  emr.emr.nSize = sizeof(emr);
2049  emr.ptlOrigin.x = x;
2050  emr.ptlOrigin.y = y;
2051  return emfdc_record( dc_attr->emf, &emr.emr );
2052 }
2053 
2055 {
2056  EMRSETWINDOWORGEX emr;
2057 
2059  emr.emr.nSize = sizeof(emr);
2060  emr.ptlOrigin.x = x;
2061  emr.ptlOrigin.y = y;
2062  return emfdc_record( dc_attr->emf, &emr.emr );
2063 }
2064 
2065 BOOL EMFDC_ScaleViewportExtEx( WINEDC *dc_attr, INT x_num, INT x_denom, INT y_num, INT y_denom )
2066 {
2068 
2070  emr.emr.nSize = sizeof(emr);
2071  emr.xNum = x_num;
2072  emr.xDenom = x_denom;
2073  emr.yNum = y_num;
2074  emr.yDenom = y_denom;
2075  return emfdc_record( dc_attr->emf, &emr.emr );
2076 }
2077 
2078 BOOL EMFDC_ScaleWindowExtEx( WINEDC *dc_attr, INT x_num, INT x_denom, INT y_num, INT y_denom )
2079 {
2080  EMRSCALEWINDOWEXTEX emr;
2081 
2083  emr.emr.nSize = sizeof(emr);
2084  emr.xNum = x_num;
2085  emr.xDenom = x_denom;
2086  emr.yNum = y_num;
2087  emr.yDenom = y_denom;
2088  return emfdc_record( dc_attr->emf, &emr.emr );
2089 }
2090 
2092 {
2093  EMRSETLAYOUT emr;
2094 
2095  emr.emr.iType = EMR_SETLAYOUT;
2096  emr.emr.nSize = sizeof(emr);
2097  emr.iMode = layout;
2098  return emfdc_record( dc_attr->emf, &emr.emr );
2099 }
2100 
2102 {
2104 
2106  emr.emr.nSize = sizeof(emr);
2107  emr.xform = *xform;
2108  return emfdc_record( dc_attr->emf, &emr.emr );
2109 }
2110 
2112 {
2114 
2116  emr.emr.nSize = sizeof(emr);
2117  if (mode == MWT_IDENTITY)
2118  {
2119  emr.xform.eM11 = 1.0f;
2120  emr.xform.eM12 = 0.0f;
2121  emr.xform.eM21 = 0.0f;
2122  emr.xform.eM22 = 1.0f;
2123  emr.xform.eDx = 0.0f;
2124  emr.xform.eDy = 0.0f;
2125  }
2126  else
2127  {
2128  emr.xform = *xform;
2129  }
2130  emr.iMode = mode;
2131  return emfdc_record( dc_attr->emf, &emr.emr );
2132 }
2133 
2135 {
2136  EMRSETMAPPERFLAGS emr;
2137 
2139  emr.emr.nSize = sizeof(emr);
2140  emr.dwFlags = flags;
2141  return emfdc_record( dc_attr->emf, &emr.emr );
2142 }
2143 
2145 {
2146  struct emf *emf = dc_attr->emf;
2147  EMRABORTPATH emr;
2148 
2149  emr.emr.iType = EMR_ABORTPATH;
2150  emr.emr.nSize = sizeof(emr);
2151 
2152  emf->path = FALSE;
2153  return emfdc_record( dc_attr->emf, &emr.emr );
2154 }
2155 
2157 {
2158  struct emf *emf = dc_attr->emf;
2159  EMRBEGINPATH emr;
2160 
2161  emr.emr.iType = EMR_BEGINPATH;
2162  emr.emr.nSize = sizeof(emr);
2163  if (!emfdc_record( emf, &emr.emr )) return FALSE;
2164 
2165  emf->path = TRUE;
2166  return TRUE;
2167 }
2168 
2170 {
2171  EMRCLOSEFIGURE emr;
2172 
2173  emr.emr.iType = EMR_CLOSEFIGURE;
2174  emr.emr.nSize = sizeof(emr);
2175  return emfdc_record( dc_attr->emf, &emr.emr );
2176 }
2177 
2179 {
2180  struct emf *emf = dc_attr->emf;
2181  EMRENDPATH emr;
2182 
2183  emf->path = FALSE;
2184 
2185  emr.emr.iType = EMR_ENDPATH;
2186  emr.emr.nSize = sizeof(emr);
2187  return emfdc_record( emf, &emr.emr );
2188 }
2189 
2191 {
2192  EMRFLATTENPATH emr;
2193 
2194  emr.emr.iType = EMR_FLATTENPATH;
2195  emr.emr.nSize = sizeof(emr);
2196  return emfdc_record( dc_attr->emf, &emr.emr );
2197 }
2198 
2200 {
2201  EMRSELECTCLIPPATH emr;
2202 
2204  emr.emr.nSize = sizeof(emr);
2205  emr.iMode = mode;
2206  return emfdc_record( dc_attr->emf, &emr.emr );
2207 }
2208 
2210 {
2211  EMRWIDENPATH emr;
2212 
2213  emr.emr.iType = EMR_WIDENPATH;
2214  emr.emr.nSize = sizeof(emr);
2215  return emfdc_record( dc_attr->emf, &emr.emr );
2216 }
2217 
2219 {
2220  struct emf *emf = dc_attr->emf;
2221  UINT index;
2222 
2223  HeapFree( GetProcessHeap(), 0, emf->emh );
2224  for (index = 0; index < emf->handles_size; index++)
2225  if (emf->handles[index])
2227  HeapFree( GetProcessHeap(), 0, emf->handles );
2228  return TRUE;
2229 }
2230 
2231 //
2232 // Waiting on wine support....
2233 //
2234 
2235 
2236 //
2237 // ReactOS Print Support
2238 //
2239 BOOL EMFDC_WriteEscape( WINEDC *dc_attr, INT nEscape, INT cbInput, LPSTR lpszInData, DWORD emrType)
2240 {
2241  PEMRESCAPE pemr;
2242  UINT total, rounded_size;
2243  BOOL ret;
2244 
2245  rounded_size = (cbInput+3) & ~3;
2246  total = offsetof(EMRESCAPE,Data) + rounded_size;
2247 
2248  pemr = RtlAllocateHeap( GetProcessHeap(), 0, total );
2249  if ( !pemr )
2250  return 0;
2251 
2252  RtlZeroMemory( pemr, total );
2253 
2254  pemr->emr.iType = emrType;
2255  pemr->emr.nSize = total;
2256  pemr->iEsc = nEscape;
2257  pemr->cjIn = cbInput;
2258 
2259  RtlCopyMemory( &pemr->Data[0], lpszInData, cbInput );
2260 
2261  ret = emfdc_record( dc_attr->emf, &pemr->emr );
2262 
2263  RtlFreeHeap( GetProcessHeap(), 0, pemr );
2264  return ret;
2265 }
2266 
2268 {
2269  PEMRNAMEDESCAPE pemr;
2270  UINT sizestr, total, rounded_size;
2271  INT ret;
2272 
2273  rounded_size = (cbInput+3) & ~3;
2274  total = offsetof(EMRNAMEDESCAPE,Data) + rounded_size;
2275 
2276  total += sizestr = (UINT)((wcslen(pDriver) + 1 ) * sizeof(WCHAR));
2277 
2278  pemr = RtlAllocateHeap( GetProcessHeap(), 0, total );
2279  if ( !pemr )
2280  return 0;
2281 
2282  RtlZeroMemory( pemr, total );
2283 
2284  pemr->emr.iType = EMR_NAMEDESCAPE;
2285  pemr->emr.nSize = total;
2286  pemr->iEsc = nEscape;
2287  pemr->cjIn = cbInput;
2288 
2289  RtlCopyMemory( &pemr->Data[0], lpszInData, cbInput );
2290  //
2291  // WARNING :
2292  // Need to remember with wine, theses headers are relocatable.
2293  RtlCopyMemory( &pemr->Data[rounded_size], pDriver, sizestr );
2294 
2295  ret = emfdc_record( dc_attr->emf, &pemr->emr );
2296 
2297  RtlFreeHeap( GetProcessHeap(), 0, pemr );
2298  return ret;
2299 }
2300 
2302 {
2303  EMRSETMETARGN emr;
2304 
2305  emr.emr.iType = EMR_SETMETARGN;
2306  emr.emr.nSize = sizeof(emr);
2307 
2308  return emfdc_record( dc_attr->emf, &emr.emr );
2309 }
2310 
2312 {
2313  EMRSETBRUSHORGEX emr;
2314 
2315  emr.emr.iType = EMR_SETBRUSHORGEX;
2316  emr.emr.nSize = sizeof(emr);
2317  emr.ptlOrigin.x = x;
2318  emr.ptlOrigin.y = y;
2319 
2320  return emfdc_record( dc_attr->emf, &emr.emr );
2321 }
2322 
2323 /*******************************************************************
2324  * GdiComment (GDI32.@)
2325  */
2327 {
2328  WINEDC *dc_attr;
2329  EMRGDICOMMENT *emr;
2330  UINT total, rounded_size;
2331  BOOL ret;
2332 
2333  if (!(dc_attr = get_dc_ptr( hdc )) || !dc_attr->emf) return FALSE;
2334 
2335  rounded_size = (bytes+3) & ~3;
2336  total = offsetof(EMRGDICOMMENT,Data) + rounded_size;
2337 
2338  emr = HeapAlloc(GetProcessHeap(), 0, total);
2339  emr->emr.iType = EMR_GDICOMMENT;
2340  emr->emr.nSize = total;
2341  emr->cbData = bytes;
2342  memset(&emr->Data[bytes], 0, rounded_size - bytes);
2343  memcpy(&emr->Data[0], buffer, bytes);
2344 
2345  ret = emfdc_record( dc_attr->emf, &emr->emr );
2346 
2347  HeapFree(GetProcessHeap(), 0, emr);
2348 
2349  return ret;
2350 }
2351 
2352 /**********************************************************************
2353  * CreateEnhMetaFileA (GDI32.@)
2354  */
2356  const char *description )
2357 {
2358  WCHAR *filenameW = NULL;
2359  WCHAR *descriptionW = NULL;
2360  DWORD len1, len2, total;
2361  HDC ret;
2362 
2363  if (filename)
2364  {
2365  total = MultiByteToWideChar( CP_ACP, 0, filename, -1, NULL, 0 );
2366  filenameW = HeapAlloc( GetProcessHeap(), 0, total * sizeof(WCHAR) );
2368  }
2369 
2370  if(description)
2371  {
2372  len1 = (DWORD)strlen(description);
2373  len2 = (DWORD)strlen(description + len1 + 1);
2374  total = MultiByteToWideChar( CP_ACP, 0, description, len1 + len2 + 3, NULL, 0 );
2375  descriptionW = HeapAlloc( GetProcessHeap(), 0, total * sizeof(WCHAR) );
2376  MultiByteToWideChar( CP_ACP, 0, description, len1 + len2 + 3, descriptionW, total );
2377  }
2378 
2380 
2383  return ret;
2384 }
2385 
2386 /**********************************************************************
2387  * CreateEnhMetaFileW (GDI32.@)
2388  */
2390  const WCHAR *description )
2391 {
2392  HDC ret;
2393  struct emf *emf;
2394  WINEDC *dc_attr;
2395  HANDLE file;
2396  DWORD size = 0, length = 0;
2397 
2398  TRACE( "(%p %s %s %s)\n", hdc, debugstr_w(filename), wine_dbgstr_rect(rect),
2400 
2401  //if (!(ret = NtGdiCreateMetafileDC( hdc ))) return 0;
2403  {
2404  if (dc_attr->hdc) DeleteDC( dc_attr->hdc );
2405  return 0;
2406  }
2407 
2408  ret = dc_attr->hdc;
2409 
2410  if ( !(emf = HeapAlloc( GetProcessHeap(), 0, sizeof(*emf) )))
2411  {
2412  DeleteDC( ret );
2413  return 0;
2414  }
2415 
2416  emf->dc_attr = dc_attr;
2417  dc_attr->emf = emf;
2418 
2419  if (description) /* App name\0Title\0\0 */
2420  {
2422  length += lstrlenW( description + length + 1 );
2423  length += 3;
2424  length *= 2;
2425  }
2426  size = sizeof(ENHMETAHEADER) + (length + 3) / 4 * 4;
2427 
2429  {
2430  DeleteDC( ret );
2431  return 0;
2432  }
2433  emf->dc_attr = dc_attr;
2434 
2436  HANDLE_LIST_INC * sizeof(emf->handles[0]) );
2438  emf->cur_handles = 1;
2439  emf->file = 0;
2440  emf->dc_brush = 0;
2441  emf->dc_pen = 0;
2442  emf->path = FALSE;
2443 
2444  emf->emh->iType = EMR_HEADER;
2445  emf->emh->nSize = size;
2446 
2449 
2450  if (rect)
2451  {
2452  emf->emh->rclFrame.left = rect->left;
2453  emf->emh->rclFrame.top = rect->top;
2454  emf->emh->rclFrame.right = rect->right;
2455  emf->emh->rclFrame.bottom = rect->bottom;
2456  }
2457  else
2458  {
2459  /* Set this to {0,0 - -1,-1} and update it at the end */
2460  emf->emh->rclFrame.left = emf->emh->rclFrame.top = 0;
2461  emf->emh->rclFrame.right = emf->emh->rclFrame.bottom = -1;
2462  }
2463 
2465  emf->emh->nVersion = 0x10000;
2466  emf->emh->nBytes = emf->emh->nSize;
2467  emf->emh->nRecords = 1;
2468  emf->emh->nHandles = 1;
2469 
2470  emf->emh->sReserved = 0; /* According to docs, this is reserved and must be 0 */
2471  emf->emh->nDescription = length / 2;
2472 
2473  emf->emh->offDescription = length ? sizeof(ENHMETAHEADER) : 0;
2474 
2475  emf->emh->nPalEntries = 0; /* I guess this should start at 0 */
2476 
2477  /* Size in pixels */
2480 
2481  /* Size in millimeters */
2484 
2485  /* Size in micrometers */
2486  emf->emh->szlMicrometers.cx = emf->emh->szlMillimeters.cx * 1000;
2487  emf->emh->szlMicrometers.cy = emf->emh->szlMillimeters.cy * 1000;
2488 
2489  memcpy( (char *)emf->emh + sizeof(ENHMETAHEADER), description, length );
2490 
2491  if (filename) /* disk based metafile */
2492  {
2495  {
2496  DeleteDC( ret );
2497  return 0;
2498  }
2499  emf->file = file;
2500  }
2501 
2502  TRACE( "returning %p\n", ret );
2503  return ret;
2504 }
2505 
2506 /******************************************************************
2507  * CloseEnhMetaFile (GDI32.@)
2508  */
2510 {
2511  HENHMETAFILE hmf;
2512  struct emf *emf;
2513  WINEDC *dc_attr;
2514  EMREOF emr;
2515  HANDLE mapping = 0;
2516 
2517  if (!(dc_attr = get_dc_ptr( hdc )) || !dc_attr->emf) return 0;
2518  emf = dc_attr->emf;
2519 
2520  if (dc_attr->save_level)
2521  RestoreDC( hdc, 1 );
2522 
2523  if (emf->dc_brush) DeleteObject( emf->dc_brush );
2524  if (emf->dc_pen) DeleteObject( emf->dc_pen );
2525 
2526  emr.emr.iType = EMR_EOF;
2527  emr.emr.nSize = sizeof(emr);
2528  emr.nPalEntries = 0;
2529  emr.offPalEntries = FIELD_OFFSET(EMREOF, nSizeLast);
2530  emr.nSizeLast = emr.emr.nSize;
2531  emfdc_record( emf, &emr.emr );
2532 
2534 
2535  /* Update rclFrame if not initialized in CreateEnhMetaFile */
2536  if (emf->emh->rclFrame.left > emf->emh->rclFrame.right)
2537  {
2539  emf->emh->szlMillimeters.cx * 100 / emf->emh->szlDevice.cx;
2541  emf->emh->szlMillimeters.cy * 100 / emf->emh->szlDevice.cy;
2543  emf->emh->szlMillimeters.cx * 100 / emf->emh->szlDevice.cx;
2545  emf->emh->szlMillimeters.cy * 100 / emf->emh->szlDevice.cy;
2546  }
2547 
2548  if (emf->file) /* disk based metafile */
2549  {
2550  DWORD bytes_written;
2551 
2552  if (!WriteFile( emf->file, emf->emh, emf->emh->nBytes, &bytes_written, NULL ))
2553  {
2554  CloseHandle( emf->file );
2555  return 0;
2556  }
2557  HeapFree( GetProcessHeap(), 0, emf->emh );
2559  TRACE( "mapping = %p\n", mapping );
2560  emf->emh = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
2561  TRACE( "view = %p\n", emf->emh );
2562  CloseHandle( mapping );
2563  CloseHandle( emf->file );
2564  }
2565 
2566  hmf = EMF_Create_HENHMETAFILE( emf->emh, emf->emh->nBytes, emf->file != 0 );
2567  emf->emh = NULL; /* So it won't be deleted */
2568  DeleteDC( hdc );
2569  return hmf;
2570 }
HGDIOBJ WINAPI GetStockObject(_In_ int)
BOOL EMFDC_SetDIBitsToDevice(WINEDC *dc_attr, INT x_dst, INT y_dst, DWORD width, DWORD height, INT x_src, INT y_src, UINT startscan, UINT lines, const void *bits, const BITMAPINFO *info, UINT usage)
Definition: emfdc.c:1751
BOOL EMFDC_SetTextJustification(WINEDC *dc_attr, INT extra, INT breaks)
Definition: emfdc.c:1866
int WINAPI GetObjectA(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
#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 EMFDC_StrokeAndFillPath(WINEDC *dc_attr)
Definition: emfdc.c:1309
COLORREF crBkColorSrc
Definition: wingdi.h:2079
#define abs(i)
Definition: fconv.c:206
COLORREF crColor
Definition: wingdi.h:2222
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:84
BOOL EMFDC_ExcludeClipRect(WINEDC *dc_attr, INT left, INT top, INT right, INT bottom)
Definition: emfdc.c:1947
RECTL rclBounds
Definition: wingdi.h:2038
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
BOOL EMFDC_SetBrushOrg(WINEDC *dc_attr, INT x, INT y)
Definition: emfdc.c:2311
#define EMR_ROUNDRECT
Definition: wingdi.h:118
BOOL WINAPI GetCurrentPositionEx(_In_ HDC, _Out_ LPPOINT)
Definition: coord.c:241
GLint level
Definition: gl.h:1546
BOOL EMFDC_IntersectClipRect(WINEDC *dc_attr, INT left, INT top, INT right, INT bottom)
Definition: emfdc.c:1960
BYTE bWeight
Definition: wingdi.h:1871
GLint GLint GLsizei width
Definition: gl.h:1546
COLORREF WINAPI GetBkColor(_In_ HDC)
Definition: dc.c:978
DWORD offPalEntries
Definition: wingdi.h:1861
#define EMR_SETARCDIRECTION
Definition: wingdi.h:131
UINT WINAPI GetPaletteEntries(HPALETTE hpal, UINT iStartIndex, UINT cEntries, LPPALETTEENTRY ppe)
Definition: palette.c:64
#define HORZRES
Definition: wingdi.h:716
#define max(a, b)
Definition: svc.c:63
static DWORD emfdc_create_pen(struct emf *emf, HPEN hPen)
Definition: emfdc.c:443
BYTE bFamilyType
Definition: wingdi.h:1869
#define BS_DIBPATTERN
Definition: wingdi.h:1092
BOOL EMFDC_SelectClipPath(WINEDC *dc_attr, INT mode)
Definition: emfdc.c:2199
DWORD iUsageSrc
Definition: wingdi.h:1740
DWORD iUsageMask
Definition: wingdi.h:2055
struct tagENHMETAHEADER ENHMETAHEADER
POINTL ptlCenter
Definition: wingdi.h:1709
BOOL EMFDC_FillPath(WINEDC *dc_attr)
Definition: emfdc.c:1304
#define EMR_POLYLINE
Definition: wingdi.h:78
#define CloseHandle
Definition: compat.h:598
char hdr[14]
Definition: iptest.cpp:33
BOOL EMFDC_SetPixel(WINEDC *dc_attr, INT x, INT y, COLORREF color)
Definition: emfdc.c:834
static HBRUSH hbrush
BOOL EMFDC_PatBlt(WINEDC *dc_attr, INT left, INT top, INT width, INT height, DWORD rop)
Definition: emfdc.c:1408
BOOL EMFDRV_RoundRect(WINEDC *dc, INT left, INT top, INT right, INT bottom, INT ell_width, INT ell_height)
Definition: emfdrv.c:99
BOOL WINAPI GetTextMetricsW(_In_ HDC, _Out_ LPTEXTMETRICW)
Definition: text.c:221
SIZEL szlDevice
Definition: wingdi.h:2333
BOOL EMFDC_WriteNamedEscape(WINEDC *dc_attr, PWCHAR pDriver, INT nEscape, INT cbInput, LPCSTR lpszInData)
Definition: emfdc.c:2267
POINTL ptlReference
Definition: wingdi.h:1972
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1476
long y
Definition: polytest.cpp:48
#define MapViewOfFile
Definition: compat.h:604
static BOOL rop_uses_src(DWORD rop)
Definition: emfdc.c:1445
#define INT_MAX
Definition: limits.h:40
DWORD elpWidth
Definition: wingdi.h:1943
DWORD iGraphicsMode
Definition: wingdi.h:1982
DWORD biClrImportant
Definition: amvideo.idl:40
HPEN dc_pen
Definition: emfdc.c:52
ULONG lbHatch
Definition: wingdi.h:1755
HGDIOBJ * handles
Definition: emfdc.c:49
LONG cxDest
Definition: wingdi.h:2041
WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile)
static BOOL emfdc_select_font(WINEDC *dc_attr, HFONT font)
Definition: emfdc.c:408
#define EMR_POLYLINE16
Definition: wingdi.h:160
long x
Definition: polytest.cpp:48
UINT lbStyle
Definition: wingdi.h:1747
INT save_level
Definition: gdi_private.h:131
BOOL WINAPI LPtoDP(_In_ HDC hdc, _Inout_updates_(c) LPPOINT lppt, _In_ int c)
#define HANDLE_LIST_INC
Definition: emfdc.c:56
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
Definition: mk_font.cpp:20
BYTE bContrast
Definition: wingdi.h:1873
#define TRUE
Definition: types.h:120
#define EMR_STROKEANDFILLPATH
Definition: wingdi.h:137
#define pt(x, y)
Definition: drawing.c:79
BOOL EMFDC_SetLayout(WINEDC *dc_attr, DWORD layout)
Definition: emfdc.c:2091
BOOL EMFDC_PolyPolyline(WINEDC *dc_attr, const POINT *pt, const DWORD *counts, DWORD polys)
Definition: emfdc.c:954
_In_ ULONG iType
Definition: winddi.h:3748
SIZEL szlMillimeters
Definition: wingdi.h:2334
#define WHITE_PEN
Definition: wingdi.h:905
LONG yMask
Definition: wingdi.h:2054
#define ERROR(name)
Definition: error_private.h:53
LONG biXPelsPerMeter
Definition: amvideo.idl:37
#define CP_ACP
Definition: compat.h:109
LONG cxSrc
Definition: wingdi.h:2076
DWORD cbBitsMask
Definition: wingdi.h:2091
struct tagBITMAPINFOHEADER BITMAPINFOHEADER
#define EMR_EXCLUDECLIPRECT
Definition: wingdi.h:103
char ACPI_OBJECT_TYPE * Types
Definition: acdebug.h:353
GLuint GLuint GLsizei count
Definition: gl.h:1545
#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
#define EMR_WIDENPATH
Definition: wingdi.h:140
#define EMR_STROKEPATH
Definition: wingdi.h:138
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2053
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
DWORD cptl
Definition: wingdi.h:2110
POINTL aptl[1]
Definition: wingdi.h:2097
struct tagPOINTS POINTS
static HDC
Definition: imagelist.c:92
static BOOL emfdc_select_brush(WINEDC *dc_attr, HBRUSH brush)
Definition: emfdc.c:341
POINTL ptlStart
Definition: wingdi.h:1717
BOOL EMFDC_SetTextAlign(WINEDC *dc_attr, UINT align)
Definition: emfdc.c:1856
DWORD cbBitsSrc
Definition: wingdi.h:1744
DWORD cbBmiMask
Definition: wingdi.h:2089
XFORM xformSrc
Definition: wingdi.h:2046
long bottom
Definition: polytest.cpp:53
BOOL WINAPI EMFDC_GdiComment(HDC hdc, UINT bytes, const BYTE *buffer)
Definition: emfdc.c:2326
BOOL EMFDC_AlphaBlend(WINEDC *dc_attr, INT x_dst, INT y_dst, INT width_dst, INT height_dst, HDC hdc_src, INT x_src, INT y_src, INT width_src, INT height_src, BLENDFUNCTION blend_function)
Definition: emfdc.c:1399
DWORD offBmiSrc
Definition: wingdi.h:2081
LONG cxDest
Definition: wingdi.h:1733
POINT lopnWidth
Definition: wingdi.h:1846
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
#define EMR_ENDPATH
Definition: wingdi.h:134
#define EMR_POLYLINETO
Definition: wingdi.h:80
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
BOOL EMFDC_ExtTextOut(WINEDC *dc_attr, INT x, INT y, UINT flags, const RECT *rect, const WCHAR *str, UINT count, const INT *dx)
Definition: emfdc.c:1110
#define assert(x)
Definition: debug.h:53
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
BYTE Data[1]
Definition: wingdi.h:2024
GLuint buffer
Definition: glext.h:5915
#define EMR_PAINTRGN
Definition: wingdi.h:147
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define PAN_CULTURE_LATIN
Definition: wingdi.h:464
#define WHITE_BRUSH
Definition: wingdi.h:902
DWORD iUsageMask
Definition: wingdi.h:2087
#define EMR_MOVETOEX
Definition: wingdi.h:101
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
#define EMR_CREATEPALETTE
Definition: wingdi.h:123
#define EMR_STRETCHBLT
Definition: wingdi.h:150
BOOL EMFDC_MaskBlt(WINEDC *dc_attr, INT x_dst, INT y_dst, INT width_dst, INT height_dst, HDC hdc_src, INT x_src, INT y_src, HBITMAP mask, INT x_mask, INT y_mask, DWORD rop)
Definition: emfdc.c:1477
DWORD cbBitsMask
Definition: wingdi.h:2059
#define FLOAT
Definition: i386-dis.c:518
#define TA_LEFT
Definition: wingdi.h:932
int align(int length, int align)
Definition: dsound8.c:36
FLOAT eSweepAngle
Definition: wingdi.h:1712
#define EMR_ABORTPATH
Definition: wingdi.h:142
uint16_t * PWCHAR
Definition: typedefs.h:56
const char * description
Definition: directx.c:2497
#define EMR_SETBRUSHORGEX
Definition: wingdi.h:87
DWORD offDescription
Definition: wingdi.h:2331
#define EMR_SETTEXTCOLOR
Definition: wingdi.h:98
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define EMR_EXTCREATEFONTINDIRECTW
Definition: wingdi.h:155
static void emfdc_update_bounds(struct emf *emf, RECTL *rect)
Definition: emfdc.c:84
char * LPSTR
Definition: xmlstorage.h:182
BOOL EMFDC_Ellipse(WINEDC *dc_attr, INT left, INT top, INT right, INT bottom)
Definition: emfdc.c:759
#define EMR_SETTEXTALIGN
Definition: wingdi.h:96
const char * filename
Definition: ioapi.h:135
BOOL EMFDC_SetPolyFillMode(WINEDC *dc_attr, INT mode)
Definition: emfdc.c:1917
LONG biYPelsPerMeter
Definition: amvideo.idl:38
static DWORD emfdc_create_palette(struct emf *emf, HPALETTE hPal)
Definition: emfdc.c:507
#define lstrlenW
Definition: compat.h:609
struct tagEMRSETDIBITSTODEVICE EMRSETDIBITSTODEVICE
#define EMR_SELECTPALETTE
Definition: wingdi.h:122
#define EMR_POLYDRAW
Definition: wingdi.h:130
BOOL EMFDC_SetWindowExtEx(WINEDC *dc_attr, INT cx, INT cy)
Definition: emfdc.c:2032
SIZE_T WINAPI HeapSize(HANDLE, DWORD, LPCVOID)
#define DWORD
Definition: nt_native.h:44
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
HGDIOBJ get_full_gdi_handle(HGDIOBJ handle) DECLSPEC_HIDDEN
int32_t INT
Definition: typedefs.h:58
DWORD offBitsSrc
Definition: wingdi.h:2051
static BOOL emfdc_select_pen(WINEDC *dc_attr, HPEN pen)
Definition: emfdc.c:474
& rect
Definition: startmenu.cpp:1413
LONG cySrc
Definition: wingdi.h:2077
BOOL EMFDC_ModifyWorldTransform(WINEDC *dc_attr, const XFORM *xform, DWORD mode)
Definition: emfdc.c:2111
BOOL EMFDRV_Rectangle(WINEDC *dc, INT left, INT top, INT right, INT bottom)
Definition: emfdrv.c:275
#define EMR_SELECTOBJECT
Definition: wingdi.h:111
BOOL EMFDC_SetDCPenColor(WINEDC *dc_attr, COLORREF color)
Definition: emfdc.c:1809
#define BS_NULL
Definition: wingdi.h:1087
POINTL ptlPixel
Definition: wingdi.h:2221
LOGPEN lopn
Definition: wingdi.h:1852
LONG y
Definition: windef.h:330
#define EMR_SETVIEWPORTORGEX
Definition: wingdi.h:86
BOOL EMFDRV_ArcChordPie(WINEDC *dc, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend, DWORD type)
Definition: emfdrv.c:120
DWORD elfReserved
Definition: wingdi.h:1931
BOOL EMFDC_SetWindowOrgEx(WINEDC *dc_attr, INT x, INT y)
Definition: emfdc.c:2054
BYTE RgnData[1]
Definition: wingdi.h:1996
BOOL EMFDC_SetMetaRgn(WINEDC *dc_attr)
Definition: emfdc.c:2301
#define OBJ_PEN
Definition: objidl.idl:1409
#define EMR_PLGBLT
Definition: wingdi.h:152
BOOL EMFDC_SetBkMode(WINEDC *dc_attr, INT mode)
Definition: emfdc.c:1877
static const WCHAR filenameW[]
Definition: amstream.c:41
#define EMR_SETSTRETCHBLTMODE
Definition: wingdi.h:95
LOGFONTW elfLogFont
Definition: wingdi.h:1925
UINT WINAPI GetTextAlign(_In_ HDC)
Definition: text.c:831
#define OEM_FIXED_FONT
Definition: wingdi.h:910
#define PS_SOLID
Definition: wingdi.h:586
long right
Definition: polytest.cpp:53
DWORD cbRgnData
Definition: wingdi.h:1994
#define TA_TOP
Definition: wingdi.h:930
RECTL rclBox
Definition: wingdi.h:1856
LONG y
Definition: wingdi.h:2785
#define L(x)
Definition: ntvdm.h:50
BOOL EMFDC_GradientFill(WINEDC *dc_attr, TRIVERTEX *vert_array, ULONG nvert, void *grad_array, ULONG ngrad, ULONG mode)
Definition: emfdc.c:1253
DWORD ihBrush
Definition: wingdi.h:2017
GLenum GLint GLuint mask
Definition: glext.h:6028
unsigned char * LPBYTE
Definition: typedefs.h:53
RECTL emf_bounds
Definition: gdi_private.h:132
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
static DWORD emfdc_create_brush(struct emf *emf, HBRUSH brush)
Definition: emfdc.c:251
#define FALSE
Definition: types.h:117
#define EMR_EOF
Definition: wingdi.h:88
#define EMR_INTERSECTCLIPRECT
Definition: wingdi.h:104
HBRUSH dc_brush
Definition: emfdc.c:51
unsigned int BOOL
Definition: ntddk_ex.h:94
LONG xSrc
Definition: wingdi.h:2074
long LONG
Definition: pedump.c:60
GLuint color
Definition: glext.h:6243
BOOL APIENTRY NtGdiGetTransform(_In_ HDC hdc, _In_ DWORD iXform, _Out_ LPXFORM pxf)
FLOAT eDx
Definition: wingdi.h:1725
#define TA_BASELINE
Definition: wingdi.h:928
#define GENERIC_WRITE
Definition: nt_native.h:90
long top
Definition: polytest.cpp:53
#define debugstr_w
Definition: kernel32.h:32
BOOL EMFDC_BitBlt(WINEDC *dc_attr, INT x_dst, INT y_dst, INT width, INT height, HDC hdc_src, INT x_src, INT y_src, DWORD rop)
Definition: emfdc.c:1450
#define EMR_RESTOREDC
Definition: wingdi.h:108
static int rop(int rop, int src, int dst)
Definition: nanoxwin.c:124
RECTL rcl
Definition: wingdi.h:1976
#define FIXME(fmt,...)
Definition: debug.h:111
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
EMR emr
Definition: wingdi.h:1859
DWORD biCompression
Definition: amvideo.idl:35
DWORD elpPenStyle
Definition: wingdi.h:1942
UINT lopnStyle
Definition: wingdi.h:1845
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:585
const WCHAR * str
COLORREF lopnColor
Definition: wingdi.h:1847
static struct list apts
Definition: compobj.c:78
XFORM xformSrc
Definition: wingdi.h:1738
FLOAT eM21
Definition: wingdi.h:1723
#define TA_BOTTOM
Definition: wingdi.h:929
BOOL EMFDC_ScaleViewportExtEx(WINEDC *dc_attr, INT x_num, INT x_denom, INT y_num, INT y_denom)
Definition: emfdc.c:2065
struct tagEMRSTRETCHDIBITS EMRSTRETCHDIBITS
#define offsetof(TYPE, MEMBER)
POINTL ptl
Definition: wingdi.h:2034
BOOL EMFDC_ArcChordPie(WINEDC *dc_attr, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend, DWORD type)
Definition: emfdc.c:711
FLOAT eM12
Definition: wingdi.h:1722
BOOL EMFDC_PlgBlt(WINEDC *dc_attr, const POINT *points, HDC hdc_src, INT x_src, INT y_src, INT width, INT height, HBITMAP mask, INT x_mask, INT y_mask)
Definition: emfdc.c:1584
LONG cx
Definition: windef.h:334
#define GdiGetEMFRestorDc
Definition: emfdc.c:1836
#define EMR_POLYPOLYLINE
Definition: wingdi.h:81
static void get_points_bounds(RECTL *bounds, const POINT *pts, UINT count, WINEDC *dc_attr)
Definition: emfdc.c:604
RECTL rclBounds
Definition: wingdi.h:2095
GLint GLint bottom
Definition: glext.h:7726
SHORT x
Definition: windef.h:342
LONG cyDest
Definition: wingdi.h:1734
#define EMR_EXTTEXTOUTW
Definition: wingdi.h:157
#define FILE_MAP_READ
Definition: compat.h:635
BOOL EMFDC_StretchDIBits(WINEDC *dc_attr, INT x_dst, INT y_dst, INT width_dst, INT height_dst, INT x_src, INT y_src, INT width_src, INT height_src, const void *bits, const BITMAPINFO *info, UINT usage, DWORD rop)
Definition: emfdc.c:1698
BOOL EMFDC_SetMapMode(WINEDC *dc_attr, INT mode)
Definition: emfdc.c:2011
WCHAR elfFullName[LF_FULLFACESIZE]
Definition: wingdi.h:1926
GLuint index
Definition: glext.h:6031
unsigned int dir
Definition: maze.c:112
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
static BOOL can_use_short_points(const POINT *pts, UINT count)
Definition: emfdc.c:571
long left
Definition: polytest.cpp:53
DWORD elfStyleSize
Definition: wingdi.h:1929
WINEDC * dc_attr
Definition: emfdc.c:47
COLORREF lbColor
Definition: wingdi.h:1754
DWORD nPalEntries
Definition: wingdi.h:1860
#define EMR_INVERTRGN
Definition: wingdi.h:146
DC * alloc_dc_ptr(WORD magic) DECLSPEC_HIDDEN
Definition: rosglue.c:106
BOOL EMFDC_Rectangle(WINEDC *dc_attr, INT left, INT top, INT right, INT bottom)
Definition: emfdc.c:783
COLORREF crColor
Definition: wingdi.h:2181
#define EMR_RECTANGLE
Definition: wingdi.h:117
DWORD cbBmiSrc
Definition: wingdi.h:2050
DWORD iUsageSrc
Definition: wingdi.h:2048
DWORD dSignature
Definition: wingdi.h:2324
#define GDI_HANDLE_GET_TYPE(h)
Definition: gdi.h:31
BOOL EMFDC_RoundRect(WINEDC *dc_attr, INT left, INT top, INT right, INT bottom, INT ell_width, INT ell_height)
Definition: emfdc.c:807
BYTE bSerifStyle
Definition: wingdi.h:1870
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
static UINT emfdc_add_handle(struct emf *emf, HGDIOBJ obj)
Definition: emfdc.c:199
#define EMR_GDICOMMENT
Definition: wingdi.h:143
#define EMR_MODIFYWORLDTRANSFORM
Definition: wingdi.h:110
#define TA_RIGHT
Definition: wingdi.h:933
static const RECTL empty_bounds
Definition: emfdc.c:57
eMaj lines
Definition: tritemp.h:206
Definition: uimain.c:88
BOOL EMFDC_WriteEscape(WINEDC *dc_attr, INT nEscape, INT cbInput, LPSTR lpszInData, DWORD emrType)
Definition: emfdc.c:2239
#define EMR_CREATEDIBPATTERNBRUSHPT
Definition: wingdi.h:167
BOOL EMFDC_FlattenPath(WINEDC *dc_attr)
Definition: emfdc.c:2190
RECTL rclBounds
Definition: wingdi.h:2109
#define EMR_SETROP2
Definition: wingdi.h:94
BOOL EMFDRV_LineTo(WINEDC *dc, INT x, INT y)
Definition: emfdrv.c:83
DWORD offDx
Definition: wingdi.h:1977
FxDriver * pDriver
INT APIENTRY NtGdiGetRgnBox(HRGN hRgn, PRECTL pRect)
Definition: region.c:3939
#define TRACE(s)
Definition: solgame.cpp:4
struct tagEMRBITBLT EMRBITBLT
GLsizeiptr size
Definition: glext.h:5919
RECTL rclFrame
Definition: wingdi.h:2323
#define GetProcessHeap()
Definition: compat.h:595
#define PAN_NO_FIT
Definition: wingdi.h:466
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define DEFAULT_PALETTE
Definition: wingdi.h:913
Definition: id3.c:95
BOOL EMFDC_SetDCBrushColor(WINEDC *dc_attr, COLORREF color)
Definition: emfdc.c:1791
ULONG RGBQUAD
Definition: precomp.h:50
RGBQUAD bmiColors[1]
Definition: wingdi.h:1477
Definition: cmds.c:130
BOOL WINAPI GetViewportExtEx(_In_ HDC, _Out_ LPSIZE)
Definition: coord.c:351
#define EMR_SETPIXELV
Definition: wingdi.h:89
__wchar_t WCHAR
Definition: xmlstorage.h:180
int WINAPI GetGraphicsMode(_In_ HDC)
LONG x
Definition: wingdi.h:2784
DWORD COLORREF
Definition: windef.h:300
#define OBJ_ENHMETADC
Definition: objidl.idl:1420
DWORD WINAPI GetDCDWord(_In_ HDC hdc, _In_ UINT u, _In_ DWORD dwError)
Definition: dc.c:787
#define EMR_BITBLT
Definition: wingdi.h:149
BOOL WINAPI GetWindowExtEx(_In_ HDC, _Out_ LPSIZE)
Definition: coord.c:411
DWORD cbBitsSrc
Definition: wingdi.h:2052
#define EMR_ELLIPSE
Definition: wingdi.h:116
BYTE bLetterform
Definition: wingdi.h:1876
DWORD offBitsMask
Definition: wingdi.h:2058
COLORREF lbColor
Definition: wingdi.h:1748
#define WINAPI
Definition: msvc.h:6
const char file[]
Definition: icontest.c:11
BOOL EMFDC_MoveTo(WINEDC *dc_attr, INT x, INT y)
Definition: emfdc.c:685
const char * wine_dbgstr_rect(const RECT *rect)
COLORREF crBkColorSrc
Definition: wingdi.h:1739
LONG xSrc
Definition: wingdi.h:1736
unsigned short WORD
Definition: ntddk_ex.h:93
DWORD dwRop
Definition: wingdi.h:2043
unsigned long DWORD
Definition: ntddk_ex.h:95
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
#define EMR_SCALEWINDOWEXTEX
Definition: wingdi.h:106
GLint left
Definition: glext.h:7726
DWORD offBitsSrc
Definition: wingdi.h:2083
LONG x
Definition: windef.h:329
DWORD biSizeImage
Definition: amvideo.idl:36
int WINAPI GetPath(_In_ HDC hdc, _Out_writes_opt_(cpt) LPPOINT apt, _Out_writes_opt_(cpt) LPBYTE aj, int cpt)
#define EMR_FILLRGN
Definition: wingdi.h:144
LONG cyDest
Definition: wingdi.h:2042
#define SetLastError(x)
Definition: compat.h:611
#define EMR_CREATEBRUSHINDIRECT
Definition: wingdi.h:113
#define OBJ_PAL
Definition: objidl.idl:1413
#define EMR_SELECTCLIPPATH
Definition: wingdi.h:141
GLdouble GLdouble right
Definition: glext.h:10859
HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc)
Definition: emfdc.c:2509
BITMAP bmp
Definition: alphablend.c:62
static void * store_points(POINTL *dest, const POINT *pts, UINT count, BOOL short_points)
Definition: emfdc.c:582
#define EMR_POLYGON
Definition: wingdi.h:77
GLbitfield flags
Definition: glext.h:7161
static BOOL emfdc_polylinegon(WINEDC *dc_attr, const POINT *points, INT count, DWORD type)
Definition: emfdc.c:849
#define DEFAULT_GUI_FONT
Definition: wingdi.h:909
EMR emr
Definition: wingdi.h:1715
LONG yDest
Definition: wingdi.h:2040
#define GM_COMPATIBLE
Definition: wingdi.h:864
BOOL EMFDC_CloseFigure(WINEDC *dc_attr)
Definition: emfdc.c:2169
static BOOL emfdc_poly_polylinegon(struct emf *emf, const POINT *pt, const INT *counts, UINT polys, DWORD type)
Definition: emfdc.c:903
BOOL get_brush_bitmap_info(HBRUSH handle, BITMAPINFO *info, void *bits, UINT *usage) DECLSPEC_HIDDEN
GLsizei const GLfloat * points
Definition: glext.h:8112
BYTE RgnData[1]
Definition: wingdi.h:2019
BYTE bProportion
Definition: wingdi.h:1872
DWORD elfVersion
Definition: wingdi.h:1928
static UINT emfdc_find_object(struct emf *emf, HGDIOBJ obj)
Definition: emfdc.c:222
BOOL EMFDC_AngleArc(WINEDC *dc_attr, INT x, INT y, DWORD radius, FLOAT start, FLOAT sweep)
Definition: emfdc.c:745
int ret
POINTL ptlEnd
Definition: wingdi.h:1718
static const unsigned char enhmetafile[]
Definition: olepicture.c:149
DWORD nSize
Definition: wingdi.h:1691
struct _POINTL POINTL
FLOAT eM11
Definition: wingdi.h:1721
#define EMR_DELETEOBJECT
Definition: wingdi.h:114
#define EMR_CREATEPEN
Definition: wingdi.h:112
#define EMR_FILLPATH
Definition: wingdi.h:136
BOOL EMFDC_InvertRgn(WINEDC *dc_attr, HRGN hrgn)
Definition: emfdc.c:1105
RECTL rclBox
Definition: wingdi.h:2155
BOOL EMFDC_SetTextColor(WINEDC *dc_attr, COLORREF color)
Definition: emfdc.c:1897
#define index(s, c)
Definition: various.h:29
BOOL EMFDC_StrokePath(WINEDC *dc_attr)
Definition: emfdc.c:1314
HDC hdc
Definition: main.c:9
BOOL EMFDC_Polygon(WINEDC *dc_attr, const POINT *pt, INT count)
Definition: emfdc.c:887
BOOL path
Definition: emfdc.c:53
#define EMR_HEADER
Definition: wingdi.h:75
DWORD nRecords
Definition: wingdi.h:2327
static HRGN hrgn
Definition: win.c:55
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
static DWORD layout
Definition: bitmap.c:46
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
uint32_t entry
Definition: isohybrid.c:63
BOOL EMFDC_SetWorldTransform(WINEDC *dc_attr, const XFORM *xform)
Definition: emfdc.c:2101
WCHAR elfStyle[LF_FACESIZE]
Definition: wingdi.h:1927
BOOL EMFDC_TransparentBlt(WINEDC *dc_attr, int x_dst, int y_dst, int width_dst, int height_dst, HDC hdc_src, int x_src, int y_src, int width_src, int height_src, UINT color)
Definition: emfdc.c:1468
static BOOL emfdrv_stroke_and_fill_path(struct emf *emf, INT type)
Definition: emfdc.c:665
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
LONG yDest
Definition: wingdi.h:1732
BOOL EMFDC_SetMapperFlags(WINEDC *dc_attr, DWORD flags)
Definition: emfdc.c:2134
#define GENERIC_READ
Definition: compat.h:135
Definition: time.h:68
#define err(...)
BOOL EMFDC_SaveDC(WINEDC *dc_attr)
Definition: emfdc.c:1828
BOOL EMFDC_RestoreDC(WINEDC *dc_attr, INT level)
Definition: emfdc.c:1837
GLenum mode
Definition: glext.h:6217
Definition: emfdc.c:44
UINT lbStyle
Definition: wingdi.h:1753
#define debugstr_wn
Definition: kernel32.h:33
HPEN WINAPI CreatePenIndirect(_In_ const LOGPEN *)
unsigned char BYTE
Definition: xxhash.c:193
static HPALETTE palette
Definition: clipboard.c:1345
BYTE bMidline
Definition: wingdi.h:1877
#define ENHMETA_SIGNATURE
Definition: wingdi.h:204
DWORD offBmiSrc
Definition: wingdi.h:2049
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
BOOL EMFDRV_Ellipse(WINEDC *dc, INT left, INT top, INT right, INT bottom)
Definition: emfdrv.c:255
UINT cur_handles
Definition: emfdc.c:48
#define EMR_POLYBEZIER
Definition: wingdi.h:76
ENHMETAHEADER * emh
Definition: emfdc.c:46
#define EMR_SCALEVIEWPORTEXTEX
Definition: wingdi.h:105
BOOL EMFDC_DeleteDC(WINEDC *dc_attr)
Definition: emfdc.c:2218
#define EMR_SETWINDOWEXTEX
Definition: wingdi.h:83
DWORD dwRop
Definition: wingdi.h:1735
#define EMR_SETBKMODE
Definition: wingdi.h:92
#define HORZSIZE
Definition: wingdi.h:714
#define RGN_COPY
Definition: wingdi.h:357
#define GdiWorldSpaceToDeviceSpace
Definition: gdi_private.h:221
BOOL EMFDC_SetViewportOrgEx(WINEDC *dc_attr, INT x, INT y)
Definition: emfdc.c:2043
DWORD nChars
Definition: wingdi.h:1973
#define EMR_ANGLEARC
Definition: wingdi.h:115
LONG xMask
Definition: wingdi.h:2053
DWORD cptl
Definition: wingdi.h:2096
#define EMR_EXTFLOODFILL
Definition: wingdi.h:127
DWORD offBitsMask
Definition: wingdi.h:2090
RECTL rclBounds
Definition: wingdi.h:1730
static UINT get_bitmap_info(HDC *hdc, HBITMAP *bitmap, BITMAPINFO *info)
Definition: emfdc.c:120
DWORD cbBmiMask
Definition: wingdi.h:2057
BYTE RgnData[1]
Definition: wingdi.h:2030
static BOOL emfdc_paint_invert_region(struct emf *emf, HRGN hrgn, DWORD iType)
Definition: emfdc.c:1074
DWORD offBmiSrc
Definition: wingdi.h:1741
#define EMR_CLOSEFIGURE
Definition: wingdi.h:135
RECTL rclBounds
Definition: wingdi.h:2072
SHORT y
Definition: windef.h:343
static BOOL emfdc_record(struct emf *emf, EMR *emr)
Definition: emfdc.c:59
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
BOOL EMFDC_BeginPath(WINEDC *dc_attr)
Definition: emfdc.c:2156
RECTL rclBounds
Definition: wingdi.h:2322
BOOL EMFDC_PolyDraw(WINEDC *dc_attr, const POINT *pts, const BYTE *types, DWORD count)
Definition: emfdc.c:964
DWORD iType
Definition: wingdi.h:1690
BOOL EMFDC_SelectPalette(WINEDC *dc_attr, HPALETTE palette)
Definition: emfdc.c:532
LONG ySrc
Definition: wingdi.h:1737
#define CREATE_ALWAYS
Definition: disk.h:72
#define VERTSIZE
Definition: wingdi.h:715
struct tagEMRCREATEDIBPATTERNBRUSHPT EMRCREATEDIBPATTERNBRUSHPT
BOOL EMFDC_PolyBezier(WINEDC *dc_attr, const POINT *pts, DWORD count)
Definition: emfdc.c:893
LONG ySrc
Definition: wingdi.h:2075
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
HDC WINAPI CreateEnhMetaFileW(HDC hdc, const WCHAR *filename, const RECT *rect, const WCHAR *description)
Definition: emfdc.c:2389
BOOL WINAPI DeleteDC(_In_ HDC)
#define OBJ_BRUSH
Definition: objidl.idl:1410
BOOL EMFDC_WidenPath(WINEDC *dc_attr)
Definition: emfdc.c:2209
SIZEL szlStroke
Definition: wingdi.h:2018
#define EMR_FLATTENPATH
Definition: wingdi.h:139
DWORD cbRgnData
Definition: wingdi.h:2029
static calc_node_t temp
Definition: rpn_ieee.c:38
GLuint start
Definition: gl.h:1545
DWORD fOptions
Definition: wingdi.h:1975
RECTL rclBounds
Definition: wingdi.h:1993
BOOL EMFDC_Polyline(WINEDC *dc_attr, const POINT *points, INT count)
Definition: emfdc.c:877
POINTL aptl[1]
Definition: wingdi.h:2111
static BOOL emfdc_create_font(struct emf *emf, HFONT font)
Definition: emfdc.c:374
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
#define HeapReAlloc
Definition: compat.h:593
PANOSE elfPanose
Definition: wingdi.h:1934
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
FLOAT eM22
Definition: wingdi.h:1724
#define min(a, b)
Definition: monoChain.cc:55
FLOAT eDy
Definition: wingdi.h:1726
unsigned int UINT
Definition: ndis.h:50
COLORREF crColor
Definition: wingdi.h:1962
#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
BOOL EMFDC_SetViewportExtEx(WINEDC *dc_attr, INT cx, INT cy)
Definition: emfdc.c:2021
#define PAGE_READONLY
Definition: compat.h:138
#define VERTRES
Definition: wingdi.h:717
DC * get_dc_ptr(HDC hdc) DECLSPEC_HIDDEN
Definition: rosglue.c:147
BYTE bStrokeVariation
Definition: wingdi.h:1874
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
BOOL EMFDC_LineTo(WINEDC *dc_attr, INT x, INT y)
Definition: emfdc.c:697
static const BYTE dib[]
Definition: ole2.c:201
__kernel_entry W32KAPI HRGN APIENTRY NtGdiPathToRegion(_In_ HDC hdc)
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
size_t total
GLint dx
Definition: linetemp.h:97
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define BS_PATTERN
Definition: wingdi.h:1090
#define MultiByteToWideChar
Definition: compat.h:110
RECTL rclBounds
Definition: wingdi.h:1989
BOOL EMFDC_ExtFloodFill(WINEDC *dc_attr, INT x, INT y, COLORREF color, UINT fill_type)
Definition: emfdc.c:998
BOOL EMFDC_ScaleWindowExtEx(WINEDC *dc_attr, INT x_num, INT x_denom, INT y_num, INT y_denom)
Definition: emfdc.c:2078
BOOL EMFDC_SetArcDirection(WINEDC *dc_attr, INT dir)
Definition: emfdc.c:1937
#define CreateFileW
Definition: compat.h:600
DWORD nVersion
Definition: wingdi.h:2325
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
void GDI_hdc_using_object(HGDIOBJ obj, HDC hdc) DECLSPEC_HIDDEN
Definition: rosglue.c:166
#define MWT_IDENTITY
Definition: wingdi.h:944
static const WCHAR descriptionW[]
Definition: error.c:32
BYTE bArmStyle
Definition: wingdi.h:1875
RECTL rclBounds
Definition: wingdi.h:2028
_Out_opt_ int * cx
Definition: commctrl.h:585
#define EMR_POLYPOLYGON
Definition: wingdi.h:82
int WINAPI GetDIBits(_In_ HDC hdc, _In_ HBITMAP hbm, _In_ UINT start, _In_ UINT cLines, _Out_opt_ LPVOID lpvBits, _At_((LPBITMAPINFOHEADER) lpbmi, _Inout_) LPBITMAPINFO lpbmi, _In_ UINT usage)
BOOL EMFDC_SetROP2(WINEDC *dc_attr, INT rop)
Definition: emfdc.c:1907
void GDI_hdc_not_using_object(HGDIOBJ obj, HDC hdc) DECLSPEC_HIDDEN
Definition: rosglue.c:182
COLORREF crBkColorSrc
Definition: wingdi.h:2047
RECTL rclBox
Definition: wingdi.h:1716
float FLOAT
Definition: typedefs.h:69
DWORD nSizeLast
Definition: wingdi.h:1862
static int get_dib_info_size(const BITMAPINFO *info, UINT coloruse)
Definition: gdi_private.h:212
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
unsigned int ULONG
Definition: retypes.h:1
XFORM xformSrc
Definition: wingdi.h:2078
#define EMR_MASKBLT
Definition: wingdi.h:151
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
BOOL EMFDC_ExtSelectClipRgn(WINEDC *dc_attr, HRGN hrgn, INT mode)
Definition: emfdc.c:1984
LONG xDest
Definition: wingdi.h:1731
#define EMR_SETVIEWPORTEXTEX
Definition: wingdi.h:85
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
BOOL EMFDC_FillRgn(WINEDC *dc_attr, HRGN hrgn, HBRUSH hbrush)
Definition: emfdc.c:1011
struct tagPALETTEENTRY PALETTEENTRY
DWORD bpp
Definition: surface.c:185
static HBITMAP bitmap
Definition: clipboard.c:1344
static char * dest
Definition: rtl.c:135
#define EMR_POLYDRAW16
Definition: wingdi.h:165
#define BS_HATCHED
Definition: wingdi.h:1089
DWORD cbRgnData
Definition: wingdi.h:2016
#define BS_SOLID
Definition: wingdi.h:1086
static HBITMAP
Definition: button.c:44
#define TA_CENTER
Definition: wingdi.h:931
LONG iRelative
Definition: wingdi.h:2151
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
#define EMR_POLYPOLYLINE16
Definition: wingdi.h:163
HANDLE file
Definition: emfdc.c:50
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
FLOAT eStartAngle
Definition: wingdi.h:1711
#define EMR_SETWINDOWORGEX
Definition: wingdi.h:84
#define EMR_SETDIBITSTODEVICE
Definition: wingdi.h:153
DWORD iUsageSrc
Definition: wingdi.h:2080
COLORREF EMFDRV_SetPixel(WINEDC *dc, INT x, INT y, COLORREF color)
Definition: emfdrv.c:295
BYTE bXHeight
Definition: wingdi.h:1878
DWORD elfCulture
Definition: wingdi.h:1933
#define DIB_RGB_COLORS
Definition: wingdi.h:367