ReactOS 0.4.17-dev-116-ga4b6fe9
path.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _EXTPATHDATA
 
struct  _PATH
 
struct  _EPATHOBJ
 

Macros

#define PATHTYPE_KEEPME   1
 
#define PATHTYPE_STACK   2
 
#define PATH_AllocPath()   ((PPATH) GDIOBJ_AllocObj(GDIObjType_PATH_TYPE))
 
#define PATH_AllocPathWithHandle()   ((PPATH) GDIOBJ_AllocObjWithHandle (GDI_OBJECT_TYPE_PATH, sizeof(PATH)))
 
#define PATH_LockPath(hPath)   ((PPATH)GDIOBJ_ShareLockObj((HGDIOBJ)hPath, GDI_OBJECT_TYPE_PATH))
 
#define PATH_UnlockPath(pPath)   GDIOBJ_vDereferenceObject((POBJ)pPath)
 
#define PATH_IsPathOpen(dclevel)   ( ((dclevel).hPath) && ((dclevel).flPath & DCPATH_ACTIVE) )
 

Typedefs

typedef HGDIOBJ HPATH
 
typedef HGDIOBJPHPATH
 
typedef enum tagGdiPathState GdiPathState
 
typedef struct _EXTPATHDATA EXTPATHDATA
 
typedef struct _EXTPATHDATAPEXTPATHDATA
 
typedef struct _PATH PATH
 
typedef struct _PATHPPATH
 
typedef struct _EPATHOBJ EPATHOBJ
 
typedef struct _EPATHOBJPEPATHOBJ
 

Enumerations

enum  _DCPATHFLAGS { DCPATH_ACTIVE = 0x0001 , DCPATH_SAVE = 0x0002 , DCPATH_CLOCKWISE = 0x0004 , DCPATH_SAVESTATE = 0x80000000 }
 
enum  tagGdiPathState { PATH_Null , PATH_Open , PATH_Closed }
 

Functions

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)
 
BOOL PATH_Ellipse (PDC dc, INT x1, INT y1, INT x2, INT y2)
 
PPATH FASTCALL PATH_CreatePath (int count)
 
VOID FASTCALL PATH_EmptyPath (PPATH pPath)
 
BOOL FASTCALL PATH_LineTo (PDC dc, INT x, INT y)
 
BOOL FASTCALL PATH_MoveTo (PDC dc, PPATH pPath)
 
BOOL FASTCALL PATH_PolyBezier (PDC dc, const POINT *pts, DWORD cbPoints)
 
BOOL FASTCALL PATH_PolyBezierTo (PDC dc, const POINT *pts, DWORD cbPoints)
 
BOOL FASTCALL PATH_PolyDraw (PDC dc, const POINT *pts, const BYTE *types, DWORD cbPoints)
 
BOOL FASTCALL PATH_PolylineTo (PDC dc, const POINT *pts, DWORD cbPoints)
 
BOOL FASTCALL PATH_PolyPolygon (PDC dc, const POINT *pts, const INT *counts, UINT polygons)
 
BOOL FASTCALL PATH_PolyPolyline (PDC dc, const POINT *pts, const DWORD *counts, DWORD polylines)
 
BOOL FASTCALL PATH_Rectangle (PDC dc, INT x1, INT y1, INT x2, INT y2)
 
BOOL PATH_RoundRect (DC *dc, INT x1, INT y1, INT x2, INT y2, INT ell_width, INT ell_height)
 
BOOL FASTCALL PATH_PathToRegion (PPATH pPath, INT nPolyFillMode, PREGION Rgn)
 
BOOL FASTCALL PATH_ExtTextOut (PDC dc, INT x, INT y, UINT flags, const RECTL *lprc, LPCWSTR str, UINT count, const INT *dx)
 
BOOL FASTCALL PATH_AddEntry (PPATH pPath, const POINT *pPoint, BYTE flags)
 
BOOL FASTCALL PATH_AddFlatBezier (PPATH pPath, POINT *pt, BOOL closed)
 
BOOL FASTCALL PATH_FillPath (PDC dc, PPATH pPath)
 
BOOL FASTCALL PATH_FillPathEx (PDC dc, PPATH pPath, PBRUSH pbrFill)
 
PPATH FASTCALL PATH_FlattenPath (PPATH pPath)
 
PPATH FASTCALL PATH_WidenPathEx (DC *dc, PPATH pPath)
 
BOOL FASTCALL PATH_ReserveEntries (PPATH pPath, INT numEntries)
 
BOOL FASTCALL PATH_StrokePath (DC *dc, PPATH pPath)
 
VOID FASTCALL IntGdiCloseFigure (PPATH pPath)
 
BOOL FASTCALL PATH_Delete (HPATH hPath)
 
VOID FASTCALL IntGetCurrentPositionEx (PDC dc, LPPOINT pt)
 
BOOL PATH_RestorePath (DC *, DC *)
 
BOOL PATH_SavePath (DC *, DC *)
 
BOOL IntGdiFillRgn (PDC pdc, PREGION prgn, PBRUSH pbrFill)
 
PPATH FASTCALL IntGdiWidenPath (PPATH pPath, UINT penWidth, UINT penStyle, FLOAT eMiterLimit)
 

Macro Definition Documentation

◆ PATH_AllocPath

#define PATH_AllocPath ( )    ((PPATH) GDIOBJ_AllocObj(GDIObjType_PATH_TYPE))

Definition at line 68 of file path.h.

◆ PATH_AllocPathWithHandle

#define PATH_AllocPathWithHandle ( )    ((PPATH) GDIOBJ_AllocObjWithHandle (GDI_OBJECT_TYPE_PATH, sizeof(PATH)))

Definition at line 69 of file path.h.

◆ PATH_IsPathOpen

#define PATH_IsPathOpen (   dclevel)    ( ((dclevel).hPath) && ((dclevel).flPath & DCPATH_ACTIVE) )

Definition at line 72 of file path.h.

◆ PATH_LockPath

#define PATH_LockPath (   hPath)    ((PPATH)GDIOBJ_ShareLockObj((HGDIOBJ)hPath, GDI_OBJECT_TYPE_PATH))

Definition at line 70 of file path.h.

◆ PATH_UnlockPath

#define PATH_UnlockPath (   pPath)    GDIOBJ_vDereferenceObject((POBJ)pPath)

Definition at line 71 of file path.h.

◆ PATHTYPE_KEEPME

#define PATHTYPE_KEEPME   1

Definition at line 24 of file path.h.

◆ PATHTYPE_STACK

#define PATHTYPE_STACK   2

Definition at line 25 of file path.h.

Typedef Documentation

◆ EPATHOBJ

◆ EXTPATHDATA

◆ GdiPathState

◆ HPATH

typedef HGDIOBJ HPATH

Definition at line 14 of file path.h.

◆ PATH

typedef struct _PATH PATH

◆ PEPATHOBJ

◆ PEXTPATHDATA

◆ PHPATH

typedef HGDIOBJ * PHPATH

Definition at line 14 of file path.h.

◆ PPATH

typedef struct _PATH * PPATH

Enumeration Type Documentation

◆ _DCPATHFLAGS

Enumerator
DCPATH_ACTIVE 
DCPATH_SAVE 
DCPATH_CLOCKWISE 
DCPATH_SAVESTATE 

Definition at line 4 of file path.h.

5{
6 DCPATH_ACTIVE = 0x0001,
7 DCPATH_SAVE = 0x0002,
8 DCPATH_CLOCKWISE = 0x0004,
9
10 /* ReactOS only */
11 DCPATH_SAVESTATE = 0x80000000
12};
@ DCPATH_SAVE
Definition: path.h:7
@ DCPATH_SAVESTATE
Definition: path.h:11
@ DCPATH_CLOCKWISE
Definition: path.h:8
@ DCPATH_ACTIVE
Definition: path.h:6

◆ tagGdiPathState

Enumerator
PATH_Null 
PATH_Open 
PATH_Closed 

Definition at line 16 of file path.h.

