ReactOS 0.4.16-dev-338-g34e76ad
graphicspath.c File Reference
#include <stdarg.h>
#include <math.h>
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "wingdi.h"
#include "objbase.h"
#include "gdiplus.h"
#include "gdiplus_private.h"
#include "wine/debug.h"
Include dependency graph for graphicspath.c:

Go to the source code of this file.

Classes

struct  path_list_node_t
 
struct  format_string_args
 
struct  path_header
 

Macros

#define FLAGS_INTPATH   0x4000
 

Typedefs

typedef struct path_list_node_t path_list_node_t
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (gdiplus)
 
static BOOL init_path_list (path_list_node_t **node, REAL x, REAL y)
 
static void free_path_list (path_list_node_t *node)
 
static path_list_node_tadd_path_list_node (path_list_node_t *node, REAL x, REAL y, BOOL type)
 
static INT path_list_count (path_list_node_t *node)
 
static BOOL flatten_bezier (path_list_node_t *start, REAL x2, REAL y2, REAL x3, REAL y3, path_list_node_t *end, REAL flatness)
 
GpStatus WINGDIPAPI GdipAddPathArc (GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2, REAL startAngle, REAL sweepAngle)
 
GpStatus WINGDIPAPI GdipAddPathArcI (GpPath *path, INT x1, INT y1, INT x2, INT y2, REAL startAngle, REAL sweepAngle)
 
GpStatus WINGDIPAPI GdipAddPathBezier (GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2, REAL x3, REAL y3, REAL x4, REAL y4)
 
GpStatus WINGDIPAPI GdipAddPathBezierI (GpPath *path, INT x1, INT y1, INT x2, INT y2, INT x3, INT y3, INT x4, INT y4)
 
GpStatus WINGDIPAPI GdipAddPathBeziers (GpPath *path, GDIPCONST GpPointF *points, INT count)
 
GpStatus WINGDIPAPI GdipAddPathBeziersI (GpPath *path, GDIPCONST GpPoint *points, INT count)
 
GpStatus WINGDIPAPI GdipAddPathClosedCurve (GpPath *path, GDIPCONST GpPointF *points, INT count)
 
GpStatus WINGDIPAPI GdipAddPathClosedCurveI (GpPath *path, GDIPCONST GpPoint *points, INT count)
 
GpStatus WINGDIPAPI GdipAddPathClosedCurve2 (GpPath *path, GDIPCONST GpPointF *points, INT count, REAL tension)
 
GpStatus WINGDIPAPI GdipAddPathClosedCurve2I (GpPath *path, GDIPCONST GpPoint *points, INT count, REAL tension)
 
GpStatus WINGDIPAPI GdipAddPathCurve (GpPath *path, GDIPCONST GpPointF *points, INT count)
 
GpStatus WINGDIPAPI GdipAddPathCurveI (GpPath *path, GDIPCONST GpPoint *points, INT count)
 
GpStatus WINGDIPAPI GdipAddPathCurve2 (GpPath *path, GDIPCONST GpPointF *points, INT count, REAL tension)
 
GpStatus WINGDIPAPI GdipAddPathCurve2I (GpPath *path, GDIPCONST GpPoint *points, INT count, REAL tension)
 
GpStatus WINGDIPAPI GdipAddPathCurve3 (GpPath *path, GDIPCONST GpPointF *points, INT count, INT offset, INT nseg, REAL tension)
 
GpStatus WINGDIPAPI GdipAddPathCurve3I (GpPath *path, GDIPCONST GpPoint *points, INT count, INT offset, INT nseg, REAL tension)
 
GpStatus WINGDIPAPI GdipAddPathEllipse (GpPath *path, REAL x, REAL y, REAL width, REAL height)
 
GpStatus WINGDIPAPI GdipAddPathEllipseI (GpPath *path, INT x, INT y, INT width, INT height)
 
GpStatus WINGDIPAPI GdipAddPathLine2 (GpPath *path, GDIPCONST GpPointF *points, INT count)
 
GpStatus WINGDIPAPI GdipAddPathLine2I (GpPath *path, GDIPCONST GpPoint *points, INT count)
 
GpStatus WINGDIPAPI GdipAddPathLine (GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2)
 
GpStatus WINGDIPAPI GdipAddPathLineI (GpPath *path, INT x1, INT y1, INT x2, INT y2)
 
GpStatus WINGDIPAPI GdipAddPathPath (GpPath *path, GDIPCONST GpPath *addingPath, BOOL connect)
 
GpStatus WINGDIPAPI GdipAddPathPie (GpPath *path, REAL x, REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle)
 
GpStatus WINGDIPAPI GdipAddPathPieI (GpPath *path, INT x, INT y, INT width, INT height, REAL startAngle, REAL sweepAngle)
 
GpStatus WINGDIPAPI GdipAddPathPolygon (GpPath *path, GDIPCONST GpPointF *points, INT count)
 
GpStatus WINGDIPAPI GdipAddPathPolygonI (GpPath *path, GDIPCONST GpPoint *points, INT count)
 
static float fromfixedpoint (const FIXED v)
 
static GpStatus format_string_callback (HDC dc, GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font, GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format, INT lineno, const RectF *bounds, INT *underlined_indexes, INT underlined_index_count, void *priv)
 
GpStatus WINGDIPAPI GdipAddPathString (GpPath *path, GDIPCONST WCHAR *string, INT length, GDIPCONST GpFontFamily *family, INT style, REAL emSize, GDIPCONST RectF *layoutRect, GDIPCONST GpStringFormat *format)
 
GpStatus WINGDIPAPI GdipAddPathStringI (GpPath *path, GDIPCONST WCHAR *string, INT length, GDIPCONST GpFontFamily *family, INT style, REAL emSize, GDIPCONST Rect *layoutRect, GDIPCONST GpStringFormat *format)
 
GpStatus WINGDIPAPI GdipClonePath (GpPath *path, GpPath **clone)
 
GpStatus WINGDIPAPI GdipClosePathFigure (GpPath *path)
 
GpStatus WINGDIPAPI GdipClosePathFigures (GpPath *path)
 
GpStatus WINGDIPAPI GdipCreatePath (GpFillMode fill, GpPath **path)
 
GpStatus WINGDIPAPI GdipCreatePath2 (GDIPCONST GpPointF *points, GDIPCONST BYTE *types, INT count, GpFillMode fill, GpPath **path)
 
GpStatus WINGDIPAPI GdipCreatePath2I (GDIPCONST GpPoint *points, GDIPCONST BYTE *types, INT count, GpFillMode fill, GpPath **path)
 
GpStatus WINGDIPAPI GdipDeletePath (GpPath *path)
 
GpStatus WINGDIPAPI GdipFlattenPath (GpPath *path, GpMatrix *matrix, REAL flatness)
 
GpStatus WINGDIPAPI GdipGetPathData (GpPath *path, GpPathData *pathData)
 
GpStatus WINGDIPAPI GdipGetPathFillMode (GpPath *path, GpFillMode *fillmode)
 
GpStatus WINGDIPAPI GdipGetPathLastPoint (GpPath *path, GpPointF *lastPoint)
 
GpStatus WINGDIPAPI GdipGetPathPoints (GpPath *path, GpPointF *points, INT count)
 
GpStatus WINGDIPAPI GdipGetPathPointsI (GpPath *path, GpPoint *points, INT count)
 
GpStatus WINGDIPAPI GdipGetPathTypes (GpPath *path, BYTE *types, INT count)
 
GpStatus WINGDIPAPI GdipGetPathWorldBounds (GpPath *path, GpRectF *bounds, GDIPCONST GpMatrix *matrix, GDIPCONST GpPen *pen)
 
GpStatus WINGDIPAPI GdipGetPathWorldBoundsI (GpPath *path, GpRect *bounds, GDIPCONST GpMatrix *matrix, GDIPCONST GpPen *pen)
 
GpStatus WINGDIPAPI GdipGetPointCount (GpPath *path, INT *count)
 
GpStatus WINGDIPAPI GdipReversePath (GpPath *path)
 
GpStatus WINGDIPAPI GdipIsOutlineVisiblePathPointI (GpPath *path, INT x, INT y, GpPen *pen, GpGraphics *graphics, BOOL *result)
 
GpStatus WINGDIPAPI GdipIsOutlineVisiblePathPoint (GpPath *path, REAL x, REAL y, GpPen *pen, GpGraphics *graphics, BOOL *result)
 
GpStatus WINGDIPAPI GdipIsVisiblePathPointI (GpPath *path, INT x, INT y, GpGraphics *graphics, BOOL *result)
 
GpStatus WINGDIPAPI GdipIsVisiblePathPoint (GpPath *path, REAL x, REAL y, GpGraphics *graphics, BOOL *result)
 
GpStatus WINGDIPAPI GdipStartPathFigure (GpPath *path)
 
GpStatus WINGDIPAPI GdipResetPath (GpPath *path)
 
GpStatus WINGDIPAPI GdipSetPathFillMode (GpPath *path, GpFillMode fill)
 
GpStatus WINGDIPAPI GdipTransformPath (GpPath *path, GpMatrix *matrix)
 
GpStatus WINGDIPAPI GdipWarpPath (GpPath *path, GpMatrix *matrix, GDIPCONST GpPointF *points, INT count, REAL x, REAL y, REAL width, REAL height, WarpMode warpmode, REAL flatness)
 
static void add_bevel_point (const GpPointF *endpoint, const GpPointF *nextpoint, GpPen *pen, int right_side, path_list_node_t **last_point)
 
static void widen_joint (const GpPointF *p1, const GpPointF *p2, const GpPointF *p3, GpPen *pen, path_list_node_t **last_point)
 
static void widen_cap (const GpPointF *endpoint, const GpPointF *nextpoint, GpPen *pen, GpLineCap cap, GpCustomLineCap *custom, int add_first_points, int add_last_point, path_list_node_t **last_point)
 
static void widen_open_figure (const GpPointF *points, GpPen *pen, int start, int end, GpLineCap start_cap, GpCustomLineCap *start_custom, GpLineCap end_cap, GpCustomLineCap *end_custom, path_list_node_t **last_point)
 
static void widen_closed_figure (GpPath *path, GpPen *pen, int start, int end, path_list_node_t **last_point)
 
static void widen_dashed_figure (GpPath *path, GpPen *pen, int start, int end, int closed, path_list_node_t **last_point)
 
GpStatus WINGDIPAPI GdipWidenPath (GpPath *path, GpPen *pen, GpMatrix *matrix, REAL flatness)
 
GpStatus WINGDIPAPI GdipAddPathRectangle (GpPath *path, REAL x, REAL y, REAL width, REAL height)
 
GpStatus WINGDIPAPI GdipAddPathRectangleI (GpPath *path, INT x, INT y, INT width, INT height)
 
GpStatus WINGDIPAPI GdipAddPathRectangles (GpPath *path, GDIPCONST GpRectF *rects, INT count)
 
GpStatus WINGDIPAPI GdipAddPathRectanglesI (GpPath *path, GDIPCONST GpRect *rects, INT count)
 
GpStatus WINGDIPAPI GdipSetPathMarker (GpPath *path)
 
GpStatus WINGDIPAPI GdipClearPathMarkers (GpPath *path)
 
GpStatus WINGDIPAPI GdipWindingModeOutline (GpPath *path, GpMatrix *matrix, REAL flatness)
 
static BOOL is_integer_path (const GpPath *path)
 
DWORD write_path_data (GpPath *path, void *data)
 

Macro Definition Documentation

◆ FLAGS_INTPATH

#define FLAGS_INTPATH   0x4000

Definition at line 2464 of file graphicspath.c.

Typedef Documentation

◆ path_list_node_t

Definition at line 36 of file graphicspath.c.

Function Documentation

◆ add_bevel_point()

static void add_bevel_point ( const GpPointF endpoint,
const GpPointF nextpoint,
GpPen pen,
int  right_side,
path_list_node_t **  last_point 
)
static

Definition at line 1806 of file graphicspath.c.

