ReactOS 0.4.16-dev-197-g92996da
line.c File Reference
#include <win32k.h>
#include <debug.h>
Include dependency graph for line.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

 DBG_DEFAULT_CHANNEL (GdiLine)
 
VOID FASTCALL AddPenLinesBounds (PDC dc, int count, POINT *points)
 
BOOL FASTCALL IntGdiMoveToEx (DC *dc, int X, int Y, LPPOINT Point)
 
BOOL FASTCALL GreMoveTo (HDC hdc, INT x, INT y, LPPOINT pptOut)
 
VOID FASTCALL IntGetCurrentPositionEx (PDC dc, LPPOINT pt)
 
BOOL FASTCALL IntGdiLineTo (DC *dc, int XEnd, int YEnd)
 
BOOL FASTCALL IntGdiPolyBezier (DC *dc, LPPOINT pt, DWORD Count)
 
BOOL FASTCALL IntGdiPolyBezierTo (DC *dc, LPPOINT pt, DWORD Count)
 
BOOL FASTCALL IntGdiPolyline (DC *dc, LPPOINT pt, int Count)
 
BOOL FASTCALL IntGdiPolylineTo (DC *dc, LPPOINT pt, DWORD Count)
 
BOOL FASTCALL IntGdiPolyPolyline (DC *dc, LPPOINT pt, PULONG PolyPoints, DWORD Count)
 
BOOL APIENTRY NtGdiLineTo (HDC hDC, int XEnd, int YEnd)
 
static BOOL GdiPolyDraw (IN HDC hdc, IN LPPOINT lppt, IN LPBYTE lpbTypes, IN ULONG cCount)
 
__kernel_entry W32KAPI BOOL APIENTRY NtGdiPolyDraw (_In_ HDC hdc, _In_reads_(cpt) LPPOINT ppt, _In_reads_(cpt) LPBYTE pjAttr, _In_ ULONG cpt)
 
 _Success_ (return !=FALSE)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 11 of file line.c.

Function Documentation

◆ _Success_()

_Success_ ( return = FALSE)

Definition at line 758 of file line.c.

766{
767 PDC pdc;
768 BOOL Ret;
769 POINT Point;
770
771 pdc = DC_LockDc(hdc);
772 if (!pdc) return FALSE;
773
774 Ret = IntGdiMoveToEx(pdc, x, y, &Point);
775
776 if (Ret && pptOut)
777 {
779 {
780 ProbeForWrite(pptOut, sizeof(POINT), 1);
781 RtlCopyMemory(pptOut, &Point, sizeof(POINT));
782 }
784 {
786 Ret = FALSE; // CHECKME: is this correct?
787 }
788 _SEH2_END;
789 }
790
791 DC_UnlockDc(pdc);
792
793 return Ret;
794}
FORCEINLINE VOID DC_UnlockDc(PDC pdc)
Definition: dc.h:238
FORCEINLINE PDC DC_LockDc(HDC hdc)
Definition: dc.h:220
#define FALSE
Definition: types.h:117
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned int BOOL
Definition: ntddk_ex.h:94
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
HDC hdc
Definition: main.c:9
_In_ UINT _Out_ PPOINTL pptOut
Definition: ntgdi.h:2198
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
Definition: polytest.cpp:41
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:31
BOOL FASTCALL IntGdiMoveToEx(DC *dc, int X, int Y, LPPOINT Point)
Definition: line.c:80

◆ AddPenLinesBounds()

VOID FASTCALL AddPenLinesBounds ( PDC  dc,
int  count,
POINT points 
)

Definition at line 19 of file line.c.