17{
@ PATH_Null
Definition: path.h:18
@ PATH_Open
Definition: path.h:19
@ PATH_Closed
Definition: path.h:20
enum tagGdiPathState GdiPathState

Function Documentation

◆ IntGdiCloseFigure()

VOID FASTCALL IntGdiCloseFigure ( PPATH  pPath)

Definition at line 108 of file path.c.

109{
110 ASSERT(pPath->state == PATH_Open);
111
112 // FIXME: Shouldn't we draw a line to the beginning of the figure?
113 // Set PT_CLOSEFIGURE on the last entry and start a new stroke
114 if (pPath->numEntriesUsed)
115 {
116 pPath->pFlags[pPath->numEntriesUsed - 1] |= PT_CLOSEFIGURE;
117 pPath->newStroke = TRUE;
118 }
119}
#define TRUE
Definition: types.h:120
#define ASSERT(a)
Definition: mode.c:44
BOOL newStroke
Definition: path.h:57
FLONG state
Definition: path.h:52
BYTE * pFlags
Definition: path.h:54
int numEntriesUsed
Definition: path.h:55
#define PT_CLOSEFIGURE
Definition: wingdi.h:887

Referenced by NtGdiCloseFigure(), PATH_add_outline(), PATH_Arc(), PATH_Ellipse(), PATH_Rectangle(), and PATH_RoundRect().

◆ IntGdiFillRgn()

BOOL IntGdiFillRgn ( PDC  pdc,
PREGION  prgn,
PBRUSH  pbrFill 
)

◆ IntGdiWidenPath()

PPATH FASTCALL IntGdiWidenPath ( PPATH  pPath,
UINT  penWidth,
UINT  penStyle,
FLOAT  eMiterLimit 
)

Definition at line 1802 of file path.c.

1803{
1804 INT i, j, numStrokes, numOldStrokes, penWidthIn, penWidthOut;
1805 PPATH flat_path, pNewPath = NULL, *pStrokes = NULL, *pOldStrokes, pUpPath, pDownPath;
1806 BYTE *type;
1807 DWORD joint, endcap;
1808 KFLOATING_SAVE fpsave;
1809
1810 endcap = (PS_ENDCAP_MASK & penStyle);
1811 joint = (PS_JOIN_MASK & penStyle);
1812
1813 if (!(flat_path = PATH_FlattenPath(pPath)))
1814 {
1815 ERR("PATH_FlattenPath\n");
1816 return NULL;
1817 }
1818
1819 penWidthIn = penWidth / 2;
1820 penWidthOut = penWidth / 2;
1821 if (penWidthIn + penWidthOut < penWidth)
1822 penWidthOut++;
1823
1824 numStrokes = 0;
1825
1826 for (i = 0, j = 0; i < flat_path->numEntriesUsed; i++, j++)
1827 {
1828 POINT point;
1829 if ((i == 0 || (flat_path->pFlags[i - 1] & PT_CLOSEFIGURE)) &&
1830 (flat_path->pFlags[i] != PT_MOVETO))
1831 {
1832 ERR("Expected PT_MOVETO %s, got path flag %c\n",
1833 i == 0 ? "as first point" : "after PT_CLOSEFIGURE",
1834 flat_path->pFlags[i]);
1835 goto Exit;
1836 }
1837 switch(flat_path->pFlags[i])
1838 {
1839 case PT_MOVETO:
1840 if (numStrokes > 0)
1841 {
1842 pStrokes[numStrokes - 1]->state = PATH_Closed;
1843 }
1844 numOldStrokes = numStrokes;
1845 numStrokes++;
1846 j = 0;
1847 if (numStrokes == 1)
1848 pStrokes = ExAllocatePoolWithTag(PagedPool, sizeof(*pStrokes), TAG_PATH);
1849 else
1850 {
1851 pOldStrokes = pStrokes; // Save old pointer.
1852 pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes * sizeof(*pStrokes), TAG_PATH);
1853 if (!pStrokes)
1854 {
1855 ExFreePoolWithTag(pOldStrokes, TAG_PATH);
1856 goto Exit;
1857 }
1858 RtlCopyMemory(pStrokes, pOldStrokes, numOldStrokes * sizeof(PPATH));
1859 ExFreePoolWithTag(pOldStrokes, TAG_PATH); // Free old pointer.
1860 }
1861 if (!pStrokes)
1862 {
1863 goto Exit;
1864 }
1865 pStrokes[numStrokes - 1] = ExAllocatePoolWithTag(PagedPool, sizeof(PATH), TAG_PATH);
1866 if (!pStrokes[numStrokes - 1])
1867 {
1868 ASSERT(FALSE); // FIXME
1869 }
1870 PATH_InitGdiPath(pStrokes[numStrokes - 1]);
1871 pStrokes[numStrokes - 1]->state = PATH_Open;
1872 case PT_LINETO:
1873 case (PT_LINETO | PT_CLOSEFIGURE):
1874 point.x = flat_path->pPoints[i].x;
1875 point.y = flat_path->pPoints[i].y;
1876 PATH_AddEntry(pStrokes[numStrokes - 1], &point, flat_path->pFlags[i]);
1877 break;
1878 case PT_BEZIERTO:
1879 /* Should never happen because of the FlattenPath call */
1880 ERR("Should never happen\n");
1881 break;
1882 default:
1883 ERR("Got path flag %c\n", flat_path->pFlags[i]);
1884 goto Exit;
1885 }
1886 }
1887
1888 pNewPath = PATH_CreatePath( flat_path->numEntriesUsed );
1889 if (pNewPath == NULL)
1890 {
1891 ERR("PATH_CreatePath\n");
1892 goto Exit;
1893 }
1894
1895 KeSaveFloatingPointState(&fpsave);
1896
1897 for (i = 0; i < numStrokes; i++)
1898 {
1899 pUpPath = ExAllocatePoolWithTag(PagedPool, sizeof(PATH), TAG_PATH);
1900 PATH_InitGdiPath(pUpPath);
1901 pUpPath->state = PATH_Open;
1902 pDownPath = ExAllocatePoolWithTag(PagedPool, sizeof(PATH), TAG_PATH);
1903 PATH_InitGdiPath(pDownPath);
1904 pDownPath->state = PATH_Open;
1905
1906 for (j = 0; j < pStrokes[i]->numEntriesUsed; j++)
1907 {
1908 /* Beginning or end of the path if not closed */
1909 if ((!(pStrokes[i]->pFlags[pStrokes[i]->numEntriesUsed - 1] & PT_CLOSEFIGURE)) && (j == 0 || j == pStrokes[i]->numEntriesUsed - 1))
1910 {
1911 /* Compute segment angle */
1912 INT xo, yo, xa, ya;
1913 double theta;
1914 POINT pt;
1915 POINT corners[2];
1916 if (j == 0)
1917 {
1918 xo = pStrokes[i]->pPoints[j].x;
1919 yo = pStrokes[i]->pPoints[j].y;
1920 xa = pStrokes[i]->pPoints[1].x;
1921 ya = pStrokes[i]->pPoints[1].y;
1922 }
1923 else
1924 {
1925 xa = pStrokes[i]->pPoints[j - 1].x;
1926 ya = pStrokes[i]->pPoints[j - 1].y;
1927 xo = pStrokes[i]->pPoints[j].x;
1928 yo = pStrokes[i]->pPoints[j].y;
1929 }
1930 theta = atan2(ya - yo, xa - xo);
1931 switch(endcap)
1932 {
1933 case PS_ENDCAP_SQUARE :
1934 pt.x = xo + round(sqrt(2) * penWidthOut * cos(M_PI_4 + theta));
1935 pt.y = yo + round(sqrt(2) * penWidthOut * sin(M_PI_4 + theta));
1936 PATH_AddEntry(pUpPath, &pt, (j == 0 ? PT_MOVETO : PT_LINETO));
1937 pt.x = xo + round(sqrt(2) * penWidthIn * cos(- M_PI_4 + theta));
1938 pt.y = yo + round(sqrt(2) * penWidthIn * sin(- M_PI_4 + theta));
1939 PATH_AddEntry(pUpPath, &pt, PT_LINETO);
1940 break;
1941 case PS_ENDCAP_FLAT :
1942 pt.x = xo + round(penWidthOut * cos(theta + M_PI_2));
1943 pt.y = yo + round(penWidthOut * sin(theta + M_PI_2));
1944 PATH_AddEntry(pUpPath, &pt, (j == 0 ? PT_MOVETO : PT_LINETO));
1945 pt.x = xo - round(penWidthIn * cos(theta + M_PI_2));
1946 pt.y = yo - round(penWidthIn * sin(theta + M_PI_2));
1947 PATH_AddEntry(pUpPath, &pt, PT_LINETO);
1948 break;
1949 case PS_ENDCAP_ROUND :
1950 default :
1951 corners[0].x = xo - penWidthIn;
1952 corners[0].y = yo - penWidthIn;
1953 corners[1].x = xo + penWidthOut;
1954 corners[1].y = yo + penWidthOut;
1955 PATH_DoArcPart(pUpPath , corners, theta + M_PI_2 , theta + 3 * M_PI_4, (j == 0 ? PT_MOVETO : FALSE));
1956 PATH_DoArcPart(pUpPath , corners, theta + 3 * M_PI_4 , theta + M_PI, FALSE);
1957 PATH_DoArcPart(pUpPath , corners, theta + M_PI, theta + 5 * M_PI_4, FALSE);
1958 PATH_DoArcPart(pUpPath , corners, theta + 5 * M_PI_4 , theta + 3 * M_PI_2, FALSE);
1959 break;
1960 }
1961 }
1962 /* Corpse of the path */
1963 else
1964 {
1965 /* Compute angle */
1966 INT previous, next;
1967 double xa, ya, xb, yb, xo, yo;
1968 double alpha, theta, miterWidth;
1969 DWORD _joint = joint;
1970 POINT pt;
1971 PPATH pInsidePath, pOutsidePath;
1972 if (j > 0 && j < pStrokes[i]->numEntriesUsed - 1)
1973 {
1974 previous = j - 1;
1975 next = j + 1;
1976 }
1977 else if (j == 0)
1978 {
1979 previous = pStrokes[i]->numEntriesUsed - 1;
1980 next = j + 1;
1981 }
1982 else
1983 {
1984 previous = j - 1;
1985 next = 0;
1986 }
1987 xo = pStrokes[i]->pPoints[j].x;
1988 yo = pStrokes[i]->pPoints[j].y;
1989 xa = pStrokes[i]->pPoints[previous].x;
1990 ya = pStrokes[i]->pPoints[previous].y;
1991 xb = pStrokes[i]->pPoints[next].x;
1992 yb = pStrokes[i]->pPoints[next].y;
1993 theta = atan2(yo - ya, xo - xa);
1994 alpha = atan2(yb - yo, xb - xo) - theta;
1995 if (alpha > 0) alpha -= M_PI;
1996 else alpha += M_PI;
1997 if (_joint == PS_JOIN_MITER && eMiterLimit < fabs(1 / sin(alpha / 2)))
1998 {
1999 _joint = PS_JOIN_BEVEL;
2000 }
2001 if (alpha > 0)
2002 {
2003 pInsidePath = pUpPath;
2004 pOutsidePath = pDownPath;
2005 }
2006 else if (alpha < 0)
2007 {
2008 pInsidePath = pDownPath;
2009 pOutsidePath = pUpPath;
2010 }
2011 else
2012 {
2013 continue;
2014 }
2015 /* Inside angle points */
2016 if (alpha > 0)
2017 {
2018 pt.x = xo - round(penWidthIn * cos(theta + M_PI_2));
2019 pt.y = yo - round(penWidthIn * sin(theta + M_PI_2));
2020 }
2021 else
2022 {
2023 pt.x = xo + round(penWidthIn * cos(theta + M_PI_2));
2024 pt.y = yo + round(penWidthIn * sin(theta + M_PI_2));
2025 }
2026 PATH_AddEntry(pInsidePath, &pt, PT_LINETO);
2027 if (alpha > 0)
2028 {
2029 pt.x = xo + round(penWidthIn * cos(M_PI_2 + alpha + theta));
2030 pt.y = yo + round(penWidthIn * sin(M_PI_2 + alpha + theta));
2031 }
2032 else
2033 {
2034 pt.x = xo - round(penWidthIn * cos(M_PI_2 + alpha + theta));
2035 pt.y = yo - round(penWidthIn * sin(M_PI_2 + alpha + theta));
2036 }
2037 PATH_AddEntry(pInsidePath, &pt, PT_LINETO);
2038 /* Outside angle point */
2039 switch(_joint)
2040 {
2041 case PS_JOIN_MITER :
2042 miterWidth = fabs(penWidthOut / cos(M_PI_2 - fabs(alpha) / 2));
2043 pt.x = xo + round(miterWidth * cos(theta + alpha / 2));
2044 pt.y = yo + round(miterWidth * sin(theta + alpha / 2));
2045 PATH_AddEntry(pOutsidePath, &pt, PT_LINETO);
2046 break;
2047 case PS_JOIN_BEVEL :
2048 if (alpha > 0)
2049 {
2050 pt.x = xo + round(penWidthOut * cos(theta + M_PI_2));
2051 pt.y = yo + round(penWidthOut * sin(theta + M_PI_2));
2052 }
2053 else
2054 {
2055 pt.x = xo - round(penWidthOut * cos(theta + M_PI_2));
2056 pt.y = yo - round(penWidthOut * sin(theta + M_PI_2));
2057 }
2058 PATH_AddEntry(pOutsidePath, &pt, PT_LINETO);
2059 if (alpha > 0)
2060 {
2061 pt.x = xo - round(penWidthOut * cos(M_PI_2 + alpha + theta));
2062 pt.y = yo - round(penWidthOut * sin(M_PI_2 + alpha + theta));
2063 }
2064 else
2065 {
2066 pt.x = xo + round(penWidthOut * cos(M_PI_2 + alpha + theta));
2067 pt.y = yo + round(penWidthOut * sin(M_PI_2 + alpha + theta));
2068 }
2069 PATH_AddEntry(pOutsidePath, &pt, PT_LINETO);
2070 break;
2071 case PS_JOIN_ROUND :
2072 default :
2073 if (alpha > 0)
2074 {
2075 pt.x = xo + round(penWidthOut * cos(theta + M_PI_2));
2076 pt.y = yo + round(penWidthOut * sin(theta + M_PI_2));
2077 }
2078 else
2079 {
2080 pt.x = xo - round(penWidthOut * cos(theta + M_PI_2));
2081 pt.y = yo - round(penWidthOut * sin(theta + M_PI_2));
2082 }
2083 PATH_AddEntry(pOutsidePath, &pt, PT_BEZIERTO);
2084 pt.x = xo + round(penWidthOut * cos(theta + alpha / 2));
2085 pt.y = yo + round(penWidthOut * sin(theta + alpha / 2));
2086 PATH_AddEntry(pOutsidePath, &pt, PT_BEZIERTO);
2087 if (alpha > 0)
2088 {
2089 pt.x = xo - round(penWidthOut * cos(M_PI_2 + alpha + theta));
2090 pt.y = yo - round(penWidthOut * sin(M_PI_2 + alpha + theta));
2091 }
2092 else
2093 {
2094 pt.x = xo + round(penWidthOut * cos(M_PI_2 + alpha + theta));
2095 pt.y = yo + round(penWidthOut * sin(M_PI_2 + alpha + theta));
2096 }
2097 PATH_AddEntry(pOutsidePath, &pt, PT_BEZIERTO);
2098 break;
2099 }
2100 }
2101 }
2102 type = add_points( pNewPath, pUpPath->pPoints, pUpPath->numEntriesUsed, PT_LINETO );
2103 type[0] = PT_MOVETO;
2104 reverse_points( pDownPath->pPoints, pDownPath->numEntriesUsed );
2105 type = add_points( pNewPath, pDownPath->pPoints, pDownPath->numEntriesUsed, PT_LINETO );
2106 if (pStrokes[i]->pFlags[pStrokes[i]->numEntriesUsed - 1] & PT_CLOSEFIGURE) type[0] = PT_MOVETO;
2107
2108 PATH_DestroyGdiPath(pStrokes[i]);
2109 ExFreePoolWithTag(pStrokes[i], TAG_PATH);
2110 PATH_DestroyGdiPath(pUpPath);
2111 ExFreePoolWithTag(pUpPath, TAG_PATH);
2112 PATH_DestroyGdiPath(pDownPath);
2113 ExFreePoolWithTag(pDownPath, TAG_PATH);
2114 }
2115
2116 pNewPath->state = PATH_Closed;
2117 PATH_UnlockPath(pNewPath);
2118
2120
2121Exit:
2122 if (pStrokes) ExFreePoolWithTag(pStrokes, TAG_PATH);
2123 HPATH hpathToDelete = flat_path->BaseObject.hHmgr;
2124 PATH_UnlockPath(flat_path);
2125 PATH_Delete(hpathToDelete);
2126
2127 return pNewPath;
2128}
#define ERR(fmt,...)
Definition: precomp.h:57
HGDIOBJ hHmgr(VOID)
Definition: baseobj.hpp:95
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
_ACRTIMP double __cdecl sqrt(double)
Definition: sqrt.c:5
_ACRTIMP double __cdecl fabs(double)
_ACRTIMP double __cdecl sin(double)
Definition: sin.c:21
#define M_PI_2
Definition: math.h:410
_ACRTIMP double __cdecl cos(double)
Definition: cos.c:21
_ACRTIMP double __cdecl atan2(double, double)
Definition: atan2.c:52
#define M_PI_4
Definition: math.h:411
#define pt(x, y)
Definition: drawing.c:79
POINTL point
Definition: edittest.c:50
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLclampf GLclampf GLclampf alpha
Definition: gl.h:1740
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
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 GLint GLint j
Definition: glfuncs.h:250
#define KeSaveFloatingPointState(x)
Definition: kmixer.h:32
#define KeRestoreFloatingPointState(x)
Definition: kmixer.h:33
#define M_PI
Definition: macros.h:263
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define PATH_UnlockPath(pPath)
Definition: path.h:71
static unsigned __int64 next
Definition: rand_nt.c:6
static void Exit(void)
Definition: sock.c:1330
Definition: path.h:35
BASEOBJECT BaseObject
Definition: path.h:36
POINT * pPoints
Definition: path.h:53
LONG y
Definition: windef.h:130
LONG x
Definition: windef.h:129
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
int32_t INT
Definition: typedefs.h:58
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
BOOL FASTCALL PATH_Delete(HPATH hPath)
Definition: path.c:90
VOID FASTCALL PATH_DestroyGdiPath(PPATH pPath)
Definition: path.c:80
VOID FASTCALL PATH_InitGdiPath(PPATH pPath)
Definition: path.c:142
#define round(x)
Definition: path.c:1799
static BOOL PATH_DoArcPart(PPATH pPath, POINT corners[], double angleStart, double angleEnd, BYTE startEntryType)
Definition: path.c:900
PPATH FASTCALL PATH_FlattenPath(PPATH pPath)
Definition: path.c:1420
BOOL FASTCALL PATH_AddEntry(PPATH pPath, const POINT *pPoint, BYTE flags)
Definition: path.c:262
PPATH FASTCALL PATH_CreatePath(int count)
Definition: path.c:35
static BYTE * add_points(PPATH path, const POINT *points, DWORD count, BYTE type)
Definition: path.c:490
static void reverse_points(POINT *points, UINT count)
Definition: path.c:504
#define TAG_PATH
Definition: tags.h:25
#define PS_JOIN_BEVEL
Definition: wingdi.h:597
#define PS_ENDCAP_SQUARE
Definition: wingdi.h:595
#define PS_JOIN_ROUND
Definition: wingdi.h:599
#define PS_ENDCAP_ROUND
Definition: wingdi.h:594
#define PT_LINETO
Definition: wingdi.h:885
#define PS_JOIN_MASK
Definition: wingdi.h:600
#define PT_MOVETO
Definition: wingdi.h:884
#define PT_BEZIERTO
Definition: wingdi.h:886
#define PS_JOIN_MITER
Definition: wingdi.h:598
#define PS_ENDCAP_MASK
Definition: wingdi.h:602
#define PS_ENDCAP_FLAT
Definition: wingdi.h:596
unsigned char BYTE
Definition: xxhash.c:193