1808{
1809 REAL segment_dy = nextpoint->Y-endpoint->Y;
1810 REAL segment_dx = nextpoint->X-endpoint->X;
1811 REAL segment_length = sqrtf(segment_dy*segment_dy + segment_dx*segment_dx);
1812 REAL distance = pen->width/2.0;
1813 REAL bevel_dx, bevel_dy;
1814
1815 if (segment_length == 0.0)
1816 {
1817 *last_point = add_path_list_node(*last_point, endpoint->X,
1819 return;
1820 }
1821
1822 if (right_side)
1823 {
1824 bevel_dx = -distance * segment_dy / segment_length;
1825 bevel_dy = distance * segment_dx / segment_length;
1826 }
1827 else
1828 {
1829 bevel_dx = distance * segment_dy / segment_length;
1830 bevel_dy = -distance * segment_dx / segment_length;
1831 }
1832
1833 *last_point = add_path_list_node(*last_point, endpoint->X + bevel_dx,
1834 endpoint->Y + bevel_dy, PathPointTypeLine);
1835}
float REAL
Definition: types.h:41
static path_list_node_t * add_path_list_node(path_list_node_t *node, REAL x, REAL y, BOOL type)
Definition: graphicspath.c:76
@ PathPointTypeLine
Definition: gdiplusenums.h:85
GLsizei GLsizei GLfloat distance
Definition: glext.h:11755
#define sqrtf(x)
Definition: mymath.h:59
REAL width
REAL Y
Definition: gdiplustypes.h:649
REAL X
Definition: gdiplustypes.h:648
Definition: nis.h:10

Referenced by widen_cap(), and widen_joint().

◆ add_path_list_node()

static path_list_node_t * add_path_list_node ( path_list_node_t node,
REAL  x,
REAL  y,
BOOL  type 
)
static

Definition at line 76 of file graphicspath.c.

77{
79
80 new = heap_alloc_zero(sizeof(path_list_node_t));
81 if(!new)
82 return NULL;
83
84 new->pt.X = x;
85 new->pt.Y = y;
86 new->type = type;
87 new->next = node->next;
88 node->next = new;
89
90 return new;
91}
#define NULL
Definition: types.h:112
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
Definition: dlist.c:348
void * next
Definition: dlist.c:360

Referenced by add_bevel_point(), flatten_bezier(), GdipFlattenPath(), widen_cap(), and widen_joint().

◆ flatten_bezier()

static BOOL flatten_bezier ( path_list_node_t start,
REAL  x2,
REAL  y2,
REAL  x3,
REAL  y3,
path_list_node_t end,
REAL  flatness 
)
static

Definition at line 121 of file graphicspath.c.

123{
124 /* this 5 middle points with start/end define to half-curves */
125 GpPointF mp[5];
126 GpPointF pt, pt_st;
128
129 /* calculate bezier curve middle points == new control points */
130 mp[0].X = (start->pt.X + x2) / 2.0;
131 mp[0].Y = (start->pt.Y + y2) / 2.0;
132 /* middle point between control points */
133 pt.X = (x2 + x3) / 2.0;
134 pt.Y = (y2 + y3) / 2.0;
135 mp[1].X = (mp[0].X + pt.X) / 2.0;
136 mp[1].Y = (mp[0].Y + pt.Y) / 2.0;
137 mp[4].X = (end->pt.X + x3) / 2.0;
138 mp[4].Y = (end->pt.Y + y3) / 2.0;
139 mp[3].X = (mp[4].X + pt.X) / 2.0;
140 mp[3].Y = (mp[4].Y + pt.Y) / 2.0;
141
142 mp[2].X = (mp[1].X + mp[3].X) / 2.0;
143 mp[2].Y = (mp[1].Y + mp[3].Y) / 2.0;
144
145 if ((x2 == mp[0].X && y2 == mp[0].Y && x3 == mp[1].X && y3 == mp[1].Y) ||
146 (x2 == mp[3].X && y2 == mp[3].Y && x3 == mp[4].X && y3 == mp[4].Y))
147 return TRUE;
148
149 pt = end->pt;
150 pt_st = start->pt;
151 /* check flatness as a half of distance between middle point and a linearized path */
152 if(fabs(((pt.Y - pt_st.Y)*mp[2].X + (pt_st.X - pt.X)*mp[2].Y +
153 (pt_st.Y*pt.X - pt_st.X*pt.Y))) <=
154 (0.5 * flatness*sqrtf((powf(pt.Y - pt_st.Y, 2.0) + powf(pt_st.X - pt.X, 2.0))))){
155 return TRUE;
156 }
157 else
158 /* add a middle point */
159 if(!(node = add_path_list_node(start, mp[2].X, mp[2].Y, PathPointTypeLine)))
160 return FALSE;
161
162 /* do the same with halves */
163 flatten_bezier(start, mp[0].X, mp[0].Y, mp[1].X, mp[1].Y, node, flatness);
164 flatten_bezier(node, mp[3].X, mp[3].Y, mp[4].X, mp[4].Y, end, flatness);
165
166 return TRUE;
167}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define Y(I)
static BOOL flatten_bezier(path_list_node_t *start, REAL x2, REAL y2, REAL x3, REAL y3, path_list_node_t *end, REAL flatness)
Definition: graphicspath.c:121
#define pt(x, y)
Definition: drawing.c:79
GLuint start
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
_Check_return_ float __cdecl powf(_In_ float b, _In_ float e)
Definition: math.h:232
_Check_return_ _CRT_JIT_INTRINSIC double __cdecl fabs(_In_ double x)
Definition: fabs.c:17
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3710
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG _In_ LONG y2
Definition: winddi.h:3711

Referenced by flatten_bezier(), and GdipFlattenPath().

◆ format_string_callback()

static GpStatus format_string_callback ( HDC  dc,
GDIPCONST WCHAR string,
INT  index,
INT  length,
GDIPCONST GpFont font,
GDIPCONST RectF rect,
GDIPCONST GpStringFormat format,
INT  lineno,
const RectF bounds,
INT underlined_indexes,
INT  underlined_index_count,
void priv 
)
static

Definition at line 912 of file graphicspath.c.

917{
918 static const MAT2 identity = { {0,1}, {0,0}, {0,0}, {0,1} };
919 struct format_string_args *args = priv;
920 GpPath *path = args->path;
922 float x = rect->X + (bounds->X - rect->X) * args->scale;
923 float y = rect->Y + (bounds->Y - rect->Y) * args->scale;
924 int i;
925
926 if (underlined_index_count)
927 FIXME("hotkey underlines not drawn yet\n");
928
929 if (y + bounds->Height * args->scale > args->maxY)
930 args->maxY = y + bounds->Height * args->scale;
931
932 for (i = index; i < length; ++i)
933 {
934 GLYPHMETRICS gm;
935 TTPOLYGONHEADER *ph = NULL, *origph;
936 char *start;
937 DWORD len, ofs = 0;
938 len = GetGlyphOutlineW(dc, string[i], GGO_BEZIER, &gm, 0, NULL, &identity);
939 if (len == GDI_ERROR)
940 {
942 break;
943 }
944 origph = ph = heap_alloc_zero(len);
945 start = (char *)ph;
946 if (!ph || !lengthen_path(path, len / sizeof(POINTFX)))
947 {
948 heap_free(ph);
950 break;
951 }
952 GetGlyphOutlineW(dc, string[i], GGO_BEZIER, &gm, len, start, &identity);
953
954 ofs = 0;
955 while (ofs < len)
956 {
957 DWORD ofs_start = ofs;
958 ph = (TTPOLYGONHEADER*)&start[ofs];
959 path->pathdata.Types[path->pathdata.Count] = PathPointTypeStart;
960 path->pathdata.Points[path->pathdata.Count].X = x + fromfixedpoint(ph->pfxStart.x) * args->scale;
961 path->pathdata.Points[path->pathdata.Count++].Y = y + args->ascent - fromfixedpoint(ph->pfxStart.y) * args->scale;
962 TRACE("Starting at count %i with pos %f, %f)\n", path->pathdata.Count, x, y);
963 ofs += sizeof(*ph);
964 while (ofs - ofs_start < ph->cb)
965 {
966 TTPOLYCURVE *curve = (TTPOLYCURVE*)&start[ofs];
967 int j;
968 ofs += sizeof(TTPOLYCURVE) + (curve->cpfx - 1) * sizeof(POINTFX);
969
970 switch (curve->wType)
971 {
972 case TT_PRIM_LINE:
973 for (j = 0; j < curve->cpfx; ++j)
974 {
975 path->pathdata.Types[path->pathdata.Count] = PathPointTypeLine;
976 path->pathdata.Points[path->pathdata.Count].X = x + fromfixedpoint(curve->apfx[j].x) * args->scale;
977 path->pathdata.Points[path->pathdata.Count++].Y = y + args->ascent - fromfixedpoint(curve->apfx[j].y) * args->scale;
978 }
979 break;
980 case TT_PRIM_CSPLINE:
981 for (j = 0; j < curve->cpfx; ++j)
982 {
983 path->pathdata.Types[path->pathdata.Count] = PathPointTypeBezier;
984 path->pathdata.Points[path->pathdata.Count].X = x + fromfixedpoint(curve->apfx[j].x) * args->scale;
985 path->pathdata.Points[path->pathdata.Count++].Y = y + args->ascent - fromfixedpoint(curve->apfx[j].y) * args->scale;
986 }
987 break;
988 default:
989 ERR("Unhandled type: %u\n", curve->wType);
991 }
992 }
993 path->pathdata.Types[path->pathdata.Count - 1] |= PathPointTypeCloseSubpath;
994 }
995 path->newfigure = TRUE;
996 x += gm.gmCellIncX * args->scale;
997 y += gm.gmCellIncY * args->scale;
998
999 heap_free(origph);
1000 if (status != Ok)
1001 break;
1002 }
1003
1004 return status;
1005}
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERR(fmt,...)
Definition: precomp.h:57
static float fromfixedpoint(const FIXED v)
Definition: graphicspath.c:897
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL lengthen_path(GpPath *path, INT len)
Definition: gdiplus.c:405
@ PathPointTypeBezier
Definition: gdiplusenums.h:86
@ PathPointTypeCloseSubpath
Definition: gdiplusenums.h:90
@ PathPointTypeStart
Definition: gdiplusenums.h:84
Status
Definition: gdiplustypes.h:25
@ Ok
Definition: gdiplustypes.h:26
@ OutOfMemory
Definition: gdiplustypes.h:29
@ GenericError
Definition: gdiplustypes.h:27
GLuint index
Definition: glext.h:6031
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLenum GLsizei len
Definition: glext.h:6722
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
static const WCHAR dc[]
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
#define TRACE(s)
Definition: solgame.cpp:4
& rect
Definition: startmenu.cpp:1413
REAL Height
Definition: gdiplustypes.h:664
REAL X
Definition: gdiplustypes.h:661
REAL Y
Definition: gdiplustypes.h:662
short gmCellIncX
Definition: wingdi.h:2445
short gmCellIncY
Definition: wingdi.h:2446
Definition: wingdi.h:2472
Definition: match.c:390
Definition: ps.c:97
FIXED y
Definition: wingdi.h:2709
FIXED x
Definition: wingdi.h:2708
POINTFX apfx[1]
Definition: wingdi.h:2714
POINTFX pfxStart
Definition: wingdi.h:2719
struct tagPOINTFX POINTFX
#define TT_PRIM_CSPLINE
Definition: wingdi.h:1321
struct tagTTPOLYCURVE TTPOLYCURVE
#define GDI_ERROR
Definition: wingdi.h:1309
#define TT_PRIM_LINE
Definition: wingdi.h:1319
DWORD WINAPI GetGlyphOutlineW(_In_ HDC hdc, _In_ UINT uChar, _In_ UINT fuFormat, _Out_ LPGLYPHMETRICS lpgm, _In_ DWORD cjBuffer, _Out_writes_bytes_opt_(cjBuffer) LPVOID pvBuffer, _In_ CONST MAT2 *lpmat2)
#define GGO_BEZIER
Definition: wingdi.h:851

Referenced by GdipAddPathString().

◆ free_path_list()

static void free_path_list ( path_list_node_t node)
static

Definition at line 59 of file graphicspath.c.

60{
62
63 while(n){
64 n = n->next;
66 node = n;
67 }
68}
GLdouble n
Definition: glext.h:7729

Referenced by GdipFlattenPath(), and GdipWidenPath().

◆ fromfixedpoint()

static float fromfixedpoint ( const FIXED  v)
static

Definition at line 897 of file graphicspath.c.

898{
899 float f = ((float)v.fract) / (1<<(sizeof(v.fract)*8));
900 f += v.value;
901 return f;
902}
const GLdouble * v
Definition: gl.h:2040
GLfloat f
Definition: glext.h:7540
#define f
Definition: ke_i.h:83
static float(__cdecl *square_half_float)(float x

Referenced by format_string_callback().

◆ GdipAddPathArc()

GpStatus WINGDIPAPI GdipAddPathArc ( GpPath path,
REAL  x1,
REAL  y1,
REAL  x2,
REAL  y2,
REAL  startAngle,
REAL  sweepAngle 
)

Definition at line 195 of file graphicspath.c.

197{
198 INT count, old_count, i;
199
200 TRACE("(%p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n",
201 path, x1, y1, x2, y2, startAngle, sweepAngle);
202
203 if(!path)
204 return InvalidParameter;
205
206 count = arc2polybezier(NULL, x1, y1, x2, y2, startAngle, sweepAngle);
207
208 if(count == 0)
209 return Ok;
211 return OutOfMemory;
212
213 old_count = path->pathdata.Count;
214 arc2polybezier(&path->pathdata.Points[old_count], x1, y1, x2, y2,
215 startAngle, sweepAngle);
216
217 for(i = 0; i < count; i++){
218 path->pathdata.Types[old_count + i] = PathPointTypeBezier;
219 }
220
221 path->pathdata.Types[old_count] =
223 path->newfigure = FALSE;
224 path->pathdata.Count += count;
225
226 return Ok;
227}
INT arc2polybezier(GpPointF *points, REAL x1, REAL y1, REAL x2, REAL y2, REAL startAngle, REAL sweepAngle)
Definition: gdiplus.c:223
@ InvalidParameter
Definition: gdiplustypes.h:28
GLuint GLuint GLsizei count
Definition: gl.h:1545
int32_t INT
Definition: typedefs.h:58
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG y1
Definition: winddi.h:3709
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3708

Referenced by GdipAddPathArcI(), GdipDrawArc(), test_arc(), test_flatten(), test_getregiondata(), test_linei(), test_pathpath(), and test_worldbounds().

◆ GdipAddPathArcI()

GpStatus WINGDIPAPI GdipAddPathArcI ( GpPath path,
INT  x1,
INT  y1,
INT  x2,
INT  y2,
REAL  startAngle,
REAL  sweepAngle 
)

Definition at line 234 of file graphicspath.c.

236{
237 TRACE("(%p, %d, %d, %d, %d, %.2f, %.2f)\n",
238 path, x1, y1, x2, y2, startAngle, sweepAngle);
239
240 return GdipAddPathArc(path,(REAL)x1,(REAL)y1,(REAL)x2,(REAL)y2,startAngle,sweepAngle);
241}
GpStatus WINGDIPAPI GdipAddPathArc(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2, REAL startAngle, REAL sweepAngle)
Definition: graphicspath.c:195

◆ GdipAddPathBezier()

GpStatus WINGDIPAPI GdipAddPathBezier ( GpPath path,
REAL  x1,
REAL  y1,
REAL  x2,
REAL  y2,
REAL  x3,
REAL  y3,
REAL  x4,
REAL  y4 
)

Definition at line 243 of file graphicspath.c.

245{
246 INT old_count;
247
248 TRACE("(%p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n",
249 path, x1, y1, x2, y2, x3, y3, x4, y4);
250
251 if(!path)
252 return InvalidParameter;
253
254 if(!lengthen_path(path, 4))
255 return OutOfMemory;
256
257 old_count = path->pathdata.Count;
258
259 path->pathdata.Points[old_count].X = x1;
260 path->pathdata.Points[old_count].Y = y1;
261 path->pathdata.Points[old_count + 1].X = x2;
262 path->pathdata.Points[old_count + 1].Y = y2;
263 path->pathdata.Points[old_count + 2].X = x3;
264 path->pathdata.Points[old_count + 2].Y = y3;
265 path->pathdata.Points[old_count + 3].X = x4;
266 path->pathdata.Points[old_count + 3].Y = y4;
267
268 path->pathdata.Types[old_count] =
270 path->pathdata.Types[old_count + 1] = PathPointTypeBezier;
271 path->pathdata.Types[old_count + 2] = PathPointTypeBezier;
272 path->pathdata.Types[old_count + 3] = PathPointTypeBezier;
273
274 path->newfigure = FALSE;
275 path->pathdata.Count += 4;
276
277 return Ok;
278}

Referenced by GdipAddPathBezierI().

◆ GdipAddPathBezierI()

GpStatus WINGDIPAPI GdipAddPathBezierI ( GpPath path,
INT  x1,
INT  y1,
INT  x2,
INT  y2,
INT  x3,
INT  y3,
INT  x4,
INT  y4 
)

Definition at line 280 of file graphicspath.c.

282{
283 TRACE("(%p, %d, %d, %d, %d, %d, %d, %d, %d)\n",
284 path, x1, y1, x2, y2, x3, y3, x4, y4);
285
286 return GdipAddPathBezier(path,(REAL)x1,(REAL)y1,(REAL)x2,(REAL)y2,(REAL)x3,(REAL)y3,
287 (REAL)x4,(REAL)y4);
288}
GpStatus WINGDIPAPI GdipAddPathBezier(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2, REAL x3, REAL y3, REAL x4, REAL y4)
Definition: graphicspath.c:243

◆ GdipAddPathBeziers()

GpStatus WINGDIPAPI GdipAddPathBeziers ( GpPath path,
GDIPCONST GpPointF points,
INT  count 
)

Definition at line 290 of file graphicspath.c.

292{
293 INT i, old_count;
294
295 TRACE("(%p, %p, %d)\n", path, points, count);
296
297 if(!path || !points || ((count - 1) % 3))
298 return InvalidParameter;
299
301 return OutOfMemory;
302
303 old_count = path->pathdata.Count;
304
305 for(i = 0; i < count; i++){
306 path->pathdata.Points[old_count + i].X = points[i].X;
307 path->pathdata.Points[old_count + i].Y = points[i].Y;
308 path->pathdata.Types[old_count + i] = PathPointTypeBezier;
309 }
310
311 path->pathdata.Types[old_count] =
313 path->newfigure = FALSE;
314 path->pathdata.Count += count;
315
316 return Ok;
317}
GLsizei const GLfloat * points
Definition: glext.h:8112

Referenced by GdipAddPathBeziersI(), GdipAddPathClosedCurve2(), GdipAddPathCurve2(), and GdipDrawBeziers().

◆ GdipAddPathBeziersI()

GpStatus WINGDIPAPI GdipAddPathBeziersI ( GpPath path,
GDIPCONST GpPoint points,
INT  count 
)

Definition at line 319 of file graphicspath.c.

321{
322 GpPointF *ptsF;
324 INT i;
325
326 TRACE("(%p, %p, %d)\n", path, points, count);
327
328 if(!points || ((count - 1) % 3))
329 return InvalidParameter;
330
331 ptsF = heap_alloc_zero(sizeof(GpPointF) * count);
332 if(!ptsF)
333 return OutOfMemory;
334
335 for(i = 0; i < count; i++){
336 ptsF[i].X = (REAL)points[i].X;
337 ptsF[i].Y = (REAL)points[i].Y;
338 }
339
341 heap_free(ptsF);
342
343 return ret;
344}
GpStatus WINGDIPAPI GdipAddPathBeziers(GpPath *path, GDIPCONST GpPointF *points, INT count)
Definition: graphicspath.c:290
int ret

◆ GdipAddPathClosedCurve()

GpStatus WINGDIPAPI GdipAddPathClosedCurve ( GpPath path,
GDIPCONST GpPointF points,
INT  count 
)

Definition at line 346 of file graphicspath.c.

348{
349 TRACE("(%p, %p, %d)\n", path, points, count);
350
352}
GpStatus WINGDIPAPI GdipAddPathClosedCurve2(GpPath *path, GDIPCONST GpPointF *points, INT count, REAL tension)
Definition: graphicspath.c:362

◆ GdipAddPathClosedCurve2()

GpStatus WINGDIPAPI GdipAddPathClosedCurve2 ( GpPath path,
GDIPCONST GpPointF points,
INT  count,
REAL  tension 
)

Definition at line 362 of file graphicspath.c.

364{
365 INT i, len_pt = (count + 1)*3-2;
366 GpPointF *pt;
367 GpPointF *pts;
368 REAL x1, x2, y1, y2;
370
371 TRACE("(%p, %p, %d, %.2f)\n", path, points, count, tension);
372
373 if(!path || !points || count <= 1)
374 return InvalidParameter;
375
376 pt = heap_alloc_zero(len_pt * sizeof(GpPointF));
377 pts = heap_alloc_zero((count + 1)*sizeof(GpPointF));
378 if(!pt || !pts){
379 heap_free(pt);
380 heap_free(pts);
381 return OutOfMemory;
382 }
383
384 /* copy source points to extend with the last one */
385 memcpy(pts, points, sizeof(GpPointF)*count);
386 pts[count] = pts[0];
387
388 tension = tension * TENSION_CONST;
389
390 for(i = 0; i < count-1; i++){
391 calc_curve_bezier(&(pts[i]), tension, &x1, &y1, &x2, &y2);
392
393 pt[3*i+2].X = x1;
394 pt[3*i+2].Y = y1;
395 pt[3*i+3].X = pts[i+1].X;
396 pt[3*i+3].Y = pts[i+1].Y;
397 pt[3*i+4].X = x2;
398 pt[3*i+4].Y = y2;
399 }
400
401 /* points [len_pt-2] and [0] are calculated
402 separately to connect splines properly */
403 pts[0] = points[count-1];
404 pts[1] = points[0]; /* equals to start and end of a resulting path */
405 pts[2] = points[1];
406
407 calc_curve_bezier(pts, tension, &x1, &y1, &x2, &y2);
408 pt[len_pt-2].X = x1;
409 pt[len_pt-2].Y = y1;
410 pt[0].X = pts[1].X;
411 pt[0].Y = pts[1].Y;
412 pt[1].X = x2;
413 pt[1].Y = y2;
414 /* close path */
415 pt[len_pt-1].X = pt[0].X;
416 pt[len_pt-1].Y = pt[0].Y;
417
418 stat = GdipAddPathBeziers(path, pt, len_pt);
419
420 /* close figure */
421 if(stat == Ok){
422 path->pathdata.Types[path->pathdata.Count - 1] |= PathPointTypeCloseSubpath;
423 path->newfigure = TRUE;
424 }
425
426 heap_free(pts);
427 heap_free(pt);
428
429 return stat;
430}
#define stat
Definition: acwin.h:99
void calc_curve_bezier(const GpPointF *pts, REAL tension, REAL *x1, REAL *y1, REAL *x2, REAL *y2)
Definition: gdiplus.c:379
#define TENSION_CONST
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Definition: stat.h:55

Referenced by GdipAddPathClosedCurve(), GdipAddPathClosedCurve2I(), GdipDrawClosedCurve2(), GdipFillClosedCurve2(), and test_addclosedcurve().

◆ GdipAddPathClosedCurve2I()

GpStatus WINGDIPAPI GdipAddPathClosedCurve2I ( GpPath path,
GDIPCONST GpPoint points,
INT  count,
REAL  tension 
)

Definition at line 432 of file graphicspath.c.

434{
435 GpPointF *ptf;
436 INT i;
438
439 TRACE("(%p, %p, %d, %.2f)\n", path, points, count, tension);
440
441 if(!path || !points || count <= 1)
442 return InvalidParameter;
443
444 ptf = heap_alloc_zero(sizeof(GpPointF)*count);
445 if(!ptf)
446 return OutOfMemory;
447
448 for(i = 0; i < count; i++){
449 ptf[i].X = (REAL)points[i].X;
450 ptf[i].Y = (REAL)points[i].Y;
451 }
452
453 stat = GdipAddPathClosedCurve2(path, ptf, count, tension);
454
455 heap_free(ptf);
456
457 return stat;
458}

Referenced by GdipAddPathClosedCurveI().

◆ GdipAddPathClosedCurveI()

GpStatus WINGDIPAPI GdipAddPathClosedCurveI ( GpPath path,
GDIPCONST GpPoint points,
INT  count 
)

Definition at line 354 of file graphicspath.c.

356{
357 TRACE("(%p, %p, %d)\n", path, points, count);
358
360}
GpStatus WINGDIPAPI GdipAddPathClosedCurve2I(GpPath *path, GDIPCONST GpPoint *points, INT count, REAL tension)
Definition: graphicspath.c:432

◆ GdipAddPathCurve()

GpStatus WINGDIPAPI GdipAddPathCurve ( GpPath path,
GDIPCONST GpPointF points,
INT  count 
)

Definition at line 460 of file graphicspath.c.

461{
462 TRACE("(%p, %p, %d)\n", path, points, count);
463
464 if(!path || !points || count <= 1)
465 return InvalidParameter;
466
467 return GdipAddPathCurve2(path, points, count, 1.0);
468}
GpStatus WINGDIPAPI GdipAddPathCurve2(GpPath *path, GDIPCONST GpPointF *points, INT count, REAL tension)
Definition: graphicspath.c:480

◆ GdipAddPathCurve2()

GpStatus WINGDIPAPI GdipAddPathCurve2 ( GpPath path,
GDIPCONST GpPointF points,
INT  count,
REAL  tension 
)

Definition at line 480 of file graphicspath.c.

482{
483 INT i, len_pt = count*3-2;
484 GpPointF *pt;
485 REAL x1, x2, y1, y2;
487
488 TRACE("(%p, %p, %d, %.2f)\n", path, points, count, tension);
489
490 if(!path || !points || count <= 1)
491 return InvalidParameter;
492
493 pt = heap_alloc_zero(len_pt * sizeof(GpPointF));
494 if(!pt)
495 return OutOfMemory;
496
497 tension = tension * TENSION_CONST;
498
500 tension, &x1, &y1);
501
502 pt[0].X = points[0].X;
503 pt[0].Y = points[0].Y;
504 pt[1].X = x1;
505 pt[1].Y = y1;
506
507 for(i = 0; i < count-2; i++){
508 calc_curve_bezier(&(points[i]), tension, &x1, &y1, &x2, &y2);
509
510 pt[3*i+2].X = x1;
511 pt[3*i+2].Y = y1;
512 pt[3*i+3].X = points[i+1].X;
513 pt[3*i+3].Y = points[i+1].Y;
514 pt[3*i+4].X = x2;
515 pt[3*i+4].Y = y2;
516 }
517
519 points[count-2].X, points[count-2].Y, tension, &x1, &y1);
520
521 pt[len_pt-2].X = x1;
522 pt[len_pt-2].Y = y1;
523 pt[len_pt-1].X = points[count-1].X;
524 pt[len_pt-1].Y = points[count-1].Y;
525
526 stat = GdipAddPathBeziers(path, pt, len_pt);
527
528 heap_free(pt);
529
530 return stat;
531}
void calc_curve_bezier_endp(REAL xend, REAL yend, REAL xadj, REAL yadj, REAL tension, REAL *x, REAL *y)
Definition: gdiplus.c:396