20{
21 DWORD join, endcap;
22 RECTL bounds, rect;
23 LONG lWidth;
24 PBRUSH pbrLine;
25
26 /* Get BRUSH from current pen. */
27 pbrLine = dc->dclevel.pbrLine;
28 ASSERT(pbrLine);
29
30 lWidth = 0;
31
32 // Setup bounds
33 bounds.left = bounds.top = INT_MAX;
34 bounds.right = bounds.bottom = INT_MIN;
35
36 if (((pbrLine->ulPenStyle & PS_TYPE_MASK) & PS_GEOMETRIC) || pbrLine->lWidth > 1)
37 {
38 /* Windows uses some heuristics to estimate the distance from the point that will be painted */
39 lWidth = pbrLine->lWidth + 2;
40 endcap = (PS_ENDCAP_MASK & pbrLine->ulPenStyle);
41 join = (PS_JOIN_MASK & pbrLine->ulPenStyle);
42 if (join == PS_JOIN_MITER)
43 {
44 lWidth *= 5;
45 if (endcap == PS_ENDCAP_SQUARE) lWidth = (lWidth * 3 + 1) / 2;
46 }
47 else
48 {
49 if (endcap == PS_ENDCAP_SQUARE) lWidth -= lWidth / 4;
50 else lWidth = (lWidth + 1) / 2;
51 }
52 }
53
54 while (count-- > 0)
55 {
56 rect.left = points->x - lWidth;
57 rect.top = points->y - lWidth;
58 rect.right = points->x + lWidth + 1;
59 rect.bottom = points->y + lWidth + 1;
60 RECTL_bUnionRect(&bounds, &bounds, &rect);
61 points++;
62 }
63
64 DPRINT("APLB dc %p l %d t %d\n",dc,rect.left,rect.top);
65 DPRINT(" r %d b %d\n",rect.right,rect.bottom);
66
67 {
68 RECTL rcRgn = dc->erclClip; // Use the clip box for now.
69
70 if (RECTL_bIntersectRect( &rcRgn, &rcRgn, &bounds ))
71 IntUpdateBoundsRect(dc, &rcRgn);
72 else
73 IntUpdateBoundsRect(dc, &bounds);
74 }
75}
VOID FASTCALL IntUpdateBoundsRect(PDC, PRECTL)
Definition: dcutil.c:694
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizei const GLfloat * points
Definition: glext.h:8112
#define INT_MIN
Definition: limits.h:39
#define INT_MAX
Definition: limits.h:40
static const WCHAR dc[]
LOCAL int join(int *aux, int a, int b)
Definition: match.c:560
#define ASSERT(a)
Definition: mode.c:44
long LONG
Definition: pedump.c:60
#define DPRINT
Definition: sndvol32.h:73
& rect
Definition: startmenu.cpp:1413
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
BOOL FASTCALL RECTL_bUnionRect(_Out_ RECTL *prclDst, _In_ const RECTL *prcl1, _In_ const RECTL *prcl2)
Definition: rect.c:18
BOOL FASTCALL RECTL_bIntersectRect(_Out_ RECTL *prclDst, _In_ const RECTL *prcl1, _In_ const RECTL *prcl2)
Definition: rect.c:55
#define PS_ENDCAP_SQUARE
Definition: wingdi.h:595
#define PS_GEOMETRIC
Definition: wingdi.h:583
#define PS_JOIN_MASK
Definition: wingdi.h:600
#define PS_JOIN_MITER
Definition: wingdi.h:598
#define PS_ENDCAP_MASK
Definition: wingdi.h:602
#define PS_TYPE_MASK
Definition: wingdi.h:603

Referenced by IntGdiLineTo(), and IntGdiPolyline().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( GdiLine  )

◆ GdiPolyDraw()

static BOOL GdiPolyDraw ( IN HDC  hdc,
IN LPPOINT  lppt,
IN LPBYTE  lpbTypes,
IN ULONG  cCount 
)
static

Definition at line 538 of file line.c.