Referenced by PATH_WidenPathEx().

◆ 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}
#define CoordLPtoDP(pdc, ppt)
Definition: coord.h:187
HDC dc
Definition: cylfrac.c:34
#define DIRTY_STYLESTATE
Definition: ntgdihdl.h:133
#define DIRTY_PTFXCURRENT
Definition: ntgdihdl.h:132
POINTL ptlCurrent
Definition: ntgdihdl.h:311
ULONG ulDirty_
Definition: ntgdihdl.h:294
POINTL ptfxCurrent
Definition: ntgdihdl.h:312

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

◆ PATH_AddEntry()

BOOL FASTCALL PATH_AddEntry ( PPATH  pPath,
const POINT pPoint,
BYTE  flags 
)

Definition at line 262 of file path.c.

266{
267 ASSERT(pPath != NULL);
268
269 /* FIXME: If newStroke is true, perhaps we want to check that we're
270 * getting a PT_MOVETO
271 */
272 TRACE("(%d,%d) - %d\n", pPoint->x, pPoint->y, flags);
273
274 /* Reserve enough memory for an extra path entry */
275 if (!PATH_ReserveEntries(pPath, pPath->numEntriesUsed + 1))
276 return FALSE;
277
278 /* Store information in path entry */
279 pPath->pPoints[pPath->numEntriesUsed] = *pPoint;
280 pPath->pFlags[pPath->numEntriesUsed] = flags;
281
282 /* Increment entry count */
283 pPath->numEntriesUsed++;
284
285 return TRUE;
286}
GLbitfield flags
Definition: glext.h:7161
#define TRACE(s)
Definition: solgame.cpp:4
BOOL FASTCALL PATH_ReserveEntries(PPATH pPath, INT numEntries)
Definition: path.c:296

Referenced by IntGdiWidenPath(), PATH_add_outline(), PATH_AddFlatBezier(), PATH_Arc(), PATH_BezierTo(), PATH_FlattenPath(), PATH_LineTo(), and PATH_PolyPolyline().

◆ PATH_AddFlatBezier()

BOOL FASTCALL PATH_AddFlatBezier ( PPATH  pPath,
POINT pt,
BOOL  closed 
)

Definition at line 1391 of file path.c.

1395{
1396 POINT *pts;
1397 BOOL ret = FALSE;
1398 INT no, i;
1399
1400 pts = GDI_Bezier(pt, 4, &no);
1401 if (!pts) return FALSE;
1402
1403 for (i = 1; i < no; i++)
1404 {
1405 if (!(ret = PATH_AddEntry(pPath, &pts[i], (i == no - 1 && closed) ? PT_LINETO | PT_CLOSEFIGURE : PT_LINETO)))
1406 break;
1407 }
1408
1410 return ret;
1411}
POINT * GDI_Bezier(const POINT *Points, INT count, INT *nPtsOut)
Definition: bezier.c:189
static WCHAR no[MAX_STRING_RESOURCE_LEN]
Definition: object.c:2340
return ret
Definition: mutex.c:146
unsigned int BOOL
Definition: ntddk_ex.h:94
#define TAG_BEZIER
Definition: tags.h:13

Referenced by PATH_FlattenPath().

◆ PATH_Arc()

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 at line 965 of file path.c.