Referenced by GdipAddPathCurve(), GdipAddPathCurve2I(), GdipAddPathCurve3(), GdipDrawCurve2(), and test_addcurve().

◆ GdipAddPathCurve2I()

GpStatus WINGDIPAPI GdipAddPathCurve2I ( GpPath path,
GDIPCONST GpPoint points,
INT  count,
REAL  tension 
)

Definition at line 533 of file graphicspath.c.

535{
536 GpPointF *ptf;
537 INT i;
539
540 TRACE("(%p, %p, %d, %.2f)\n", path, points, count, tension);
541
542 if(!path || !points || count <= 1)
543 return InvalidParameter;
544
545 ptf = heap_alloc_zero(sizeof(GpPointF)*count);
546 if(!ptf)
547 return OutOfMemory;
548
549 for(i = 0; i < count; i++){
550 ptf[i].X = (REAL)points[i].X;
551 ptf[i].Y = (REAL)points[i].Y;
552 }
553
554 stat = GdipAddPathCurve2(path, ptf, count, tension);
555
556 heap_free(ptf);
557
558 return stat;
559}

Referenced by GdipAddPathCurve3I(), and GdipAddPathCurveI().

◆ GdipAddPathCurve3()

GpStatus WINGDIPAPI GdipAddPathCurve3 ( GpPath path,
GDIPCONST GpPointF points,
INT  count,
INT  offset,
INT  nseg,
REAL  tension 
)

Definition at line 561 of file graphicspath.c.

563{
564 TRACE("(%p, %p, %d, %d, %d, %.2f)\n", path, points, count, offset, nseg, tension);
565
566 if(!path || !points || offset + 1 >= count || count - offset < nseg + 1)
567 return InvalidParameter;
568
569 return GdipAddPathCurve2(path, &points[offset], nseg + 1, tension);
570}
GLintptr offset
Definition: glext.h:5920

Referenced by test_addcurve().

◆ GdipAddPathCurve3I()

GpStatus WINGDIPAPI GdipAddPathCurve3I ( GpPath path,
GDIPCONST GpPoint points,
INT  count,
INT  offset,
INT  nseg,
REAL  tension 
)

Definition at line 572 of file graphicspath.c.

574{
575 TRACE("(%p, %p, %d, %d, %d, %.2f)\n", path, points, count, offset, nseg, tension);
576
577 if(!path || !points || offset + 1 >= count || count - offset < nseg + 1)
578 return InvalidParameter;
579
580 return GdipAddPathCurve2I(path, &points[offset], nseg + 1, tension);
581}
GpStatus WINGDIPAPI GdipAddPathCurve2I(GpPath *path, GDIPCONST GpPoint *points, INT count, REAL tension)
Definition: graphicspath.c:533

◆ GdipAddPathCurveI()

GpStatus WINGDIPAPI GdipAddPathCurveI ( GpPath path,
GDIPCONST GpPoint points,
INT  count 
)

Definition at line 470 of file graphicspath.c.

471{
472 TRACE("(%p, %p, %d)\n", path, points, count);
473
474 if(!path || !points || count <= 1)
475 return InvalidParameter;
476
477 return GdipAddPathCurve2I(path, points, count, 1.0);
478}

◆ GdipAddPathEllipse()

GpStatus WINGDIPAPI GdipAddPathEllipse ( GpPath path,
REAL  x,
REAL  y,
REAL  width,
REAL  height 
)

Definition at line 583 of file graphicspath.c.

585{
586 INT old_count, numpts;
587
588 TRACE("(%p, %.2f, %.2f, %.2f, %.2f)\n", path, x, y, width, height);
589
590 if(!path)
591 return InvalidParameter;
592
594 return OutOfMemory;
595
596 old_count = path->pathdata.Count;
597 if((numpts = arc2polybezier(&path->pathdata.Points[old_count], x, y, width,
598 height, 0.0, 360.0)) != MAX_ARC_PTS){
599 ERR("expected %d points but got %d\n", MAX_ARC_PTS, numpts);
600 return GenericError;
601 }
602
603 memset(&path->pathdata.Types[old_count + 1], PathPointTypeBezier,
604 MAX_ARC_PTS - 1);
605
606 /* An ellipse is an intrinsic figure (always is its own subpath). */
607 path->pathdata.Types[old_count] = PathPointTypeStart;
608 path->pathdata.Types[old_count + MAX_ARC_PTS - 1] |= PathPointTypeCloseSubpath;
609 path->newfigure = TRUE;
610 path->pathdata.Count += MAX_ARC_PTS;
611
612 return Ok;
613}
#define MAX_ARC_PTS
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
#define memset(x, y, z)
Definition: compat.h:39

Referenced by GdipAddPathEllipseI(), GdipDrawEllipse(), GdipFillEllipse(), test_combinereplace(), test_ellipse(), test_flatten(), test_hascurve(), test_isvisiblepoint(), test_isvisiblerect(), test_nextpathtype(), test_transform(), and test_translate().

◆ GdipAddPathEllipseI()

GpStatus WINGDIPAPI GdipAddPathEllipseI ( GpPath path,
INT  x,
INT  y,
INT  width,
INT  height 
)

Definition at line 615 of file graphicspath.c.

617{
618 TRACE("(%p, %d, %d, %d, %d)\n", path, x, y, width, height);
619
621}
GpStatus WINGDIPAPI GdipAddPathEllipse(GpPath *path, REAL x, REAL y, REAL width, REAL height)
Definition: graphicspath.c:583

◆ GdipAddPathLine()

GpStatus WINGDIPAPI GdipAddPathLine ( GpPath path,
REAL  x1,
REAL  y1,
REAL  x2,
REAL  y2 
)

Definition at line 704 of file graphicspath.c.

705{
706 INT old_count;
707
708 TRACE("(%p, %.2f, %.2f, %.2f, %.2f)\n", path, x1, y1, x2, y2);
709
710 if(!path)
711 return InvalidParameter;
712
713 if(!lengthen_path(path, 2))
714 return OutOfMemory;
715
716 old_count = path->pathdata.Count;
717
718 path->pathdata.Points[old_count].X = x1;
719 path->pathdata.Points[old_count].Y = y1;
720 path->pathdata.Points[old_count + 1].X = x2;
721 path->pathdata.Points[old_count + 1].Y = y2;
722
723 path->pathdata.Types[old_count] =
725 path->pathdata.Types[old_count + 1] = PathPointTypeLine;
726
727 path->newfigure = FALSE;
728 path->pathdata.Count += 2;
729
730 return Ok;
731}

Referenced by GdipAddPathLineI(), GdipAddPathPie(), GdipAddPathRectangle(), test_addcurve(), test_drawpath(), test_fillpath(), test_flatten(), test_getpathdata(), test_getregiondata(), test_getsubpathcount(), test_isvalid(), test_nextmarker(), test_nextmarkerpath(), test_nextpathtype(), test_nextsubpathpath(), test_pen_thickness(), test_polygon(), and test_widen().

◆ GdipAddPathLine2()

GpStatus WINGDIPAPI GdipAddPathLine2 ( GpPath path,
GDIPCONST GpPointF points,
INT  count 
)

Definition at line 623 of file graphicspath.c.

625{
626 INT i, old_count;
627
628 TRACE("(%p, %p, %d)\n", path, points, count);
629
630 if(!path || !points)
631 return InvalidParameter;
632
634 return OutOfMemory;
635
636 old_count = path->pathdata.Count;
637
638 for(i = 0; i < count; i++){
639 path->pathdata.Points[old_count + i].X = points[i].X;
640 path->pathdata.Points[old_count + i].Y = points[i].Y;
641 path->pathdata.Types[old_count + i] = PathPointTypeLine;
642 }
643
644 if(path->newfigure){
645 path->pathdata.Types[old_count] = PathPointTypeStart;
646 path->newfigure = FALSE;
647 }
648
649 path->pathdata.Count += count;
650
651 return Ok;
652}

Referenced by GdipAddPathLine2I(), GdipAddPathRectangle(), GdipCreatePathGradient(), GdipDrawLines(), test_ellipse(), test_line2(), test_reverse(), and test_worldbounds().

◆ GdipAddPathLine2I()

GpStatus WINGDIPAPI GdipAddPathLine2I ( GpPath path,
GDIPCONST GpPoint points,
INT  count 
)

Definition at line 654 of file graphicspath.c.

655{
656 GpPointF *pointsF;
657 INT i;
659
660 TRACE("(%p, %p, %d)\n", path, points, count);
661
662 if(count <= 0)
663 return InvalidParameter;
664
665 pointsF = heap_alloc_zero(sizeof(GpPointF) * count);
666 if(!pointsF) return OutOfMemory;
667
668 for(i = 0;i < count; i++){
669 pointsF[i].X = (REAL)points[i].X;
670 pointsF[i].Y = (REAL)points[i].Y;
671 }
672
673 stat = GdipAddPathLine2(path, pointsF, count);
674
675 heap_free(pointsF);
676
677 return stat;
678}
GpStatus WINGDIPAPI GdipAddPathLine2(GpPath *path, GDIPCONST GpPointF *points, INT count)
Definition: graphicspath.c:623