543{
544 PDC dc;
545 PDC_ATTR pdcattr;
546 POINT bzr[4];
547 volatile PPOINT line_pts, line_pts_old, bzr_pts;
548 INT num_pts, num_bzr_pts, space, space_old, size;
549 ULONG i;
550 BOOL result = FALSE;
551
552 dc = DC_LockDc(hdc);
553 if (!dc) return FALSE;
554 pdcattr = dc->pdcattr;
555
556 if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
558
559 if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
561
562 if (!cCount)
563 {
565 return TRUE;
566 }
567
568 line_pts = NULL;
569 line_pts_old = NULL;
570 bzr_pts = NULL;
571
572 {
573 if (PATH_IsPathOpen(dc->dclevel))
574 {
575 result = PATH_PolyDraw(dc, (const POINT *)lppt, (const BYTE *)lpbTypes, cCount);
576 goto Cleanup;
577 }
578
579 /* Check for valid point types */
580 for (i = 0; i < cCount; i++)
581 {
582 switch (lpbTypes[i])
583 {
584 case PT_MOVETO:
586 case PT_LINETO:
587 break;
588 case PT_BEZIERTO:
589 if((i + 2 < cCount) && (lpbTypes[i + 1] == PT_BEZIERTO) &&
590 ((lpbTypes[i + 2] & ~PT_CLOSEFIGURE) == PT_BEZIERTO))
591 {
592 i += 2;
593 break;
594 }
595 default:
596 goto Cleanup;
597 }
598 }
599
600 space = cCount + 300;
601 line_pts = ExAllocatePoolWithTag(PagedPool, space * sizeof(POINT), TAG_SHAPE);
602 if (line_pts == NULL)
603 {
604 result = FALSE;
605 goto Cleanup;
606 }
607
608 num_pts = 1;
609
610 line_pts[0].x = pdcattr->ptlCurrent.x;
611 line_pts[0].y = pdcattr->ptlCurrent.y;
612
613 for ( i = 0; i < cCount; i++ )
614 {
615 switch (lpbTypes[i])
616 {
617 case PT_MOVETO:
618 if (num_pts >= 2) IntGdiPolyline( dc, line_pts, num_pts );
619 num_pts = 0;
620 line_pts[num_pts++] = lppt[i];
621 break;
622 case PT_LINETO:
623 case (PT_LINETO | PT_CLOSEFIGURE):
624 line_pts[num_pts++] = lppt[i];
625 break;
626 case PT_BEZIERTO:
627 bzr[0].x = line_pts[num_pts - 1].x;
628 bzr[0].y = line_pts[num_pts - 1].y;
629 RtlCopyMemory( &bzr[1], &lppt[i], 3 * sizeof(POINT) );
630
631 if ((bzr_pts = GDI_Bezier( bzr, 4, &num_bzr_pts )))
632 {
633 size = num_pts + (cCount - i) + num_bzr_pts;
634 if (space < size)
635 {
636 space_old = space;
637 space = size * 2;
638 line_pts_old = line_pts;
639 line_pts = ExAllocatePoolWithTag(PagedPool, space * sizeof(POINT), TAG_SHAPE);
640 if (!line_pts) goto Cleanup;
641 RtlCopyMemory(line_pts, line_pts_old, space_old * sizeof(POINT));
642 ExFreePoolWithTag(line_pts_old, TAG_SHAPE);
643 line_pts_old = NULL;
644 }
645 RtlCopyMemory( &line_pts[num_pts], &bzr_pts[1], (num_bzr_pts - 1) * sizeof(POINT) );
646 num_pts += num_bzr_pts - 1;
648 bzr_pts = NULL;
649 }
650 i += 2;
651 break;
652 }
653 if (lpbTypes[i] & PT_CLOSEFIGURE) line_pts[num_pts++] = line_pts[0];
654 }
655
656 if (num_pts >= 2) IntGdiPolyline( dc, line_pts, num_pts );
657 IntGdiMoveToEx( dc, line_pts[num_pts - 1].x, line_pts[num_pts - 1].y, NULL );
658 result = TRUE;
659 }
660
661Cleanup:
662
663 if (line_pts != NULL)
664 {
665 ExFreePoolWithTag(line_pts, TAG_SHAPE);
666 }
667
668 if ((line_pts_old != NULL) && (line_pts_old != line_pts))
669 {
670 ExFreePoolWithTag(line_pts_old, TAG_SHAPE);
671 }
672
673 if (bzr_pts != NULL)
674 {
676 }
677
679
680 return result;
681}
POINT * GDI_Bezier(const POINT *Points, INT count, INT *nPtsOut)
Definition: bezier.c:189
VOID FASTCALL DC_vUpdateLineBrush(PDC pdc)
Definition: dcobjs.c:62
VOID FASTCALL DC_vUpdateFillBrush(PDC pdc)
Definition: dcobjs.c:16
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
static const WCHAR Cleanup[]
Definition: register.c:80
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
GLsizeiptr size
Definition: glext.h:5919
GLuint64EXT * result
Definition: glext.h:11304
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 ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#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
#define PATH_IsPathOpen(dclevel)
Definition: path.h:72
POINTL ptlCurrent
Definition: ntgdihdl.h:311
ULONG ulDirty_
Definition: ntgdihdl.h:294
LONG y
Definition: windef.h:330
LONG x
Definition: windef.h:329
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
BOOL FASTCALL IntGdiPolyline(DC *dc, LPPOINT pt, int Count)
Definition: line.c:327
BOOL FASTCALL PATH_PolyDraw(PDC dc, const POINT *pts, const BYTE *types, DWORD cbPoints)
Definition: path.c:1180
#define TAG_SHAPE
Definition: tags.h:14
#define TAG_BEZIER
Definition: tags.h:13
#define PT_LINETO
Definition: wingdi.h:885
#define PT_CLOSEFIGURE
Definition: wingdi.h:887
#define PT_MOVETO
Definition: wingdi.h:884
#define PT_BEZIERTO
Definition: wingdi.h:886
unsigned char BYTE
Definition: xxhash.c:193

Referenced by NtGdiPolyDraw().

◆ GreMoveTo()

BOOL FASTCALL GreMoveTo ( HDC  hdc,
INT  x,
INT  y,
LPPOINT  pptOut 
)

Definition at line 110 of file line.c.