977{
978 double angleStart, angleEnd, angleStartQuadrant, angleEndQuadrant = 0.0;
979 /* Initialize angleEndQuadrant to silence gcc's warning */
980 FLOATL x, y;
981 POINT corners[2], pointStart, pointEnd;
982 POINT centre, pointCurPos;
983 BOOL start, end, Ret = TRUE;
984 INT temp;
985 BOOL clockwise;
986 PPATH pPath;
987
988 /* FIXME: This function should check for all possible error returns */
989 /* FIXME: Do we have to respect newStroke? */
990
991 ASSERT(dc);
992
993 pPath = PATH_LockPath(dc->dclevel.hPath);
994 if (!pPath) return FALSE;
995
996 if (direction)
997 clockwise = ((direction == AD_CLOCKWISE) !=0 );
998 else
999 clockwise = ((dc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
1000
1001 /* Check for zero height / width */
1002 /* FIXME: Only in GM_COMPATIBLE? */
1003 if (x1 == x2 || y1 == y2)
1004 {
1005 Ret = TRUE;
1006 goto ArcExit;
1007 }
1008 /* Convert points to device coordinates */
1009 corners[0].x = x1; corners[0].y = y1;
1010 corners[1].x = x2; corners[1].y = y2;
1011 pointStart.x = xStart; pointStart.y = yStart;
1012 pointEnd.x = xEnd; pointEnd.y = yEnd;
1013 INTERNAL_LPTODP(dc, corners, 2);
1014 INTERNAL_LPTODP(dc, &pointStart, 1);
1015 INTERNAL_LPTODP(dc, &pointEnd, 1);
1016
1017 /* Make sure first corner is top left and second corner is bottom right */
1018 if (corners[0].x > corners[1].x)
1019 {
1020 temp = corners[0].x;
1021 corners[0].x = corners[1].x;
1022 corners[1].x = temp;
1023 }
1024 if (corners[0].y > corners[1].y)
1025 {
1026 temp = corners[0].y;
1027 corners[0].y = corners[1].y;
1028 corners[1].y = temp;
1029 }
1030
1031 /* Compute start and end angle */
1032 PATH_NormalizePoint(corners, &pointStart, &x, &y);
1033 angleStart = atan2(*(FLOAT*)&y, *(FLOAT*)&x);
1034 PATH_NormalizePoint(corners, &pointEnd, &x, &y);
1035 angleEnd = atan2(*(FLOAT*)&y, *(FLOAT*)&x);
1036
1037 /* Make sure the end angle is "on the right side" of the start angle */
1038 if (clockwise)
1039 {
1040 if (angleEnd <= angleStart)
1041 {
1042 angleEnd += 2 * M_PI;
1043 ASSERT(angleEnd >= angleStart);
1044 }
1045 }
1046 else
1047 {
1048 if (angleEnd >= angleStart)
1049 {
1050 angleEnd -= 2 * M_PI;
1051 ASSERT(angleEnd <= angleStart);
1052 }
1053 }
1054
1055 /* In GM_COMPATIBLE, don't include bottom and right edges */
1056 if (dc->pdcattr->iGraphicsMode == GM_COMPATIBLE)
1057 {
1058 corners[1].x--;
1059 corners[1].y--;
1060 }
1061
1062 /* arcto: Add a PT_MOVETO only if this is the first entry in a stroke */
1063 if (lines == GdiTypeArcTo && pPath->newStroke) // -1
1064 {
1065 pPath->newStroke = FALSE;
1066 IntGetCurrentPositionEx(dc, &pointCurPos);
1067 CoordLPtoDP(dc, &pointCurPos);
1068 if (!PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO))
1069 {
1070 Ret = FALSE;
1071 goto ArcExit;
1072 }
1073 }
1074
1075 /* Add the arc to the path with one Bezier spline per quadrant that the
1076 * arc spans */
1077 start = TRUE;
1078 end = FALSE;
1079 do
1080 {
1081 /* Determine the start and end angles for this quadrant */
1082 if (start)
1083 {
1084 angleStartQuadrant = angleStart;
1085 if (clockwise)
1086 angleEndQuadrant = (floor(angleStart / M_PI_2) + 1.0) * M_PI_2;
1087 else
1088 angleEndQuadrant = (ceil(angleStart / M_PI_2) - 1.0) * M_PI_2;
1089 }
1090 else
1091 {
1092 angleStartQuadrant = angleEndQuadrant;
1093 if (clockwise)
1094 angleEndQuadrant += M_PI_2;
1095 else
1096 angleEndQuadrant -= M_PI_2;
1097 }
1098
1099 /* Have we reached the last part of the arc? */
1100 if ((clockwise && angleEnd < angleEndQuadrant) ||
1101 (!clockwise && angleEnd > angleEndQuadrant))
1102 {
1103 /* Adjust the end angle for this quadrant */
1104 angleEndQuadrant = angleEnd;
1105 end = TRUE;
1106 }
1107
1108 /* Add the Bezier spline to the path */
1109 PATH_DoArcPart(pPath,
1110 corners,
1111 angleStartQuadrant,
1112 angleEndQuadrant,
1113 start ? (lines == GdiTypeArcTo ? PT_LINETO : PT_MOVETO) : FALSE); // -1
1114 start = FALSE;
1115 }
1116 while (!end);
1117
1118 if (lines == GdiTypeArcTo)
1119 {
1120 update_current_pos( pPath );
1121 }
1122 else /* chord: close figure. pie: add line and close figure */
1123 if (lines == GdiTypeChord) // 1
1124 {
1125 IntGdiCloseFigure(pPath);
1126 }
1127 else if (lines == GdiTypePie) // 2
1128 {
1129 centre.x = (corners[0].x + corners[1].x) / 2;
1130 centre.y = (corners[0].y + corners[1].y) / 2;
1131 if (!PATH_AddEntry(pPath, &centre, PT_LINETO | PT_CLOSEFIGURE))
1132 Ret = FALSE;
1133 }
1134ArcExit:
1135 PATH_UnlockPath(pPath);
1136 return Ret;
1137}
static BOOLEAN INTERNAL_LPTODP(DC *dc, LPPOINT points, UINT count)
Definition: coord.h:47
_ACRTIMP double __cdecl ceil(double)
Definition: ceil.c:18
_ACRTIMP double __cdecl floor(double)
Definition: floor.c:18
GLuint start
Definition: gl.h:1545
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
direction
Definition: netio.c:882
@ GdiTypeChord
Definition: ntgdityp.h:22
@ GdiTypeArcTo
Definition: ntgdityp.h:21
@ GdiTypePie
Definition: ntgdityp.h:23
#define PATH_LockPath(hPath)
Definition: path.h:70
static calc_node_t temp
Definition: rpn_ieee.c:38
eMaj lines
Definition: tritemp.h:206
float FLOAT
Definition: typedefs.h:69
VOID FASTCALL IntGetCurrentPositionEx(PDC dc, LPPOINT pt)
Definition: line.c:130
static void update_current_pos(PPATH path)
Definition: path.c:529
VOID FASTCALL IntGdiCloseFigure(PPATH pPath)
Definition: path.c:108
static VOID PATH_NormalizePoint(POINTL corners[], const POINTL *pPoint, FLOATL *pX, FLOATL *pY)
Definition: path.c:401
FLOAT FLOATL
Definition: winddi.h:114
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3708
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG y1
Definition: winddi.h:3709
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG _In_ LONG y2
Definition: winddi.h:3711
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3710
#define GM_COMPATIBLE
Definition: wingdi.h:864
#define AD_CLOCKWISE
Definition: wingdi.h:668

Referenced by IntGdiArcInternal().

◆ PATH_CreatePath()

PPATH FASTCALL PATH_CreatePath ( int  count)

Definition at line 35 of file path.c.

36{
38
39 if (!pPath)
40 {
42 return NULL;
43 }
44
45 TRACE("CreatePath p 0x%p\n", pPath);
46 // Path handles are shared. Also due to recursion with in the same thread.
47 GDIOBJ_vUnlockObject((POBJ)pPath); // Unlock
48 pPath = PATH_LockPath(pPath->BaseObject.hHmgr); // Share Lock.
49
50 /* Make sure that path is empty */
51 PATH_EmptyPath(pPath);
52
54
56
58 RtlZeroMemory( pPath->pPoints, count * sizeof(POINT));
60 RtlZeroMemory( pPath->pFlags, count * sizeof(BYTE));
61
62 /* Initialize variables for new path */
63 pPath->numEntriesUsed = 0;
64 pPath->newStroke = TRUE;
65 pPath->state = PATH_Open;
66 pPath->pos.x = pPath->pos.y = 0;
67#if DBG
68 PathCount++;
69 TRACE("Create Path %d\n",PathCount);
70#endif
71 return pPath;
72}
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define PATH_AllocPathWithHandle()
Definition: path.h:69
POINT pos
Definition: path.h:58
int numEntriesAllocated
Definition: path.h:56
#define max(a, b)
Definition: svc.c:63
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
VOID NTAPI GDIOBJ_vUnlockObject(POBJ pobj)
Definition: gdiobj.c:887
#define NUM_ENTRIES_INITIAL
Definition: path.c:21
VOID FASTCALL PATH_EmptyPath(PPATH pPath)
Definition: path.c:246
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:21

Referenced by IntGdiLineTo(), IntGdiPolygon(), IntGdiPolyline(), IntGdiWidenPath(), IntRectangle(), NtGdiBeginPath(), PATH_FlattenPath(), PATH_RestorePath(), and PATH_SavePath().

◆ PATH_Delete()

BOOL FASTCALL PATH_Delete ( HPATH  hPath)

Definition at line 90 of file path.c.

91{
92 PPATH pPath;
93 if (!hPath) return FALSE;
94 pPath = PATH_LockPath(hPath);
95 if (!pPath) return FALSE;
98#if DBG
99 PathCount--;
100 TRACE("Delete Path %d\n",PathCount);
101#endif
102 return TRUE;
103}
VOID NTAPI GDIOBJ_vDeleteObject(POBJ pobj)
Definition: gdiobj.c:1118

Referenced by DC_vCleanup(), IntGdiCleanDC(), IntGdiLineTo(), IntGdiPolygon(), IntGdiPolyline(), IntGdiWidenPath(), IntRectangle(), NtGdiAbortPath(), NtGdiBeginPath(), NtGdiFillPath(), NtGdiFlattenPath(), NtGdiPathToRegion(), NtGdiSelectClipPath(), NtGdiStrokeAndFillPath(), NtGdiStrokePath(), NtGdiWidenPath(), PATH_FlattenPath(), and PATH_StrokePath().

◆ PATH_Ellipse()

BOOL PATH_Ellipse ( PDC  dc,
INT  x1,
INT  y1,
INT  x2,
INT  y2 
)

Definition at line 792 of file path.c.

798{
799 PPATH pPath;
800 POINT points[13];
801 RECTL rect;
802 BYTE *type;
803 LONG xRadius, yRadius, xOffset, yOffset;
805
806 TRACE("PATH_Ellipse: %p -> (%d, %d) - (%d, %d)\n",
807 dc, x1, y1, x2, y2);
808
809 if (!PATH_CheckRect(dc, &rect, x1, y1, x2, y2))
810 {
811 return TRUE;
812 }
813
814 xRadius = RECTL_lGetWidth(&rect) / 2;
815 yRadius = RECTL_lGetHeight(&rect) / 2;
816
817 /* Get the four points which box our ellipse */
818 left.x = rect.left; left.y = rect.top + yRadius;
819 top.x = rect.left + xRadius; top.y = rect.top;
820 right.x = rect.right; right.y = rect.bottom - yRadius;
821 bottom.x = rect.right - xRadius; bottom.y = rect.bottom;
822
823 /*
824 * See here to understand what's happening
825 * https://stackoverflow.com/questions/1734745/how-to-create-circle-with-b%C3%A9zier-curves
826 */
827 xOffset = EngMulDiv(RECTL_lGetWidth(&rect), 55428475, 200000000); /* w * 0.55428475 / 2 */
828 yOffset = EngMulDiv(RECTL_lGetHeight(&rect), 55428475, 200000000); /* h * 0.55428475 / 2 */
829 TRACE("xOffset %d, yOffset %d, Rect WxH: %dx%d.\n",
831
832 pPath = PATH_LockPath(dc->dclevel.hPath);
833 if (!pPath)
834 return FALSE;
835
836 /* Starting point: Right */
837 points[0] = right;
838
839 /* first curve - going up, left */
840 points[1] = right;
841 points[1].y -= yOffset;
842 points[2] = top;
843 points[2].x += xOffset;
844
845 /* top */
846 points[3] = top;
847
848 /* second curve - going left, down*/
849 points[4] = top;
850 points[4].x -= xOffset;
851 points[5] = left;
852 points[5].y -= yOffset;
853
854 /* Left */
855 points[6] = left;
856
857 /* Third curve - going down, right */
858 points[7] = left;
859 points[7].y += yOffset;
860 points[8] = bottom;
861 points[8].x -= xOffset;
862
863 /* bottom */
864 points[9] = bottom;
865
866 /* Fourth curve - Going right, up */
867 points[10] = bottom;
868 points[10].x += xOffset;
869 points[11] = right;
870 points[11].y += yOffset;
871
872 /* Back to starting point */
873 points[12] = right;
874
875 if (dc->dclevel.flPath & DCPATH_CLOCKWISE) reverse_points( points, 13 );
876 if (!(type = add_points( pPath, points, 13, PT_BEZIERTO )))
877 {
878 ERR("PATH_Ellipse No add\n");
879 PATH_UnlockPath(pPath);
880 return FALSE;
881 }
882 type[0] = PT_MOVETO;
883
884 IntGdiCloseFigure(pPath);
885 PATH_UnlockPath(pPath);
886 return TRUE;
887}
int yOffset
Definition: appswitch.c:58
int xOffset
Definition: appswitch.c:58
RECT rect
Definition: combotst.c:67
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLdouble GLdouble right
Definition: glext.h:10859
GLint left
Definition: glext.h:7726
GLint GLint bottom
Definition: glext.h:7726
GLsizei const GLfloat * points
Definition: glext.h:8112
long LONG
Definition: pedump.c:60
LONG right
Definition: windef.h:108
LONG bottom
Definition: windef.h:109
LONG top
Definition: windef.h:107
LONG left
Definition: windef.h:106
static BOOL PATH_CheckRect(DC *dc, RECTL *rect, INT x1, INT y1, INT x2, INT y2)
Definition: path.c:433
FORCEINLINE LONG RECTL_lGetWidth(_In_ const RECTL *prcl)
Definition: rect.h:93
FORCEINLINE LONG RECTL_lGetHeight(_In_ const RECTL *prcl)
Definition: rect.h:86
ENGAPI INT APIENTRY EngMulDiv(_In_ INT a, _In_ INT b, _In_ INT c)
Definition: math.c:26

Referenced by NtGdiEllipse().

◆ PATH_EmptyPath()

VOID FASTCALL PATH_EmptyPath ( PPATH  pPath)

Definition at line 246 of file path.c.

247{
248 ASSERT(pPath != NULL);
249
250 pPath->state = PATH_Null;
251 pPath->numEntriesUsed = 0;
252}

Referenced by PATH_CreatePath().

◆ PATH_ExtTextOut()

BOOL FASTCALL PATH_ExtTextOut ( PDC  dc,
INT  x,
INT  y,
UINT  flags,
const RECTL lprc,
LPCWSTR  str,
UINT  count,
const INT dx 
)

Definition at line 2370 of file path.c.

2379{
2380 PPATH pPath;
2381 unsigned int idx, ggo_flags = GGO_NATIVE;
2382 POINT offset = {0, 0};
2383
2384 pPath = PATH_LockPath(dc->dclevel.hPath);
2385 if (!pPath)
2386 {
2387 return FALSE;
2388 }
2389
2390 if (pPath->state != PATH_Open)
2391 {
2392 ERR("PATH_ExtTextOut not open\n");
2393 return FALSE;
2394 }
2395
2396 if (!count) return TRUE;
2397 if (flags & ETO_GLYPH_INDEX) ggo_flags |= GGO_GLYPH_INDEX;
2398
2399 for (idx = 0; idx < count; idx++)
2400 {
2401 MAT2 identity = { {0, 1}, {0, 0}, {0, 0}, {0, 1} };
2402 GLYPHMETRICS gm;
2403 DWORD dwSize;
2404 void *outline;
2405
2407 str[idx],
2408 ggo_flags,
2409 &gm,
2410 0,
2411 NULL,
2412 &identity,
2413 TRUE);
2414 if (dwSize == GDI_ERROR)
2415 {
2416 // With default DC font,,, bitmap font?
2417 // ExtTextOut on a path with bitmap font selected shouldn't fail.
2418 // This just leads to empty path generated.
2419 // Ref : test_emf_ExtTextOut_on_path
2420 continue;
2421 }
2422
2423 /* Add outline only if char is printable */
2424 if (dwSize)
2425 {
2427 if (!outline)
2428 {
2429 PATH_UnlockPath(pPath);
2430 return FALSE;
2431 }
2432
2434 str[idx],
2435 ggo_flags,
2436 &gm,
2437 dwSize,
2438 outline,
2439 &identity,
2440 TRUE);
2441
2442 PATH_add_outline(dc, pPath, x + offset.x, y + offset.y, outline, dwSize);
2443
2445 }
2446
2447 if (dx)
2448 {
2449 if (flags & ETO_PDY)
2450 {
2451 offset.x += dx[idx * 2];
2452 offset.y += dx[idx * 2 + 1];
2453 }
2454 else
2455 offset.x += dx[idx];
2456 }
2457 else
2458 {
2459 offset.x += gm.gmCellIncX;
2460 offset.y += gm.gmCellIncY;
2461 }
2462 }
2463 PATH_UnlockPath(pPath);
2464 return TRUE;
2465}
unsigned int idx
Definition: utils.c:41
ULONG FASTCALL ftGdiGetGlyphOutline(PDC dc, WCHAR wch, UINT iFormat, LPGLYPHMETRICS pgm, ULONG cjBuf, PVOID pvBuf, const MAT2 *pmat2, BOOL bIgnoreRotation)
Definition: freetype.c:4444
GLintptr offset
Definition: glext.h:5920
GLint dx
Definition: linetemp.h:97
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
const WCHAR * str
short gmCellIncX
Definition: wingdi.h:2891
short gmCellIncY
Definition: wingdi.h:2892
Definition: wingdi.h:2918
Definition: mesh.c:5330
static BOOL FASTCALL PATH_add_outline(PDC dc, PPATH pPath, INT x, INT y, TTPOLYGONHEADER *header, DWORD size)
Definition: path.c:2273
#define GGO_GLYPH_INDEX
Definition: wingdi.h:855
#define GDI_ERROR
Definition: wingdi.h:1309
#define ETO_PDY
Definition: wingdi.h:657
#define GGO_NATIVE
Definition: wingdi.h:850