Referenced by GdipCreatePathGradientI().

◆ GdipAddPathLineI()

GpStatus WINGDIPAPI GdipAddPathLineI ( GpPath path,
INT  x1,
INT  y1,
INT  x2,
INT  y2 
)

Definition at line 738 of file graphicspath.c.

739{
740 TRACE("(%p, %d, %d, %d, %d)\n", path, x1, y1, x2, y2);
741
742 return GdipAddPathLine(path, (REAL)x1, (REAL)y1, (REAL)x2, (REAL)y2);
743}
GpStatus WINGDIPAPI GdipAddPathLine(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2)
Definition: graphicspath.c:704

Referenced by test_GdipFillPath(), and test_linei().

◆ GdipAddPathPath()

GpStatus WINGDIPAPI GdipAddPathPath ( GpPath path,
GDIPCONST GpPath addingPath,
BOOL  connect 
)

Definition at line 745 of file graphicspath.c.

747{
748 INT old_count, count;
749
750 TRACE("(%p, %p, %d)\n", path, addingPath, connect);
751
752 if(!path || !addingPath)
753 return InvalidParameter;
754
755 old_count = path->pathdata.Count;
756 count = addingPath->pathdata.Count;
757
759 return OutOfMemory;
760
761 memcpy(&path->pathdata.Points[old_count], addingPath->pathdata.Points,
762 count * sizeof(GpPointF));
763 memcpy(&path->pathdata.Types[old_count], addingPath->pathdata.Types, count);
764
765 if(path->newfigure || !connect)
766 path->pathdata.Types[old_count] = PathPointTypeStart;
767 else
768 path->pathdata.Types[old_count] = PathPointTypeLine;
769
770 path->newfigure = FALSE;
771 path->pathdata.Count += count;
772
773 return Ok;
774}

Referenced by test_pathpath().

◆ GdipAddPathPie()

GpStatus WINGDIPAPI GdipAddPathPie ( GpPath path,
REAL  x,
REAL  y,
REAL  width,
REAL  height,
REAL  startAngle,
REAL  sweepAngle 
)

Definition at line 776 of file graphicspath.c.

778{
779 GpPointF *ptf;
781 INT i, count;
782
783 TRACE("(%p, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n",
784 path, x, y, width, height, startAngle, sweepAngle);
785
786 if(!path)
787 return InvalidParameter;
788
789 /* on zero width/height only start point added */
790 if(width <= 1e-7 || height <= 1e-7){
791 if(!lengthen_path(path, 1))
792 return OutOfMemory;
793 path->pathdata.Points[0].X = x + width / 2.0;
794 path->pathdata.Points[0].Y = y + height / 2.0;
796 path->pathdata.Count = 1;
797 return InvalidParameter;
798 }
799
800 count = arc2polybezier(NULL, x, y, width, height, startAngle, sweepAngle);
801
802 if(count == 0)
803 return Ok;
804
805 ptf = heap_alloc_zero(sizeof(GpPointF)*count);
806 if(!ptf)
807 return OutOfMemory;
808
809 arc2polybezier(ptf, x, y, width, height, startAngle, sweepAngle);
810
811 status = GdipAddPathLine(path, x + width/2, y + height/2, ptf[0].X, ptf[0].Y);
812 if(status != Ok){
813 heap_free(ptf);
814 return status;
815 }
816 /* one spline is already added as a line endpoint */
817 if(!lengthen_path(path, count - 1)){
818 heap_free(ptf);
819 return OutOfMemory;
820 }
821
822 memcpy(&(path->pathdata.Points[path->pathdata.Count]), &(ptf[1]),sizeof(GpPointF)*(count-1));
823 for(i = 0; i < count-1; i++)
824 path->pathdata.Types[path->pathdata.Count+i] = PathPointTypeBezier;
825
826 path->pathdata.Count += count-1;
827
829
830 heap_free(ptf);
831
832 return status;
833}
GpStatus WINGDIPAPI GdipClosePathFigure(GpPath *path)
#define e
Definition: ke_i.h:82

Referenced by GdipAddPathPieI(), GdipDrawPie(), GdipFillPie(), and test_addpie().

◆ GdipAddPathPieI()

GpStatus WINGDIPAPI GdipAddPathPieI ( GpPath path,
INT  x,
INT  y,
INT  width,
INT  height,
REAL  startAngle,
REAL  sweepAngle 
)

Definition at line 835 of file graphicspath.c.

837{
838 TRACE("(%p, %d, %d, %d, %d, %.2f, %.2f)\n",
839 path, x, y, width, height, startAngle, sweepAngle);
840
841 return GdipAddPathPie(path, (REAL)x, (REAL)y, (REAL)width, (REAL)height, startAngle, sweepAngle);
842}
GpStatus WINGDIPAPI GdipAddPathPie(GpPath *path, REAL x, REAL y, REAL width, REAL height, REAL startAngle, REAL sweepAngle)
Definition: graphicspath.c:776

◆ GdipAddPathPolygon()

GpStatus WINGDIPAPI GdipAddPathPolygon ( GpPath path,
GDIPCONST GpPointF points,
INT  count 
)

Definition at line 844 of file graphicspath.c.

845{
846 INT old_count;
847
848 TRACE("(%p, %p, %d)\n", path, points, count);
849
850 if(!path || !points || count < 3)
851 return InvalidParameter;
852
854 return OutOfMemory;
855
856 old_count = path->pathdata.Count;
857
858 memcpy(&path->pathdata.Points[old_count], points, count*sizeof(GpPointF));
859 memset(&path->pathdata.Types[old_count + 1], PathPointTypeLine, count - 1);
860
861 /* A polygon is an intrinsic figure */
862 path->pathdata.Types[old_count] = PathPointTypeStart;
863 path->pathdata.Types[old_count + count - 1] |= PathPointTypeCloseSubpath;
864 path->newfigure = TRUE;
865 path->pathdata.Count += count;
866
867 return Ok;
868}

Referenced by GdipAddPathPolygonI(), GdipDrawPolygon(), GdipEnumerateMetafileSrcRectDestPoints(), GdipFillPolygon(), and test_polygon().

◆ GdipAddPathPolygonI()

GpStatus WINGDIPAPI GdipAddPathPolygonI ( GpPath path,
GDIPCONST GpPoint points,
INT  count 
)

Definition at line 870 of file graphicspath.c.

871{
872 GpPointF *ptf;
874 INT i;
875
876 TRACE("(%p, %p, %d)\n", path, points, count);
877
878 if(!points || count < 3)
879 return InvalidParameter;
880
881 ptf = heap_alloc_zero(sizeof(GpPointF) * count);
882 if(!ptf)
883 return OutOfMemory;
884
885 for(i = 0; i < count; i++){
886 ptf[i].X = (REAL)points[i].X;
887 ptf[i].Y = (REAL)points[i].Y;
888 }
889
891
892 heap_free(ptf);
893
894 return status;
895}
GpStatus WINGDIPAPI GdipAddPathPolygon(GpPath *path, GDIPCONST GpPointF *points, INT count)
Definition: graphicspath.c:844

Referenced by GdipFillPolygonI().

◆ GdipAddPathRectangle()

GpStatus WINGDIPAPI GdipAddPathRectangle ( GpPath path,
REAL  x,
REAL  y,
REAL  width,
REAL  height 
)

Definition at line 2296 of file graphicspath.c.

2298{
2299 GpPath *backup;
2300 GpPointF ptf[2];
2301 GpStatus retstat;
2302 BOOL old_new;
2303
2304 TRACE("(%p, %.2f, %.2f, %.2f, %.2f)\n", path, x, y, width, height);
2305
2306 if(!path)
2307 return InvalidParameter;
2308
2309 if (width <= 0.0 || height <= 0.0)
2310 return Ok;
2311
2312 /* make a backup copy of path data */
2313 if((retstat = GdipClonePath(path, &backup)) != Ok)
2314 return retstat;
2315
2316 /* rectangle should start as new path */
2317 old_new = path->newfigure;
2318 path->newfigure = TRUE;
2319 if((retstat = GdipAddPathLine(path,x,y,x+width,y)) != Ok){
2320 path->newfigure = old_new;
2321 goto fail;
2322 }
2323
2324 ptf[0].X = x+width;
2325 ptf[0].Y = y+height;
2326 ptf[1].X = x;
2327 ptf[1].Y = y+height;
2328
2329 if((retstat = GdipAddPathLine2(path, ptf, 2)) != Ok) goto fail;
2330 path->pathdata.Types[path->pathdata.Count-1] |= PathPointTypeCloseSubpath;
2331
2332 /* free backup */
2334 return Ok;
2335
2336fail:
2337 /* reverting */
2338 heap_free(path->pathdata.Points);
2339 heap_free(path->pathdata.Types);
2340 memcpy(path, backup, sizeof(*path));
2342
2343 return retstat;
2344}
static long backup()
Definition: maze.c:403
GpStatus WINGDIPAPI GdipDeletePath(GpPath *path)
GpStatus WINGDIPAPI GdipClonePath(GpPath *path, GpPath **clone)
unsigned int BOOL
Definition: ntddk_ex.h:94

Referenced by GdipAddPathRectangleI(), GdipAddPathRectangles(), GdipCreateRegionHrgn(), GdipDrawRectangle(), get_region_hrgn(), test_captype(), test_constructor_destructor(), test_empty_rect(), test_GdipFillPath(), test_gethrgn(), test_getregiondata(), test_hascurve(), test_inset(), test_isvisible(), test_lastpoint(), test_linejoin(), test_nextmarker(), test_nextmarkerpath(), test_rect(), test_scale(), and transform_region_element().

◆ GdipAddPathRectangleI()

GpStatus WINGDIPAPI GdipAddPathRectangleI ( GpPath path,
INT  x,
INT  y,
INT  width,
INT  height 
)

Definition at line 2346 of file graphicspath.c.

2348{
2349 TRACE("(%p, %d, %d, %d, %d)\n", path, x, y, width, height);
2350
2352}
GpStatus WINGDIPAPI GdipAddPathRectangle(GpPath *path, REAL x, REAL y, REAL width, REAL height)

Referenced by test_getregiondata().

◆ GdipAddPathRectangles()

GpStatus WINGDIPAPI GdipAddPathRectangles ( GpPath path,
GDIPCONST GpRectF rects,
INT  count 
)

Definition at line 2354 of file graphicspath.c.

2355{
2356 GpPath *backup;
2357 GpStatus retstat;
2358 INT i;
2359
2360 TRACE("(%p, %p, %d)\n", path, rects, count);
2361
2362 /* count == 0 - verified condition */
2363 if(!path || !rects || count == 0)
2364 return InvalidParameter;
2365
2366 if(count < 0)
2367 return OutOfMemory;
2368
2369 /* make a backup copy */
2370 if((retstat = GdipClonePath(path, &backup)) != Ok)
2371 return retstat;
2372
2373 for(i = 0; i < count; i++){
2374 if((retstat = GdipAddPathRectangle(path,rects[i].X,rects[i].Y,rects[i].Width,rects[i].Height)) != Ok)
2375 goto fail;
2376 }
2377
2378 /* free backup */
2380 return Ok;
2381
2382fail:
2383 /* reverting */
2384 heap_free(path->pathdata.Points);
2385 heap_free(path->pathdata.Types);
2386 memcpy(path, backup, sizeof(*path));
2388
2389 return retstat;
2390}
_In_ HFONT _Out_ PUINT _Out_ PUINT Width
Definition: font.h:89
_In_ HFONT _Out_ PUINT Height
Definition: font.h:88

Referenced by GdipAddPathRectanglesI(), GdipDrawRectangles(), GdipFillRectangles(), and test_rect().

◆ GdipAddPathRectanglesI()

GpStatus WINGDIPAPI GdipAddPathRectanglesI ( GpPath path,
GDIPCONST GpRect rects,
INT  count 
)

Definition at line 2392 of file graphicspath.c.

2393{
2394 GpRectF *rectsF;
2395 GpStatus retstat;
2396 INT i;
2397
2398 TRACE("(%p, %p, %d)\n", path, rects, count);
2399
2400 if(!rects || count == 0)
2401 return InvalidParameter;
2402
2403 if(count < 0)
2404 return OutOfMemory;
2405
2406 rectsF = heap_alloc_zero(sizeof(GpRectF)*count);
2407
2408 for(i = 0;i < count;i++){
2409 rectsF[i].X = (REAL)rects[i].X;
2410 rectsF[i].Y = (REAL)rects[i].Y;
2411 rectsF[i].Width = (REAL)rects[i].Width;
2412 rectsF[i].Height = (REAL)rects[i].Height;
2413 }
2414
2415 retstat = GdipAddPathRectangles(path, rectsF, count);
2416 heap_free(rectsF);
2417
2418 return retstat;
2419}
GpStatus WINGDIPAPI GdipAddPathRectangles(GpPath *path, GDIPCONST GpRectF *rects, INT count)
REAL Width
Definition: gdiplustypes.h:663

◆ GdipAddPathString()

GpStatus WINGDIPAPI GdipAddPathString ( GpPath path,
GDIPCONST WCHAR string,
INT  length,
GDIPCONST GpFontFamily family,
INT  style,
REAL  emSize,
GDIPCONST RectF layoutRect,
GDIPCONST GpStringFormat format 
)

Definition at line 1007 of file graphicspath.c.