114{
115 BOOL Ret;
116 PDC dc;
117 if (!(dc = DC_LockDc(hdc)))
118 {
120 return FALSE;
121 }
122 Ret = IntGdiMoveToEx(dc, x, y, pptOut);
124 return Ret;
125}
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:22

Referenced by IntDrawDiagEdge(), IntDrawMenuBarTemp(), IntDrawRectEdge(), MENU_DrawMenuItem(), NC_DoNCPaint(), TEXT_DrawUnderscore(), and UserDrawCaptionBar().

◆ IntGdiLineTo()

BOOL FASTCALL IntGdiLineTo ( DC dc,
int  XEnd,
int  YEnd 
)

Definition at line 148 of file line.c.

151{
152 SURFACE *psurf;
153 BOOL Ret = TRUE;
154 PBRUSH pbrLine;
155 RECTL Bounds;
156 POINT Points[2];
157 PDC_ATTR pdcattr;
158 PPATH pPath;
159
161
162 pdcattr = dc->pdcattr;
163
164 if (PATH_IsPathOpen(dc->dclevel))
165 {
166 Ret = PATH_LineTo(dc, XEnd, YEnd);
167 }
168 else
169 {
170 psurf = dc->dclevel.pSurface;
171 if (NULL == psurf)
172 {
174 return FALSE;
175 }
176
177 Points[0].x = pdcattr->ptlCurrent.x;
178 Points[0].y = pdcattr->ptlCurrent.y;
179 Points[1].x = XEnd;
180 Points[1].y = YEnd;
181
182 IntLPtoDP(dc, Points, 2);
183
184 /* The DCOrg is in device coordinates */
185 Points[0].x += dc->ptlDCOrig.x;
186 Points[0].y += dc->ptlDCOrig.y;
187 Points[1].x += dc->ptlDCOrig.x;
188 Points[1].y += dc->ptlDCOrig.y;
189
190 Bounds.left = min(Points[0].x, Points[1].x);
191 Bounds.top = min(Points[0].y, Points[1].y);
192 Bounds.right = max(Points[0].x, Points[1].x);
193 Bounds.bottom = max(Points[0].y, Points[1].y);
194
195 /* Get BRUSH from current pen. */
196 pbrLine = dc->dclevel.pbrLine;
197 ASSERT(pbrLine);
198
199 if (dc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR))
200 {
201 DPRINT("Bounds dc %p l %d t %d\n",dc,Bounds.left,Bounds.top);
202 DPRINT(" r %d b %d\n",Bounds.right,Bounds.bottom);
203 AddPenLinesBounds(dc, 2, Points);
204 }
205
206 if (!(pbrLine->flAttrs & BR_IS_NULL))
207 {
208 if (IntIsEffectiveWidePen(pbrLine))
209 {
210 /* Clear the path */
211 PATH_Delete(dc->dclevel.hPath);
212 dc->dclevel.hPath = NULL;
213
214 /* Begin a path */
215 pPath = PATH_CreatePath(2);
216 dc->dclevel.flPath |= DCPATH_ACTIVE;
217 dc->dclevel.hPath = pPath->BaseObject.hHmgr;
219 IntLPtoDP(dc, &pPath->pos, 1);
220
221 PATH_MoveTo(dc, pPath);
222 PATH_LineTo(dc, XEnd, YEnd);
223
224 /* Close the path */
225 pPath->state = PATH_Closed;
226 dc->dclevel.flPath &= ~DCPATH_ACTIVE;
227
228 /* Actually stroke a path */
229 Ret = PATH_StrokePath(dc, pPath);
230
231 /* Clear the path */
232 PATH_UnlockPath(pPath);
233 PATH_Delete(dc->dclevel.hPath);
234 dc->dclevel.hPath = NULL;
235 }
236 else
237 {
238 Ret = IntEngLineTo(&psurf->SurfObj,
239 (CLIPOBJ *)&dc->co,
240 &dc->eboLine.BrushObject,
241 Points[0].x, Points[0].y,
242 Points[1].x, Points[1].y,
243 &Bounds,
244 ROP2_TO_MIX(pdcattr->jROP2));
245 }
246 }
247 }
248
249 if (Ret)
250 {
251 pdcattr->ptlCurrent.x = XEnd;
252 pdcattr->ptlCurrent.y = YEnd;
253 pdcattr->ptfxCurrent = pdcattr->ptlCurrent;
254 CoordLPtoDP(dc, &pdcattr->ptfxCurrent); // Update fx
256 }
257
258 return Ret;
259}
HGDIOBJ hHmgr(VOID)
Definition: baseobj.hpp:95
#define CoordLPtoDP(pdc, ppt)
Definition: coord.h:187
static BOOLEAN IntLPtoDP(DC *pdc, PPOINTL ppt, UINT count)
Definition: coord.h:182
#define ASSERT_DC_PREPARED(pdc)
Definition: dc.h:300
@ DC_ACCUM_APP
Definition: dc.h:25
@ DC_ACCUM_WMGR
Definition: dc.h:24
#define BR_IS_NULL
Definition: brush.h:105
#define ROP2_TO_MIX(Rop2)
Definition: inteng.h:40
#define min(a, b)
Definition: monoChain.cc:55
#define DIRTY_PTLCURRENT
Definition: ntgdihdl.h:131
#define DIRTY_STYLESTATE
Definition: ntgdihdl.h:133
#define DIRTY_PTFXCURRENT
Definition: ntgdihdl.h:132
#define PATH_UnlockPath(pPath)
Definition: path.h:71
@ PATH_Closed
Definition: path.h:20
@ DCPATH_ACTIVE
Definition: path.h:6
#define IntIsEffectiveWidePen(pbrLine)
Definition: pen.h:33
void IntEngLineTo(SURFOBJ *, CLIPOBJ, PBRUSHOBJ, int x1, int y1, int x2, int y2, RECTL *, MIX mix)
Definition: polytest.cpp:107
POINTL ptfxCurrent
Definition: ntgdihdl.h:312
BYTE jROP2
Definition: ntgdihdl.h:307
Definition: path.h:35
POINT pos
Definition: path.h:58
BASEOBJECT BaseObject
Definition: path.h:36
FLONG state
Definition: path.h:52
SURFOBJ SurfObj
Definition: surface.h:8
#define max(a, b)
Definition: svc.c:63
VOID FASTCALL IntGetCurrentPositionEx(PDC dc, LPPOINT pt)
Definition: line.c:130
VOID FASTCALL AddPenLinesBounds(PDC dc, int count, POINT *points)
Definition: line.c:19
BOOL FASTCALL PATH_Delete(HPATH hPath)
Definition: path.c:90
BOOL FASTCALL PATH_LineTo(PDC dc, INT x, INT y)
Definition: path.c:583
BOOL FASTCALL PATH_StrokePath(DC *dc, PPATH pPath)
Definition: path.c:1597
PPATH FASTCALL PATH_CreatePath(int count)
Definition: path.c:35
BOOL FASTCALL PATH_MoveTo(PDC dc, PPATH pPath)
Definition: path.c:554