Referenced by IntExtTextOutW().

◆ PATH_FillPath()

BOOL FASTCALL PATH_FillPath ( PDC  dc,
PPATH  pPath 
)

Definition at line 1518 of file path.c.

1521{
1522 return PATH_FillPathEx(dc, pPath, NULL);
1523}
BOOL FASTCALL PATH_FillPathEx(PDC dc, PPATH pPath, PBRUSH pbrFill)
Definition: path.c:1527

Referenced by NtGdiFillPath(), and NtGdiStrokeAndFillPath().

◆ PATH_FillPathEx()

BOOL FASTCALL PATH_FillPathEx ( PDC  dc,
PPATH  pPath,
PBRUSH  pbrFill 
)

Definition at line 1527 of file path.c.

1531{
1532 INT mapMode, graphicsMode;
1533 SIZE ptViewportExt, ptWindowExt;
1534 POINTL ptViewportOrg, ptWindowOrg;
1535 XFORML xform;
1536 PREGION Rgn;
1537 PDC_ATTR pdcattr = dc->pdcattr;
1538
1539 /* Allocate a temporary region */
1540 Rgn = IntSysCreateRectpRgn(0, 0, 0, 0);
1541 if (!Rgn)
1542 {
1544 return FALSE;
1545 }
1546
1547 if (!PATH_PathToRegion(pPath, pdcattr->jFillMode, Rgn))
1548 {
1549 TRACE("PFP : Fail P2R\n");
1550 /* EngSetLastError ? */
1551 REGION_Delete(Rgn);
1552 return FALSE;
1553 }
1554
1555 /* Since PaintRgn interprets the region as being in logical coordinates
1556 * but the points we store for the path are already in device
1557 * coordinates, we have to set the mapping mode to MM_TEXT temporarily.
1558 * Using SaveDC to save information about the mapping mode / world
1559 * transform would be easier but would require more overhead, especially
1560 * now that SaveDC saves the current path.
1561 */
1562
1563 /* Save the information about the old mapping mode */
1564 mapMode = pdcattr->iMapMode;
1565 ptViewportExt = pdcattr->szlViewportExt;
1566 ptViewportOrg = pdcattr->ptlViewportOrg;
1567 ptWindowExt = pdcattr->szlWindowExt;
1568 ptWindowOrg = pdcattr->ptlWindowOrg;
1569
1570 /* Save world transform
1571 * NB: The Windows documentation on world transforms would lead one to
1572 * believe that this has to be done only in GM_ADVANCED; however, my
1573 * tests show that resetting the graphics mode to GM_COMPATIBLE does
1574 * not reset the world transform.
1575 */
1576 MatrixS2XForm(&xform, &dc->pdcattr->mxWorldToPage);
1577
1578 /* Set MM_TEXT */
1580 pdcattr->ptlViewportOrg.x = 0;
1581 pdcattr->ptlViewportOrg.y = 0;
1582 pdcattr->ptlWindowOrg.x = 0;
1583 pdcattr->ptlWindowOrg.y = 0;
1584
1585 graphicsMode = pdcattr->iGraphicsMode;
1586 pdcattr->iGraphicsMode = GM_ADVANCED;
1588 pdcattr->iGraphicsMode = graphicsMode;
1589
1590 /* Paint the region */
1591 IntGdiFillRgn(dc, Rgn, pbrFill);
1592 REGION_Delete(Rgn);
1593 /* Restore the old mapping mode */
1594 IntGdiSetMapMode(dc, mapMode);
1595 pdcattr->szlViewportExt = ptViewportExt;
1596 pdcattr->ptlViewportOrg = ptViewportOrg;
1597 pdcattr->szlWindowExt = ptWindowExt;
1598 pdcattr->ptlWindowOrg = ptWindowOrg;
1599
1600 /* Go to GM_ADVANCED temporarily to restore the world transform */
1601 graphicsMode = pdcattr->iGraphicsMode;
1602 pdcattr->iGraphicsMode = GM_ADVANCED;
1604 pdcattr->iGraphicsMode = graphicsMode;
1605 return TRUE;
1606}
#define MatrixS2XForm(x, m)
Definition: coord.h:200
int APIENTRY IntGdiSetMapMode(PDC dc, int MapMode)
Definition: coord.c:828
BOOL NTAPI GreModifyWorldTransform(PDC pdc, const XFORML *pxform, DWORD dwMode)
Definition: coord.c:461
SIZEL szlViewportExt
Definition: ntgdihdl.h:344
INT iMapMode
Definition: ntgdihdl.h:338
INT iGraphicsMode
Definition: ntgdihdl.h:306
POINTL ptlViewportOrg
Definition: ntgdihdl.h:343
POINTL ptlWindowOrg
Definition: ntgdihdl.h:341
BYTE jFillMode
Definition: ntgdihdl.h:309
SIZEL szlWindowExt
Definition: ntgdihdl.h:342
Definition: region.h:8
BOOL IntGdiFillRgn(_In_ PDC pdc, _In_ PREGION prgn, _In_opt_ PBRUSH pbrFill)
Definition: bitblt.c:1190
BOOL FASTCALL PATH_PathToRegion(PPATH pPath, INT Mode, PREGION Rgn)
Definition: path.c:1463
VOID FASTCALL REGION_Delete(PREGION pRgn)
Definition: region.c:2449
PREGION FASTCALL IntSysCreateRectpRgn(INT LeftRect, INT TopRect, INT RightRect, INT BottomRect)
Definition: region.c:2407
#define MWT_SET
Definition: ntgdi.h:169
#define GM_ADVANCED
Definition: wingdi.h:865
#define MM_TEXT
Definition: wingdi.h:873
#define MWT_IDENTITY
Definition: wingdi.h:944

Referenced by PATH_FillPath(), and PATH_StrokePath().

◆ PATH_FlattenPath()

PPATH FASTCALL PATH_FlattenPath ( PPATH  pPath)

Definition at line 1420 of file path.c.

1421{
1422 PPATH newPath;
1423 INT srcpt;
1424 TRACE("PATH_FlattenPath\n");
1425 if (!(newPath = PATH_CreatePath(pPath->numEntriesUsed))) return NULL;
1426
1427 for (srcpt = 0; srcpt < pPath->numEntriesUsed; srcpt++)
1428 {
1429 switch(pPath->pFlags[srcpt] & ~PT_CLOSEFIGURE)
1430 {
1431 case PT_MOVETO:
1432 case PT_LINETO:
1433 if (!PATH_AddEntry(newPath, &pPath->pPoints[srcpt], pPath->pFlags[srcpt]))
1434 {
1435 PATH_UnlockPath(newPath);
1436 PATH_Delete(newPath->BaseObject.hHmgr);
1437 return NULL;
1438 }
1439 break;
1440 case PT_BEZIERTO:
1441 if(!PATH_AddFlatBezier(newPath, &pPath->pPoints[srcpt - 1], pPath->pFlags[srcpt + 2] & PT_CLOSEFIGURE))
1442 {
1443 PATH_UnlockPath(newPath);
1444 PATH_Delete(newPath->BaseObject.hHmgr);
1445 return NULL;
1446 }
1447 srcpt += 2;
1448 break;
1449 }
1450 }
1451 TRACE("PATH_FlattenPath good\n");
1452 newPath->state = pPath->state;
1453 return newPath;
1454}
BOOL FASTCALL PATH_AddFlatBezier(PPATH pPath, POINT *pt, BOOL closed)
Definition: path.c:1391

Referenced by IntGdiWidenPath(), NtGdiFillPath(), NtGdiFlattenPath(), NtGdiPathToRegion(), NtGdiSelectClipPath(), NtGdiStrokeAndFillPath(), and NtGdiStrokePath().

◆ PATH_LineTo()

BOOL FASTCALL PATH_LineTo ( PDC  dc,
INT  x,
INT  y 
)

Definition at line 593 of file path.c.

597{
598 BOOL Ret;
599 PPATH pPath;
600 POINT point, pointCurPos;
601
602 pPath = PATH_LockPath(dc->dclevel.hPath);
603 if (!pPath) return FALSE;
604
605 point.x = x;
606 point.y = y;
607
608 // Coalesce a MoveTo point.
609 if ( !PATH_MoveTo(dc, pPath) )
610 {
611 /* Add a PT_MOVETO if necessary */
612 if (pPath->newStroke)
613 {
614 TRACE("Line To : New Stroke\n");
615 pPath->newStroke = FALSE;
616 IntGetCurrentPositionEx(dc, &pointCurPos);
617 CoordLPtoDP(dc, &pointCurPos);
618 if (!PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO))
619 {
620 PATH_UnlockPath(pPath);
621 return FALSE;
622 }
623 }
624 }
625 Ret = add_log_points_new_stroke(dc, pPath, &point, 1, PT_LINETO , FALSE);
626 PATH_UnlockPath(pPath);
627 return Ret;
628}
static BOOL add_log_points_new_stroke(DC *dc, PPATH path, const POINT *points, DWORD count, BYTE type, BOOL bExtraPt)
Definition: path.c:543
BOOL FASTCALL PATH_MoveTo(PDC dc, PPATH pPath)
Definition: path.c:564