1008{
1009 GpFont *font;
1011 LOGFONTW lfw;
1012 HANDLE hfont;
1013 HDC dc;
1014 GpGraphics *graphics;
1015 GpPath *backup;
1016 struct format_string_args args;
1017 int i;
1018 UINT16 native_height;
1019 RectF scaled_layout_rect;
1020 TEXTMETRICW textmetric;
1021
1022 TRACE("(%p, %s, %d, %p, %d, %f, %p, %p)\n", path, debugstr_w(string), length, family, style, emSize, layoutRect, format);
1023 if (!path || !string || !family || !emSize || !layoutRect || !format)
1024 return InvalidParameter;
1025
1026 status = GdipGetEmHeight(family, style, &native_height);
1027 if (status != Ok)
1028 return status;
1029
1030 scaled_layout_rect.X = layoutRect->X;
1031 scaled_layout_rect.Y = layoutRect->Y;
1032 scaled_layout_rect.Width = layoutRect->Width * native_height / emSize;
1033 scaled_layout_rect.Height = layoutRect->Height * native_height / emSize;
1034
1035 if ((status = GdipClonePath(path, &backup)) != Ok)
1036 return status;
1037
1039 status = GdipCreateFromHDC(dc, &graphics);
1040 if (status != Ok)
1041 {
1042 DeleteDC(dc);
1044 return status;
1045 }
1046
1047 status = GdipCreateFont(family, native_height, style, UnitPixel, &font);
1048 if (status != Ok)
1049 {
1050 GdipDeleteGraphics(graphics);
1051 DeleteDC(dc);
1053 return status;
1054 }
1055
1056 get_log_fontW(font, graphics, &lfw);
1058 GdipDeleteGraphics(graphics);
1059
1060 hfont = CreateFontIndirectW(&lfw);
1061 if (!hfont)
1062 {
1063 WARN("Failed to create font\n");
1064 DeleteDC(dc);
1066 return GenericError;
1067 }
1068
1070
1071 GetTextMetricsW(dc, &textmetric);
1072
1073 args.path = path;
1074 args.maxY = 0;
1075 args.scale = emSize / native_height;
1076 args.ascent = textmetric.tmAscent * args.scale;
1077 status = gdip_format_string(dc, string, length, NULL, &scaled_layout_rect,
1079
1080 DeleteDC(dc);
1082
1083 if (status != Ok) /* free backup */
1084 {
1085 heap_free(path->pathdata.Points);
1086 heap_free(path->pathdata.Types);
1087 *path = *backup;
1089 return status;
1090 }
1091 if (format && format->line_align == StringAlignmentCenter && layoutRect->Y + args.maxY < layoutRect->Height)
1092 {
1093 float inc = layoutRect->Height + layoutRect->Y - args.maxY;
1094 inc /= 2;
1095 for (i = backup->pathdata.Count; i < path->pathdata.Count; ++i)
1096 path->pathdata.Points[i].Y += inc;
1097 } else if (format && format->line_align == StringAlignmentFar) {
1098 float inc = layoutRect->Height + layoutRect->Y - args.maxY;
1099 for (i = backup->pathdata.Count; i < path->pathdata.Count; ++i)
1100 path->pathdata.Points[i].Y += inc;
1101 }
1103 return status;
1104}
static HFONT hfont
unsigned short UINT16
Arabic default style
Definition: afstyles.h:94
#define WARN(fmt,...)
Definition: precomp.h:61
GpStatus WINGDIPAPI GdipDeleteFont(GpFont *font)
Definition: font.c:270
GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily, REAL emSize, INT style, Unit unit, GpFont **font)
Definition: font.c:144
GpStatus WINGDIPAPI GdipGetEmHeight(GDIPCONST GpFontFamily *family, INT style, UINT16 *EmHeight)
Definition: font.c:918
GpStatus WINGDIPAPI GdipCreateFromHDC(HDC hdc, GpGraphics **graphics)
Definition: graphics.c:2395
GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics)
Definition: graphics.c:2581
static GpStatus format_string_callback(HDC dc, GDIPCONST WCHAR *string, INT index, INT length, GDIPCONST GpFont *font, GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format, INT lineno, const RectF *bounds, INT *underlined_indexes, INT underlined_index_count, void *priv)
Definition: graphicspath.c:912
pKey DeleteObject()
GpStatus gdip_format_string(HDC hdc, GDIPCONST WCHAR *string, INT length, GDIPCONST GpFont *font, GDIPCONST RectF *rect, GDIPCONST GpStringFormat *format, int ignore_empty_clip, gdip_format_string_callback callback, void *user_data) DECLSPEC_HIDDEN
Definition: graphics.c:5205
void get_log_fontW(const GpFont *, GpGraphics *, LOGFONTW *) DECLSPEC_HIDDEN
Definition: graphics.c:2305
@ StringAlignmentCenter
Definition: gdiplusenums.h:266
@ StringAlignmentFar
Definition: gdiplusenums.h:267
@ UnitPixel
Definition: gdiplusenums.h:29
#define debugstr_w
Definition: kernel32.h:32
static HDC
Definition: imagelist.c:88
Definition: mk_font.cpp:20
Definition: format.c:58
LONG tmAscent
Definition: wingdi.h:2384
BOOL WINAPI GetTextMetricsW(_In_ HDC, _Out_ LPTEXTMETRICW)
Definition: text.c:221
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
HFONT WINAPI CreateFontIndirectW(_In_ const LOGFONTW *)
BOOL WINAPI DeleteDC(_In_ HDC)

Referenced by GdipAddPathStringI().

◆ GdipAddPathStringI()

GpStatus WINGDIPAPI GdipAddPathStringI ( GpPath path,
GDIPCONST WCHAR string,
INT  length,
GDIPCONST GpFontFamily family,
INT  style,
REAL  emSize,
GDIPCONST Rect layoutRect,
GDIPCONST GpStringFormat format 
)

Definition at line 1106 of file graphicspath.c.

1107{
1108 if (layoutRect)
1109 {
1110 RectF layoutRectF = {
1111 (REAL)layoutRect->X,
1112 (REAL)layoutRect->Y,
1113 (REAL)layoutRect->Width,
1114 (REAL)layoutRect->Height
1115 };
1116 return GdipAddPathString(path, string, length, family, style, emSize, &layoutRectF, format);
1117 }
1118 return InvalidParameter;
1119}
GpStatus WINGDIPAPI GdipAddPathString(GpPath *path, GDIPCONST WCHAR *string, INT length, GDIPCONST GpFontFamily *family, INT style, REAL emSize, GDIPCONST RectF *layoutRect, GDIPCONST GpStringFormat *format)

◆ GdipClearPathMarkers()

GpStatus WINGDIPAPI GdipClearPathMarkers ( GpPath path)

Definition at line 2439 of file graphicspath.c.

2440{
2441 INT count;
2442 INT i;
2443
2444 TRACE("(%p)\n", path);
2445
2446 if(!path)
2447 return InvalidParameter;
2448
2449 count = path->pathdata.Count;
2450
2451 for(i = 0; i < count - 1; i++){
2452 path->pathdata.Types[i] &= ~PathPointTypePathMarker;
2453 }
2454
2455 return Ok;
2456}

◆ GdipClonePath()

GpStatus WINGDIPAPI GdipClonePath ( GpPath path,
GpPath **  clone 
)

Definition at line 1135 of file graphicspath.c.

1136{
1137 TRACE("(%p, %p)\n", path, clone);
1138
1139 if(!path || !clone)
1140 return InvalidParameter;
1141
1142 *clone = heap_alloc_zero(sizeof(GpPath));
1143 if(!*clone) return OutOfMemory;
1144
1145 **clone = *path;
1146
1147 (*clone)->pathdata.Points = heap_alloc_zero(path->datalen * sizeof(PointF));
1148 (*clone)->pathdata.Types = heap_alloc_zero(path->datalen);
1149 if(!(*clone)->pathdata.Points || !(*clone)->pathdata.Types){
1150 heap_free((*clone)->pathdata.Points);
1151 heap_free((*clone)->pathdata.Types);
1152 heap_free(*clone);
1153 return OutOfMemory;
1154 }
1155
1156 memcpy((*clone)->pathdata.Points, path->pathdata.Points,
1157 path->datalen * sizeof(PointF));
1158 memcpy((*clone)->pathdata.Types, path->pathdata.Types, path->datalen);
1159
1160 return Ok;
1161}

Referenced by brush_fill_pixels(), clone_element(), GdipAddPathRectangle(), GdipAddPathRectangles(), GdipAddPathString(), GdipCloneBrush(), GdipCreatePathGradientFromPath(), GdipCreateRegionPath(), GdipIsOutlineVisiblePathPoint(), GdipSetClipPath(), GdipWidenPath(), SOFTWARE_GdipDrawPath(), and SOFTWARE_GdipDrawThinPath().

◆ GdipClosePathFigure()

GpStatus WINGDIPAPI GdipClosePathFigure ( GpPath path)

Definition at line 1163 of file graphicspath.c.

1164{
1165 TRACE("(%p)\n", path);
1166
1167 if(!path)
1168 return InvalidParameter;
1169
1170 if(path->pathdata.Count > 0){
1171 path->pathdata.Types[path->pathdata.Count - 1] |= PathPointTypeCloseSubpath;
1172 path->newfigure = TRUE;
1173 }
1174
1175 return Ok;
1176}

Referenced by GdipAddPathPie(), test_ellipse(), test_getregiondata(), test_line2(), test_linei(), test_nextpathtype(), test_nextsubpathpath(), test_pen_thickness(), and test_reverse().

◆ GdipClosePathFigures()

GpStatus WINGDIPAPI GdipClosePathFigures ( GpPath path)

Definition at line 1178 of file graphicspath.c.

1179{
1180 INT i;
1181
1182 TRACE("(%p)\n", path);
1183
1184 if(!path)
1185 return InvalidParameter;
1186
1187 for(i = 1; i < path->pathdata.Count; i++){
1188 if(path->pathdata.Types[i] == PathPointTypeStart)
1189 path->pathdata.Types[i-1] |= PathPointTypeCloseSubpath;
1190 }
1191
1192 path->newfigure = TRUE;
1193
1194 return Ok;
1195}

◆ GdipCreatePath()

GpStatus WINGDIPAPI GdipCreatePath ( GpFillMode  fill,
GpPath **  path 
)

Definition at line 1197 of file graphicspath.c.

1198{
1199 TRACE("(%d, %p)\n", fill, path);
1200
1201 if(!path)
1202 return InvalidParameter;
1203
1204 *path = heap_alloc_zero(sizeof(GpPath));
1205 if(!*path) return OutOfMemory;
1206
1207 (*path)->fill = fill;
1208 (*path)->newfigure = TRUE;
1209
1210 return Ok;
1211}
_STLP_MOVE_TO_STD_NAMESPACE void fill(_ForwardIter __first, _ForwardIter __last, const _Tp &__val)
Definition: _algobase.h:449

Referenced by GdipCreatePathGradient(), GdipCreatePathGradientI(), GdipCreateRegionHrgn(), GdipDrawArc(), GdipDrawBeziers(), GdipDrawClosedCurve2(), GdipDrawCurve2(), GdipDrawEllipse(), GdipDrawLines(), GdipDrawPie(), GdipDrawPolygon(), GdipDrawRectangle(), GdipDrawRectangles(), GdipEnumerateMetafileSrcRectDestPoints(), GdipFillClosedCurve2(), GdipFillEllipse(), GdipFillPie(), GdipFillPolygon(), GdipFillPolygonI(), GdipFillRectangles(), get_region_hrgn(), metafile_deserialize_path(), read_element(), test_addclosedcurve(), test_addcurve(), test_addpie(), test_arc(), test_captype(), test_combinereplace(), test_constructor_destructor(), test_drawpath(), test_ellipse(), test_empty_rect(), test_fillpath(), test_flatten(), test_GdipFillPath(), test_Get_Release_DC(), test_gethrgn(), test_getpathdata(), test_getregiondata(), test_getsubpathcount(), test_hascurve(), test_inset(), test_isvalid(), test_isvisible(), test_isvisiblepoint(), test_isvisiblerect(), test_lastpoint(), test_line2(), test_linei(), test_linejoin(), test_nextmarker(), test_nextmarkerpath(), test_nextpathtype(), test_nextsubpath(), test_nextsubpathpath(), test_pathgradientpath(), test_pathpath(), test_pen_thickness(), test_polygon(), test_rect(), test_reverse(), test_scale(), test_transform(), test_translate(), test_widen(), test_worldbounds(), and transform_region_element().

◆ GdipCreatePath2()

GpStatus WINGDIPAPI GdipCreatePath2 ( GDIPCONST GpPointF points,
GDIPCONST BYTE types,
INT  count,
GpFillMode  fill,
GpPath **  path 
)

Definition at line 1213 of file graphicspath.c.

1215{
1216 TRACE("(%p, %p, %d, %d, %p)\n", points, types, count, fill, path);
1217
1218 if(!path)
1219 return InvalidParameter;
1220
1221 *path = heap_alloc_zero(sizeof(GpPath));
1222 if(!*path) return OutOfMemory;
1223
1224 (*path)->pathdata.Points = heap_alloc_zero(count * sizeof(PointF));
1225 (*path)->pathdata.Types = heap_alloc_zero(count);
1226
1227 if(!(*path)->pathdata.Points || !(*path)->pathdata.Types){
1228 heap_free((*path)->pathdata.Points);
1229 heap_free((*path)->pathdata.Types);
1230 heap_free(*path);
1231 return OutOfMemory;
1232 }
1233
1234 memcpy((*path)->pathdata.Points, points, count * sizeof(PointF));
1235 memcpy((*path)->pathdata.Types, types, count);
1236 (*path)->pathdata.Count = count;
1237 (*path)->datalen = count;
1238
1239 (*path)->fill = fill;
1240 (*path)->newfigure = TRUE;
1241
1242 return Ok;
1243}
Definition: cmds.c:130

Referenced by GdipCreatePath2I().

◆ GdipCreatePath2I()

GpStatus WINGDIPAPI GdipCreatePath2I ( GDIPCONST GpPoint points,
GDIPCONST BYTE types,
INT  count,
GpFillMode  fill,
GpPath **  path 
)

Definition at line 1245 of file graphicspath.c.

1247{
1248 GpPointF *ptF;
1249 GpStatus ret;
1250 INT i;
1251
1252 TRACE("(%p, %p, %d, %d, %p)\n", points, types, count, fill, path);
1253
1254 ptF = heap_alloc_zero(sizeof(GpPointF)*count);
1255
1256 for(i = 0;i < count; i++){
1257 ptF[i].X = (REAL)points[i].X;
1258 ptF[i].Y = (REAL)points[i].Y;
1259 }
1260
1262
1263 heap_free(ptF);
1264
1265 return ret;
1266}
GpStatus WINGDIPAPI GdipCreatePath2(GDIPCONST GpPointF *points, GDIPCONST BYTE *types, INT count, GpFillMode fill, GpPath **path)

◆ GdipDeletePath()

GpStatus WINGDIPAPI GdipDeletePath ( GpPath path)

Definition at line 1268 of file graphicspath.c.

1269{
1270 TRACE("(%p)\n", path);
1271
1272 if(!path)
1273 return InvalidParameter;
1274
1275 heap_free(path->pathdata.Points);
1276 heap_free(path->pathdata.Types);
1277 heap_free(path);
1278
1279 return Ok;
1280}

Referenced by brush_fill_pixels(), delete_element(), GdipAddPathRectangle(), GdipAddPathRectangles(), GdipAddPathString(), GdipCloneBrush(), GdipCreatePathGradient(), GdipCreatePathGradientFromPath(), GdipCreatePathGradientI(), GdipCreateRegionHrgn(), GdipDeleteBrush(), GdipDrawArc(), GdipDrawBeziers(), GdipDrawClosedCurve2(), GdipDrawCurve2(), GdipDrawEllipse(), GdipDrawLines(), GdipDrawPie(), GdipDrawPolygon(), GdipDrawRectangle(), GdipDrawRectangles(), GdipEnumerateMetafileSrcRectDestPoints(), GdipFillClosedCurve2(), GdipFillEllipse(), GdipFillPie(), GdipFillPolygon(), GdipFillPolygonI(), GdipFillRectangles(), GdipIsOutlineVisiblePathPoint(), GdipSetClipPath(), GdipWidenPath(), get_region_hrgn(), metafile_deserialize_path(), metafile_free_object_table_entry(), SOFTWARE_GdipDrawPath(), SOFTWARE_GdipDrawThinPath(), test_addclosedcurve(), test_addcurve(), test_addpie(), test_arc(), test_captype(), test_combinereplace(), test_constructor_destructor(), test_drawpath(), test_ellipse(), test_empty_rect(), test_fillpath(), test_flatten(), test_GdipFillPath(), test_Get_Release_DC(), test_gethrgn(), test_getpathdata(), test_getregiondata(), test_getsubpathcount(), test_hascurve(), test_inset(), test_isvalid(), test_isvisible(), test_isvisiblepoint(), test_isvisiblerect(), test_lastpoint(), test_line2(), test_linei(), test_linejoin(), test_nextmarker(), test_nextmarkerpath(), test_nextpathtype(), test_nextsubpath(), test_nextsubpathpath(), test_pathgradientpath(), test_pathpath(), test_pen_thickness(), test_polygon(), test_rect(), test_reverse(), test_scale(), test_transform(), test_translate(), test_widen(), test_worldbounds(), and transform_region_element().

◆ GdipFlattenPath()

GpStatus WINGDIPAPI GdipFlattenPath ( GpPath path,
GpMatrix matrix,
REAL  flatness 
)

Definition at line 1282 of file graphicspath.c.

