ReactOS  0.4.15-dev-3453-gff89651
emfdrv.c
Go to the documentation of this file.
1 /*
2  * Enhanced MetaFile driver
3  *
4  * Copyright 1999 Huw D M Davies
5  * Copyright 2021 Jacek Caban for CodeWeavers
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 //#include "ntgdi_private.h"
23 #include "wine/config.h"
24 
25 #include <stdarg.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include "windef.h"
30 #include "winbase.h"
31 #include "wingdi.h"
32 #include "winnls.h"
33 #include "winerror.h"
34 #include "gdi_private.h"
35 #ifdef __REACTOS__
36 #include "wine/winternl.h"
37 #else
38 #include "winternl.h"
39 #endif
40 #include "wine/wingdi16.h"
41 #include "wine/debug.h"
42 
43 #define M_PI 3.14159265358979323846
44 #define M_PI_2 1.570796326794896619
45 
47 {
48  RECTL *bounds = &dc->emf_bounds;
49  RECTL vport_rect = *rect;
50 
51  //lp_to_dp( dc, (POINT *)&vport_rect, 2 );
52  LPtoDP(dc->hdc, (POINT *)&vport_rect, 2 );
53 
54  /* The coordinate systems may be mirrored
55  (LPtoDP handles points, not rectangles) */
56  if (vport_rect.left > vport_rect.right)
57  {
58  LONG temp = vport_rect.right;
59  vport_rect.right = vport_rect.left;
60  vport_rect.left = temp;
61  }
62  if (vport_rect.top > vport_rect.bottom)
63  {
64  LONG temp = vport_rect.bottom;
65  vport_rect.bottom = vport_rect.top;
66  vport_rect.top = temp;
67  }
68 
69  if (bounds->left > bounds->right)
70  {
71  /* first bounding rectangle */
72  *bounds = vport_rect;
73  }
74  else
75  {
76  bounds->left = min( bounds->left, vport_rect.left );
77  bounds->top = min( bounds->top, vport_rect.top );
78  bounds->right = max( bounds->right, vport_rect.right );
79  bounds->bottom = max( bounds->bottom, vport_rect.bottom );
80  }
81 }
82 
84 {
85  RECTL bounds;
86  POINT pt;
87 
88  //pt = dc->attr->cur_pos;
89  GetCurrentPositionEx(dc->hdc, &pt);
90 
91  bounds.left = min( x, pt.x );
92  bounds.top = min( y, pt.y );
93  bounds.right = max( x, pt.x );
94  bounds.bottom = max( y, pt.y );
95  emfdrv_update_bounds( dc, &bounds );
96  return TRUE;
97 }
98 
100  INT bottom, INT ell_width, INT ell_height )
101 {
102  RECTL bounds;
103 
104  if (left == right || top == bottom) return FALSE;
105 
106  bounds.left = min( left, right );
107  bounds.top = min( top, bottom );
108  bounds.right = max( left, right );
109  bounds.bottom = max( top, bottom );
110  if (GetGraphicsMode(dc->hdc) == GM_COMPATIBLE)//dc->attr->graphics_mode == GM_COMPATIBLE)
111  {
112  bounds.right--;
113  bounds.bottom--;
114  }
115 
116  emfdrv_update_bounds( dc, &bounds );
117  return TRUE;
118 }
119 
121  INT xstart, INT ystart, INT xend, INT yend, DWORD type )
122 {
123  INT temp, x_centre, y_centre, i;
124  double angle_start, angle_end;
125  double xinter_start, yinter_start, xinter_end, yinter_end;
126  EMRARC emr;
127  RECTL bounds;
128 
129  if (left == right || top == bottom) return FALSE;
130 
131  if (left > right) { temp = left; left = right; right = temp; }
132  if (top > bottom) { temp = top; top = bottom; bottom = temp; }
133 
134  if (GetGraphicsMode(dc->hdc) == GM_COMPATIBLE)//dc->attr->graphics_mode == GM_COMPATIBLE)
135  {
136  right--;
137  bottom--;
138  }
139 
140  emr.emr.iType = type;
141  emr.emr.nSize = sizeof(emr);
142  emr.rclBox.left = left;
143  emr.rclBox.top = top;
144  emr.rclBox.right = right;
145  emr.rclBox.bottom = bottom;
146  emr.ptlStart.x = xstart;
147  emr.ptlStart.y = ystart;
148  emr.ptlEnd.x = xend;
149  emr.ptlEnd.y = yend;
150 
151  /* Now calculate the BBox */
152  x_centre = (left + right + 1) / 2;
153  y_centre = (top + bottom + 1) / 2;
154 
155  xstart -= x_centre;
156  ystart -= y_centre;
157  xend -= x_centre;
158  yend -= y_centre;
159 
160  /* invert y co-ords to get angle anti-clockwise from x-axis */
161  angle_start = atan2( -(double)ystart, (double)xstart );
162  angle_end = atan2( -(double)yend, (double)xend );
163 
164  /* These are the intercepts of the start/end lines with the arc */
165  xinter_start = (right - left + 1)/2 * cos(angle_start) + x_centre;
166  yinter_start = -(bottom - top + 1)/2 * sin(angle_start) + y_centre;
167  xinter_end = (right - left + 1)/2 * cos(angle_end) + x_centre;
168  yinter_end = -(bottom - top + 1)/2 * sin(angle_end) + y_centre;
169 
170  if (angle_start < 0) angle_start += 2 * M_PI;
171  if (angle_end < 0) angle_end += 2 * M_PI;
172  if (angle_end < angle_start) angle_end += 2 * M_PI;
173 
174  bounds.left = min( xinter_start, xinter_end );
175  bounds.top = min( yinter_start, yinter_end );
176  bounds.right = max( xinter_start, xinter_end );
177  bounds.bottom = max( yinter_start, yinter_end );
178 
179  for (i = 0; i <= 8; i++)
180  {
181  if(i * M_PI / 2 < angle_start) /* loop until we're past start */
182  continue;
183  if(i * M_PI / 2 > angle_end) /* if we're past end we're finished */
184  break;
185 
186  /* the arc touches the rectangle at the start of quadrant i, so adjust
187  BBox to reflect this. */
188 
189  switch(i % 4) {
190  case 0:
191  bounds.right = right;
192  break;
193  case 1:
194  bounds.top = top;
195  break;
196  case 2:
197  bounds.left = left;
198  break;
199  case 3:
200  bounds.bottom = bottom;
201  break;
202  }
203  }
204 
205  /* If we're drawing a pie then make sure we include the centre */
206  if (type == EMR_PIE)
207  {
208  if (bounds.left > x_centre) bounds.left = x_centre;
209  else if (bounds.right < x_centre) bounds.right = x_centre;
210  if (bounds.top > y_centre) bounds.top = y_centre;
211  else if (bounds.bottom < y_centre) bounds.bottom = y_centre;
212  }
213  else if (type == EMR_ARCTO)
214  {
215  POINT pt;
216  //pt = dc->attr->cur_pos;
217  GetCurrentPositionEx(dc->hdc, &pt);
218  bounds.left = min( bounds.left, pt.x );
219  bounds.top = min( bounds.top, pt.y );
220  bounds.right = max( bounds.right, pt.x );
221  bounds.bottom = max( bounds.bottom, pt.y );
222  }
223  emfdrv_update_bounds( dc, &bounds );
224  return TRUE;
225 }
226 
228  INT xstart, INT ystart, INT xend, INT yend )
229 {
230  return EMFDRV_ArcChordPie( dc, left, top, right, bottom, xstart, ystart,
231  xend, yend, EMR_ARC );
232 }
233 
235  INT xstart, INT ystart, INT xend, INT yend )
236 {
237  return EMFDRV_ArcChordPie( dc, left, top, right, bottom, xstart, ystart,
238  xend, yend, EMR_ARCTO );
239 }
240 
242  INT xstart, INT ystart, INT xend, INT yend )
243 {
244  return EMFDRV_ArcChordPie( dc, left, top, right, bottom, xstart, ystart,
245  xend, yend, EMR_PIE );
246 }
247 
249  INT xstart, INT ystart, INT xend, INT yend )
250 {
251  return EMFDRV_ArcChordPie( dc, left, top, right, bottom, xstart, ystart,
252  xend, yend, EMR_CHORD );
253 }
254 
256 {
257  RECTL bounds;
258 
259  if (left == right || top == bottom) return FALSE;
260 
261  bounds.left = min( left, right );
262  bounds.top = min( top, bottom );
263  bounds.right = max( left, right );
264  bounds.bottom = max( top, bottom );
265  if (GetGraphicsMode(dc->hdc) == GM_COMPATIBLE)//dc->attr->graphics_mode == GM_COMPATIBLE)
266  {
267  bounds.right--;
268  bounds.bottom--;
269  }
270 
271  emfdrv_update_bounds( dc, &bounds );
272  return TRUE;
273 }
274 
276 {
277  RECTL bounds;
278 
279  if (left == right || top == bottom) return FALSE;
280 
281  bounds.left = min( left, right );
282  bounds.top = min( top, bottom );
283  bounds.right = max( left, right );
284  bounds.bottom = max( top, bottom );
285  if (GetGraphicsMode(dc->hdc) == GM_COMPATIBLE)//dc->attr->graphics_mode == GM_COMPATIBLE)
286  {
287  bounds.right--;
288  bounds.bottom--;
289  }
290 
291  emfdrv_update_bounds( dc, &bounds );
292  return TRUE;
293 }
294 
296 {
297  RECTL bounds;
298 
299  bounds.left = bounds.right = x;
300  bounds.top = bounds.bottom = y;
301  emfdrv_update_bounds( dc, &bounds );
302  return CLR_INVALID;
303 }
304 
306 {
307  /* FIXME: update bounding rect */
308  return TRUE;
309 }
310 
312 {
313  /* FIXME: update bounding rect */
314  return TRUE;
315 }
316 
318 {
319  /* FIXME: update bounding rect */
320  return TRUE;
321 }
322 
324  const DWORD *counts, UINT polys )
325 {
326  /* FIXME: update bounding rect */
327  return TRUE;
328 }
329 
331  const INT *counts, UINT polys )
332 {
333  /* FIXME: update bounding rect */
334  return TRUE;
335 }
336 
338  const BYTE *types, DWORD count )
339 {
340  /* FIXME: update bounding rect */
341  return TRUE;
342 }
343 
345 {
346  /* FIXME: update bounding rect */
347  return TRUE;
348 }
349 
351 {
352  /* FIXME: update bounding rect */
353  return TRUE;
354 }
355 
357 {
358  /* FIXME: update bounding rect */
359  return TRUE;
360 }
361 
363  LPCWSTR str, UINT count, const INT *lpDx )
364 {
365  /* FIXME: update bounding rect */
366  return TRUE;
367 }
368 
370  void *grad_array, ULONG ngrad, ULONG mode )
371 {
372  /* FIXME: update bounding rect */
373  return TRUE;
374 }
375 
377 {
378  /* FIXME: update bound rect */
379  return TRUE;
380 }
381 
383 {
384  /* FIXME: update bound rect */
385  return TRUE;
386 }
387 
389 {
390  /* FIXME: update bound rect */
391  return TRUE;
392 }
393 
394 BOOL EMFDRV_AlphaBlend( WINEDC *dc_dst, INT x_dst, INT y_dst, INT width_dst, INT height_dst,
395  HDC dc_src, INT x_src, INT y_src, INT width_src, INT height_src,
397 {
398  /* FIXME: update bound rect */
399  return TRUE;
400 }
401 
403 {
404  /* FIXME: update bound rect */
405  return TRUE;
406 }
407 
408 INT EMFDRV_StretchDIBits( WINEDC *dc, INT x_dst, INT y_dst, INT width_dst,
409  INT height_dst, INT x_src, INT y_src, INT width_src,
410  INT height_src, const void *bits, BITMAPINFO *info,
411  UINT wUsage, DWORD dwRop )
412 {
413  /* FIXME: Update bound rect */
414  return height_src;
415 }
416 
418  DWORD height, INT x_src, INT y_src, UINT startscan,
419  UINT lines, const void *bits, BITMAPINFO *info,
420  UINT usage )
421 {
422  /* FIXME: Update bound rect */
423  return lines;
424 }
425 
427 {
428  return 0;
429 }
430 
INT EMFDRV_StretchDIBits(WINEDC *dc, 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, BITMAPINFO *info, UINT wUsage, DWORD dwRop)
Definition: emfdrv.c:408
BOOL EMFDRV_PolyDraw(WINEDC *dc, const POINT *pts, const BYTE *types, DWORD count)
Definition: emfdrv.c:337
GLenum func
Definition: glext.h:6028
BOOL EMFDRV_PolyBezierTo(WINEDC *dc, const POINT *pts, DWORD count)
Definition: emfdrv.c:317
BOOL EMFDRV_PatBlt(WINEDC *dc, INT left, INT top, INT width, INT height, DWORD rop)
Definition: emfdrv.c:402
BOOL WINAPI GetCurrentPositionEx(_In_ HDC, _Out_ LPPOINT)
Definition: coord.c:241
GLint GLint GLsizei width
Definition: gl.h:1546
#define max(a, b)
Definition: svc.c:63
BOOL EMFDRV_InvertRgn(WINEDC *dc, HRGN hrgn)
Definition: emfdrv.c:356
valarray< _Tp > atan2(const valarray< _Tp > &__x, const valarray< _Tp > &__y)
Definition: _valarray.h:928
static HBRUSH hbrush
BOOL EMFDRV_RoundRect(WINEDC *dc, INT left, INT top, INT right, INT bottom, INT ell_width, INT ell_height)
Definition: emfdrv.c:99
#define EMR_ARCTO
Definition: wingdi.h:129
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
BOOL WINAPI LPtoDP(_In_ HDC hdc, _Inout_updates_(c) LPPOINT lppt, _In_ int c)
BOOL EMFDRV_GradientFill(WINEDC *dc, TRIVERTEX *vert_array, ULONG nvert, void *grad_array, ULONG ngrad, ULONG mode)
Definition: emfdrv.c:369
#define TRUE
Definition: types.h:120
#define pt(x, y)
Definition: drawing.c:79
GLuint GLuint GLsizei count
Definition: gl.h:1545
BOOL EMFDRV_AlphaBlend(WINEDC *dc_dst, INT x_dst, INT y_dst, INT width_dst, INT height_dst, HDC dc_src, INT x_src, INT y_src, INT width_src, INT height_src, BLENDFUNCTION func)
Definition: emfdrv.c:394
BOOL EMFDRV_PolyBezier(WINEDC *dc, const POINT *pts, DWORD count)
Definition: emfdrv.c:311
static HDC
Definition: imagelist.c:92
POINTL ptlStart
Definition: wingdi.h:1717
#define CLR_INVALID
Definition: wingdi.h:883
long bottom
Definition: polytest.cpp:53
BOOL EMFDRV_Arc(WINEDC *dc, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend)
Definition: emfdrv.c:227
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static void emfdrv_update_bounds(WINEDC *dc, RECTL *rect)
Definition: emfdrv.c:46
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
int32_t INT
Definition: typedefs.h:58
& rect
Definition: startmenu.cpp:1413
BOOL EMFDRV_Rectangle(WINEDC *dc, INT left, INT top, INT right, INT bottom)
Definition: emfdrv.c:275
LONG y
Definition: windef.h:330
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
long right
Definition: polytest.cpp:53
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
GLuint color
Definition: glext.h:6243
long top
Definition: polytest.cpp:53
BOOL EMFDRV_PolylineTo(WINEDC *dc, const POINT *pt, INT count)
Definition: emfdrv.c:305
static int rop(int rop, int src, int dst)
Definition: nanoxwin.c:124
const WCHAR * str
_STLP_DECLSPEC complex< float > _STLP_CALL cos(const complex< float > &)
BOOL EMFDRV_PolyPolygon(WINEDC *dc, const POINT *pt, const INT *counts, UINT polys)
Definition: emfdrv.c:330
GLint GLint bottom
Definition: glext.h:7726
long left
Definition: polytest.cpp:53
BOOL EMFDRV_PolyPolyline(WINEDC *dc, const POINT *pt, const DWORD *counts, UINT polys)
Definition: emfdrv.c:323
BOOL EMFDRV_Chord(WINEDC *dc, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend)
Definition: emfdrv.c:248
eMaj lines
Definition: tritemp.h:206
BOOL EMFDRV_LineTo(WINEDC *dc, INT x, INT y)
Definition: emfdrv.c:83
Definition: cmds.c:130
int WINAPI GetGraphicsMode(_In_ HDC)
DWORD COLORREF
Definition: windef.h:300
BOOL EMFDRV_FillPath(WINEDC *dc)
Definition: emfdrv.c:376
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint left
Definition: glext.h:7726
LONG x
Definition: windef.h:329
BOOL EMFDRV_FillRgn(WINEDC *dc, HRGN hrgn, HBRUSH hbrush)
Definition: emfdrv.c:344
GLdouble GLdouble right
Definition: glext.h:10859
HBITMAP EMFDRV_SelectBitmap(WINEDC *dc, HBITMAP hbitmap)
Definition: emfdrv.c:426
GLbitfield flags
Definition: glext.h:7161
EMR emr
Definition: wingdi.h:1715
#define GM_COMPATIBLE
Definition: wingdi.h:864
#define EMR_PIE
Definition: wingdi.h:121
POINTL ptlEnd
Definition: wingdi.h:1718
DWORD nSize
Definition: wingdi.h:1691
#define EMR_CHORD
Definition: wingdi.h:120
#define M_PI
Definition: emfdrv.c:43
static HRGN hrgn
Definition: win.c:55
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
GLenum mode
Definition: glext.h:6217
unsigned char BYTE
Definition: xxhash.c:193
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
INT EMFDRV_SetDIBitsToDevice(WINEDC *dc, INT x_dst, INT y_dst, DWORD width, DWORD height, INT x_src, INT y_src, UINT startscan, UINT lines, const void *bits, BITMAPINFO *info, UINT usage)
Definition: emfdrv.c:417
#define EMR_ARC
Definition: wingdi.h:119
DWORD iType
Definition: wingdi.h:1690
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
static calc_node_t temp
Definition: rpn_ieee.c:38
#define min(a, b)
Definition: monoChain.cc:55
BOOL EMFDRV_StrokePath(WINEDC *dc)
Definition: emfdrv.c:388
unsigned int UINT
Definition: ndis.h:50
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
RECTL rclBox
Definition: wingdi.h:1716
BOOL EMFDRV_ArcTo(WINEDC *dc, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend)
Definition: emfdrv.c:234
unsigned int ULONG
Definition: retypes.h:1
static const WCHAR dc[]
static HBITMAP hbitmap
BOOL EMFDRV_StrokeAndFillPath(WINEDC *dc)
Definition: emfdrv.c:382
static HBITMAP
Definition: button.c:44
_STLP_DECLSPEC complex< float > _STLP_CALL sin(const complex< float > &)
BOOL EMFDRV_FrameRgn(WINEDC *dc, HRGN hrgn, HBRUSH hbrush, INT width, INT height)
Definition: emfdrv.c:350
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
COLORREF EMFDRV_SetPixel(WINEDC *dc, INT x, INT y, COLORREF color)
Definition: emfdrv.c:295
BOOL EMFDRV_Pie(WINEDC *dc, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend)
Definition: emfdrv.c:241
BOOL EMFDRV_ExtTextOut(WINEDC *dc, INT x, INT y, UINT flags, const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx)
Definition: emfdrv.c:362