ReactOS  0.4.13-dev-455-g28ed234
graphics.c
Go to the documentation of this file.
1 /*
2  * Enhanced MetaFile driver graphics functions
3  *
4  * Copyright 1999 Huw D M Davies
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include "config.h"
22 #include "wine/port.h"
23 
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <string.h>
27 
28 #include "windef.h"
29 #include "winbase.h"
30 #include "wingdi.h"
32 #include "wine/debug.h"
33 
35 
36 static const RECTL empty_bounds = { 0, 0, -1, -1 };
37 
38 /* determine if we can use 16-bit points to store all the input points */
39 static BOOL can_use_short_points( const POINT *pts, UINT count )
40 {
41  UINT i;
42 
43  for (i = 0; i < count; i++)
44  if (((pts[i].x + 0x8000) & ~0xffff) || ((pts[i].y + 0x8000) & ~0xffff))
45  return FALSE;
46  return TRUE;
47 }
48 
49 /* store points in either long or short format; return a pointer to the end of the stored data */
50 static void *store_points( POINTL *dest, const POINT *pts, UINT count, BOOL short_points )
51 {
52  if (short_points)
53  {
54  UINT i;
55  POINTS *dest_short = (POINTS *)dest;
56 
57  for (i = 0; i < count; i++)
58  {
59  dest_short[i].x = pts[i].x;
60  dest_short[i].y = pts[i].y;
61  }
62  return dest_short + count;
63  }
64  else
65  {
66  memcpy( dest, pts, count * sizeof(*dest) );
67  return dest + count;
68  }
69 }
70 
71 /* compute the bounds of an array of points, optionally including the current position */
72 #ifdef __REACTOS__
73 static void get_points_bounds( RECTL *bounds, const POINT *pts, UINT count, HDC hdc )
74 #else
75 static void get_points_bounds( RECTL *bounds, const POINT *pts, UINT count, DC *dc )
76 #endif
77 {
78  UINT i;
79 #ifdef __REACTOS__
80  if (hdc)
81  {
82  POINT cur_pt;
83  GetCurrentPositionEx( hdc, &cur_pt );
84  bounds->left = bounds->right = cur_pt.x;
85  bounds->top = bounds->bottom = cur_pt.y;
86  }
87 #else
88  if (dc)
89  {
90  bounds->left = bounds->right = dc->cur_pos.x;
91  bounds->top = bounds->bottom = dc->cur_pos.y;
92  }
93 #endif
94  else if (count)
95  {
96  bounds->left = bounds->right = pts[0].x;
97  bounds->top = bounds->bottom = pts[0].y;
98  }
99  else *bounds = empty_bounds;
100 
101  for (i = 0; i < count; i++)
102  {
103  bounds->left = min( bounds->left, pts[i].x );
104  bounds->right = max( bounds->right, pts[i].x );
105  bounds->top = min( bounds->top, pts[i].y );
106  bounds->bottom = max( bounds->bottom, pts[i].y );
107  }
108 }
109 
110 /* helper for path stroke and fill functions */
111 #ifdef __REACTOS__
113 {
115  LPPOINT Points;
116  LPBYTE Types;
117  INT nSize;
118 
119  emr.emr.iType = type;
120  emr.emr.nSize = sizeof(emr);
121 
122  nSize = GetPath(dev->hdc, NULL, NULL, 0);
123  if (nSize != -1)
124  {
125  Points = HeapAlloc( GetProcessHeap(), 0, nSize*sizeof(POINT) );
126  Types = HeapAlloc( GetProcessHeap(), 0, nSize*sizeof(BYTE) );
127 
128  GetPath(dev->hdc, Points, Types, nSize);
129  get_points_bounds( &emr.rclBounds, Points, nSize, 0 );
130 
131  HeapFree( GetProcessHeap(), 0, Points );
132  HeapFree( GetProcessHeap(), 0, Types );
133 
134  TRACE("GetBounds l %d t %d r %d b %d\n",emr.rclBounds.left, emr.rclBounds.top, emr.rclBounds.right, emr.rclBounds.bottom);
135  }
136  else emr.rclBounds = empty_bounds;
137 
138  if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
139  if (nSize == -1 ) return FALSE;
141  return TRUE;
142 }
143 #else
145 {
146  DC *dc = get_physdev_dc( dev );
148  struct gdi_path *path;
149  POINT *points;
150  BYTE *flags;
151 
152  emr.emr.iType = type;
153  emr.emr.nSize = sizeof(emr);
154 
155  if ((path = get_gdi_flat_path( dc, NULL )))
156  {
157  int count = get_gdi_path_data( path, &points, &flags );
159  free_gdi_path( path );
160  }
161  else emr.rclBounds = empty_bounds;
162 
163  if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
164  if (!path) return FALSE;
166  return TRUE;
167 }
168 #endif
169 
170 /**********************************************************************
171  * EMFDRV_MoveTo
172  */
174 {
175  EMRMOVETOEX emr;
176 
177  emr.emr.iType = EMR_MOVETOEX;
178  emr.emr.nSize = sizeof(emr);
179  emr.ptl.x = x;
180  emr.ptl.y = y;
181 
182  return EMFDRV_WriteRecord( dev, &emr.emr );
183 }
184 
185 /***********************************************************************
186  * EMFDRV_LineTo
187  */
189 {
190  EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
191 #ifndef __REACTOS__
192  DC *dc = get_physdev_dc( dev );
193 #endif
194  POINT pt;
195  EMRLINETO emr;
196  RECTL bounds;
197 
198  emr.emr.iType = EMR_LINETO;
199  emr.emr.nSize = sizeof(emr);
200  emr.ptl.x = x;
201  emr.ptl.y = y;
202 
203  if(!EMFDRV_WriteRecord( dev, &emr.emr ))
204  return FALSE;
205 #ifdef __REACTOS__
206  GetCurrentPositionEx( dev->hdc, &pt );
207 #else
208  pt = dc->cur_pos;
209 #endif
210  bounds.left = min(x, pt.x);
211  bounds.top = min(y, pt.y);
212  bounds.right = max(x, pt.x);
213  bounds.bottom = max(y, pt.y);
214 
215  if(!physDev->path)
216  EMFDRV_UpdateBBox( dev, &bounds );
217 
218  return TRUE;
219 }
220 
221 
222 /***********************************************************************
223  * EMFDRV_ArcChordPie
224  */
225 static BOOL
227  INT xstart, INT ystart, INT xend, INT yend, DWORD iType )
228 {
229  EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
230 #ifndef __REACTOS__
231  DC *dc = get_physdev_dc( dev );
232 #endif
233  INT temp, xCentre, yCentre, i;
234  double angleStart, angleEnd;
235  double xinterStart, yinterStart, xinterEnd, yinterEnd;
236  EMRARC emr;
237  RECTL bounds;
238 
239  if(left == right || top == bottom) return FALSE;
240 
241  if(left > right) {temp = left; left = right; right = temp;}
242  if(top > bottom) {temp = top; top = bottom; bottom = temp;}
243 #ifdef __REACTOS__
244  if(GetGraphicsMode(dev->hdc) == GM_COMPATIBLE) {
245 #else
246  if(dc->GraphicsMode == GM_COMPATIBLE) {
247 #endif
248  right--;
249  bottom--;
250  }
251 
252  emr.emr.iType = iType;
253  emr.emr.nSize = sizeof(emr);
254  emr.rclBox.left = left;
255  emr.rclBox.top = top;
256  emr.rclBox.right = right;
257  emr.rclBox.bottom = bottom;
258  emr.ptlStart.x = xstart;
259  emr.ptlStart.y = ystart;
260  emr.ptlEnd.x = xend;
261  emr.ptlEnd.y = yend;
262 
263 
264  /* Now calculate the BBox */
265  xCentre = (left + right + 1) / 2;
266  yCentre = (top + bottom + 1) / 2;
267 
268  xstart -= xCentre;
269  ystart -= yCentre;
270  xend -= xCentre;
271  yend -= yCentre;
272 
273  /* invert y co-ords to get angle anti-clockwise from x-axis */
274  angleStart = atan2( -(double)ystart, (double)xstart);
275  angleEnd = atan2( -(double)yend, (double)xend);
276 
277  /* These are the intercepts of the start/end lines with the arc */
278 
279  xinterStart = (right - left + 1)/2 * cos(angleStart) + xCentre;
280  yinterStart = -(bottom - top + 1)/2 * sin(angleStart) + yCentre;
281  xinterEnd = (right - left + 1)/2 * cos(angleEnd) + xCentre;
282  yinterEnd = -(bottom - top + 1)/2 * sin(angleEnd) + yCentre;
283 
284  if(angleStart < 0) angleStart += 2 * M_PI;
285  if(angleEnd < 0) angleEnd += 2 * M_PI;
286  if(angleEnd < angleStart) angleEnd += 2 * M_PI;
287 
288  bounds.left = min(xinterStart, xinterEnd);
289  bounds.top = min(yinterStart, yinterEnd);
290  bounds.right = max(xinterStart, xinterEnd);
291  bounds.bottom = max(yinterStart, yinterEnd);
292 
293  for(i = 0; i <= 8; i++) {
294  if(i * M_PI / 2 < angleStart) /* loop until we're past start */
295  continue;
296  if(i * M_PI / 2 > angleEnd) /* if we're past end we're finished */
297  break;
298 
299  /* the arc touches the rectangle at the start of quadrant i, so adjust
300  BBox to reflect this. */
301 
302  switch(i % 4) {
303  case 0:
304  bounds.right = right;
305  break;
306  case 1:
307  bounds.top = top;
308  break;
309  case 2:
310  bounds.left = left;
311  break;
312  case 3:
313  bounds.bottom = bottom;
314  break;
315  }
316  }
317 
318  /* If we're drawing a pie then make sure we include the centre */
319  if(iType == EMR_PIE) {
320  if(bounds.left > xCentre) bounds.left = xCentre;
321  else if(bounds.right < xCentre) bounds.right = xCentre;
322  if(bounds.top > yCentre) bounds.top = yCentre;
323  else if(bounds.bottom < yCentre) bounds.bottom = yCentre;
324  }
325  if (iType == EMR_ARCTO)
326  {
327  POINT pt;
328 #ifdef __REACTOS__
329  GetCurrentPositionEx( dev->hdc, &pt );
330 #else
331  pt = dc->cur_pos;
332 #endif
333  bounds.left = min( bounds.left, pt.x );
334  bounds.top = min( bounds.top, pt.y );
335  bounds.right = max( bounds.right, pt.x );
336  bounds.bottom = max( bounds.bottom, pt.y );
337  }
338  if(!EMFDRV_WriteRecord( dev, &emr.emr ))
339  return FALSE;
340  if(!physDev->path)
341  EMFDRV_UpdateBBox( dev, &bounds );
342  return TRUE;
343 }
344 
345 
346 /***********************************************************************
347  * EMFDRV_Arc
348  */
350  INT xstart, INT ystart, INT xend, INT yend )
351 {
352  return EMFDRV_ArcChordPie( dev, left, top, right, bottom, xstart, ystart,
353  xend, yend, EMR_ARC );
354 }
355 
356 /***********************************************************************
357  * EMFDRV_ArcTo
358  */
360  INT xstart, INT ystart, INT xend, INT yend )
361 {
362  return EMFDRV_ArcChordPie( dev, left, top, right, bottom, xstart, ystart,
363  xend, yend, EMR_ARCTO );
364 }
365 
366 /***********************************************************************
367  * EMFDRV_Pie
368  */
370  INT xstart, INT ystart, INT xend, INT yend )
371 {
372  return EMFDRV_ArcChordPie( dev, left, top, right, bottom, xstart, ystart,
373  xend, yend, EMR_PIE );
374 }
375 
376 
377 /***********************************************************************
378  * EMFDRV_Chord
379  */
381  INT xstart, INT ystart, INT xend, INT yend )
382 {
383  return EMFDRV_ArcChordPie( dev, left, top, right, bottom, xstart, ystart,
384  xend, yend, EMR_CHORD );
385 }
386 
387 /***********************************************************************
388  * EMFDRV_AngleArc
389  */
391 {
392  EMRANGLEARC emr;
393 
394  emr.emr.iType = EMR_ANGLEARC;
395  emr.emr.nSize = sizeof( emr );
396  emr.ptlCenter.x = x;
397  emr.ptlCenter.y = y;
398  emr.nRadius = radius;
399  emr.eStartAngle = start;
400  emr.eSweepAngle = sweep;
401 
402  return EMFDRV_WriteRecord( dev, &emr.emr );
403 }
404 
405 /***********************************************************************
406  * EMFDRV_Ellipse
407  */
409 {
410  EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
411 #ifndef __REACTOS__
412  DC *dc = get_physdev_dc( dev );
413 #endif
414  EMRELLIPSE emr;
415  INT temp;
416 
417  TRACE("%d,%d - %d,%d\n", left, top, right, bottom);
418 
419  if(left == right || top == bottom) return FALSE;
420 
421  if(left > right) {temp = left; left = right; right = temp;}
422  if(top > bottom) {temp = top; top = bottom; bottom = temp;}
423 #ifdef __REACTOS__
424  if(GetGraphicsMode(dev->hdc) == GM_COMPATIBLE) {
425 #else
426  if(dc->GraphicsMode == GM_COMPATIBLE) {
427 #endif
428  right--;
429  bottom--;
430  }
431 
432  emr.emr.iType = EMR_ELLIPSE;
433  emr.emr.nSize = sizeof(emr);
434  emr.rclBox.left = left;
435  emr.rclBox.top = top;
436  emr.rclBox.right = right;
437  emr.rclBox.bottom = bottom;
438 
439  if(!physDev->path)
440  EMFDRV_UpdateBBox( dev, &emr.rclBox );
441  return EMFDRV_WriteRecord( dev, &emr.emr );
442 }
443 
444 /***********************************************************************
445  * EMFDRV_Rectangle
446  */
448 {
449  EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
450 #ifndef __REACTOS__
451  DC *dc = get_physdev_dc( dev );
452 #endif
453  EMRRECTANGLE emr;
454  INT temp;
455 
456  TRACE("%d,%d - %d,%d\n", left, top, right, bottom);
457 
458  if(left == right || top == bottom) return FALSE;
459 
460  if(left > right) {temp = left; left = right; right = temp;}
461  if(top > bottom) {temp = top; top = bottom; bottom = temp;}
462 #ifdef __REACTOS__
463  if(GetGraphicsMode(dev->hdc) == GM_COMPATIBLE) {
464 #else
465  if(dc->GraphicsMode == GM_COMPATIBLE) {
466 #endif
467  right--;
468  bottom--;
469  }
470 
471  emr.emr.iType = EMR_RECTANGLE;
472  emr.emr.nSize = sizeof(emr);
473  emr.rclBox.left = left;
474  emr.rclBox.top = top;
475  emr.rclBox.right = right;
476  emr.rclBox.bottom = bottom;
477 
478  if(!physDev->path)
479  EMFDRV_UpdateBBox( dev, &emr.rclBox );
480  return EMFDRV_WriteRecord( dev, &emr.emr );
481 }
482 
483 /***********************************************************************
484  * EMFDRV_RoundRect
485  */
487  INT bottom, INT ell_width, INT ell_height )
488 {
489  EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
490 #ifndef __REACTOS__
491  DC *dc = get_physdev_dc( dev );
492 #endif
493  EMRROUNDRECT emr;
494  INT temp;
495 
496  if(left == right || top == bottom) return FALSE;
497 
498  if(left > right) {temp = left; left = right; right = temp;}
499  if(top > bottom) {temp = top; top = bottom; bottom = temp;}
500 #ifdef __REACTOS__
501  if(GetGraphicsMode(dev->hdc) == GM_COMPATIBLE) {
502 #else
503  if(dc->GraphicsMode == GM_COMPATIBLE) {
504 #endif
505  right--;
506  bottom--;
507  }
508 
509  emr.emr.iType = EMR_ROUNDRECT;
510  emr.emr.nSize = sizeof(emr);
511  emr.rclBox.left = left;
512  emr.rclBox.top = top;
513  emr.rclBox.right = right;
514  emr.rclBox.bottom = bottom;
515  emr.szlCorner.cx = ell_width;
516  emr.szlCorner.cy = ell_height;
517 
518  if(!physDev->path)
519  EMFDRV_UpdateBBox( dev, &emr.rclBox );
520  return EMFDRV_WriteRecord( dev, &emr.emr );
521 }
522 
523 /***********************************************************************
524  * EMFDRV_SetPixel
525  */
527 {
528  EMRSETPIXELV emr;
529 
530  emr.emr.iType = EMR_SETPIXELV;
531  emr.emr.nSize = sizeof(emr);
532  emr.ptlPixel.x = x;
533  emr.ptlPixel.y = y;
534  emr.crColor = color;
535 
536  if (EMFDRV_WriteRecord( dev, &emr.emr )) {
537  RECTL bounds;
538  bounds.left = bounds.right = x;
539  bounds.top = bounds.bottom = y;
540  EMFDRV_UpdateBBox( dev, &bounds );
541  return color;
542  }
543  return -1;
544 }
545 
546 /**********************************************************************
547  * EMFDRV_Polylinegon
548  *
549  * Helper for EMFDRV_Poly{line|gon}
550  */
551 static BOOL
553 {
554  EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
555 #ifndef __REACTOS__
556  DC *dc = get_physdev_dc( dev );
557 #endif
558  EMRPOLYLINE *emr;
559  DWORD size;
560  BOOL ret, use_small_emr = can_use_short_points( pt, count );
561 
562  size = use_small_emr ? offsetof( EMRPOLYLINE16, apts[count] ) : offsetof( EMRPOLYLINE, aptl[count] );
563 
564  emr = HeapAlloc( GetProcessHeap(), 0, size );
565  emr->emr.iType = use_small_emr ? iType + EMR_POLYLINE16 - EMR_POLYLINE : iType;
566  emr->emr.nSize = size;
567  emr->cptl = count;
568 
569  store_points( emr->aptl, pt, count, use_small_emr );
570 
571  if (!physDev->path)
573 #ifdef __REACTOS__
574  (iType == EMR_POLYBEZIERTO || iType == EMR_POLYLINETO) ? dev->hdc : 0 );
575 #else
576  (iType == EMR_POLYBEZIERTO || iType == EMR_POLYLINETO) ? dc : 0 );
577 #endif
578  else
579  emr->rclBounds = empty_bounds;
580 
581  ret = EMFDRV_WriteRecord( dev, &emr->emr );
582  if (ret && !physDev->path)
583  EMFDRV_UpdateBBox( dev, &emr->rclBounds );
584  HeapFree( GetProcessHeap(), 0, emr );
585  return ret;
586 }
587 
588 
589 /**********************************************************************
590  * EMFDRV_Polyline
591  */
593 {
595 }
596 
597 /**********************************************************************
598  * EMFDRV_PolylineTo
599  */
601 {
603 }
604 
605 /**********************************************************************
606  * EMFDRV_Polygon
607  */
609 {
610  if(count < 2) return FALSE;
612 }
613 
614 /**********************************************************************
615  * EMFDRV_PolyBezier
616  */
618 {
619  return EMFDRV_Polylinegon( dev, pts, count, EMR_POLYBEZIER );
620 }
621 
622 /**********************************************************************
623  * EMFDRV_PolyBezierTo
624  */
626 {
627  return EMFDRV_Polylinegon( dev, pts, count, EMR_POLYBEZIERTO );
628 }
629 
630 
631 /**********************************************************************
632  * EMFDRV_PolyPolylinegon
633  *
634  * Helper for EMFDRV_PolyPoly{line|gon}
635  */
636 static BOOL
637 EMFDRV_PolyPolylinegon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polys,
638  DWORD iType)
639 {
640  EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
641  EMRPOLYPOLYLINE *emr;
642  DWORD cptl = 0, poly, size;
643  BOOL ret, use_small_emr, bounds_valid = TRUE;
644 
645  for(poly = 0; poly < polys; poly++) {
646  cptl += counts[poly];
647  if(counts[poly] < 2) bounds_valid = FALSE;
648  }
649  if(!cptl) bounds_valid = FALSE;
650  use_small_emr = can_use_short_points( pt, cptl );
651 
652  size = FIELD_OFFSET(EMRPOLYPOLYLINE, aPolyCounts[polys]);
653  if(use_small_emr)
654  size += cptl * sizeof(POINTS);
655  else
656  size += cptl * sizeof(POINTL);
657 
658  emr = HeapAlloc( GetProcessHeap(), 0, size );
659 
660  emr->emr.iType = iType;
661  if(use_small_emr) emr->emr.iType += EMR_POLYPOLYLINE16 - EMR_POLYPOLYLINE;
662 
663  emr->emr.nSize = size;
664  if(bounds_valid && !physDev->path)
665  get_points_bounds( &emr->rclBounds, pt, cptl, 0 );
666  else
667  emr->rclBounds = empty_bounds;
668  emr->nPolys = polys;
669  emr->cptl = cptl;
670 
671  if(polys)
672  {
673  memcpy( emr->aPolyCounts, counts, polys * sizeof(DWORD) );
674  store_points( (POINTL *)(emr->aPolyCounts + polys), pt, cptl, use_small_emr );
675  }
676 
677  ret = EMFDRV_WriteRecord( dev, &emr->emr );
678  if(ret && !bounds_valid)
679  {
680  ret = FALSE;
682  }
683  if(ret && !physDev->path)
684  EMFDRV_UpdateBBox( dev, &emr->rclBounds );
685  HeapFree( GetProcessHeap(), 0, emr );
686  return ret;
687 }
688 
689 /**********************************************************************
690  * EMFDRV_PolyPolyline
691  */
692 BOOL EMFDRV_PolyPolyline(PHYSDEV dev, const POINT* pt, const DWORD* counts, DWORD polys)
693 {
694  return EMFDRV_PolyPolylinegon( dev, pt, (const INT *)counts, polys,
696 }
697 
698 /**********************************************************************
699  * EMFDRV_PolyPolygon
700  */
701 BOOL EMFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polys )
702 {
703  return EMFDRV_PolyPolylinegon( dev, pt, counts, polys, EMR_POLYPOLYGON );
704 }
705 
706 
707 /**********************************************************************
708  * EMFDRV_PolyDraw
709  */
711 {
712  EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
713  EMRPOLYDRAW *emr;
714  BOOL ret;
715  BYTE *types_dest;
716  BOOL use_small_emr = can_use_short_points( pts, count );
717  DWORD size;
718 
719  size = use_small_emr ? offsetof( EMRPOLYDRAW16, apts[count] ) : offsetof( EMRPOLYDRAW, aptl[count] );
720  size += (count + 3) & ~3;
721 
722  if (!(emr = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
723 
724  emr->emr.iType = use_small_emr ? EMR_POLYDRAW16 : EMR_POLYDRAW;
725  emr->emr.nSize = size;
726  emr->cptl = count;
727 
728  types_dest = store_points( emr->aptl, pts, count, use_small_emr );
729  memcpy( types_dest, types, count );
730  if (count & 3) memset( types_dest + count, 0, 4 - (count & 3) );
731 
732  if (!physDev->path)
733  get_points_bounds( &emr->rclBounds, pts, count, 0 );
734  else
735  emr->rclBounds = empty_bounds;
736 
737  ret = EMFDRV_WriteRecord( dev, &emr->emr );
738  if (ret && !physDev->path) EMFDRV_UpdateBBox( dev, &emr->rclBounds );
739  HeapFree( GetProcessHeap(), 0, emr );
740  return ret;
741 }
742 
743 
744 /**********************************************************************
745  * EMFDRV_ExtFloodFill
746  */
748 {
749  EMREXTFLOODFILL emr;
750 
751  emr.emr.iType = EMR_EXTFLOODFILL;
752  emr.emr.nSize = sizeof(emr);
753  emr.ptlStart.x = x;
754  emr.ptlStart.y = y;
755  emr.crColor = color;
756  emr.iMode = fillType;
757 
758  return EMFDRV_WriteRecord( dev, &emr.emr );
759 }
760 
761 
762 /*********************************************************************
763  * EMFDRV_FillRgn
764  */
766 {
767  EMRFILLRGN *emr;
768  DWORD size, rgnsize, index;
769  BOOL ret;
770 
772  if(!index) return FALSE;
773 
774  rgnsize = GetRegionData( hrgn, 0, NULL );
775  size = rgnsize + offsetof(EMRFILLRGN,RgnData);
776  emr = HeapAlloc( GetProcessHeap(), 0, size );
777 
778  GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
779 
780  emr->emr.iType = EMR_FILLRGN;
781  emr->emr.nSize = size;
782  emr->rclBounds.left = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.left;
783  emr->rclBounds.top = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.top;
784  emr->rclBounds.right = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.right - 1;
785  emr->rclBounds.bottom = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.bottom - 1;
786  emr->cbRgnData = rgnsize;
787  emr->ihBrush = index;
788 
789  ret = EMFDRV_WriteRecord( dev, &emr->emr );
790  if(ret)
791  EMFDRV_UpdateBBox( dev, &emr->rclBounds );
792  HeapFree( GetProcessHeap(), 0, emr );
793  return ret;
794 }
795 /*********************************************************************
796  * EMFDRV_FrameRgn
797  */
799 {
800  EMRFRAMERGN *emr;
801  DWORD size, rgnsize, index;
802  BOOL ret;
803 
805  if(!index) return FALSE;
806 
807  rgnsize = GetRegionData( hrgn, 0, NULL );
808  size = rgnsize + offsetof(EMRFRAMERGN,RgnData);
809  emr = HeapAlloc( GetProcessHeap(), 0, size );
810 
811  GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
812 
813  emr->emr.iType = EMR_FRAMERGN;
814  emr->emr.nSize = size;
815  emr->rclBounds.left = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.left;
816  emr->rclBounds.top = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.top;
817  emr->rclBounds.right = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.right - 1;
818  emr->rclBounds.bottom = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.bottom - 1;
819  emr->cbRgnData = rgnsize;
820  emr->ihBrush = index;
821  emr->szlStroke.cx = width;
822  emr->szlStroke.cy = height;
823 
824  ret = EMFDRV_WriteRecord( dev, &emr->emr );
825  if(ret)
826  EMFDRV_UpdateBBox( dev, &emr->rclBounds );
827  HeapFree( GetProcessHeap(), 0, emr );
828  return ret;
829 }
830 
831 /*********************************************************************
832  * EMFDRV_PaintInvertRgn
833  *
834  * Helper for EMFDRV_{Paint|Invert}Rgn
835  */
837 {
838  EMRINVERTRGN *emr;
839  DWORD size, rgnsize;
840  BOOL ret;
841 
842 
843  rgnsize = GetRegionData( hrgn, 0, NULL );
844  size = rgnsize + offsetof(EMRINVERTRGN,RgnData);
845  emr = HeapAlloc( GetProcessHeap(), 0, size );
846 
847  GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData );
848 
849  emr->emr.iType = iType;
850  emr->emr.nSize = size;
851  emr->rclBounds.left = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.left;
852  emr->rclBounds.top = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.top;
853  emr->rclBounds.right = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.right - 1;
854  emr->rclBounds.bottom = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.bottom - 1;
855  emr->cbRgnData = rgnsize;
856 
857  ret = EMFDRV_WriteRecord( dev, &emr->emr );
858  if(ret)
859  EMFDRV_UpdateBBox( dev, &emr->rclBounds );
860  HeapFree( GetProcessHeap(), 0, emr );
861  return ret;
862 }
863 
864 /**********************************************************************
865  * EMFDRV_PaintRgn
866  */
868 {
870 }
871 
872 /**********************************************************************
873  * EMFDRV_InvertRgn
874  */
876 {
878 }
879 
880 /**********************************************************************
881  * EMFDRV_ExtTextOut
882  */
884  LPCWSTR str, UINT count, const INT *lpDx )
885 {
886  EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
887 #ifndef __REACTOS__
888  DC *dc = get_physdev_dc( dev );
889 #endif
890  EMREXTTEXTOUTW *pemr;
891  DWORD nSize;
892  BOOL ret;
893  int textHeight = 0;
894  int textWidth = 0;
895 #ifdef __REACTOS__
896  const UINT textAlign = GetTextAlign( dev->hdc );
897  const INT graphicsMode = GetGraphicsMode( dev->hdc );
898 #else
899  const UINT textAlign = dc->textAlign;
900  const INT graphicsMode = dc->GraphicsMode;
901 #endif
902  FLOAT exScale, eyScale;
903 
904  nSize = sizeof(*pemr) + ((count+1) & ~1) * sizeof(WCHAR) + count * sizeof(INT);
905 
906  TRACE("%s %s count %d nSize = %d\n", debugstr_wn(str, count),
907  wine_dbgstr_rect(lprect), count, nSize);
909 
910  if (graphicsMode == GM_COMPATIBLE)
911  {
912  const INT horzSize = GetDeviceCaps( dev->hdc, HORZSIZE );
913  const INT horzRes = GetDeviceCaps( dev->hdc, HORZRES );
914  const INT vertSize = GetDeviceCaps( dev->hdc, VERTSIZE );
915  const INT vertRes = GetDeviceCaps( dev->hdc, VERTRES );
916  SIZE wndext, vportext;
917 
918  GetViewportExtEx( dev->hdc, &vportext );
919  GetWindowExtEx( dev->hdc, &wndext );
920  exScale = 100.0 * ((FLOAT)horzSize / (FLOAT)horzRes) /
921  ((FLOAT)wndext.cx / (FLOAT)vportext.cx);
922  eyScale = 100.0 * ((FLOAT)vertSize / (FLOAT)vertRes) /
923  ((FLOAT)wndext.cy / (FLOAT)vportext.cy);
924  }
925  else
926  {
927  exScale = 0.0;
928  eyScale = 0.0;
929  }
930 
931  pemr->emr.iType = EMR_EXTTEXTOUTW;
932  pemr->emr.nSize = nSize;
933  pemr->iGraphicsMode = graphicsMode;
934  pemr->exScale = exScale;
935  pemr->eyScale = eyScale;
936  pemr->emrtext.ptlReference.x = x;
937  pemr->emrtext.ptlReference.y = y;
938  pemr->emrtext.nChars = count;
939  pemr->emrtext.offString = sizeof(*pemr);
940  memcpy((char*)pemr + pemr->emrtext.offString, str, count * sizeof(WCHAR));
941  pemr->emrtext.fOptions = flags;
942  if(!lprect) {
943  pemr->emrtext.rcl.left = pemr->emrtext.rcl.top = 0;
944  pemr->emrtext.rcl.right = pemr->emrtext.rcl.bottom = -1;
945  } else {
946  pemr->emrtext.rcl.left = lprect->left;
947  pemr->emrtext.rcl.top = lprect->top;
948  pemr->emrtext.rcl.right = lprect->right;
949  pemr->emrtext.rcl.bottom = lprect->bottom;
950  }
951 
952  pemr->emrtext.offDx = pemr->emrtext.offString + ((count+1) & ~1) * sizeof(WCHAR);
953  if(lpDx) {
954  UINT i;
955  SIZE strSize;
956  memcpy((char*)pemr + pemr->emrtext.offDx, lpDx, count * sizeof(INT));
957  for (i = 0; i < count; i++) {
958  textWidth += lpDx[i];
959  }
960  if (GetTextExtentPoint32W( dev->hdc, str, count, &strSize ))
961  textHeight = strSize.cy;
962  }
963  else {
964  UINT i;
965  INT *dx = (INT *)((char*)pemr + pemr->emrtext.offDx);
966  SIZE charSize;
967  for (i = 0; i < count; i++) {
968  if (GetTextExtentPoint32W( dev->hdc, str + i, 1, &charSize )) {
969  dx[i] = charSize.cx;
970  textWidth += charSize.cx;
971  textHeight = max(textHeight, charSize.cy);
972  }
973  }
974  }
975 
976  if (physDev->path)
977  {
978  pemr->rclBounds.left = pemr->rclBounds.top = 0;
979  pemr->rclBounds.right = pemr->rclBounds.bottom = -1;
980  goto no_bounds;
981  }
982 
983  /* FIXME: handle font escapement */
984  switch (textAlign & (TA_LEFT | TA_RIGHT | TA_CENTER)) {
985  case TA_CENTER: {
986  pemr->rclBounds.left = x - (textWidth / 2) - 1;
987  pemr->rclBounds.right = x + (textWidth / 2) + 1;
988  break;
989  }
990  case TA_RIGHT: {
991  pemr->rclBounds.left = x - textWidth - 1;
992  pemr->rclBounds.right = x;
993  break;
994  }
995  default: { /* TA_LEFT */
996  pemr->rclBounds.left = x;
997  pemr->rclBounds.right = x + textWidth + 1;
998  }
999  }
1000 
1001  switch (textAlign & (TA_TOP | TA_BOTTOM | TA_BASELINE)) {
1002  case TA_BASELINE: {
1003  TEXTMETRICW tm;
1004  if (!GetTextMetricsW( dev->hdc, &tm ))
1005  tm.tmDescent = 0;
1006  /* Play safe here... it's better to have a bounding box */
1007  /* that is too big than too small. */
1008  pemr->rclBounds.top = y - textHeight - 1;
1009  pemr->rclBounds.bottom = y + tm.tmDescent + 1;
1010  break;
1011  }
1012  case TA_BOTTOM: {
1013  pemr->rclBounds.top = y - textHeight - 1;
1014  pemr->rclBounds.bottom = y;
1015  break;
1016  }
1017  default: { /* TA_TOP */
1018  pemr->rclBounds.top = y;
1019  pemr->rclBounds.bottom = y + textHeight + 1;
1020  }
1021  }
1022  EMFDRV_UpdateBBox( dev, &pemr->rclBounds );
1023 
1024 no_bounds:
1025  ret = EMFDRV_WriteRecord( dev, &pemr->emr );
1026  HeapFree( GetProcessHeap(), 0, pemr );
1027  return ret;
1028 }
1029 
1030 /**********************************************************************
1031  * EMFDRV_GradientFill
1032  */
1034  void *grad_array, ULONG ngrad, ULONG mode )
1035 {
1036  EMRGRADIENTFILL *emr;
1037  ULONG i, pt, size, num_pts = ngrad * (mode == GRADIENT_FILL_TRIANGLE ? 3 : 2);
1038  const ULONG *pts = (const ULONG *)grad_array;
1039  BOOL ret;
1040 
1041  size = FIELD_OFFSET(EMRGRADIENTFILL, Ver[nvert]) + num_pts * sizeof(pts[0]);
1042 
1043  emr = HeapAlloc( GetProcessHeap(), 0, size );
1044  if (!emr) return FALSE;
1045 
1046  for (i = 0; i < num_pts; i++)
1047  {
1048  pt = pts[i];
1049 
1050  if (i == 0)
1051  {
1052  emr->rclBounds.left = emr->rclBounds.right = vert_array[pt].x;
1053  emr->rclBounds.top = emr->rclBounds.bottom = vert_array[pt].y;
1054  }
1055  else
1056  {
1057  if (vert_array[pt].x < emr->rclBounds.left)
1058  emr->rclBounds.left = vert_array[pt].x;
1059  else if (vert_array[pt].x > emr->rclBounds.right)
1060  emr->rclBounds.right = vert_array[pt].x;
1061  if (vert_array[pt].y < emr->rclBounds.top)
1062  emr->rclBounds.top = vert_array[pt].y;
1063  else if (vert_array[pt].y > emr->rclBounds.bottom)
1064  emr->rclBounds.bottom = vert_array[pt].y;
1065  }
1066  }
1067  emr->rclBounds.right--;
1068  emr->rclBounds.bottom--;
1069 
1070  emr->emr.iType = EMR_GRADIENTFILL;
1071  emr->emr.nSize = size;
1072  emr->nVer = nvert;
1073  emr->nTri = ngrad;
1074  emr->ulMode = mode;
1075  memcpy( emr->Ver, vert_array, nvert * sizeof(vert_array[0]) );
1076  memcpy( emr->Ver + nvert, pts, num_pts * sizeof(pts[0]) );
1077 
1078  EMFDRV_UpdateBBox( dev, &emr->rclBounds );
1079  ret = EMFDRV_WriteRecord( dev, &emr->emr );
1080  HeapFree( GetProcessHeap(), 0, emr );
1081  return ret;
1082 }
1083 
1084 /**********************************************************************
1085  * EMFDRV_FillPath
1086  */
1088 {
1090 }
1091 
1092 /**********************************************************************
1093  * EMFDRV_StrokeAndFillPath
1094  */
1096 {
1098 }
1099 
1100 /**********************************************************************
1101  * EMFDRV_StrokePath
1102  */
1104 {
1106 }
static const RECTL empty_bounds
Definition: graphics.c:36
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
COLORREF crColor
Definition: wingdi.h:2200
BOOL EMFDRV_Chord(PHYSDEV dev, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend)
Definition: graphics.c:380
#define EMR_ROUNDRECT
Definition: wingdi.h:118
BOOL WINAPI GetCurrentPositionEx(_In_ HDC, _Out_ LPPOINT)
Definition: coord.c:241
BOOL EMFDRV_InvertRgn(PHYSDEV dev, HRGN hrgn)
Definition: graphics.c:875
GLint GLint GLsizei width
Definition: gl.h:1546
BOOL EMFDRV_FrameRgn(PHYSDEV dev, HRGN hrgn, HBRUSH hbrush, INT width, INT height)
Definition: graphics.c:798
#define HORZRES
Definition: wingdi.h:715
#define max(a, b)
Definition: svc.c:63
#define TRUE
Definition: types.h:120
POINTL ptlCenter
Definition: wingdi.h:1687
valarray< _Tp > atan2(const valarray< _Tp > &__x, const valarray< _Tp > &__y)
Definition: _valarray.h:928
#define EMR_POLYLINE
Definition: wingdi.h:78
static HBRUSH hbrush
BOOL WINAPI GetTextMetricsW(_In_ HDC, _Out_ LPTEXTMETRICW)
Definition: text.c:221
POINTL ptlReference
Definition: wingdi.h:1950
#define EMR_ARCTO
Definition: wingdi.h:129
long y
Definition: polytest.cpp:48
BOOL EMFDRV_WriteRecord(PHYSDEV dev, EMR *emr) DECLSPEC_HIDDEN
Definition: init.c:193
DWORD iGraphicsMode
Definition: wingdi.h:1960
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
BOOL EMFDRV_Pie(PHYSDEV dev, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend)
Definition: graphics.c:369
#define FLOAT
Definition: i386-dis.c:516
#define EMR_POLYLINE16
Definition: wingdi.h:160
long x
Definition: polytest.cpp:48
BOOL EMFDRV_Polyline(PHYSDEV dev, const POINT *pt, INT count)
Definition: graphics.c:592
BOOL EMFDRV_Polygon(PHYSDEV dev, const POINT *pt, INT count)
Definition: graphics.c:608
#define EMR_STROKEANDFILLPATH
Definition: wingdi.h:137
#define pt(x, y)
Definition: drawing.c:79
GLsizei const GLchar ** path
Definition: glext.h:7234
static BOOL EMFDRV_PaintInvertRgn(PHYSDEV dev, HRGN hrgn, DWORD iType)
Definition: graphics.c:836
_In_ ULONG iType
Definition: winddi.h:3748
GLuint GLuint GLsizei count
Definition: gl.h:1545
DWORD ihBrush
Definition: wingdi.h:1973
#define EMR_LINETO
Definition: wingdi.h:128
#define EMR_STROKEPATH
Definition: wingdi.h:138
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2024
DWORD cptl
Definition: wingdi.h:2088
POINTL aptl[1]
Definition: wingdi.h:2075
struct tagPOINTS POINTS
static HDC
Definition: imagelist.c:92
BOOL EMFDRV_LineTo(PHYSDEV dev, INT x, INT y)
Definition: graphics.c:188
static EMFDRV_PDEVICE * get_emf_physdev(PHYSDEV dev)
POINTL ptlStart
Definition: wingdi.h:1695
BOOL EMFDRV_AngleArc(PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT start, FLOAT sweep)
Definition: graphics.c:390
LONG top
Definition: windef.h:292
long bottom
Definition: polytest.cpp:53
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define EMR_POLYLINETO
Definition: wingdi.h:80
#define EMR_PAINTRGN
Definition: wingdi.h:147
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
WINE_DEFAULT_DEBUG_CHANNEL(gdiplus)
#define EMR_MOVETOEX
Definition: wingdi.h:101
HDC dc
Definition: cylfrac.c:34
#define TA_LEFT
Definition: wingdi.h:931
FLOAT eSweepAngle
Definition: wingdi.h:1690
LONG left
Definition: windef.h:291
static BOOL can_use_short_points(const POINT *pts, UINT count)
Definition: graphics.c:39
COLORREF EMFDRV_SetPixel(PHYSDEV dev, INT x, INT y, COLORREF color)
Definition: graphics.c:526
LONG right
Definition: windef.h:293
BOOL EMFDRV_PolyPolyline(PHYSDEV dev, const POINT *pt, const DWORD *counts, DWORD polys)
Definition: graphics.c:692
#define EMR_POLYDRAW
Definition: wingdi.h:130
int32_t INT
Definition: typedefs.h:56
BOOL EMFDRV_Arc(PHYSDEV dev, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend)
Definition: graphics.c:349
static void * store_points(POINTL *dest, const POINT *pts, UINT count, BOOL short_points)
Definition: graphics.c:50
POINTL ptlPixel
Definition: wingdi.h:2199
LONG y
Definition: windef.h:315
BYTE RgnData[1]
Definition: wingdi.h:1974
UINT WINAPI GetTextAlign(_In_ HDC)
Definition: text.c:806
BOOL EMFDRV_PolyBezierTo(PHYSDEV dev, const POINT *pts, DWORD count)
Definition: graphics.c:625
long right
Definition: polytest.cpp:53
DWORD cbRgnData
Definition: wingdi.h:1972
#define TA_TOP
Definition: wingdi.h:929
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
RECTL rclBox
Definition: wingdi.h:1834
LONG y
Definition: wingdi.h:2763
BOOL EMFDRV_Ellipse(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
Definition: graphics.c:408
DWORD ihBrush
Definition: wingdi.h:1995
unsigned char * LPBYTE
Definition: typedefs.h:52
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint color
Definition: glext.h:6243
#define TA_BASELINE
Definition: wingdi.h:927
long top
Definition: polytest.cpp:53
BOOL EMFDRV_PolyDraw(PHYSDEV dev, const POINT *pts, const BYTE *types, DWORD count)
Definition: graphics.c:710
BOOL EMFDRV_ExtFloodFill(PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType)
Definition: graphics.c:747
RECTL rcl
Definition: wingdi.h:1954
BOOL EMFDRV_StrokePath(PHYSDEV dev)
Definition: graphics.c:1103
BOOL EMFDRV_PaintRgn(PHYSDEV dev, HRGN hrgn)
Definition: graphics.c:867
const WCHAR * str
static struct list apts
Definition: compobj.c:81
BOOL EMFDRV_MoveTo(PHYSDEV dev, INT x, INT y)
Definition: graphics.c:173
_STLP_DECLSPEC complex< float > _STLP_CALL cos(const complex< float > &)
#define TA_BOTTOM
Definition: wingdi.h:928
BOOL EMFDRV_FillPath(PHYSDEV dev)
Definition: graphics.c:1087
smooth NULL
Definition: ftsmooth.c:416
#define offsetof(TYPE, MEMBER)
POINTL ptl
Definition: wingdi.h:2012
LONG cx
Definition: windef.h:319
#define EMR_POLYPOLYLINE
Definition: wingdi.h:81
RECTL rclBounds
Definition: wingdi.h:2073
GLint GLint bottom
Definition: glext.h:7726
SHORT x
Definition: windef.h:327
#define EMR_EXTTEXTOUTW
Definition: wingdi.h:157
BOOL EMFDRV_StrokeAndFillPath(PHYSDEV dev)
Definition: graphics.c:1095
GLuint index
Definition: glext.h:6031
static BOOL EMFDRV_ArcChordPie(PHYSDEV dev, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend, DWORD iType)
Definition: graphics.c:226
#define EMR_FRAMERGN
Definition: wingdi.h:145
DWORD nRadius
Definition: wingdi.h:1688
long left
Definition: polytest.cpp:53
#define EMR_INVERTRGN
Definition: wingdi.h:146
#define EMR_RECTANGLE
Definition: wingdi.h:117
#define TA_RIGHT
Definition: wingdi.h:932
static BOOL emfdrv_stroke_and_fill_path(PHYSDEV dev, INT type)
Definition: graphics.c:144
RECTL rclBounds
Definition: wingdi.h:2087
DWORD offDx
Definition: wingdi.h:1955
#define TRACE(s)
Definition: solgame.cpp:4
Definition: polytest.cpp:40
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
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
void EMFDRV_UpdateBBox(PHYSDEV dev, RECTL *rect) DECLSPEC_HIDDEN
Definition: init.c:230
int WINAPI GetGraphicsMode(_In_ HDC)
LONG x
Definition: wingdi.h:2762
BOOL EMFDRV_PolylineTo(PHYSDEV dev, const POINT *pt, INT count)
Definition: graphics.c:600
DWORD COLORREF
Definition: windef.h:285
BOOL WINAPI GetWindowExtEx(_In_ HDC, _Out_ LPSIZE)
Definition: coord.c:411
#define EMR_ELLIPSE
Definition: wingdi.h:116
const char * wine_dbgstr_rect(const RECT *rect)
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint left
Definition: glext.h:7726
LONG x
Definition: windef.h:314
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
#define SetLastError(x)
Definition: compat.h:409
GLdouble GLdouble right
Definition: glext.h:10859
#define EMR_POLYGON
Definition: wingdi.h:77
GLbitfield flags
Definition: glext.h:7161
EMR emr
Definition: wingdi.h:1693
#define GM_COMPATIBLE
Definition: wingdi.h:863
GLsizei const GLfloat * points
Definition: glext.h:8112
BYTE RgnData[1]
Definition: wingdi.h:1997
#define EMR_PIE
Definition: wingdi.h:121
int ret
POINTL ptlEnd
Definition: wingdi.h:1696
static const unsigned char enhmetafile[]
Definition: olepicture.c:149
DWORD nSize
Definition: wingdi.h:1669
struct _POINTL POINTL
#define EMR_FILLPATH
Definition: wingdi.h:136
#define EMR_CHORD
Definition: wingdi.h:120
RECTL rclBox
Definition: wingdi.h:2133
#define index(s, c)
Definition: various.h:29
HDC hdc
Definition: main.c:9
BOOL EMFDRV_PolyBezier(PHYSDEV dev, const POINT *pts, DWORD count)
Definition: graphics.c:617
static HRGN hrgn
Definition: win.c:55
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned char BYTE
Definition: mem.h:68
Definition: time.h:76
GLenum mode
Definition: glext.h:6217
#define debugstr_wn
Definition: kernel32.h:33
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
BOOL EMFDRV_RoundRect(PHYSDEV dev, INT left, INT top, INT right, INT bottom, INT ell_width, INT ell_height)
Definition: graphics.c:486
#define EMR_POLYBEZIER
Definition: wingdi.h:76
#define HORZSIZE
Definition: wingdi.h:713
DWORD nChars
Definition: wingdi.h:1951
#define EMR_ANGLEARC
Definition: wingdi.h:115
DWORD cptl
Definition: wingdi.h:2074
#define EMR_EXTFLOODFILL
Definition: wingdi.h:127
#define EMR_ARC
Definition: wingdi.h:119
BYTE RgnData[1]
Definition: wingdi.h:2008
SHORT y
Definition: windef.h:328
DWORD iType
Definition: wingdi.h:1668
#define VERTSIZE
Definition: wingdi.h:714
SIZEL szlStroke
Definition: wingdi.h:1996
static BOOL EMFDRV_PolyPolylinegon(PHYSDEV dev, const POINT *pt, const INT *counts, UINT polys, DWORD iType)
Definition: graphics.c:637
DWORD cbRgnData
Definition: wingdi.h:2007
static calc_node_t temp
Definition: rpn_ieee.c:38
char ACPI_OBJECT_TYPE * Types
Definition: acdebug.h:343
GLuint start
Definition: gl.h:1545
DWORD fOptions
Definition: wingdi.h:1953
RECTL rclBounds
Definition: wingdi.h:1971
DWORD EMFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush) DECLSPEC_HIDDEN
Definition: objects.c:111
POINTL aptl[1]
Definition: wingdi.h:2089
WINEDC * get_physdev_dc(PHYSDEV dev)
Definition: rosglue.c:190
Definition: services.c:325
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define M_PI
Definition: macros.h:263
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
COLORREF crColor
Definition: wingdi.h:1940
DWORD offString
Definition: wingdi.h:1952
#define VERTRES
Definition: wingdi.h:716
BOOL EMFDRV_ExtTextOut(PHYSDEV dev, INT x, INT y, UINT flags, const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx)
Definition: graphics.c:883
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint dx
Definition: linetemp.h:97
RECTL rclBounds
Definition: wingdi.h:1967
BOOL EMFDRV_ArcTo(PHYSDEV dev, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend)
Definition: graphics.c:359
BOOL EMFDRV_GradientFill(PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert, void *grad_array, ULONG ngrad, ULONG mode)
Definition: graphics.c:1033
RECTL rclBounds
Definition: wingdi.h:2006
#define EMR_POLYPOLYGON
Definition: wingdi.h:82
RECTL rclBox
Definition: wingdi.h:1694
float FLOAT
Definition: typedefs.h:67
unsigned int ULONG
Definition: retypes.h:1
LONG bottom
Definition: windef.h:294
static char * dest
Definition: rtl.c:135
#define EMR_POLYDRAW16
Definition: wingdi.h:165
DWORD cbRgnData
Definition: wingdi.h:1994
#define TA_CENTER
Definition: wingdi.h:930
BOOL EMFDRV_PolyPolygon(PHYSDEV dev, const POINT *pt, const INT *counts, UINT polys)
Definition: graphics.c:701
_STLP_DECLSPEC complex< float > _STLP_CALL sin(const complex< float > &)
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
#define EMR_POLYPOLYLINE16
Definition: wingdi.h:163
FLOAT eStartAngle
Definition: wingdi.h:1689
static void get_points_bounds(RECTL *bounds, const POINT *pts, UINT count, DC *dc)
Definition: graphics.c:75
static BOOL EMFDRV_Polylinegon(PHYSDEV dev, const POINT *pt, INT count, DWORD iType)
Definition: graphics.c:552
RECTL rclBounds
Definition: wingdi.h:1993
BOOL EMFDRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
Definition: graphics.c:447
#define memset(x, y, z)
Definition: compat.h:39
LONG cy
Definition: windef.h:320
DWORD WINAPI GetRegionData(_In_ HRGN hrgn, _In_ DWORD nCount, _Out_writes_bytes_to_opt_(nCount, return) LPRGNDATA lpRgnData)
#define HeapFree(x, y, z)
Definition: compat.h:394
BOOL WINAPI GetTextExtentPoint32W(_In_ HDC hdc, _In_reads_(c) LPCWSTR lpString, _In_ int c, _Out_ LPSIZE psizl)
#define EMR_POLYBEZIERTO
Definition: wingdi.h:79
SIZEL szlCorner
Definition: wingdi.h:2134
EMRTEXT emrtext
Definition: wingdi.h:1963
BOOL EMFDRV_FillRgn(PHYSDEV dev, HRGN hrgn, HBRUSH hbrush)
Definition: graphics.c:765