1283{
1285 GpPointF pt;
1286 INT i = 1;
1287 INT startidx = 0;
1288 GpStatus stat;
1289
1290 TRACE("(%p, %p, %.2f)\n", path, matrix, flatness);
1291
1292 if(!path)
1293 return InvalidParameter;
1294
1295 if(path->pathdata.Count == 0)
1296 return Ok;
1297
1299 if(stat != Ok)
1300 return stat;
1301
1302 pt = path->pathdata.Points[0];
1303 if(!init_path_list(&list, pt.X, pt.Y))
1304 return OutOfMemory;
1305
1306 node = list;
1307
1308 while(i < path->pathdata.Count){
1309
1310 BYTE type = path->pathdata.Types[i] & PathPointTypePathTypeMask;
1312
1313 pt = path->pathdata.Points[i];
1314
1315 /* save last start point index */
1317 startidx = i;
1318
1319 /* always add line points and start points */
1321 if(!add_path_list_node(node, pt.X, pt.Y, path->pathdata.Types[i]))
1322 goto memout;
1323
1324 node = node->next;
1325 ++i;
1326 continue;
1327 }
1328
1329 /* Bezier curve */
1330
1331 /* test for closed figure */
1332 if(path->pathdata.Types[i+1] & PathPointTypeCloseSubpath){
1333 pt = path->pathdata.Points[startidx];
1334 ++i;
1335 }
1336 else
1337 {
1338 i += 2;
1339 pt = path->pathdata.Points[i];
1340 };
1341
1342 start = node;
1343 /* add Bezier end point */
1344 type = (path->pathdata.Types[i] & ~PathPointTypePathTypeMask) | PathPointTypeLine;
1345 if(!add_path_list_node(node, pt.X, pt.Y, type))
1346 goto memout;
1347 node = node->next;
1348
1349 /* flatten curve */
1350 if(!flatten_bezier(start, path->pathdata.Points[i-2].X, path->pathdata.Points[i-2].Y,
1351 path->pathdata.Points[i-1].X, path->pathdata.Points[i-1].Y,
1352 node, flatness))
1353 goto memout;
1354
1355 ++i;
1356 }/* while */
1357
1358 /* store path data back */
1360 if(!lengthen_path(path, i))
1361 goto memout;
1362 path->pathdata.Count = i;
1363
1364 node = list;
1365 for(i = 0; i < path->pathdata.Count; i++){
1366 path->pathdata.Points[i] = node->pt;
1367 path->pathdata.Types[i] = node->type;
1368 node = node->next;
1369 }
1370
1372 return Ok;
1373
1374memout:
1376 return OutOfMemory;
1377}
Definition: list.h:37
static INT path_list_count(path_list_node_t *node)
Definition: graphicspath.c:94
static void free_path_list(path_list_node_t *node)
Definition: graphicspath.c:59
static BOOL init_path_list(path_list_node_t **node, REAL x, REAL y)
Definition: graphicspath.c:44
GpStatus WINGDIPAPI GdipTransformPath(GpPath *path, GpMatrix *matrix)
@ PathPointTypePathTypeMask
Definition: gdiplusenums.h:87
GLuint GLenum matrix
Definition: glext.h:9407
#define list
Definition: rosglue.h:35
unsigned char BYTE
Definition: xxhash.c:193

Referenced by brush_fill_pixels(), GdipWidenPath(), SOFTWARE_GdipDrawThinPath(), and test_flatten().

◆ GdipGetPathData()

GpStatus WINGDIPAPI GdipGetPathData ( GpPath path,
GpPathData pathData 
)

Definition at line 1379 of file graphicspath.c.

1380{
1381 TRACE("(%p, %p)\n", path, pathData);
1382
1383 if(!path || !pathData)
1384 return InvalidParameter;
1385
1386 /* Only copy data. pathData allocation/freeing controlled by wrapper class.
1387 Assumed that pathData is enough wide to get all data - controlled by wrapper too. */
1388 memcpy(pathData->Points, path->pathdata.Points, sizeof(PointF) * pathData->Count);
1389 memcpy(pathData->Types , path->pathdata.Types , pathData->Count);
1390
1391 return Ok;
1392}
PointF * Points
Definition: gdiplustypes.h:655
BYTE * Types
Definition: gdiplustypes.h:656

Referenced by test_getpathdata().

◆ GdipGetPathFillMode()

GpStatus WINGDIPAPI GdipGetPathFillMode ( GpPath path,
GpFillMode fillmode 
)

Definition at line 1394 of file graphicspath.c.

1395{
1396 TRACE("(%p, %p)\n", path, fillmode);
1397
1398 if(!path || !fillmode)
1399 return InvalidParameter;
1400
1401 *fillmode = path->fill;
1402
1403 return Ok;
1404}

◆ GdipGetPathLastPoint()

GpStatus WINGDIPAPI GdipGetPathLastPoint ( GpPath path,
GpPointF lastPoint 
)

Definition at line 1406 of file graphicspath.c.

1407{
1408 INT count;
1409
1410 TRACE("(%p, %p)\n", path, lastPoint);
1411
1412 if(!path || !lastPoint)
1413 return InvalidParameter;
1414
1415 count = path->pathdata.Count;
1416 if(count > 0)
1417 *lastPoint = path->pathdata.Points[count-1];
1418
1419 return Ok;
1420}

Referenced by test_lastpoint().

◆ GdipGetPathPoints()

GpStatus WINGDIPAPI GdipGetPathPoints ( GpPath path,
GpPointF points,
INT  count 
)

Definition at line 1422 of file graphicspath.c.

1423{
1424 TRACE("(%p, %p, %d)\n", path, points, count);
1425
1426 if(!path)
1427 return InvalidParameter;
1428
1429 if(count < path->pathdata.Count)
1430 return InsufficientBuffer;
1431
1432 memcpy(points, path->pathdata.Points, path->pathdata.Count * sizeof(GpPointF));
1433
1434 return Ok;
1435}
@ InsufficientBuffer
Definition: gdiplustypes.h:31

Referenced by GdipGetPathPointsI(), and ok_path().

◆ GdipGetPathPointsI()

GpStatus WINGDIPAPI GdipGetPathPointsI ( GpPath path,
GpPoint points,
INT  count 
)

Definition at line 1437 of file graphicspath.c.

1438{
1439 GpStatus ret;
1440 GpPointF *ptf;
1441 INT i;
1442
1443 TRACE("(%p, %p, %d)\n", path, points, count);
1444
1445 if(count <= 0)
1446 return InvalidParameter;
1447
1448 ptf = heap_alloc_zero(sizeof(GpPointF)*count);
1449 if(!ptf) return OutOfMemory;
1450
1452 if(ret == Ok)
1453 for(i = 0;i < count;i++){
1454 points[i].X = gdip_round(ptf[i].X);
1455 points[i].Y = gdip_round(ptf[i].Y);
1456 };
1457 heap_free(ptf);
1458
1459 return ret;
1460}
GpStatus WINGDIPAPI GdipGetPathPoints(GpPath *path, GpPointF *points, INT count)
static INT gdip_round(REAL x)

◆ GdipGetPathTypes()

GpStatus WINGDIPAPI GdipGetPathTypes ( GpPath path,
BYTE types,
INT  count 
)

Definition at line 1462 of file graphicspath.c.

1463{
1464 TRACE("(%p, %p, %d)\n", path, types, count);
1465
1466 if(!path)
1467 return InvalidParameter;
1468
1469 if(count < path->pathdata.Count)
1470 return InsufficientBuffer;
1471
1472 memcpy(types, path->pathdata.Types, path->pathdata.Count);
1473
1474 return Ok;
1475}

Referenced by ok_path().

◆ GdipGetPathWorldBounds()

GpStatus WINGDIPAPI GdipGetPathWorldBounds ( GpPath path,
GpRectF bounds,
GDIPCONST GpMatrix matrix,
GDIPCONST GpPen pen 
)

Definition at line 1481 of file graphicspath.c.

1483{
1484 GpPointF * points, temp_pts[4];
1485 INT count, i;
1486 REAL path_width = 1.0, width, height, temp, low_x, low_y, high_x, high_y;
1487
1488 TRACE("(%p, %p, %p, %p)\n", path, bounds, matrix, pen);
1489
1490 /* Matrix and pen can be null. */
1491 if(!path || !bounds)
1492 return InvalidParameter;
1493
1494 /* If path is empty just return. */
1495 count = path->pathdata.Count;
1496 if(count == 0){
1497 bounds->X = bounds->Y = bounds->Width = bounds->Height = 0.0;
1498 return Ok;
1499 }
1500
1501 points = path->pathdata.Points;
1502
1503 low_x = high_x = points[0].X;
1504 low_y = high_y = points[0].Y;
1505
1506 for(i = 1; i < count; i++){
1507 low_x = min(low_x, points[i].X);
1508 low_y = min(low_y, points[i].Y);
1509 high_x = max(high_x, points[i].X);
1510 high_y = max(high_y, points[i].Y);
1511 }
1512
1513 width = high_x - low_x;
1514 height = high_y - low_y;
1515
1516 /* This looks unusual but it's the only way I can imitate windows. */
1517 if(matrix){
1518 temp_pts[0].X = low_x;
1519 temp_pts[0].Y = low_y;
1520 temp_pts[1].X = low_x;
1521 temp_pts[1].Y = high_y;
1522 temp_pts[2].X = high_x;
1523 temp_pts[2].Y = high_y;
1524 temp_pts[3].X = high_x;
1525 temp_pts[3].Y = low_y;
1526
1528 low_x = temp_pts[0].X;
1529 low_y = temp_pts[0].Y;
1530
1531 for(i = 1; i < 4; i++){
1532 low_x = min(low_x, temp_pts[i].X);
1533 low_y = min(low_y, temp_pts[i].Y);
1534 }
1535
1536 temp = width;
1537 width = height * fabs(matrix->matrix[2]) + width * fabs(matrix->matrix[0]);
1538 height = height * fabs(matrix->matrix[3]) + temp * fabs(matrix->matrix[1]);
1539 }
1540
1541 if(pen){
1542 path_width = pen->width / 2.0;
1543
1544 if(count > 2)
1545 path_width = max(path_width, pen->width * pen->miterlimit / 2.0);
1546 /* FIXME: this should probably also check for the startcap */
1547 if(pen->endcap & LineCapNoAnchor)
1548 path_width = max(path_width, pen->width * 2.2);
1549
1550 low_x -= path_width;
1551 low_y -= path_width;
1552 width += 2.0 * path_width;
1553 height += 2.0 * path_width;
1554 }
1555
1556 bounds->X = low_x;
1557 bounds->Y = low_y;
1558 bounds->Width = width;
1559 bounds->Height = height;
1560
1561 return Ok;
1562}
GpStatus WINGDIPAPI GdipTransformMatrixPoints(GpMatrix *matrix, GpPointF *pts, INT count)
Definition: matrix.c:363
@ LineCapNoAnchor
Definition: gdiplusenums.h:66
#define min(a, b)
Definition: monoChain.cc:55
static calc_node_t temp
Definition: rpn_ieee.c:38
#define max(a, b)
Definition: svc.c:63

Referenced by create_path_gradient(), GdipGetPathGradientRect(), GdipGetPathWorldBoundsI(), and test_worldbounds().

◆ GdipGetPathWorldBoundsI()

GpStatus WINGDIPAPI GdipGetPathWorldBoundsI ( GpPath path,
GpRect bounds,
GDIPCONST GpMatrix matrix,
GDIPCONST GpPen pen 
)

Definition at line 1564 of file graphicspath.c.

1566{
1567 GpStatus ret;
1568 GpRectF boundsF;
1569
1570 TRACE("(%p, %p, %p, %p)\n", path, bounds, matrix, pen);
1571
1572 ret = GdipGetPathWorldBounds(path,&boundsF,matrix,pen);
1573
1574 if(ret == Ok){
1575 bounds->X = gdip_round(boundsF.X);
1576 bounds->Y = gdip_round(boundsF.Y);
1577 bounds->Width = gdip_round(boundsF.Width);
1578 bounds->Height = gdip_round(boundsF.Height);
1579 }
1580
1581 return ret;
1582}
GpStatus WINGDIPAPI GdipGetPathWorldBounds(GpPath *path, GpRectF *bounds, GDIPCONST GpMatrix *matrix, GDIPCONST GpPen *pen)
INT Width
Definition: gdiplustypes.h:671
INT Height
Definition: gdiplustypes.h:672
INT X
Definition: gdiplustypes.h:669
INT Y
Definition: gdiplustypes.h:670

◆ GdipGetPointCount()

GpStatus WINGDIPAPI GdipGetPointCount ( GpPath path,
INT count 
)

Definition at line 1584 of file graphicspath.c.

1585{
1586 TRACE("(%p, %p)\n", path, count);
1587
1588 if(!path)
1589 return InvalidParameter;
1590
1591 *count = path->pathdata.Count;
1592
1593 return Ok;
1594}

Referenced by ok_path(), test_empty_rect(), test_getpathdata(), test_nextmarkerpath(), test_nextsubpathpath(), and test_widen().

◆ GdipIsOutlineVisiblePathPoint()

GpStatus WINGDIPAPI GdipIsOutlineVisiblePathPoint ( GpPath path,
REAL  x,
REAL  y,
GpPen pen,
GpGraphics graphics,
BOOL result 
)

Definition at line 1660 of file graphicspath.c.

1662{
1663 GpStatus stat;
1664 GpPath *wide_path;
1666
1667 TRACE("(%p,%0.2f,%0.2f,%p,%p,%p)\n", path, x, y, pen, graphics, result);
1668
1669 if(!path || !pen)
1670 return InvalidParameter;
1671
1672 stat = GdipClonePath(path, &wide_path);
1673
1674 if (stat != Ok)
1675 return stat;
1676
1677 if (pen->unit == UnitPixel && graphics != NULL)
1678 {
1680
1681 if (stat == Ok)
1684 }
1685
1686 if (stat == Ok)
1687 stat = GdipWidenPath(wide_path, pen, transform, 1.0);
1688
1689 if (pen->unit == UnitPixel && graphics != NULL)
1690 {
1691 if (stat == Ok)
1693
1694 if (stat == Ok)
1695 stat = GdipTransformPath(wide_path, transform);
1696 }
1697
1698 if (stat == Ok)
1699 stat = GdipIsVisiblePathPoint(wide_path, x, y, graphics, result);
1700
1702
1703 GdipDeletePath(wide_path);
1704
1705 return stat;
1706}
GpStatus WINGDIPAPI GdipWidenPath(GpPath *path, GpPen *pen, GpMatrix *matrix, REAL flatness)
GpStatus WINGDIPAPI GdipIsVisiblePathPoint(GpPath *path, REAL x, REAL y, GpGraphics *graphics, BOOL *result)
GpStatus WINGDIPAPI GdipDeleteMatrix(GpMatrix *matrix)
Definition: matrix.c:160
GpStatus WINGDIPAPI GdipCreateMatrix(GpMatrix **matrix)
Definition: matrix.c:140
GpStatus WINGDIPAPI GdipInvertMatrix(GpMatrix *matrix)
Definition: matrix.c:185
GpStatus get_graphics_transform(GpGraphics *graphics, GpCoordinateSpace dst_space, GpCoordinateSpace src_space, GpMatrix *matrix) DECLSPEC_HIDDEN
Definition: graphics.c:6875
@ CoordinateSpaceDevice
Definition: gdiplusenums.h:369
@ CoordinateSpaceWorld
Definition: gdiplusenums.h:367
GLuint GLenum GLenum transform
Definition: glext.h:9407
GLuint64EXT * result
Definition: glext.h:11304
GpUnit unit

Referenced by GdipIsOutlineVisiblePathPointI().

◆ GdipIsOutlineVisiblePathPointI()

GpStatus WINGDIPAPI GdipIsOutlineVisiblePathPointI ( GpPath path,
INT  x,
INT  y,
GpPen pen,
GpGraphics graphics,
BOOL result 
)

Definition at line 1652 of file graphicspath.c.

1654{
1655 TRACE("(%p, %d, %d, %p, %p, %p)\n", path, x, y, pen, graphics, result);
1656
1657 return GdipIsOutlineVisiblePathPoint(path, x, y, pen, graphics, result);
1658}
GpStatus WINGDIPAPI GdipIsOutlineVisiblePathPoint(GpPath *path, REAL x, REAL y, GpPen *pen, GpGraphics *graphics, BOOL *result)

◆ GdipIsVisiblePathPoint()

GpStatus WINGDIPAPI GdipIsVisiblePathPoint ( GpPath path,
REAL  x,
REAL  y,
GpGraphics graphics,
BOOL result 
)

Definition at line 1718 of file graphicspath.c.

