ReactOS 0.4.16-dev-122-g325d74c
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
36static const RECTL empty_bounds = { 0, 0, -1, -1 };
37
38/* determine if we can use 16-bit points to store all the input points */
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 */
50static 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__
73static void get_points_bounds( RECTL *bounds, const POINT *pts, UINT count, HDC hdc )
74#else
75static 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;
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 );
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 */
225static 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)
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)
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)
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 */
551static 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)
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{
620}
621
622/**********************************************************************
623 * EMFDRV_PolyBezierTo
624 */
626{
628}
629
630
631/**********************************************************************
632 * EMFDRV_PolyPolylinegon
633 *
634 * Helper for EMFDRV_PolyPoly{line|gon}
635 */
636static BOOL
637EMFDRV_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)
685 HeapFree( GetProcessHeap(), 0, emr );
686 return ret;
687}
688
689/**********************************************************************
690 * EMFDRV_PolyPolyline
691 */
692BOOL 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 */
701BOOL 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
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)
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)
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)
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: {
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
1024no_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
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 HRGN hrgn
static HBRUSH hbrush
_STLP_DECLSPEC complex< float > _STLP_CALL cos(const complex< float > &)
_STLP_DECLSPEC complex< float > _STLP_CALL sin(const complex< float > &)
valarray< _Tp > atan2(const valarray< _Tp > &__x, const valarray< _Tp > &__y)
Definition: _valarray.h:928
char ACPI_OBJECT_TYPE * Types
Definition: acdebug.h:354
static const char * wine_dbgstr_rect(const RECT *prc)
Definition: atltest.h:160
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static struct list apts
Definition: compobj.c:78
#define pt(x, y)
Definition: drawing.c:79
static EMFDRV_PDEVICE * get_emf_physdev(PHYSDEV dev)
BOOL EMFDRV_WriteRecord(PHYSDEV dev, EMR *emr) DECLSPEC_HIDDEN
Definition: init.c:194
DWORD EMFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush) DECLSPEC_HIDDEN
Definition: objects.c:111
void EMFDRV_UpdateBBox(PHYSDEV dev, RECTL *rect) DECLSPEC_HIDDEN
Definition: init.c:231
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint start
Definition: gl.h:1545
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLuint color
Definition: glext.h:6243
GLuint index
Definition: glext.h:6031
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLdouble GLdouble right
Definition: glext.h:10859
GLenum mode
Definition: glext.h:6217
GLint left
Definition: glext.h:7726
GLbitfield flags
Definition: glext.h:7161
GLint GLint bottom
Definition: glext.h:7726
GLsizei const GLfloat * points
Definition: glext.h:8112
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
#define FLOAT
Definition: i386-dis.c:525
#define debugstr_wn
Definition: kernel32.h:33
GLint dx
Definition: linetemp.h:97
#define M_PI
Definition: macros.h:263
static const WCHAR dc[]
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:88
static char * dest
Definition: rtl.c:135
static const unsigned char enhmetafile[]
Definition: olepicture.c:149
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
const WCHAR * str
static calc_node_t temp
Definition: rpn_ieee.c:38
#define offsetof(TYPE, MEMBER)
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
Definition: polytest.cpp:41
long bottom
Definition: polytest.cpp:53
long right
Definition: polytest.cpp:53
long top
Definition: polytest.cpp:53
long left
Definition: polytest.cpp:53
LONG y
Definition: windef.h:330
LONG x
Definition: windef.h:329
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
LONG y
Definition: wingdi.h:2785
LONG x
Definition: wingdi.h:2784
FLOAT eSweepAngle
Definition: wingdi.h:1712
FLOAT eStartAngle
Definition: wingdi.h:1711
DWORD nRadius
Definition: wingdi.h:1710
POINTL ptlCenter
Definition: wingdi.h:1709
POINTL ptlStart
Definition: wingdi.h:1717
RECTL rclBox
Definition: wingdi.h:1716
POINTL ptlEnd
Definition: wingdi.h:1718
EMR emr
Definition: wingdi.h:1715
RECTL rclBox
Definition: wingdi.h:1856
COLORREF crColor
Definition: wingdi.h:1962
DWORD iGraphicsMode
Definition: wingdi.h:1982
EMRTEXT emrtext
Definition: wingdi.h:1985
RECTL rclBounds
Definition: wingdi.h:1989
BYTE RgnData[1]
Definition: wingdi.h:1996
DWORD cbRgnData
Definition: wingdi.h:1994
RECTL rclBounds
Definition: wingdi.h:1993
DWORD ihBrush
Definition: wingdi.h:1995
SIZEL szlStroke
Definition: wingdi.h:2018
RECTL rclBounds
Definition: wingdi.h:2015
DWORD ihBrush
Definition: wingdi.h:2017
DWORD cbRgnData
Definition: wingdi.h:2016
BYTE RgnData[1]
Definition: wingdi.h:2019
TRIVERTEX Ver[1]
Definition: wingdi.h:2797
RECTL rclBounds
Definition: wingdi.h:2028
BYTE RgnData[1]
Definition: wingdi.h:2030
DWORD cbRgnData
Definition: wingdi.h:2029
POINTL ptl
Definition: wingdi.h:2034
POINTL aptl[1]
Definition: wingdi.h:2097
RECTL rclBounds
Definition: wingdi.h:2095
DWORD cptl
Definition: wingdi.h:2096
RECTL rclBounds
Definition: wingdi.h:2109
DWORD cptl
Definition: wingdi.h:2110
POINTL aptl[1]
Definition: wingdi.h:2111
DWORD aPolyCounts[1]
Definition: wingdi.h:2124
RECTL rclBox
Definition: wingdi.h:2155
SIZEL szlCorner
Definition: wingdi.h:2156
POINTL ptlPixel
Definition: wingdi.h:2221
COLORREF crColor
Definition: wingdi.h:2222
DWORD fOptions
Definition: wingdi.h:1975
DWORD offDx
Definition: wingdi.h:1977
DWORD nChars
Definition: wingdi.h:1973
RECTL rcl
Definition: wingdi.h:1976
POINTL ptlReference
Definition: wingdi.h:1972
DWORD offString
Definition: wingdi.h:1974
DWORD iType
Definition: wingdi.h:1690
DWORD nSize
Definition: wingdi.h:1691
SHORT y
Definition: windef.h:343
SHORT x
Definition: windef.h:342
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
Definition: time.h:68
Definition: cmds.c:130
#define max(a, b)
Definition: svc.c:63
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
float FLOAT
Definition: typedefs.h:69
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
int ret
BOOL EMFDRV_PaintRgn(PHYSDEV dev, HRGN hrgn)
Definition: graphics.c:867
BOOL EMFDRV_PolyDraw(PHYSDEV dev, const POINT *pts, const BYTE *types, DWORD count)
Definition: graphics.c:710
static BOOL EMFDRV_Polylinegon(PHYSDEV dev, const POINT *pt, INT count, DWORD iType)
Definition: graphics.c:552
BOOL EMFDRV_FillRgn(PHYSDEV dev, HRGN hrgn, HBRUSH hbrush)
Definition: graphics.c:765
static BOOL EMFDRV_PolyPolylinegon(PHYSDEV dev, const POINT *pt, const INT *counts, UINT polys, DWORD iType)
Definition: graphics.c:637
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
BOOL EMFDRV_FillPath(PHYSDEV dev)
Definition: graphics.c:1087
BOOL EMFDRV_Polyline(PHYSDEV dev, const POINT *pt, INT count)
Definition: graphics.c:592
static BOOL EMFDRV_PaintInvertRgn(PHYSDEV dev, HRGN hrgn, DWORD iType)
Definition: graphics.c:836
static void * store_points(POINTL *dest, const POINT *pts, UINT count, BOOL short_points)
Definition: graphics.c:50
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_FrameRgn(PHYSDEV dev, HRGN hrgn, HBRUSH hbrush, INT width, INT height)
Definition: graphics.c:798
BOOL EMFDRV_RoundRect(PHYSDEV dev, INT left, INT top, INT right, INT bottom, INT ell_width, INT ell_height)
Definition: graphics.c:486
static const RECTL empty_bounds
Definition: graphics.c:36
COLORREF EMFDRV_SetPixel(PHYSDEV dev, INT x, INT y, COLORREF color)
Definition: graphics.c:526
BOOL EMFDRV_InvertRgn(PHYSDEV dev, HRGN hrgn)
Definition: graphics.c:875
BOOL EMFDRV_GradientFill(PHYSDEV dev, TRIVERTEX *vert_array, ULONG nvert, void *grad_array, ULONG ngrad, ULONG mode)
Definition: graphics.c:1033
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
BOOL EMFDRV_PolyBezierTo(PHYSDEV dev, const POINT *pts, DWORD count)
Definition: graphics.c:625
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
static void get_points_bounds(RECTL *bounds, const POINT *pts, UINT count, DC *dc)
Definition: graphics.c:75
BOOL EMFDRV_ExtFloodFill(PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType)
Definition: graphics.c:747
BOOL EMFDRV_StrokeAndFillPath(PHYSDEV dev)
Definition: graphics.c:1095
BOOL EMFDRV_MoveTo(PHYSDEV dev, INT x, INT y)
Definition: graphics.c:173
static BOOL can_use_short_points(const POINT *pts, UINT count)
Definition: graphics.c:39
BOOL EMFDRV_StrokePath(PHYSDEV dev)
Definition: graphics.c:1103
BOOL EMFDRV_PolyBezier(PHYSDEV dev, const POINT *pts, DWORD count)
Definition: graphics.c:617
BOOL EMFDRV_PolylineTo(PHYSDEV dev, const POINT *pt, INT count)
Definition: graphics.c:600
BOOL EMFDRV_AngleArc(PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT start, FLOAT sweep)
Definition: graphics.c:390
BOOL EMFDRV_PolyPolygon(PHYSDEV dev, const POINT *pt, const INT *counts, UINT polys)
Definition: graphics.c:701
BOOL EMFDRV_LineTo(PHYSDEV dev, INT x, INT y)
Definition: graphics.c:188
BOOL EMFDRV_Polygon(PHYSDEV dev, const POINT *pt, INT count)
Definition: graphics.c:608
BOOL EMFDRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
Definition: graphics.c:447
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
BOOL EMFDRV_Ellipse(PHYSDEV dev, INT left, INT top, INT right, INT bottom)
Definition: graphics.c:408
BOOL EMFDRV_PolyPolyline(PHYSDEV dev, const POINT *pt, const DWORD *counts, DWORD polys)
Definition: graphics.c:692
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 BOOL emfdrv_stroke_and_fill_path(PHYSDEV dev, INT type)
Definition: graphics.c:144
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2084
_In_ ULONG iType
Definition: winddi.h:3748
struct _POINTL POINTL
struct tagPOINTS POINTS
DWORD COLORREF
Definition: windef.h:300
#define GM_COMPATIBLE
Definition: wingdi.h:864
#define EMR_POLYPOLYLINE
Definition: wingdi.h:81
#define EMR_FRAMERGN
Definition: wingdi.h:145
BOOL WINAPI GetTextMetricsW(_In_ HDC, _Out_ LPTEXTMETRICW)
Definition: text.c:221
#define HORZRES
Definition: wingdi.h:716
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
#define EMR_POLYLINE
Definition: wingdi.h:78
UINT WINAPI GetTextAlign(_In_ HDC)
Definition: text.c:838
int WINAPI GetGraphicsMode(_In_ HDC)
#define EMR_POLYDRAW16
Definition: wingdi.h:165
#define EMR_POLYLINE16
Definition: wingdi.h:160
#define EMR_POLYGON
Definition: wingdi.h:77
BOOL WINAPI GetCurrentPositionEx(_In_ HDC, _Out_ LPPOINT)
Definition: coord.c:241
#define EMR_PIE
Definition: wingdi.h:121
#define EMR_STROKEANDFILLPATH
Definition: wingdi.h:137
#define VERTSIZE
Definition: wingdi.h:715
#define EMR_PAINTRGN
Definition: wingdi.h:147
#define EMR_LINETO
Definition: wingdi.h:128
#define EMR_EXTTEXTOUTW
Definition: wingdi.h:157
#define EMR_MOVETOEX
Definition: wingdi.h:101
#define TA_RIGHT
Definition: wingdi.h:933
#define TA_LEFT
Definition: wingdi.h:932
#define EMR_RECTANGLE
Definition: wingdi.h:117
#define HORZSIZE
Definition: wingdi.h:714
#define EMR_POLYLINETO
Definition: wingdi.h:80
#define EMR_ANGLEARC
Definition: wingdi.h:115
#define VERTRES
Definition: wingdi.h:717
#define EMR_ELLIPSE
Definition: wingdi.h:116
#define EMR_FILLPATH
Definition: wingdi.h:136
#define EMR_ARCTO
Definition: wingdi.h:129
#define EMR_EXTFLOODFILL
Definition: wingdi.h:127
#define EMR_SETPIXELV
Definition: wingdi.h:89
BOOL WINAPI GetWindowExtEx(_In_ HDC, _Out_ LPSIZE)
Definition: coord.c:411
#define EMR_INVERTRGN
Definition: wingdi.h:146
#define TA_TOP
Definition: wingdi.h:930
#define EMR_CHORD
Definition: wingdi.h:120
#define TA_BOTTOM
Definition: wingdi.h:929
#define TA_BASELINE
Definition: wingdi.h:928
DWORD WINAPI GetRegionData(_In_ HRGN hrgn, _In_ DWORD nCount, _Out_writes_bytes_to_opt_(nCount, return) LPRGNDATA lpRgnData)
#define EMR_ROUNDRECT
Definition: wingdi.h:118
#define TA_CENTER
Definition: wingdi.h:931
#define EMR_POLYPOLYLINE16
Definition: wingdi.h:163
BOOL WINAPI GetViewportExtEx(_In_ HDC, _Out_ LPSIZE)
Definition: coord.c:351
#define EMR_POLYBEZIER
Definition: wingdi.h:76
#define EMR_POLYBEZIERTO
Definition: wingdi.h:79
#define EMR_STROKEPATH
Definition: wingdi.h:138
#define EMR_ARC
Definition: wingdi.h:119
#define EMR_POLYDRAW
Definition: wingdi.h:130
BOOL WINAPI GetTextExtentPoint32W(_In_ HDC hdc, _In_reads_(c) LPCWSTR lpString, _In_ int c, _Out_ LPSIZE psizl)
#define EMR_POLYPOLYGON
Definition: wingdi.h:82
#define EMR_FILLRGN
Definition: wingdi.h:144
int WINAPI GetPath(_In_ HDC hdc, _Out_writes_opt_(cpt) LPPOINT apt, _Out_writes_opt_(cpt) LPBYTE aj, int cpt)
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193