Referenced by IntGdiLineTo(), IntGdiPolygon(), IntGdiPolyline(), and IntRectangle().

◆ PATH_MoveTo()

BOOL FASTCALL PATH_MoveTo ( PDC  dc,
PPATH  pPath 
)

Definition at line 564 of file path.c.

567{
568 if (!pPath) return FALSE;
569
570 // GDI32 : Signal from user space of a change in position.
571 if (dc->pdcattr->ulDirty_ & DIRTY_STYLESTATE)
572 {
573 TRACE("MoveTo has changed\n");
574 pPath->newStroke = TRUE;
575 // Set position and clear the signal flag.
577 IntLPtoDP( dc, &pPath->pos, 1 );
578 return TRUE;
579 }
580
581 return FALSE;
582}
static BOOLEAN IntLPtoDP(DC *pdc, PPOINTL ppt, UINT count)
Definition: coord.h:182

Referenced by IntGdiLineTo(), IntGdiPolygon(), IntGdiPolyline(), IntRectangle(), and PATH_LineTo().

◆ PATH_PathToRegion()

BOOL FASTCALL PATH_PathToRegion ( PPATH  pPath,
INT  nPolyFillMode,
PREGION  Rgn 
)

Definition at line 1463 of file path.c.

1467{
1468 int i, pos, polygons;
1469 PULONG counts;
1470 int Ret;
1471
1472 if (!pPath->numEntriesUsed) return FALSE;
1473
1474 counts = ExAllocatePoolWithTag(PagedPool, (pPath->numEntriesUsed / 2) * sizeof(*counts), TAG_PATH);
1475 if (!counts)
1476 {
1477 ERR("Failed to allocate %lu strokes\n", (pPath->numEntriesUsed / 2) * sizeof(*counts));
1479 return FALSE;
1480 }
1481
1482 pos = polygons = 0;
1483 ASSERT( pPath->pFlags[0] == PT_MOVETO );
1484 for (i = 1; i < pPath->numEntriesUsed; i++)
1485 {
1486 if (pPath->pFlags[i] != PT_MOVETO) continue;
1487 counts[polygons++] = i - pos;
1488 pos = i;
1489 }
1490 if (i > pos + 1) counts[polygons++] = i - pos;
1491
1492 ASSERT( polygons <= pPath->numEntriesUsed / 2 );
1493
1494 /* Fill the region with the strokes */
1495 Ret = REGION_SetPolyPolygonRgn(Rgn,
1496 pPath->pPoints,
1497 counts,
1498 polygons,
1499 Mode);
1500 if (!Ret)
1501 {
1502 ERR("REGION_SetPolyPolygonRgn failed\n");
1503 }
1504
1505 ExFreePoolWithTag(counts, TAG_PATH);
1506
1507 /* Success! */
1508 return Ret;
1509}
_In_ ULONG Mode
Definition: hubbusif.h:303
uint32_t * PULONG
Definition: typedefs.h:59
BOOL FASTCALL REGION_SetPolyPolygonRgn(_Inout_ PREGION prgn, _In_ const POINT *ppt, _In_ const ULONG *pcPoints, _In_ ULONG cPolygons, _In_ INT iMode)
Definition: region.c:3254

Referenced by NtGdiPathToRegion(), NtGdiSelectClipPath(), and PATH_FillPathEx().

◆ PATH_PolyBezier()

BOOL FASTCALL PATH_PolyBezier ( PDC  dc,
const POINT pts,
DWORD  cbPoints 
)

Definition at line 1164 of file path.c.

1168{
1169 PPATH pPath;
1170 BYTE *type;
1171
1172 ASSERT(dc);
1173 ASSERT(pts);
1174 ASSERT(cbPoints);
1175
1176 pPath = PATH_LockPath(dc->dclevel.hPath);
1177 if (!pPath) return FALSE;
1178
1179 type = add_log_points(dc, pPath, pts, cbPoints, PT_BEZIERTO, FALSE);
1180 if (!type) return FALSE;
1181
1182 type[0] = PT_MOVETO;
1183
1184 PATH_UnlockPath(pPath);
1185 return TRUE;
1186}
static BYTE * add_log_points(DC *dc, PPATH path, const POINT *points, DWORD count, BYTE type, BOOL bExtraPt)
Definition: path.c:463

Referenced by IntGdiPolyBezier().

◆ PATH_PolyBezierTo()

BOOL FASTCALL PATH_PolyBezierTo ( PDC  dc,
const POINT pts,
DWORD  cbPoints 
)

Definition at line 1141 of file path.c.

1145{
1146 PPATH pPath;
1147 BOOL ret;
1148
1149 ASSERT(dc);
1150 ASSERT(pts);
1151 ASSERT(cbPoints);
1152
1153 pPath = PATH_LockPath(dc->dclevel.hPath);
1154 if (!pPath) return FALSE;
1155
1156 ret = add_log_points_new_stroke(dc, pPath, pts, cbPoints, PT_BEZIERTO , TRUE);
1157
1158 PATH_UnlockPath(pPath);
1159 return ret;
1160}

Referenced by IntGdiPolyBezierTo().

◆ PATH_PolyDraw()

BOOL FASTCALL PATH_PolyDraw ( PDC  dc,
const POINT pts,
const BYTE types,
DWORD  cbPoints 
)

Definition at line 1190 of file path.c.

1195{
1196 PPATH pPath;
1197 POINT orig_pos, cur_pos;
1198 ULONG i, lastmove = 0;
1199
1200 pPath = PATH_LockPath(dc->dclevel.hPath);
1201 if (!pPath) return FALSE;
1202
1203 if (pPath->state != PATH_Open)
1204 {
1205 PATH_UnlockPath(pPath);
1206 return FALSE;
1207 }
1208
1209 for (i = 0; i < pPath->numEntriesUsed; i++) if (pPath->pFlags[i] == PT_MOVETO) lastmove = i;
1210 orig_pos = pPath->pos;
1211
1212 IntGetCurrentPositionEx(dc, &cur_pos);
1213
1214 TRACE("PPD : Current pos X %d Y %d\n",pPath->pos.x, pPath->pos.y);
1215 TRACE("PPD : last %d pos X %d Y %d\n",lastmove, pPath->pPoints[lastmove].x, pPath->pPoints[lastmove].y);
1216
1217
1218 for(i = 0; i < cbPoints; i++)
1219 {
1220 switch (types[i])
1221 {
1222 case PT_MOVETO:
1223 pPath->newStroke = TRUE;
1224 pPath->pos = pts[i];
1225 IntLPtoDP( dc, &pPath->pos, 1);
1226 lastmove = pPath->numEntriesUsed;
1227 break;
1228 case PT_LINETO:
1230 if (!add_log_points_new_stroke(dc, pPath, &pts[i], 1, PT_LINETO , FALSE))
1231 {
1232 PATH_UnlockPath(pPath);
1233 return FALSE;
1234 }
1235 break;
1236 case PT_BEZIERTO:
1237 if ((i + 2 < cbPoints) && (types[i + 1] == PT_BEZIERTO) &&
1238 (types[i + 2] & ~PT_CLOSEFIGURE) == PT_BEZIERTO)
1239 {
1240 if (!add_log_points_new_stroke(dc, pPath, &pts[i], 3, PT_BEZIERTO , FALSE))
1241 {
1242 PATH_UnlockPath(pPath);
1243 return FALSE;
1244 }
1245 i += 2;
1246 break;
1247 }
1248 /* fall through */
1249 default:
1250 /* restore original position */
1251 pPath->pos = orig_pos;
1252
1253 TRACE("PPD Bad : pos X %d Y %d\n",pPath->pos.x, pPath->pos.y);
1254
1255 IntGdiMoveToEx(dc, cur_pos.x, cur_pos.y, NULL);
1256
1257 PATH_UnlockPath(pPath);
1258 return FALSE;
1259 }
1260
1261 if (types[i] & PT_CLOSEFIGURE)
1262 {
1263 close_figure( pPath );
1264 pPath->pos = pPath->pPoints[lastmove];
1265 TRACE("PPD close : pos X %d Y %d\n",pPath->pos.x, pPath->pos.y);
1266 }
1267 }
1268 PATH_UnlockPath(pPath);
1269 return TRUE;
1270}
BOOL FASTCALL IntGdiMoveToEx(DC *dc, int X, int Y, LPPOINT Point)
Definition: line.c:80
Definition: cmds.c:130
uint32_t ULONG
Definition: typedefs.h:59
static void close_figure(PPATH path)
Definition: path.c:536

Referenced by GdiPolyDraw().

◆ PATH_PolylineTo()

BOOL FASTCALL PATH_PolylineTo ( PDC  dc,
const POINT pts,
DWORD  cbPoints 
)

Definition at line 1274 of file path.c.

1278{
1279 PPATH pPath;
1280 BOOL ret;
1281
1282 ASSERT(dc);
1283 ASSERT(pts);
1284 ASSERT(cbPoints);
1285
1286 if (cbPoints < 1) return FALSE;
1287
1288 pPath = PATH_LockPath(dc->dclevel.hPath);
1289 if (!pPath) return FALSE;
1290
1291 if (pPath->newStroke)
1292 cbPoints--;
1293
1294 ret = add_log_points_new_stroke(dc, pPath, pts, cbPoints, PT_LINETO , TRUE);
1295 PATH_UnlockPath(pPath);
1296 return ret;
1297}

Referenced by IntGdiPolylineTo().

◆ PATH_PolyPolygon()

BOOL FASTCALL PATH_PolyPolygon ( PDC  dc,
const POINT pts,
const INT counts,
UINT  polygons 
)

Definition at line 1301 of file path.c.

1306{
1307 UINT poly, count;
1308 BYTE *type;
1309 PPATH pPath;
1310
1311 ASSERT(dc);
1312 ASSERT(pts);
1313 ASSERT(counts);
1314 ASSERT(polygons);
1315
1316 if (!polygons) return FALSE;
1317
1318 pPath = PATH_LockPath(dc->dclevel.hPath);
1319 if (!pPath) return FALSE;
1320
1321
1322 for (poly = count = 0; poly < polygons; poly++)
1323 {
1324 if (counts[poly] < 2)
1325 {
1326 PATH_UnlockPath(pPath);
1327 return FALSE;
1328 }
1329 count += counts[poly];
1330 }
1331
1332 type = add_log_points(dc, pPath, pts, count, PT_LINETO, FALSE);
1333 if (!type)
1334 {
1335 PATH_UnlockPath(pPath);
1336 return FALSE;
1337 }
1338
1339 /* make the first point of each polyline a PT_MOVETO, and close the last one */
1340 for (poly = 0; poly < polygons; type += counts[poly++])
1341 {
1342 type[0] = PT_MOVETO;
1343 type[counts[poly] - 1] = PT_LINETO | PT_CLOSEFIGURE;
1344 }
1345 PATH_UnlockPath(pPath);
1346 return TRUE;
1347}
unsigned int UINT
Definition: ndis.h:50

Referenced by IntGdiPolyPolygon().

◆ PATH_PolyPolyline()

BOOL FASTCALL PATH_PolyPolyline ( PDC  dc,
const POINT pts,
const DWORD counts,
DWORD  polylines 
)

Definition at line 1351 of file path.c.

1356{
1357 POINT pt;
1358 ULONG poly, point, i;
1359 PPATH pPath;
1360
1361 ASSERT(dc);
1362 ASSERT(pts);
1363 ASSERT(counts);
1364 ASSERT(polylines);
1365
1366 pPath = PATH_LockPath(dc->dclevel.hPath);
1367 if (!pPath)
1368 {
1369 return FALSE;
1370 }
1371
1372 for (i = 0, poly = 0; poly < polylines; poly++)
1373 {
1374 for (point = 0; point < counts[poly]; point++, i++)
1375 {
1376 pt = pts[i];
1377 CoordLPtoDP(dc, &pt);
1378 PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO);
1379 }
1380 }
1381 TRACE("PATH_PolyPolyline end count %d\n",pPath->numEntriesUsed);
1382 PATH_UnlockPath(pPath);
1383 return TRUE;
1384}

