ReactOS 0.4.15-dev-7994-gb388cb6
arc.c
Go to the documentation of this file.
1#include <win32k.h>
2
3#define NDEBUG
4#include <debug.h>
5
6/*
7 * A couple of macros to fill a single pixel or a line
8 */
9#define PUTPIXEL(x,y,BrushInst) \
10 ret = ret && IntEngLineTo(&psurf->SurfObj, \
11 (CLIPOBJ *)&dc->co, \
12 &BrushInst.BrushObject, \
13 x, y, (x)+1, y, \
14 &RectBounds, \
15 ROP2_TO_MIX(pdcattr->jROP2));
16
17#define PUTLINE(x1,y1,x2,y2,BrushInst) \
18 ret = ret && IntEngLineTo(&psurf->SurfObj, \
19 (CLIPOBJ *)&dc->co, \
20 &BrushInst.BrushObject, \
21 x1, y1, x2, y2, \
22 &RectBounds, \
23 ROP2_TO_MIX(pdcattr->jROP2));
24
25static
26BOOL
29 int Left,
30 int Top,
31 int Right,
32 int Bottom,
33 int XRadialStart,
34 int YRadialStart,
35 int XRadialEnd,
36 int YRadialEnd,
37 ARCTYPE arctype)
38{
39 PDC_ATTR pdcattr;
40 RECTL RectBounds, RectSEpts;
41 PBRUSH pbrPen;
42 SURFACE *psurf;
43 BOOL ret = TRUE;
44 LONG PenWidth, PenOrigWidth;
45 double AngleStart, AngleEnd;
46 LONG CenterX, CenterY;
47
48 if (Right < Left)
49 {
50 INT tmp = Right; Right = Left; Left = tmp;
51 }
52 if (Bottom < Top)
53 {
54 INT tmp = Bottom; Bottom = Top; Top = tmp;
55 }
56
57 /* Check if the target rect is empty */
58 if ((Left == Right) || (Top == Bottom)) return TRUE;
59
60 // FIXME: this needs to be verified
61 if ((arctype == GdiTypeChord ) || (arctype == GdiTypePie))
62 {
63 if ((Right - Left == 1) || (Bottom - Top == 1))
64 return TRUE;
65 }
66
67
68 pdcattr = dc->pdcattr;
69
70 pbrPen = PEN_ShareLockPen(pdcattr->hpen);
71 if (!pbrPen)
72 {
73 DPRINT1("Arc Fail 1\n");
75 return FALSE;
76 }
77
78 PenOrigWidth = PenWidth = pbrPen->lWidth;
79 if (pbrPen->ulPenStyle == PS_NULL) PenWidth = 0;
80
81 if (pbrPen->ulPenStyle == PS_INSIDEFRAME)
82 {
83 if (2*PenWidth > (Right - Left)) PenWidth = (Right -Left + 1)/2;
84 if (2*PenWidth > (Bottom - Top)) PenWidth = (Bottom -Top + 1)/2;
85 Left += PenWidth / 2;
86 Right -= (PenWidth - 1) / 2;
87 Top += PenWidth / 2;
88 Bottom -= (PenWidth - 1) / 2;
89 }
90
91 if (!PenWidth) PenWidth = 1;
92 pbrPen->lWidth = PenWidth;
93
94 RectBounds.left = Left;
95 RectBounds.right = Right;
96 RectBounds.top = Top;
97 RectBounds.bottom = Bottom;
98
99 RectSEpts.left = XRadialStart;
100 RectSEpts.top = YRadialStart;
101 RectSEpts.right = XRadialEnd;
102 RectSEpts.bottom = YRadialEnd;
103
104 IntLPtoDP(dc, (LPPOINT)&RectBounds, 2);
105 IntLPtoDP(dc, (LPPOINT)&RectSEpts, 2);
106
107 RectBounds.left += dc->ptlDCOrig.x;
108 RectBounds.right += dc->ptlDCOrig.x;
109 RectBounds.top += dc->ptlDCOrig.y;
110 RectBounds.bottom += dc->ptlDCOrig.y;
111
112 RectSEpts.left += dc->ptlDCOrig.x;
113 RectSEpts.top += dc->ptlDCOrig.y;
114 RectSEpts.right += dc->ptlDCOrig.x;
115 RectSEpts.bottom += dc->ptlDCOrig.y;
116
117 DPRINT("1: StartX: %d, StartY: %d, EndX: %d, EndY: %d\n",
118 RectSEpts.left,RectSEpts.top,RectSEpts.right,RectSEpts.bottom);
119
120 DPRINT("1: Left: %d, Top: %d, Right: %d, Bottom: %d\n",
121 RectBounds.left,RectBounds.top,RectBounds.right,RectBounds.bottom);
122
123 CenterX = (RectBounds.right + RectBounds.left) / 2;
124 CenterY = (RectBounds.bottom + RectBounds.top) / 2;
125 AngleEnd = atan2((RectSEpts.bottom - CenterY), RectSEpts.right - CenterX)*(360.0/(M_PI*2));
126 AngleStart = atan2((RectSEpts.top - CenterY), RectSEpts.left - CenterX)*(360.0/(M_PI*2));
127
128 /* Edge Case: Check if the start segments overlaps(is equal) the end segment */
129 if (AngleEnd == AngleStart)
130 {
131 AngleStart = AngleEnd + 360.0; // Arc(), ArcTo(), Pie() and Chord() are counterclockwise APIs.
132 }
133
134 if ((arctype == GdiTypePie) || (arctype == GdiTypeChord))
135 {
136 ret = IntFillArc( dc,
137 RectBounds.left,
138 RectBounds.top,
139 abs(RectBounds.right-RectBounds.left), // Width
140 abs(RectBounds.bottom-RectBounds.top), // Height
141 AngleStart,
142 AngleEnd,
143 arctype);
144 }
145
146 if(ret)
147 {
148 ret = IntDrawArc( dc,
149 RectBounds.left,
150 RectBounds.top,
151 abs(RectBounds.right-RectBounds.left), // Width
152 abs(RectBounds.bottom-RectBounds.top), // Height
153 AngleStart,
154 AngleEnd,
155 arctype,
156 pbrPen);
157 }
158
159 psurf = dc->dclevel.pSurface;
160 if (NULL == psurf)
161 {
162 DPRINT1("Arc Fail 2\n");
163 PEN_ShareUnlockPen(pbrPen);
165 return FALSE;
166 }
167
168 if (arctype == GdiTypePie)
169 {
170 PUTLINE(CenterX, CenterY, RectSEpts.left, RectSEpts.top, dc->eboLine);
171 PUTLINE(RectSEpts.right, RectSEpts.bottom, CenterX, CenterY, dc->eboLine);
172 }
173 if (arctype == GdiTypeChord)
174 PUTLINE(RectSEpts.right, RectSEpts.bottom, RectSEpts.left, RectSEpts.top, dc->eboLine);
175
176 pbrPen->lWidth = PenOrigWidth;
177 PEN_ShareUnlockPen(pbrPen);
178 DPRINT("IntArc Exit.\n");
179 return ret;
180}
181
182
185 ARCTYPE arctype,
186 DC *dc,
187 int LeftRect,
188 int TopRect,
189 int RightRect,
190 int BottomRect,
191 int XStartArc,
192 int YStartArc,
193 int XEndArc,
194 int YEndArc)
195{
196 BOOL Ret;
197 //PDC_ATTR pdcattr;
198
199 DPRINT("StartX: %d, StartY: %d, EndX: %d, EndY: %d\n",
200 XStartArc,YStartArc,XEndArc,YEndArc);
201 DPRINT("Left: %d, Top: %d, Right: %d, Bottom: %d\n",
202 LeftRect,TopRect,RightRect,BottomRect);
203
204 if ((LeftRect == RightRect) || (TopRect == BottomRect)) return TRUE;
205
206 if (PATH_IsPathOpen(dc->dclevel))
207 {
208 return PATH_Arc( dc,
209 LeftRect,
210 TopRect,
211 RightRect,
212 BottomRect,
213 XStartArc,
214 YStartArc,
215 XEndArc,
216 YEndArc,
217 0,
218 arctype);
219 }
220
221 //pdcattr = dc->pdcattr;
222
223 if (arctype == GdiTypeArcTo)
224 {
225 if (dc->dclevel.flPath & DCPATH_CLOCKWISE)
226 IntGdiLineTo(dc, XEndArc, YEndArc);
227 else
228 IntGdiLineTo(dc, XStartArc, YStartArc);
229 }
230
231 Ret = IntArc( dc,
232 LeftRect,
233 TopRect,
234 RightRect,
235 BottomRect,
236 XStartArc,
237 YStartArc,
238 XEndArc,
239 YEndArc,
240 arctype);
241
242 if (arctype == GdiTypeArcTo)
243 {
244 if (dc->dclevel.flPath & DCPATH_CLOCKWISE)
245 IntGdiMoveToEx(dc, XStartArc, YStartArc, NULL);
246 else
247 IntGdiMoveToEx(dc, XEndArc, YEndArc, NULL);
248 }
249 return Ret;
250}
251
252BOOL
255 INT x,
256 INT y,
257 DWORD dwRadius,
258 FLOAT eStartAngle,
259 FLOAT eSweepAngle)
260{
261 INT x1, y1, x2, y2, arcdir;
262 BOOL result;
263
264 /* Calculate the end point */
265 x2 = x + (INT)(cos(((eStartAngle+eSweepAngle)/360)*(M_PI*2)) * dwRadius);
266 y2 = y - (INT)(sin(((eStartAngle+eSweepAngle)/360)*(M_PI*2)) * dwRadius);
267
268 x1 = x + (INT)(cos((eStartAngle/360)*(M_PI*2)) * dwRadius);
269 y1 = y - (INT)(sin((eStartAngle/360)*(M_PI*2)) * dwRadius);
270
271 arcdir = pDC->dclevel.flPath & DCPATH_CLOCKWISE;
272 if (eSweepAngle >= 0)
273 pDC->dclevel.flPath &= ~DCPATH_CLOCKWISE;
274 else
275 pDC->dclevel.flPath |= DCPATH_CLOCKWISE;
276
278 pDC,
279 x-dwRadius,
280 y-dwRadius,
281 x+dwRadius,
282 y+dwRadius,
283 x1,
284 y1,
285 x2,
286 y2 );
287
288 pDC->dclevel.flPath |= (arcdir & DCPATH_CLOCKWISE);
289
290 if (result)
291 {
292 IntGdiMoveToEx(pDC, x2, y2, NULL);
293 }
294 return result;
295}
296
297/* FUNCTIONS *****************************************************************/
298
299BOOL
302 IN HDC hDC,
303 IN INT x,
304 IN INT y,
305 IN DWORD dwRadius,
306 IN DWORD dwStartAngle,
307 IN DWORD dwSweepAngle)
308{
309 DC *pDC;
310 BOOL Ret = FALSE;
311 gxf_long worker, worker1;
312 KFLOATING_SAVE FloatSave;
314
315 pDC = DC_LockDc (hDC);
316 if(!pDC)
317 {
319 return FALSE;
320 }
321
322 status = KeSaveFloatingPointState(&FloatSave);
323 if (!NT_SUCCESS(status))
324 {
325 DC_UnlockDc( pDC );
326 return FALSE;
327 }
328
329 worker.l = dwStartAngle;
330 worker1.l = dwSweepAngle;
332 if (pDC->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
334 if (pDC->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
336 Ret = IntGdiAngleArc( pDC, x, y, dwRadius, worker.f, worker1.f);
337 DC_vFinishBlit(pDC, NULL);
338 DC_UnlockDc( pDC );
339
340 KeRestoreFloatingPointState(&FloatSave);
341
342 return Ret;
343}
344
345BOOL
348 ARCTYPE arctype,
349 HDC hDC,
350 int LeftRect,
351 int TopRect,
352 int RightRect,
353 int BottomRect,
354 int XStartArc,
355 int YStartArc,
356 int XEndArc,
357 int YEndArc)
358{
359 DC *dc;
360 BOOL Ret;
361 KFLOATING_SAVE FloatSave;
363
364 dc = DC_LockDc (hDC);
365 if(!dc)
366 {
368 return FALSE;
369 }
370 if (arctype > GdiTypePie)
371 {
374 return FALSE;
375 }
376
378
379 if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
381
382 if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
384
385 status = KeSaveFloatingPointState(&FloatSave);
386 if (!NT_SUCCESS(status))
387 {
388 DC_UnlockDc( dc );
389 return FALSE;
390 }
391
392 Ret = IntGdiArcInternal(
393 arctype,
394 dc,
395 LeftRect,
396 TopRect,
397 RightRect,
398 BottomRect,
399 XStartArc,
400 YStartArc,
401 XEndArc,
402 YEndArc);
403
404 KeRestoreFloatingPointState(&FloatSave);
406 DC_UnlockDc( dc );
407 return Ret;
408}
409
static HDC hDC
Definition: 3dtext.c:33
_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
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
static LPHIST_ENTRY Bottom
Definition: history.c:54
static LPHIST_ENTRY Top
Definition: history.c:53
static BOOLEAN IntLPtoDP(DC *pdc, PPOINTL ppt, UINT count)
Definition: coord.h:182
VOID FASTCALL DC_vPrepareDCsForBlit(PDC pdcDest, const RECT *rcDest, PDC pdcSrc, const RECT *rcSrc)
Definition: dclife.c:505
VOID FASTCALL DC_vUpdateLineBrush(PDC pdc)
Definition: dcobjs.c:62
VOID FASTCALL DC_vFinishBlit(PDC pdc1, PDC pdc2)
Definition: dclife.c:614
FORCEINLINE VOID DC_UnlockDc(PDC pdc)
Definition: dc.h:238
VOID FASTCALL DC_vUpdateFillBrush(PDC pdc)
Definition: dcobjs.c:16
FORCEINLINE PDC DC_LockDc(HDC hdc)
Definition: dc.h:220
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define APIENTRY
Definition: api.h:79
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
BOOL FASTCALL IntDrawArc(PDC dc, INT XLeft, INT YLeft, INT Width, INT Height, double StartArc, double EndArc, ARCTYPE arctype, PBRUSH pbrush)
Definition: drawing.c:1342
BOOL FASTCALL IntFillArc(PDC dc, INT XLeft, INT YLeft, INT Width, INT Height, double StartArc, double EndArc, ARCTYPE arctype)
Definition: drawing.c:1306
#define abs(i)
Definition: fconv.c:206
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint64EXT * result
Definition: glext.h:11304
BOOL FASTCALL IntGdiLineTo(DC *dc, int XEnd, int YEnd)
Definition: line.c:146
BOOL FASTCALL IntGdiMoveToEx(DC *dc, int X, int Y, LPPOINT Point)
Definition: line.c:78
#define KeSaveFloatingPointState(x)
Definition: kmixer.h:32
#define KeRestoreFloatingPointState(x)
Definition: kmixer.h:33
#define M_PI
Definition: macros.h:263
static const WCHAR dc[]
static HDC
Definition: imagelist.c:92
#define FASTCALL
Definition: nt_native.h:50
BOOL FASTCALL IntGdiAngleArc(PDC pDC, INT x, INT y, DWORD dwRadius, FLOAT eStartAngle, FLOAT eSweepAngle)
Definition: arc.c:254
BOOL FASTCALL IntGdiArcInternal(ARCTYPE arctype, DC *dc, int LeftRect, int TopRect, int RightRect, int BottomRect, int XStartArc, int YStartArc, int XEndArc, int YEndArc)
Definition: arc.c:184
#define PUTLINE(x1, y1, x2, y2, BrushInst)
Definition: arc.c:17
static BOOL FASTCALL IntArc(DC *dc, int Left, int Top, int Right, int Bottom, int XRadialStart, int YRadialStart, int XRadialEnd, int YRadialEnd, ARCTYPE arctype)
Definition: arc.c:28
__kernel_entry W32KAPI BOOL APIENTRY NtGdiAngleArc(_In_ HDC hdc, _In_ INT x, _In_ INT y, _In_ DWORD dwRadius, _In_ DWORD dwStartAngle, _In_ DWORD dwSweepAngle)
__kernel_entry W32KAPI BOOL APIENTRY NtGdiArcInternal(_In_ ARCTYPE arctype, _In_ HDC hdc, _In_ INT x1, _In_ INT y1, _In_ INT x2, _In_ INT y2, _In_ INT x3, _In_ INT y3, _In_ INT x4, _In_ INT y4)
#define DIRTY_FILL
Definition: ntgdihdl.h:123
#define DC_PEN_DIRTY
Definition: ntgdihdl.h:136
#define DIRTY_LINE
Definition: ntgdihdl.h:124
#define DC_BRUSH_DIRTY
Definition: ntgdihdl.h:135
@ GdiTypeChord
Definition: ntgdityp.h:22
@ GdiTypeArcTo
Definition: ntgdityp.h:21
@ GdiTypePie
Definition: ntgdityp.h:23
enum _ARCTYPE ARCTYPE
#define PATH_IsPathOpen(dclevel)
Definition: path.h:72
@ DCPATH_CLOCKWISE
Definition: path.h:8
long LONG
Definition: pedump.c:60
#define PEN_ShareUnlockPen(ppen)
Definition: pen.h:18
#define INT
Definition: polytest.cpp:20
#define DPRINT
Definition: sndvol32.h:71
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
Definition: types.h:101
HANDLE hpen
Definition: ntgdihdl.h:296
Definition: ps.c:97
float FLOAT
Definition: typedefs.h:69
int32_t INT
Definition: typedefs.h:58
#define IN
Definition: typedefs.h:39
ULONG l
Definition: ntgdityp.h:427
FLOAT f
Definition: ntgdityp.h:426
int ret
BOOL FASTCALL PATH_Arc(PDC dc, INT x1, INT y1, INT x2, INT y2, INT xStart, INT yStart, INT xEnd, INT yEnd, INT direction, INT lines)
Definition: path.c:955
PBRUSH FASTCALL PEN_ShareLockPen(HPEN hobj)
Definition: pen.c:61
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3710
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG y1
Definition: winddi.h:3709
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3708
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG _In_ LONG y2
Definition: winddi.h:3711
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:22
#define ERROR_INTERNAL_ERROR
Definition: winerror.h:840
#define PS_NULL
Definition: wingdi.h:591
#define PS_INSIDEFRAME
Definition: wingdi.h:593