Referenced by IntGdiArcInternal(), and NtGdiLineTo().

◆ IntGdiMoveToEx()

BOOL FASTCALL IntGdiMoveToEx ( DC dc,
int  X,
int  Y,
LPPOINT  Point 
)

Definition at line 80 of file line.c.

84{
85 PDC_ATTR pdcattr = dc->pdcattr;
86 if ( Point )
87 {
88 if ( pdcattr->ulDirty_ & DIRTY_PTLCURRENT ) // Double hit!
89 {
90 Point->x = pdcattr->ptfxCurrent.x; // ret prev before change.
91 Point->y = pdcattr->ptfxCurrent.y;
92 IntDPtoLP ( dc, Point, 1); // Reconvert back.
93 }
94 else
95 {
96 Point->x = pdcattr->ptlCurrent.x;
97 Point->y = pdcattr->ptlCurrent.y;
98 }
99 }
100 pdcattr->ptlCurrent.x = X;
101 pdcattr->ptlCurrent.y = Y;
102 pdcattr->ptfxCurrent = pdcattr->ptlCurrent;
103 CoordLPtoDP(dc, &pdcattr->ptfxCurrent); // Update fx
105
106 return TRUE;
107}
static BOOLEAN IntDPtoLP(DC *pdc, PPOINTL ppt, UINT count)
Definition: coord.h:192
#define Y(I)
#define X(b, s)

Referenced by _Success_(), add_log_points_new_stroke(), GdiPolyDraw(), GreMoveTo(), IntGdiAngleArc(), IntGdiArcInternal(), PATH_PolyDraw(), and PATH_StrokePath().

◆ IntGdiPolyBezier()

BOOL FASTCALL IntGdiPolyBezier ( DC dc,
LPPOINT  pt,
DWORD  Count 
)

Definition at line 262 of file line.c.

265{
266 BOOL ret = FALSE; // Default to FAILURE
267
268 if ( PATH_IsPathOpen(dc->dclevel) )
269 {
270 return PATH_PolyBezier ( dc, pt, Count );
271 }
272
273 /* We'll convert it into line segments and draw them using Polyline */
274 {
275 POINT *Pts;
276 INT nOut;
277
278 Pts = GDI_Bezier ( pt, Count, &nOut );
279 if ( Pts )
280 {
281 ret = IntGdiPolyline(dc, Pts, nOut);
283 }
284 }
285
286 return ret;
287}
#define pt(x, y)
Definition: drawing.c:79
int Count
Definition: noreturn.cpp:7
int ret
BOOL FASTCALL PATH_PolyBezier(PDC dc, const POINT *pts, DWORD cbPoints)
Definition: path.c:1154