Referenced by IntGdiPolyPolyline().

◆ PATH_Rectangle()

BOOL FASTCALL PATH_Rectangle ( PDC  dc,
INT  x1,
INT  y1,
INT  x2,
INT  y2 
)

Definition at line 637 of file path.c.

643{
644 PPATH pPath;
645 RECTL rect;
646 POINTL points[4];
647 BYTE *type;
648
649 pPath = PATH_LockPath(dc->dclevel.hPath);
650 if (!pPath) return FALSE;
651
652 if (!PATH_CheckRect(dc, &rect, x1, y1, x2, y2))
653 {
654 PATH_UnlockPath(pPath);
655 return TRUE;
656 }
657
658 points[0].x = rect.right; points[0].y = rect.top;
659 points[1].x = rect.left; points[1].y = rect.top;
660 points[2].x = rect.left; points[2].y = rect.bottom;
661 points[3].x = rect.right; points[3].y = rect.bottom;
662
663 if (dc->dclevel.flPath & DCPATH_CLOCKWISE) reverse_points(points, 4 );
664
665 if (!(type = add_points( pPath, points, 4, PT_LINETO )))
666 {
667 PATH_UnlockPath(pPath);
668 return FALSE;
669 }
670 type[0] = PT_MOVETO;
671
672 /* Close the rectangle figure */
673 IntGdiCloseFigure(pPath) ;
674 PATH_UnlockPath(pPath);
675 return TRUE;
676}

Referenced by IntRectangle(), and PATH_RoundRect().

◆ PATH_ReserveEntries()

BOOL FASTCALL PATH_ReserveEntries ( PPATH  pPath,
INT  numEntries 
)

Definition at line 296 of file path.c.

299{
300 INT numEntriesToAllocate;
301 POINT *pPointsNew;
302 BYTE *pFlagsNew;
303
304 ASSERT(pPath != NULL);
305 ASSERT(numEntries >= 0);
306
307 /* Do we have to allocate more memory? */
308 if (numEntries > pPath->numEntriesAllocated)
309 {
310 /* Find number of entries to allocate. We let the size of the array
311 * grow exponentially, since that will guarantee linear time
312 * complexity. */
313 if (pPath->numEntriesAllocated)
314 {
315 numEntriesToAllocate = pPath->numEntriesAllocated;
316 while (numEntriesToAllocate < numEntries)
317 numEntriesToAllocate = numEntriesToAllocate * GROW_FACTOR_NUMER / GROW_FACTOR_DENOM;
318 }
319 else
320 numEntriesToAllocate = numEntries;
321
322 /* Allocate new arrays */
323 pPointsNew = (POINT *)ExAllocatePoolWithTag(PagedPool, numEntriesToAllocate * sizeof(POINT), TAG_PATH);
324 if (!pPointsNew)
325 return FALSE;
326
327 pFlagsNew = (BYTE *)ExAllocatePoolWithTag(PagedPool, numEntriesToAllocate * sizeof(BYTE), TAG_PATH);
328 if (!pFlagsNew)
329 {
330 ExFreePoolWithTag(pPointsNew, TAG_PATH);
331 return FALSE;
332 }
333
334 /* Copy old arrays to new arrays and discard old arrays */
335 if (pPath->pPoints)
336 {
337 ASSERT(pPath->pFlags);
338
339 memcpy(pPointsNew, pPath->pPoints, sizeof(POINT)*pPath->numEntriesUsed);
340 memcpy(pFlagsNew, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed);
341
344 }
345
346 pPath->pPoints = pPointsNew;
347 pPath->pFlags = pFlagsNew;
348 pPath->numEntriesAllocated = numEntriesToAllocate;
349 }
350
351 return TRUE;
352}
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define GROW_FACTOR_DENOM
Definition: path.c:24
#define GROW_FACTOR_NUMER
Definition: path.c:23

Referenced by add_log_points(), add_points(), PATH_AddEntry(), and PATH_AssignGdiPath().

◆ PATH_RestorePath()

BOOL PATH_RestorePath ( DC dst,
DC src 
)

Definition at line 209 of file path.c.

210{
211 TRACE("PATH_RestorePath\n");
212
213 if (dst->dclevel.hPath == NULL)
214 {
215 PPATH pdstPath, psrcPath = PATH_LockPath(src->dclevel.hPath);
216 TRACE("PATH_RestorePath 1\n");
217 pdstPath = PATH_CreatePath(psrcPath->numEntriesAllocated);
218 dst->dclevel.flPath = src->dclevel.flPath;
219 dst->dclevel.hPath = pdstPath->BaseObject.hHmgr;
220
221 PATH_AssignGdiPath(pdstPath, psrcPath);
222
223 PATH_UnlockPath(pdstPath);
224 PATH_UnlockPath(psrcPath);
225 }
226 else
227 {
228 PPATH pdstPath, psrcPath = PATH_LockPath(src->dclevel.hPath);
229 pdstPath = PATH_LockPath(dst->dclevel.hPath);
230 TRACE("PATH_RestorePath 2\n");
231 dst->dclevel.flPath = src->dclevel.flPath & (DCPATH_CLOCKWISE|DCPATH_ACTIVE);
232 PATH_AssignGdiPath(pdstPath, psrcPath);
233
234 PATH_UnlockPath(pdstPath);
235 PATH_UnlockPath(psrcPath);
236 }
237 return TRUE;
238}
GLenum src
Definition: glext.h:6340
GLenum GLenum dst
Definition: glext.h:6340
BOOL FASTCALL PATH_AssignGdiPath(PPATH pPathDest, const PPATH pPathSrc)
Definition: path.c:166

Referenced by DC_vRestoreDC().

◆ PATH_RoundRect()

BOOL PATH_RoundRect ( DC dc,
INT  x1,
INT  y1,
INT  x2,
INT  y2,
INT  ell_width,
INT  ell_height 
)

Definition at line 685 of file path.c.