1719{
1720 GpRegion *region;
1721 HRGN hrgn;
1723
1724 if(!path || !result) return InvalidParameter;
1725
1726 status = GdipCreateRegionPath(path, &region);
1727 if(status != Ok)
1728 return status;
1729
1730 status = GdipGetRegionHRgn(region, graphics, &hrgn);
1731 if(status != Ok){
1732 GdipDeleteRegion(region);
1733 return status;
1734 }
1735
1737
1739 GdipDeleteRegion(region);
1740
1741 return Ok;
1742}
static HRGN hrgn
GpStatus WINGDIPAPI GdipGetRegionHRgn(GpRegion *region, GpGraphics *graphics, HRGN *hrgn)
Definition: region.c:1194
GpStatus WINGDIPAPI GdipCreateRegionPath(GpPath *path, GpRegion **region)
Definition: region.c:425
GpStatus WINGDIPAPI GdipDeleteRegion(GpRegion *region)
Definition: region.c:571
BOOL WINAPI PtInRegion(_In_ HRGN, _In_ int, _In_ int)

Referenced by GdipIsOutlineVisiblePathPoint(), GdipIsVisiblePathPointI(), test_empty_rect(), and test_isvisible().

◆ GdipIsVisiblePathPointI()

GpStatus WINGDIPAPI GdipIsVisiblePathPointI ( GpPath path,
INT  x,
INT  y,
GpGraphics graphics,
BOOL result 
)

Definition at line 1708 of file graphicspath.c.

1709{
1710 TRACE("(%p, %d, %d, %p, %p)\n", path, x, y, graphics, result);
1711
1712 return GdipIsVisiblePathPoint(path, x, y, graphics, result);
1713}

◆ GdipResetPath()

GpStatus WINGDIPAPI GdipResetPath ( GpPath path)

Definition at line 1756 of file graphicspath.c.

1757{
1758 TRACE("(%p)\n", path);
1759
1760 if(!path)
1761 return InvalidParameter;
1762
1763 path->pathdata.Count = 0;
1764 path->newfigure = TRUE;
1765 path->fill = FillModeAlternate;
1766
1767 return Ok;
1768}
@ FillModeAlternate
Definition: gdiplusenums.h:55

Referenced by GdipPathIterNextMarkerPath(), GdipPathIterNextSubpathPath(), test_addcurve(), test_addpie(), test_flatten(), test_GdipFillPath(), test_transform(), test_translate(), and test_widen().

◆ GdipReversePath()

GpStatus WINGDIPAPI GdipReversePath ( GpPath path)

Definition at line 1596 of file graphicspath.c.

1597{
1598 INT i, count;
1599 INT start = 0; /* position in reversed path */
1600 GpPathData revpath;
1601
1602 TRACE("(%p)\n", path);
1603
1604 if(!path)
1605 return InvalidParameter;
1606
1607 count = path->pathdata.Count;
1608
1609 if(count == 0) return Ok;
1610
1611 revpath.Points = heap_alloc_zero(sizeof(GpPointF)*count);
1612 revpath.Types = heap_alloc_zero(sizeof(BYTE)*count);
1613 revpath.Count = count;
1614 if(!revpath.Points || !revpath.Types){
1615 heap_free(revpath.Points);
1616 heap_free(revpath.Types);
1617 return OutOfMemory;
1618 }
1619
1620 for(i = 0; i < count; i++){
1621
1622 /* find next start point */
1623 if(path->pathdata.Types[count-i-1] == PathPointTypeStart){
1624 INT j;
1625 for(j = start; j <= i; j++){
1626 revpath.Points[j] = path->pathdata.Points[count-j-1];
1627 revpath.Types[j] = path->pathdata.Types[count-j-1];
1628 }
1629 /* mark start point */
1630 revpath.Types[start] = PathPointTypeStart;
1631 /* set 'figure' endpoint type */
1632 if(i-start > 1){
1633 revpath.Types[i] = path->pathdata.Types[count-start-1] & ~PathPointTypePathTypeMask;
1634 revpath.Types[i] |= revpath.Types[i-1];
1635 }
1636 else
1637 revpath.Types[i] = path->pathdata.Types[start];
1638
1639 start = i+1;
1640 }
1641 }
1642
1643 memcpy(path->pathdata.Points, revpath.Points, sizeof(GpPointF)*count);
1644 memcpy(path->pathdata.Types, revpath.Types, sizeof(BYTE)*count);
1645
1646 heap_free(revpath.Points);
1647 heap_free(revpath.Types);
1648
1649 return Ok;
1650}

Referenced by test_reverse().

◆ GdipSetPathFillMode()

GpStatus WINGDIPAPI GdipSetPathFillMode ( GpPath path,
GpFillMode  fill 
)

Definition at line 1770 of file graphicspath.c.

1771{
1772 TRACE("(%p, %d)\n", path, fill);
1773
1774 if(!path)
1775 return InvalidParameter;
1776
1777 path->fill = fill;
1778
1779 return Ok;
1780}

◆ GdipSetPathMarker()

GpStatus WINGDIPAPI GdipSetPathMarker ( GpPath path)

Definition at line 2421 of file graphicspath.c.

2422{
2423 INT count;
2424
2425 TRACE("(%p)\n", path);
2426
2427 if(!path)
2428 return InvalidParameter;
2429
2430 count = path->pathdata.Count;
2431
2432 /* set marker flag */
2433 if(count > 0)
2434 path->pathdata.Types[count-1] |= PathPointTypePathMarker;
2435
2436 return Ok;
2437}
@ PathPointTypePathMarker
Definition: gdiplusenums.h:89

Referenced by test_nextmarker(), and test_nextmarkerpath().

◆ GdipStartPathFigure()

GpStatus WINGDIPAPI GdipStartPathFigure ( GpPath path)

Definition at line 1744 of file graphicspath.c.

1745{
1746 TRACE("(%p)\n", path);
1747
1748 if(!path)
1749 return InvalidParameter;
1750
1751 path->newfigure = TRUE;
1752
1753 return Ok;
1754}

Referenced by test_getsubpathcount().

◆ GdipTransformPath()

GpStatus WINGDIPAPI GdipTransformPath ( GpPath path,
GpMatrix matrix 
)

Definition at line 1782 of file graphicspath.c.

1783{
1784 TRACE("(%p, %p)\n", path, matrix);
1785
1786 if(!path)
1787 return InvalidParameter;
1788
1789 if(path->pathdata.Count == 0 || !matrix)
1790 return Ok;
1791
1792 return GdipTransformMatrixPoints(matrix, path->pathdata.Points,
1793 path->pathdata.Count);
1794}

Referenced by brush_fill_pixels(), GdipFlattenPath(), GdipIsOutlineVisiblePathPoint(), GdipSetClipPath(), GdipWidenPath(), SOFTWARE_GdipDrawPath(), and test_flatten().

◆ GdipWarpPath()

GpStatus WINGDIPAPI GdipWarpPath ( GpPath path,
GpMatrix matrix,
GDIPCONST GpPointF points,
INT  count,
REAL  x,
REAL  y,
REAL  width,
REAL  height,
WarpMode  warpmode,
REAL  flatness 
)

Definition at line 1796 of file graphicspath.c.

1799{
1800 FIXME("(%p,%p,%p,%i,%0.2f,%0.2f,%0.2f,%0.2f,%i,%0.2f)\n", path, matrix,
1801 points, count, x, y, width, height, warpmode, flatness);
1802
1803 return NotImplemented;
1804}
@ NotImplemented
Definition: gdiplustypes.h:32

◆ GdipWidenPath()

GpStatus WINGDIPAPI GdipWidenPath ( GpPath path,
GpPen pen,
GpMatrix matrix,
REAL  flatness 
)

Definition at line 2197 of file graphicspath.c.