Referenced by IntGdiPolyBezierTo(), and NtGdiPolyPolyDraw().

◆ IntGdiPolyBezierTo()

BOOL FASTCALL IntGdiPolyBezierTo ( DC dc,
LPPOINT  pt,
DWORD  Count 
)

Definition at line 290 of file line.c.

293{
294 BOOL ret = FALSE; // Default to failure
295 PDC_ATTR pdcattr = dc->pdcattr;
296
297 if ( PATH_IsPathOpen(dc->dclevel) )
299 else /* We'll do it using PolyBezier */
300 {
301 POINT *npt;
303 sizeof(POINT) * (Count + 1),
304 TAG_BEZIER);
305 if ( npt )
306 {
307 npt[0].x = pdcattr->ptlCurrent.x;
308 npt[0].y = pdcattr->ptlCurrent.y;
309 memcpy(npt + 1, pt, sizeof(POINT) * Count);
310 ret = IntGdiPolyBezier(dc, npt, Count+1);
312 }
313 }
314 if ( ret )
315 {
316 pdcattr->ptlCurrent.x = pt[Count-1].x;
317 pdcattr->ptlCurrent.y = pt[Count-1].y;
318 pdcattr->ptfxCurrent = pdcattr->ptlCurrent;
319 CoordLPtoDP(dc, &pdcattr->ptfxCurrent); // Update fx
321 }
322
323 return ret;
324}
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
BOOL FASTCALL IntGdiPolyBezier(DC *dc, LPPOINT pt, DWORD Count)
Definition: line.c:262
BOOL FASTCALL PATH_PolyBezierTo(PDC dc, const POINT *pts, DWORD cbPoints)
Definition: path.c:1131

Referenced by NtGdiPolyPolyDraw().

◆ IntGdiPolyline()

BOOL FASTCALL IntGdiPolyline ( DC dc,
LPPOINT  pt,
int  Count 
)

Definition at line 327 of file line.c.

330{
331 SURFACE *psurf;
332 BRUSH *pbrLine;
333 LPPOINT Points;
334 BOOL Ret = TRUE;
335 LONG i;
336 PDC_ATTR pdcattr = dc->pdcattr;
337 PPATH pPath;
338
339 if (!dc->dclevel.pSurface)
340 {
341 return TRUE;
342 }
343
345 psurf = dc->dclevel.pSurface;
346
347 /* Get BRUSHOBJ from current pen. */
348 pbrLine = dc->dclevel.pbrLine;
349 ASSERT(pbrLine);
350
351 if (!(pbrLine->flAttrs & BR_IS_NULL))
352 {
353 Points = EngAllocMem(0, Count * sizeof(POINT), GDITAG_TEMP);
354 if (Points != NULL)
355 {
356 RtlCopyMemory(Points, pt, Count * sizeof(POINT));
357 IntLPtoDP(dc, Points, Count);
358
359 /* Offset the array of points by the DC origin */
360 for (i = 0; i < Count; i++)
361 {
362 Points[i].x += dc->ptlDCOrig.x;
363 Points[i].y += dc->ptlDCOrig.y;
364 }
365
366 if (dc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR))
367 {
368 AddPenLinesBounds(dc, Count, Points);
369 }
370
371 if (IntIsEffectiveWidePen(pbrLine))
372 {
373 /* Clear the path */
374 PATH_Delete(dc->dclevel.hPath);
375 dc->dclevel.hPath = NULL;
376
377 /* Begin a path */
378 pPath = PATH_CreatePath(Count);
379 dc->dclevel.flPath |= DCPATH_ACTIVE;
380 dc->dclevel.hPath = pPath->BaseObject.hHmgr;
381 pPath->pos = pt[0];
382 IntLPtoDP(dc, &pPath->pos, 1);
383
384 PATH_MoveTo(dc, pPath);
385 for (i = 1; i < Count; ++i)
386 {
387 PATH_LineTo(dc, pt[i].x, pt[i].y);
388 }
389
390 /* Close the path */
391 pPath->state = PATH_Closed;
392 dc->dclevel.flPath &= ~DCPATH_ACTIVE;
393
394 /* Actually stroke a path */
395 Ret = PATH_StrokePath(dc, pPath);
396
397 /* Clear the path */
398 PATH_UnlockPath(pPath);
399 PATH_Delete(dc->dclevel.hPath);
400 dc->dclevel.hPath = NULL;
401 }
402 else
403 {
404 Ret = IntEngPolyline(&psurf->SurfObj,
405 (CLIPOBJ *)&dc->co,
406 &dc->eboLine.BrushObject,
407 Points,
408 Count,
409 ROP2_TO_MIX(pdcattr->jROP2));
410 }
411 EngFreeMem(Points);
412 }
413 else
414 {
415 Ret = FALSE;
416 }
417 }
418
420
421 return Ret;
422}
Definition: brush.hpp:16
VOID FASTCALL DC_vPrepareDCsForBlit(PDC pdcDest, const RECT *rcDest, PDC pdcSrc, const RECT *rcSrc)
Definition: dclife.c:505
VOID FASTCALL DC_vFinishBlit(PDC pdc1, PDC pdc2)
Definition: dclife.c:614
BOOL APIENTRY IntEngPolyline(SURFOBJ *DestSurf, CLIPOBJ *Clip, BRUSHOBJ *Brush, CONST LPPOINT pt, LONG dCount, MIX mix)
Definition: lineto.c:703
#define EngFreeMem
Definition: polytest.cpp:56
void * EngAllocMem(int zero, unsigned long size, int tag=0)
Definition: polytest.cpp:70
ULONG flAttrs
Definition: brush.h:19
#define GDITAG_TEMP
Definition: tags.h:167