693{
694 PPATH pPath;
695 RECTL rect, ellipse;
696 POINT points[16];
697 BYTE *type;
699
700 if (!ell_width || !ell_height) return PATH_Rectangle( dc, x1, y1, x2, y2 );
701
702 pPath = PATH_LockPath(dc->dclevel.hPath);
703 if (!pPath) return FALSE;
704
705 if (!PATH_CheckRect(dc, &rect, x1, y1, x2, y2))
706 {
707 PATH_UnlockPath(pPath);
708 return TRUE;
709 }
710
711 RECTL_vSetRect(&ellipse, 0, 0, ell_width, ell_height);
712 IntLPtoDP( dc, (PPOINT)&ellipse, 2 );
713 RECTL_vMakeWellOrdered(&ellipse);
714 ell_width = min(RECTL_lGetWidth(&ellipse), RECTL_lGetWidth(&rect));
715 ell_height = min(RECTL_lGetHeight(&ellipse), RECTL_lGetHeight(&rect));
716
717 /*
718 * See here to understand what's happening
719 * https://stackoverflow.com/questions/1734745/how-to-create-circle-with-b%C3%A9zier-curves
720 */
721 xOffset = EngMulDiv(ell_width, 44771525, 200000000); /* w * (1 - 0.5522847) / 2 */
722 yOffset = EngMulDiv(ell_height, 44771525, 200000000); /* h * (1 - 0.5522847) / 2 */
723 TRACE("xOffset %d, yOffset %d, Rect WxH: %dx%d.\n",
725
726 /*
727 * Get half width & height.
728 * Do not use integer division, we need the rounding made by EngMulDiv.
729 */
730 ell_width = EngMulDiv(ell_width, 1, 2);
731 ell_height = EngMulDiv(ell_height, 1, 2);
732
733 /* starting point */
734 points[0].x = rect.right;
735 points[0].y = rect.top + ell_height;
736 /* first curve */
737 points[1].x = rect.right;
738 points[1].y = rect.top + yOffset;
739 points[2].x = rect.right - xOffset;
740 points[2].y = rect.top;
741 points[3].x = rect.right - ell_width;
742 points[3].y = rect.top;
743 /* horizontal line */
744 points[4].x = rect.left + ell_width;
745 points[4].y = rect.top;
746 /* second curve */
747 points[5].x = rect.left + xOffset;
748 points[5].y = rect.top;
749 points[6].x = rect.left;
750 points[6].y = rect.top + yOffset;
751 points[7].x = rect.left;
752 points[7].y = rect.top + ell_height;
753 /* vertical line */
754 points[8].x = rect.left;
755 points[8].y = rect.bottom - ell_height;
756 /* third curve */
757 points[9].x = rect.left;
758 points[9].y = rect.bottom - yOffset;
759 points[10].x = rect.left + xOffset;
760 points[10].y = rect.bottom;
761 points[11].x = rect.left + ell_width;
762 points[11].y = rect.bottom;
763 /* horizontal line */
764 points[12].x = rect.right - ell_width;
765 points[12].y = rect.bottom;
766 /* fourth curve */
767 points[13].x = rect.right - xOffset;
768 points[13].y = rect.bottom;
769 points[14].x = rect.right;
770 points[14].y = rect.bottom - yOffset;
771 points[15].x = rect.right;
772 points[15].y = rect.bottom - ell_height;
773
774 if (dc->dclevel.flPath & DCPATH_CLOCKWISE) reverse_points( points, 16 );
775 if (!(type = add_points( pPath, points, 16, PT_BEZIERTO )))
776 {
777 PATH_UnlockPath(pPath);
778 return FALSE;
779 }
780 type[0] = PT_MOVETO;
781 type[4] = type[8] = type[12] = PT_LINETO;
782
783 IntGdiCloseFigure(pPath);
784 PATH_UnlockPath(pPath);
785 return TRUE;
786}
#define min(a, b)
Definition: monoChain.cc:55
BOOL FASTCALL PATH_Rectangle(PDC dc, INT x1, INT y1, INT x2, INT y2)
Definition: path.c:637
VOID FASTCALL RECTL_vMakeWellOrdered(_Inout_ RECTL *prcl)
Definition: rect.c:81
FORCEINLINE VOID RECTL_vSetRect(_Out_ RECTL *prcl, _In_ LONG left, _In_ LONG top, _In_ LONG right, _In_ LONG bottom)
Definition: rect.h:5

Referenced by IntRoundRect().

◆ PATH_SavePath()

BOOL PATH_SavePath ( DC dst,
DC src 
)

Definition at line 187 of file path.c.

188{
189 PPATH pdstPath, psrcPath = PATH_LockPath(src->dclevel.hPath);
190 TRACE("PATH_SavePath\n");
191 if (psrcPath)
192 {
193 TRACE("PATH_SavePath 1\n");
194
195 pdstPath = PATH_CreatePath(psrcPath->numEntriesAllocated);
196
197 dst->dclevel.flPath = src->dclevel.flPath;
198
199 dst->dclevel.hPath = pdstPath->BaseObject.hHmgr;
200
201 PATH_AssignGdiPath(pdstPath, psrcPath);
202
203 PATH_UnlockPath(pdstPath);
204 PATH_UnlockPath(psrcPath);
205 }
206 return TRUE;
207}

Referenced by NtGdiSaveDC().

◆ PATH_StrokePath()

BOOL FASTCALL PATH_StrokePath ( DC dc,
PPATH  pPath 
)

Definition at line 1610 of file path.c.

1613{
1614 BOOL ret = FALSE;
1615 INT nLinePts, nAlloc, jOldFillMode, i = 0;
1616 POINT *pLinePts = NULL;
1617 POINT ptViewportOrg, ptWindowOrg;
1618 SIZE szViewportExt, szWindowExt;
1619 DWORD mapMode, graphicsMode;
1620 XFORM xform;
1621 PDC_ATTR pdcattr = dc->pdcattr;
1622 PBRUSH pbrLine;
1623 PPATH pNewPath;
1624
1625 TRACE("Enter %s\n", __FUNCTION__);
1626
1627 pbrLine = dc->dclevel.pbrLine;
1628 if (IntIsEffectiveWidePen(pbrLine))
1629 {
1630 pNewPath = PATH_WidenPathEx(dc, pPath);
1631 if (pNewPath)
1632 {
1633 /* Fill the path with the WINDING fill mode */
1634 jOldFillMode = pdcattr->jFillMode;
1635 pdcattr->jFillMode = WINDING;
1636 PATH_FillPathEx(dc, pNewPath, pbrLine);
1637 pdcattr->jFillMode = jOldFillMode;
1638
1639 PATH_Delete(pNewPath->BaseObject.hHmgr);
1640 return TRUE;
1641 }
1642 }
1643
1644 /* Save the mapping mode info */
1645 mapMode = pdcattr->iMapMode;
1646
1647 szViewportExt = *DC_pszlViewportExt(dc);
1648 ptViewportOrg = dc->pdcattr->ptlViewportOrg;
1649 szWindowExt = dc->pdcattr->szlWindowExt;
1650 ptWindowOrg = dc->pdcattr->ptlWindowOrg;
1651
1652 MatrixS2XForm(&xform, &dc->pdcattr->mxWorldToPage);
1653
1654 /* Set MM_TEXT */
1655 pdcattr->iMapMode = MM_TEXT;
1656 pdcattr->ptlViewportOrg.x = 0;
1657 pdcattr->ptlViewportOrg.y = 0;
1658 pdcattr->ptlWindowOrg.x = 0;
1659 pdcattr->ptlWindowOrg.y = 0;
1660 graphicsMode = pdcattr->iGraphicsMode;
1661 pdcattr->iGraphicsMode = GM_ADVANCED;
1663 pdcattr->iGraphicsMode = graphicsMode;
1664
1665 /* Allocate enough memory for the worst case without beziers (one PT_MOVETO
1666 * and the rest PT_LINETO with PT_CLOSEFIGURE at the end) plus some buffer
1667 * space in case we get one to keep the number of reallocations small. */
1668 nAlloc = pPath->numEntriesUsed + 1 + 300;
1669 pLinePts = ExAllocatePoolWithTag(PagedPool, nAlloc * sizeof(POINT), TAG_PATH);
1670 if (!pLinePts)
1671 {
1672 ERR("Can't allocate pool!\n");
1674 goto end;
1675 }
1676 nLinePts = 0;
1677
1678 for (i = 0; i < pPath->numEntriesUsed; i++)
1679 {
1680 if ((i == 0 || (pPath->pFlags[i - 1] & PT_CLOSEFIGURE))
1681 && (pPath->pFlags[i] != PT_MOVETO))
1682 {
1683 ERR("Expected PT_MOVETO %s, got path flag %d\n",
1684 i == 0 ? "as first point" : "after PT_CLOSEFIGURE",
1685 (INT)pPath->pFlags[i]);
1686 goto end;
1687 }
1688
1689 switch(pPath->pFlags[i])
1690 {
1691 case PT_MOVETO:
1692 TRACE("Got PT_MOVETO (%ld, %ld)\n",
1693 pPath->pPoints[i].x, pPath->pPoints[i].y);
1694 if (nLinePts >= 2) IntGdiPolyline(dc, pLinePts, nLinePts);
1695 nLinePts = 0;
1696 pLinePts[nLinePts++] = pPath->pPoints[i];
1697 break;
1698 case PT_LINETO:
1699 case (PT_LINETO | PT_CLOSEFIGURE):
1700 TRACE("Got PT_LINETO (%ld, %ld)\n",
1701 pPath->pPoints[i].x, pPath->pPoints[i].y);
1702 pLinePts[nLinePts++] = pPath->pPoints[i];
1703 break;
1704 case PT_BEZIERTO:
1705 TRACE("Got PT_BEZIERTO\n");
1706 if (pPath->pFlags[i + 1] != PT_BEZIERTO ||
1707 (pPath->pFlags[i + 2] & ~PT_CLOSEFIGURE) != PT_BEZIERTO)
1708 {
1709 ERR("Path didn't contain 3 successive PT_BEZIERTOs\n");
1710 ret = FALSE;
1711 goto end;
1712 }
1713 else
1714 {
1715 INT nBzrPts, nMinAlloc;
1716 POINT *pBzrPts = GDI_Bezier(&pPath->pPoints[i - 1], 4, &nBzrPts);
1717 /* Make sure we have allocated enough memory for the lines of
1718 * this bezier and the rest of the path, assuming we won't get
1719 * another one (since we won't reallocate again then). */
1720 nMinAlloc = nLinePts + (pPath->numEntriesUsed - i) + nBzrPts;
1721 if (nAlloc < nMinAlloc)
1722 {
1723 // Reallocate memory
1724
1725 POINT *Realloc = NULL;
1726 nAlloc = nMinAlloc * 2;
1727
1729 nAlloc * sizeof(POINT),
1730 TAG_PATH);
1731
1732 if (!Realloc)
1733 {
1734 ERR("Can't allocate pool!\n");
1735 ExFreePoolWithTag(pBzrPts, TAG_BEZIER);
1736 goto end;
1737 }
1738
1739 memcpy(Realloc, pLinePts, nLinePts * sizeof(POINT));
1740 ExFreePoolWithTag(pLinePts, TAG_PATH);
1741 pLinePts = Realloc;
1742 }
1743 memcpy(&pLinePts[nLinePts], &pBzrPts[1], (nBzrPts - 1) * sizeof(POINT));
1744 nLinePts += nBzrPts - 1;
1745 ExFreePoolWithTag(pBzrPts, TAG_BEZIER);
1746 i += 2;
1747 }
1748 break;
1749 default:
1750 ERR("Got path flag %d (not supported)\n", (INT)pPath->pFlags[i]);
1751 goto end;
1752 }
1753
1754 if (pPath->pFlags[i] & PT_CLOSEFIGURE)
1755 {
1756 pLinePts[nLinePts++] = pLinePts[0];
1757 }
1758 }
1759 if (nLinePts >= 2)
1760 IntGdiPolyline(dc, pLinePts, nLinePts);
1761
1762 ret = TRUE;
1763
1764end:
1765 if (pLinePts) ExFreePoolWithTag(pLinePts, TAG_PATH);
1766
1767 /* Restore the old mapping mode */
1768 pdcattr->iMapMode = mapMode;
1769 pdcattr->szlWindowExt.cx = szWindowExt.cx;
1770 pdcattr->szlWindowExt.cy = szWindowExt.cy;
1771 pdcattr->ptlWindowOrg.x = ptWindowOrg.x;
1772 pdcattr->ptlWindowOrg.y = ptWindowOrg.y;
1773
1774 pdcattr->szlViewportExt.cx = szViewportExt.cx;
1775 pdcattr->szlViewportExt.cy = szViewportExt.cy;
1776 pdcattr->ptlViewportOrg.x = ptViewportOrg.x;
1777 pdcattr->ptlViewportOrg.y = ptViewportOrg.y;
1778
1779 /* Restore the world transform */
1780 XForm2MatrixS(&dc->pdcattr->mxWorldToPage, &xform);
1781
1782 /* If we've moved the current point then get its new position
1783 which will be in device (MM_TEXT) co-ords, convert it to
1784 logical co-ords and re-set it. This basically updates
1785 dc->CurPosX|Y so that their values are in the correct mapping
1786 mode.
1787 */
1788 if (i > 0)
1789 {
1790 POINT pt;
1792 IntDPtoLP(dc, &pt, 1);
1793 IntGdiMoveToEx(dc, pt.x, pt.y, NULL);
1794 }
1795 TRACE("Leave %s, ret=%d\n", __FUNCTION__, ret);
1796 return ret;
1797}
#define WINDING
Definition: constants.h:279
#define XForm2MatrixS(m, x)
Definition: coord.h:199
FORCEINLINE PSIZEL DC_pszlViewportExt(PDC pdc)
Definition: coord.h:111
static BOOLEAN IntDPtoLP(DC *pdc, PPOINTL ppt, UINT count)
Definition: coord.h:192
#define __FUNCTION__
Definition: types.h:116
BOOL FASTCALL IntGdiPolyline(DC *dc, LPPOINT pt, int Count)
Definition: line.c:327
void * Realloc(void *, size_t)
#define IntIsEffectiveWidePen(pbrLine)
Definition: pen.h:33
Definition: types.h:101
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
PPATH FASTCALL PATH_WidenPathEx(DC *dc, PPATH pPath)
Definition: path.c:2151

Referenced by IntGdiLineTo(), IntGdiPolygon(), IntGdiPolyline(), IntRectangle(), NtGdiStrokeAndFillPath(), and NtGdiStrokePath().

◆ PATH_WidenPathEx()

PPATH FASTCALL PATH_WidenPathEx ( DC dc,
PPATH  pPath 
)

Definition at line 2151 of file path.c.

2152{
2153 INT size;
2154 UINT penWidth, penStyle;
2155 DWORD obj_type;
2156 LPEXTLOGPEN elp;
2157 PDC_ATTR pdcattr = dc->pdcattr;
2158
2159 if (pPath->state != PATH_Closed)
2160 {
2161 TRACE("PWP 1\n");
2163 return NULL;
2164 }
2165
2166 size = GreGetObject(pdcattr->hpen, 0, NULL);
2167 if (!size)
2168 {
2169 TRACE("PWP 2\n");
2171 return NULL;
2172 }
2173
2175 if (elp == NULL)
2176 {
2177 TRACE("PWP 3\n");
2179 return NULL;
2180 }
2181
2182 GreGetObject(pdcattr->hpen, size, elp);
2183
2184 obj_type = GDI_HANDLE_GET_TYPE(pdcattr->hpen);
2185 if (obj_type == GDI_OBJECT_TYPE_PEN)
2186 {
2187 penStyle = ((LOGPEN*)elp)->lopnStyle;
2188 }
2189 else if (obj_type == GDI_OBJECT_TYPE_EXTPEN)
2190 {
2191 penStyle = elp->elpPenStyle;
2192 }
2193 else
2194 {
2195 TRACE("PWP 4\n");
2198 return NULL;
2199 }
2200
2201 penWidth = elp->elpWidth;
2203
2204 /* The function cannot apply to cosmetic pens */
2205 if (obj_type == GDI_OBJECT_TYPE_EXTPEN &&
2206 (PS_TYPE_MASK & penStyle) == PS_COSMETIC)
2207 {
2208 TRACE("PWP 5\n");
2210 return FALSE;
2211 }
2212
2213 return IntGdiWidenPath(pPath, penWidth, penStyle, dc->dclevel.laPath.eMiterLimit);
2214}
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define GDI_HANDLE_GET_TYPE(h)
Definition: gdi.h:31
#define GDI_OBJECT_TYPE_EXTPEN
Definition: gdi.h:55
#define GDI_OBJECT_TYPE_PEN
Definition: gdi.h:54
GLsizeiptr size
Definition: glext.h:5919
HANDLE hpen
Definition: ntgdihdl.h:296
DWORD elpWidth
Definition: wingdi.h:2389
DWORD elpPenStyle
Definition: wingdi.h:2388
INT NTAPI GreGetObject(IN HGDIOBJ hobj, IN INT cbCount, OUT PVOID pvBuffer)
Definition: gdiobj.c:1277
PPATH FASTCALL IntGdiWidenPath(PPATH pPath, UINT penWidth, UINT penStyle, FLOAT eMiterLimit)
Definition: path.c:1802
#define ERROR_CAN_NOT_COMPLETE
Definition: winerror.h:906
#define PS_COSMETIC
Definition: wingdi.h:584
#define PS_TYPE_MASK
Definition: wingdi.h:603

Referenced by PATH_StrokePath(), and PATH_WidenPath().