2199{
2200 GpPath *flat_path=NULL;
2202 path_list_node_t *points=NULL, *last_point=NULL;
2203 int i, subpath_start=0, new_length;
2204 BYTE type;
2205
2206 TRACE("(%p,%p,%p,%0.2f)\n", path, pen, matrix, flatness);
2207
2208 if (!path || !pen)
2209 return InvalidParameter;
2210
2211 if (path->pathdata.Count <= 1)
2212 return OutOfMemory;
2213
2214 status = GdipClonePath(path, &flat_path);
2215
2216 if (status == Ok)
2217 status = GdipFlattenPath(flat_path, pen->unit == UnitPixel ? matrix : NULL, flatness);
2218
2219 if (status == Ok && !init_path_list(&points, 314.0, 22.0))
2221
2222 if (status == Ok)
2223 {
2224 last_point = points;
2225
2226 if (pen->endcap > LineCapTriangle)
2227 FIXME("unimplemented end cap %x\n", pen->endcap);
2228
2229 if (pen->startcap > LineCapTriangle)
2230 FIXME("unimplemented start cap %x\n", pen->startcap);
2231
2232 if (pen->dashcap != DashCapFlat)
2233 FIXME("unimplemented dash cap %d\n", pen->dashcap);
2234
2235 if (pen->join == LineJoinRound)
2236 FIXME("unimplemented line join %d\n", pen->join);
2237
2238 if (pen->align != PenAlignmentCenter)
2239 FIXME("unimplemented pen alignment %d\n", pen->align);
2240
2241 for (i=0; i < flat_path->pathdata.Count; i++)
2242 {
2243 type = flat_path->pathdata.Types[i];
2244
2246 subpath_start = i;
2247
2249 {
2250 if (pen->dash != DashStyleSolid)
2251 widen_dashed_figure(flat_path, pen, subpath_start, i, 1, &last_point);
2252 else
2253 widen_closed_figure(flat_path, pen, subpath_start, i, &last_point);
2254 }
2255 else if (i == flat_path->pathdata.Count-1 ||
2257 {
2258 if (pen->dash != DashStyleSolid)
2259 widen_dashed_figure(flat_path, pen, subpath_start, i, 0, &last_point);
2260 else
2261 widen_open_figure(flat_path->pathdata.Points, pen, subpath_start, i, pen->startcap, pen->customstart, pen->endcap, pen->customend, &last_point);
2262 }
2263 }
2264
2265 new_length = path_list_count(points)-1;
2266
2267 if (!lengthen_path(path, new_length))
2269 }
2270
2271 if (status == Ok)
2272 {
2273 path->pathdata.Count = new_length;
2274
2275 last_point = points->next;
2276 for (i = 0; i < new_length; i++)
2277 {
2278 path->pathdata.Points[i] = last_point->pt;
2279 path->pathdata.Types[i] = last_point->type;
2280 last_point = last_point->next;
2281 }
2282
2283 path->fill = FillModeWinding;
2284 }
2285
2287
2288 GdipDeletePath(flat_path);
2289
2290 if (status == Ok && pen->unit != UnitPixel)
2292
2293 return status;
2294}
static void widen_closed_figure(GpPath *path, GpPen *pen, int start, int end, path_list_node_t **last_point)
static void widen_dashed_figure(GpPath *path, GpPen *pen, int start, int end, int closed, path_list_node_t **last_point)
static void widen_open_figure(const GpPointF *points, GpPen *pen, int start, int end, GpLineCap start_cap, GpCustomLineCap *start_custom, GpLineCap end_cap, GpCustomLineCap *end_custom, path_list_node_t **last_point)
GpStatus WINGDIPAPI GdipFlattenPath(GpPath *path, GpMatrix *matrix, REAL flatness)
@ DashCapFlat
Definition: gdiplusenums.h:171
@ LineJoinRound
Definition: gdiplusenums.h:108
@ LineCapTriangle
Definition: gdiplusenums.h:64
@ FillModeWinding
Definition: gdiplusenums.h:56
@ DashStyleSolid
Definition: gdiplusenums.h:178
@ PenAlignmentCenter
Definition: gdiplusenums.h:155
GpPathData pathdata
GpDashStyle dash
GpLineCap startcap
GpCustomLineCap * customend
GpLineCap endcap
GpLineJoin join
GpDashCap dashcap
GpPenAlignment align
GpCustomLineCap * customstart

Referenced by GdipIsOutlineVisiblePathPoint(), SOFTWARE_GdipDrawPath(), and test_widen().

◆ GdipWindingModeOutline()

GpStatus WINGDIPAPI GdipWindingModeOutline ( GpPath path,
GpMatrix matrix,
REAL  flatness 
)

Definition at line 2458 of file graphicspath.c.

2459{
2460 FIXME("stub: %p, %p, %.2f\n", path, matrix, flatness);
2461 return NotImplemented;
2462}

◆ init_path_list()

static BOOL init_path_list ( path_list_node_t **  node,
REAL  x,
REAL  y 
)
static

Definition at line 44 of file graphicspath.c.

45{
46 *node = heap_alloc_zero(sizeof(path_list_node_t));
47 if(!*node)
48 return FALSE;
49
50 (*node)->pt.X = x;
51 (*node)->pt.Y = y;
52 (*node)->type = PathPointTypeStart;
53 (*node)->next = NULL;
54
55 return TRUE;
56}

Referenced by GdipFlattenPath(), and GdipWidenPath().

◆ is_integer_path()

static BOOL is_integer_path ( const GpPath path)
static

Definition at line 2474 of file graphicspath.c.

2475{
2476 int i;
2477
2478 if (!path->pathdata.Count) return FALSE;
2479
2480 for (i = 0; i < path->pathdata.Count; i++)
2481 {
2482 short x, y;
2483 x = gdip_round(path->pathdata.Points[i].X);
2484 y = gdip_round(path->pathdata.Points[i].Y);
2485 if (path->pathdata.Points[i].X != (REAL)x || path->pathdata.Points[i].Y != (REAL)y)
2486 return FALSE;
2487 }
2488 return TRUE;
2489}

Referenced by write_path_data().

◆ path_list_count()

static INT path_list_count ( path_list_node_t node)
static

Definition at line 94 of file graphicspath.c.

95{
96 INT count = 1;
97
98 while((node = node->next))
99 ++count;
100
101 return count;
102}

Referenced by GdipFlattenPath(), and GdipWidenPath().

◆ widen_cap()

static void widen_cap ( const GpPointF endpoint,
const GpPointF nextpoint,
GpPen pen,
GpLineCap  cap,
GpCustomLineCap custom,
int  add_first_points,
int  add_last_point,
path_list_node_t **  last_point 
)
static

Definition at line 1879 of file graphicspath.c.

1882{
1883 switch (cap)
1884 {
1885 default:
1886 case LineCapFlat:
1887 if (add_first_points)
1888 add_bevel_point(endpoint, nextpoint, pen, 1, last_point);
1889 if (add_last_point)
1890 add_bevel_point(endpoint, nextpoint, pen, 0, last_point);
1891 break;
1892 case LineCapSquare:
1893 {
1894 REAL segment_dy = nextpoint->Y-endpoint->Y;
1895 REAL segment_dx = nextpoint->X-endpoint->X;
1896 REAL segment_length = sqrtf(segment_dy*segment_dy + segment_dx*segment_dx);
1897 REAL distance = pen->width/2.0;
1898 REAL bevel_dx, bevel_dy;
1899 REAL extend_dx, extend_dy;
1900
1901 extend_dx = -distance * segment_dx / segment_length;
1902 extend_dy = -distance * segment_dy / segment_length;
1903
1904 bevel_dx = -distance * segment_dy / segment_length;
1905 bevel_dy = distance * segment_dx / segment_length;
1906
1907 if (add_first_points)
1908 *last_point = add_path_list_node(*last_point, endpoint->X + extend_dx + bevel_dx,
1909 endpoint->Y + extend_dy + bevel_dy, PathPointTypeLine);
1910
1911 if (add_last_point)
1912 *last_point = add_path_list_node(*last_point, endpoint->X + extend_dx - bevel_dx,
1913 endpoint->Y + extend_dy - bevel_dy, PathPointTypeLine);
1914
1915 break;
1916 }
1917 case LineCapRound:
1918 {
1919 REAL segment_dy = nextpoint->Y-endpoint->Y;
1920 REAL segment_dx = nextpoint->X-endpoint->X;
1921 REAL segment_length = sqrtf(segment_dy*segment_dy + segment_dx*segment_dx);
1922 REAL distance = pen->width/2.0;
1923 REAL dx, dy, dx2, dy2;
1924 const REAL control_point_distance = 0.5522847498307935; /* 4/3 * (sqrt(2) - 1) */
1925
1926 if (add_first_points)
1927 {
1928 dx = -distance * segment_dx / segment_length;
1929 dy = -distance * segment_dy / segment_length;
1930
1931 dx2 = dx * control_point_distance;
1932 dy2 = dy * control_point_distance;
1933
1934 /* first 90-degree arc */
1935 *last_point = add_path_list_node(*last_point, endpoint->X + dy,
1937
1938 *last_point = add_path_list_node(*last_point, endpoint->X + dy + dx2,
1939 endpoint->Y - dx + dy2, PathPointTypeBezier);
1940
1941 *last_point = add_path_list_node(*last_point, endpoint->X + dx + dy2,
1942 endpoint->Y + dy - dx2, PathPointTypeBezier);
1943
1944 /* midpoint */
1945 *last_point = add_path_list_node(*last_point, endpoint->X + dx,
1947
1948 /* second 90-degree arc */
1949 *last_point = add_path_list_node(*last_point, endpoint->X + dx - dy2,
1950 endpoint->Y + dy + dx2, PathPointTypeBezier);
1951
1952 *last_point = add_path_list_node(*last_point, endpoint->X - dy + dx2,
1953 endpoint->Y + dx + dy2, PathPointTypeBezier);
1954
1955 *last_point = add_path_list_node(*last_point, endpoint->X - dy,
1957 }
1958 break;
1959 }
1960 case LineCapTriangle:
1961 {
1962 REAL segment_dy = nextpoint->Y-endpoint->Y;
1963 REAL segment_dx = nextpoint->X-endpoint->X;
1964 REAL segment_length = sqrtf(segment_dy*segment_dy + segment_dx*segment_dx);
1965 REAL distance = pen->width/2.0;
1966 REAL dx, dy;
1967
1968 dx = distance * segment_dx / segment_length;
1969 dy = distance * segment_dy / segment_length;
1970
1971 if (add_first_points) {
1972 add_bevel_point(endpoint, nextpoint, pen, 1, last_point);
1973
1974 *last_point = add_path_list_node(*last_point, endpoint->X - dx,
1976 }
1977 if (add_last_point)
1978 add_bevel_point(endpoint, nextpoint, pen, 0, last_point);
1979 break;
1980 }
1981 }
1982}
static void add_bevel_point(const GpPointF *endpoint, const GpPointF *nextpoint, GpPen *pen, int right_side, path_list_node_t **last_point)
@ LineCapSquare
Definition: gdiplusenums.h:62
@ LineCapRound
Definition: gdiplusenums.h:63
@ LineCapFlat
Definition: gdiplusenums.h:61
GLenum cap
Definition: glext.h:9639
GLint dy
Definition: linetemp.h:97
GLint dx
Definition: linetemp.h:97

Referenced by widen_open_figure().

◆ widen_closed_figure()

static void widen_closed_figure ( GpPath path,
GpPen pen,
int  start,
int  end,
path_list_node_t **  last_point 
)
static

Definition at line 2017 of file graphicspath.c.

2019{
2020 int i;
2021 path_list_node_t *prev_point;
2022
2023 if (end <= start)
2024 return;
2025
2026 /* left outline */
2027 prev_point = *last_point;
2028
2029 widen_joint(&path->pathdata.Points[end], &path->pathdata.Points[start],
2030 &path->pathdata.Points[start+1], pen, last_point);
2031
2032 for (i=start+1; i<end; i++)
2033 widen_joint(&path->pathdata.Points[i-1], &path->pathdata.Points[i],
2034 &path->pathdata.Points[i+1], pen, last_point);
2035
2036 widen_joint(&path->pathdata.Points[end-1], &path->pathdata.Points[end],
2037 &path->pathdata.Points[start], pen, last_point);
2038
2039 prev_point->next->type = PathPointTypeStart;
2040 (*last_point)->type |= PathPointTypeCloseSubpath;
2041
2042 /* right outline */
2043 prev_point = *last_point;
2044
2045 widen_joint(&path->pathdata.Points[start], &path->pathdata.Points[end],
2046 &path->pathdata.Points[end-1], pen, last_point);
2047
2048 for (i=end-1; i>start; i--)
2049 widen_joint(&path->pathdata.Points[i+1], &path->pathdata.Points[i],
2050 &path->pathdata.Points[i-1], pen, last_point);
2051
2052 widen_joint(&path->pathdata.Points[start+1], &path->pathdata.Points[start],
2053 &path->pathdata.Points[end], pen, last_point);
2054
2055 prev_point->next->type = PathPointTypeStart;
2056 (*last_point)->type |= PathPointTypeCloseSubpath;
2057}
static void widen_joint(const GpPointF *p1, const GpPointF *p2, const GpPointF *p3, GpPen *pen, path_list_node_t **last_point)
path_list_node_t * next
Definition: graphicspath.c:40

Referenced by GdipWidenPath().

◆ widen_dashed_figure()

static void widen_dashed_figure ( GpPath path,
GpPen pen,
int  start,
int  end,
int  closed,
path_list_node_t **  last_point 
)
static

Definition at line 2059 of file graphicspath.c.

2061{
2062 int i, j;
2063 REAL dash_pos=0.0;
2064 int dash_index=0;
2065 const REAL *dash_pattern;
2066 REAL *dash_pattern_scaled;
2067 int dash_count;
2068 GpPointF *tmp_points;
2069 REAL segment_dy;
2070 REAL segment_dx;
2071 REAL segment_length;
2072 REAL segment_pos;
2073 int num_tmp_points=0;
2074 int draw_start_cap=0;
2075 static const REAL dash_dot_dot[6] = { 3.0, 1.0, 1.0, 1.0, 1.0, 1.0 };
2076
2077 if (end <= start)
2078 return;
2079
2080 switch (pen->dash)
2081 {
2082 case DashStyleDash:
2083 default:
2084 dash_pattern = dash_dot_dot;
2085 dash_count = 2;
2086 break;
2087 case DashStyleDot:
2088 dash_pattern = &dash_dot_dot[2];
2089 dash_count = 2;
2090 break;
2091 case DashStyleDashDot:
2092 dash_pattern = dash_dot_dot;
2093 dash_count = 4;
2094 break;
2096 dash_pattern = dash_dot_dot;
2097 dash_count = 6;
2098 break;
2099 case DashStyleCustom:
2100 dash_pattern = pen->dashes;
2101 dash_count = pen->numdashes;
2102 break;
2103 }
2104
2105 dash_pattern_scaled = heap_alloc(dash_count * sizeof(REAL));
2106 if (!dash_pattern_scaled) return;
2107
2108 for (i = 0; i < dash_count; i++)
2109 dash_pattern_scaled[i] = pen->width * dash_pattern[i];
2110
2111 tmp_points = heap_alloc_zero((end - start + 2) * sizeof(GpPoint));
2112 if (!tmp_points) {
2113 heap_free(dash_pattern_scaled);
2114 return; /* FIXME */
2115 }
2116
2117 if (!closed)
2118 draw_start_cap = 1;
2119
2120 for (j=start; j <= end; j++)
2121 {
2122 if (j == start)
2123 {
2124 if (closed)
2125 i = end;
2126 else
2127 continue;
2128 }
2129 else
2130 i = j-1;
2131
2132 segment_dy = path->pathdata.Points[j].Y - path->pathdata.Points[i].Y;
2133 segment_dx = path->pathdata.Points[j].X - path->pathdata.Points[i].X;
2134 segment_length = sqrtf(segment_dy*segment_dy + segment_dx*segment_dx);
2135 segment_pos = 0.0;
2136
2137 while (1)
2138 {
2139 if (dash_pos == 0.0)
2140 {
2141 if ((dash_index % 2) == 0)
2142 {
2143 /* start dash */
2144 num_tmp_points = 1;
2145 tmp_points[0].X = path->pathdata.Points[i].X + segment_dx * segment_pos / segment_length;
2146 tmp_points[0].Y = path->pathdata.Points[i].Y + segment_dy * segment_pos / segment_length;
2147 }
2148 else
2149 {
2150 /* end dash */
2151 tmp_points[num_tmp_points].X = path->pathdata.Points[i].X + segment_dx * segment_pos / segment_length;
2152 tmp_points[num_tmp_points].Y = path->pathdata.Points[i].Y + segment_dy * segment_pos / segment_length;
2153
2154 widen_open_figure(tmp_points, pen, 0, num_tmp_points,
2155 draw_start_cap ? pen->startcap : LineCapFlat, pen->customstart,
2156 LineCapFlat, NULL, last_point);
2157 draw_start_cap = 0;
2158 num_tmp_points = 0;
2159 }
2160 }
2161
2162 if (dash_pattern_scaled[dash_index] - dash_pos > segment_length - segment_pos)
2163 {
2164 /* advance to next segment */
2165 if ((dash_index % 2) == 0)
2166 {
2167 tmp_points[num_tmp_points] = path->pathdata.Points[j];
2168 num_tmp_points++;
2169 }
2170 dash_pos += segment_length - segment_pos;
2171 break;
2172 }
2173 else
2174 {
2175 /* advance to next dash in pattern */
2176 segment_pos += dash_pattern_scaled[dash_index] - dash_pos;
2177 dash_pos = 0.0;
2178 if (++dash_index == dash_count)
2179 dash_index = 0;
2180 continue;
2181 }
2182 }
2183 }
2184
2185 if (dash_index % 2 == 0 && num_tmp_points != 0)
2186 {
2187 /* last dash overflows last segment */
2188 widen_open_figure(tmp_points, pen, 0, num_tmp_points-1,
2189 draw_start_cap ? pen->startcap : LineCapFlat, pen->customstart,
2190 closed ? LineCapFlat : pen->endcap, pen->customend, last_point);
2191 }
2192
2193 heap_free(dash_pattern_scaled);
2194 heap_free(tmp_points);
2195}
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
@ DashStyleDot
Definition: gdiplusenums.h:180
@ DashStyleDashDot
Definition: gdiplusenums.h:181
@ DashStyleCustom
Definition: gdiplusenums.h:183
@ DashStyleDash
Definition: gdiplusenums.h:179
@ DashStyleDashDotDot
Definition: gdiplusenums.h:182
INT numdashes
REAL * dashes

Referenced by GdipWidenPath().

◆ widen_joint()

static void widen_joint ( const GpPointF p1,
const GpPointF p2,
const GpPointF p3,
GpPen pen,
path_list_node_t **  last_point 
)
static

Definition at line 1837 of file graphicspath.c.

1839{
1840 switch (pen->join)
1841 {
1842 case LineJoinMiter:
1844 if ((p2->X - p1->X) * (p3->Y - p1->Y) > (p2->Y - p1->Y) * (p3->X - p1->X))
1845 {
1846 float distance = pen->width/2.0;
1847 float length_0 = sqrtf((p2->X-p1->X)*(p2->X-p1->X)+(p2->Y-p1->Y)*(p2->Y-p1->Y));
1848 float length_1 = sqrtf((p3->X-p2->X)*(p3->X-p2->X)+(p3->Y-p2->Y)*(p3->Y-p2->Y));
1849 float dx0 = distance * (p2->X - p1->X) / length_0;
1850 float dy0 = distance * (p2->Y - p1->Y) / length_0;
1851 float dx1 = distance * (p3->X - p2->X) / length_1;
1852 float dy1 = distance * (p3->Y - p2->Y) / length_1;
1853 float det = (dy0*dx1 - dx0*dy1);
1854 float dx = (dx0*dx1*(dx0-dx1) + dy0*dy0*dx1 - dy1*dy1*dx0)/det;
1855 float dy = (dy0*dy1*(dy0-dy1) + dx0*dx0*dy1 - dx1*dx1*dy0)/det;
1856 if (dx*dx + dy*dy < pen->miterlimit*pen->miterlimit * distance*distance)
1857 {
1858 *last_point = add_path_list_node(*last_point, p2->X + dx,
1859 p2->Y + dy, PathPointTypeLine);
1860 break;
1861 }
1862 else if (pen->join == LineJoinMiter)
1863 {
1864 static int once;
1865 if (!once++)
1866 FIXME("should add a clipped corner\n");
1867 }
1868 /* else fall-through */
1869 }
1870 /* else fall-through */
1871 default:
1872 case LineJoinBevel:
1873 add_bevel_point(p2, p1, pen, 1, last_point);
1874 add_bevel_point(p2, p3, pen, 0, last_point);
1875 break;
1876 }
1877}
@ LineJoinMiter
Definition: gdiplusenums.h:106
@ LineJoinMiterClipped
Definition: gdiplusenums.h:109
@ LineJoinBevel
Definition: gdiplusenums.h:107
REAL miterlimit

Referenced by widen_closed_figure(), and widen_open_figure().

◆ widen_open_figure()

static void widen_open_figure ( const GpPointF points,
GpPen pen,
int  start,
int  end,
GpLineCap  start_cap,
GpCustomLineCap start_custom,
GpLineCap  end_cap,
GpCustomLineCap end_custom,
path_list_node_t **  last_point 
)
static

Definition at line 1984 of file graphicspath.c.

1987{
1988 int i;
1989 path_list_node_t *prev_point;
1990
1991 if (end <= start)
1992 return;
1993
1994 prev_point = *last_point;
1995
1997 pen, start_cap, start_custom, FALSE, TRUE, last_point);
1998
1999 for (i=start+1; i<end; i++)
2000 widen_joint(&points[i-1], &points[i],
2001 &points[i+1], pen, last_point);
2002
2003 widen_cap(&points[end], &points[end-1],
2004 pen, end_cap, end_custom, TRUE, TRUE, last_point);
2005
2006 for (i=end-1; i>start; i--)
2007 widen_joint(&points[i+1], &points[i],
2008 &points[i-1], pen, last_point);
2009
2011 pen, start_cap, start_custom, TRUE, FALSE, last_point);
2012
2013 prev_point->next->type = PathPointTypeStart;
2014 (*last_point)->type |= PathPointTypeCloseSubpath;
2015}
static void widen_cap(const GpPointF *endpoint, const GpPointF *nextpoint, GpPen *pen, GpLineCap cap, GpCustomLineCap *custom, int add_first_points, int add_last_point, path_list_node_t **last_point)

Referenced by GdipWidenPath(), and widen_dashed_figure().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( gdiplus  )

◆ write_path_data()

DWORD write_path_data ( GpPath path,
void data 
)

Definition at line 2491 of file graphicspath.c.

2492{
2493 struct path_header *header = data;
2494 BOOL integer_path = is_integer_path(path);
2495 DWORD i, size;
2496 BYTE *types;
2497
2498 size = sizeof(struct path_header) + path->pathdata.Count;
2499 if (integer_path)
2500 size += sizeof(short[2]) * path->pathdata.Count;
2501 else
2502 size += sizeof(float[2]) * path->pathdata.Count;
2503 size = (size + 3) & ~3;
2504
2505 if (!data) return size;
2506
2507 header->version = VERSION_MAGIC2;
2508 header->count = path->pathdata.Count;
2509 header->flags = integer_path ? FLAGS_INTPATH : 0;
2510
2511 if (integer_path)
2512 {
2513 short *points = (short*)(header + 1);
2514 for (i = 0; i < path->pathdata.Count; i++)
2515 {
2516 points[2*i] = path->pathdata.Points[i].X;
2517 points[2*i + 1] = path->pathdata.Points[i].Y;
2518 }
2519 types = (BYTE*)(points + 2*i);
2520 }
2521 else
2522 {
2523 float *points = (float*)(header + 1);
2524 for (i = 0; i < path->pathdata.Count; i++)
2525 {
2526 points[2*i] = path->pathdata.Points[i].X;
2527 points[2*i + 1] = path->pathdata.Points[i].Y;
2528 }
2529 types = (BYTE*)(points + 2*i);
2530 }
2531
2532 for (i=0; i<path->pathdata.Count; i++)
2533 types[i] = path->pathdata.Types[i];
2534 memset(types + i, 0, ((path->pathdata.Count + 3) & ~3) - path->pathdata.Count);
2535 return size;
2536}
#define FLAGS_INTPATH
static BOOL is_integer_path(const GpPath *path)
#define VERSION_MAGIC2
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
int Count
Definition: noreturn.cpp:7

Referenced by get_element_size(), METAFILE_AddPathObject(), and write_element().