Referenced by GdiPolyDraw(), IntGdiPolyBezier(), IntGdiPolylineTo(), IntGdiPolyPolyline(), and PATH_StrokePath().

◆ IntGdiPolylineTo()

BOOL FASTCALL IntGdiPolylineTo ( DC dc,
LPPOINT  pt,
DWORD  Count 
)

Definition at line 425 of file line.c.

428{
429 BOOL ret = FALSE; // Default to failure
430 PDC_ATTR pdcattr = dc->pdcattr;
431
432 if (PATH_IsPathOpen(dc->dclevel))
433 {
435 }
436 else /* Do it using Polyline */
437 {
439 sizeof(POINT) * (Count + 1),
440 TAG_SHAPE);
441 if ( pts )
442 {
443 pts[0].x = pdcattr->ptlCurrent.x;
444 pts[0].y = pdcattr->ptlCurrent.y;
445 memcpy( pts + 1, pt, sizeof(POINT) * Count);
446 ret = IntGdiPolyline(dc, pts, Count + 1);
448 }
449 }
450 if ( ret )
451 {
452 pdcattr->ptlCurrent.x = pt[Count-1].x;
453 pdcattr->ptlCurrent.y = pt[Count-1].y;
454 pdcattr->ptfxCurrent = pdcattr->ptlCurrent;
455 CoordLPtoDP(dc, &pdcattr->ptfxCurrent); // Update fx
457 }
458
459 return ret;
460}
BOOL FASTCALL PATH_PolylineTo(PDC dc, const POINT *pts, DWORD cbPoints)
Definition: path.c:1264

Referenced by NtGdiPolyPolyDraw().

◆ IntGdiPolyPolyline()

BOOL FASTCALL IntGdiPolyPolyline ( DC dc,
LPPOINT  pt,
PULONG  PolyPoints,
DWORD  Count 
)

Definition at line 464 of file line.c.

468{
469 ULONG i;
470 LPPOINT pts;
471 PULONG pc;
472 BOOL ret = FALSE; // Default to failure
473 pts = pt;
474 pc = PolyPoints;
475
476 if (PATH_IsPathOpen(dc->dclevel))
477 {
478 return PATH_PolyPolyline( dc, pt, PolyPoints, Count );
479 }
480 for (i = 0; i < Count; i++)
481 {
482 ret = IntGdiPolyline ( dc, pts, *pc );
483 if (ret == FALSE)
484 {
485 return ret;
486 }
487 pts+=*pc++;
488 }
489
490 return ret;
491}
uint32_t * PULONG
Definition: typedefs.h:59
BOOL FASTCALL PATH_PolyPolyline(PDC dc, const POINT *pts, const DWORD *counts, DWORD polylines)
Definition: path.c:1338

Referenced by NtGdiPolyPolyDraw().

◆ IntGetCurrentPositionEx()

VOID FASTCALL IntGetCurrentPositionEx ( PDC  dc,
LPPOINT  pt 
)

Definition at line 130 of file line.c.

131{
132 PDC_ATTR pdcattr = dc->pdcattr;
133
134 if ( pt )
135 {
136 if (pdcattr->ulDirty_ & DIRTY_PTFXCURRENT)
137 {
138 pdcattr->ptfxCurrent = pdcattr->ptlCurrent;
139 CoordLPtoDP(dc, &pdcattr->ptfxCurrent); // Update fx
141 }
142 pt->x = pdcattr->ptlCurrent.x;
143 pt->y = pdcattr->ptlCurrent.y;
144 }
145}

Referenced by IntGdiLineTo(), NtGdiBeginPath(), PATH_Arc(), PATH_LineTo(), PATH_MoveTo(), PATH_PolyDraw(), and PATH_StrokePath().

◆ NtGdiLineTo()

BOOL APIENTRY NtGdiLineTo ( HDC  hDC,
int  XEnd,
int  YEnd 
)

Definition at line 497 of file line.c.

500{
501 DC *dc;
502 BOOL Ret;
503 RECT rcLockRect ;
504
505 dc = DC_LockDc(hDC);
506 if (!dc)
507 {
509 return FALSE;
510 }
511
512 rcLockRect.left = dc->pdcattr->ptlCurrent.x;
513 rcLockRect.top = dc->pdcattr->ptlCurrent.y;
514 rcLockRect.right = XEnd;
515 rcLockRect.bottom = YEnd;
516
517 IntLPtoDP(dc, (PPOINT)&rcLockRect, 2);
518
519 /* The DCOrg is in device coordinates */
520 rcLockRect.left += dc->ptlDCOrig.x;
521 rcLockRect.top += dc->ptlDCOrig.y;
522 rcLockRect.right += dc->ptlDCOrig.x;
523 rcLockRect.bottom += dc->ptlDCOrig.y;
524
525 DC_vPrepareDCsForBlit(dc, &rcLockRect, NULL, NULL);
526
527 Ret = IntGdiLineTo(dc, XEnd, YEnd);
528
530
532 return Ret;
533}
static HDC hDC
Definition: 3dtext.c:33
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
BOOL FASTCALL IntGdiLineTo(DC *dc, int XEnd, int YEnd)
Definition: line.c:148

◆ NtGdiPolyDraw()

__kernel_entry W32KAPI BOOL APIENTRY NtGdiPolyDraw ( _In_ HDC  hdc,
_In_reads_(cpt) LPPOINT  ppt,
_In_reads_(cpt) LPBYTE  pjAttr,
_In_ ULONG  cpt 
)

Definition at line 687 of file line.c.

692{
693 PBYTE pjBuffer;
694 PPOINT pptSafe;
695 PBYTE pjSafe;
696 SIZE_T cjSizePt;
697 BOOL bResult;
698
699 if (cpt == 0)
700 {
701 ERR("cpt is 0\n");
702 return FALSE;
703 }
704
705 /* Validate that cpt isn't too large */
706 if (cpt > ((MAXULONG - cpt) / sizeof(*ppt)))
707 {
708 ERR("cpt is too large\n", cpt);
709 return FALSE;
710 }
711
712 /* Calculate size for a buffer */
713 cjSizePt = cpt * sizeof(*ppt);
714 ASSERT(cjSizePt + cpt > cjSizePt);
715
716 /* Allocate a buffer for all data */
717 pjBuffer = ExAllocatePoolWithTag(PagedPool, cjSizePt + cpt, TAG_SHAPE);
718 if (pjBuffer == NULL)
719 {
720 ERR("Failed to allocate buffer\n");
721 return FALSE;
722 }
723
724 pptSafe = (PPOINT)pjBuffer;
725 pjSafe = pjBuffer + cjSizePt;
726
728 {
729 ProbeArrayForRead(ppt, sizeof(*ppt), cpt, sizeof(ULONG));
730 ProbeArrayForRead(pjAttr, sizeof(*pjAttr), cpt, sizeof(BYTE));
731
732 /* Copy the arrays */
733 RtlCopyMemory(pptSafe, ppt, cjSizePt);
734 RtlCopyMemory(pjSafe, pjAttr, cpt);
735 }
737 {
739 bResult = FALSE;
740 goto Cleanup;
741 }
742 _SEH2_END;
743
744 /* Call the internal function */
745 bResult = GdiPolyDraw(hdc, pptSafe, pjSafe, cpt);
746
747Cleanup:
748
749 /* Free the buffer */
750 ExFreePoolWithTag(pjBuffer, TAG_SHAPE);
751
752 return bResult;
753}
#define ERR(fmt,...)
Definition: precomp.h:57
BYTE * PBYTE
Definition: pedump.c:66
#define MAXULONG
Definition: typedefs.h:251
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define PPOINT
Definition: precomp.h:32
static BOOL GdiPolyDraw(IN HDC hdc, IN LPPOINT lppt, IN LPBYTE lpbTypes, IN ULONG cCount)
Definition: line.c:538

Referenced by PolyDraw().