9
* Prototypes for procedures defined in this file:
12
static int SplineCurve _ANSI_ARGS_((Tk_Canvas canvas,
13
double *pointPtr, int numPoints, int numSteps,
14
XPoint xPoints[], double dblPoints[]));
16
static void SplineCurvePostscript _ANSI_ARGS_((Tcl_Interp *interp,
17
Tk_Canvas canvas, double *pointPtr,
18
int numPoints, int numSteps));
22
* "export" is a MetroWerks specific pragma. It flags the linker that
23
* any symbols that are defined when this pragma is on will be exported
24
* to shared libraries that link with this library.
27
int Tkspline_Init( Tcl_Interp *interp );
28
int Tkspline_SafeInit( Tcl_Interp *interp );
31
# define VERSION "0.4"
34
int Tkspline_Init _ANSI_ARGS_((Tcl_Interp *interp));
36
int Tkspline_SafeInit _ANSI_ARGS_((Tcl_Interp *interp));
39
* structure that is hooked in to describe the new smoothing method
42
static Tk_SmoothMethod splineSmoothMethod = {
43
"spline", /* used as in: -smooth spline */
44
SplineCurve, /* canvas curve generator */
45
SplineCurvePostscript, /* postscript curve generator */
50
*--------------------------------------------------------------
54
* Given a set of spline control points draw the Bezier splines.
55
* There must be 3N+1 points for bezier splines, otherwise smoothing
56
* defaults to using the builtin algorithm.
57
* Produces output points in either of two forms.
60
* Either or both of the xPoints or dblPoints arrays are filled
61
* in. The return value is the number of points placed in the
67
*--------------------------------------------------------------
72
SplineCurve(canvas, pointPtr, numPoints, numSteps, xPoints, dblPoints)
73
Tk_Canvas canvas; /* Canvas in which curve is to be
75
double *pointPtr; /* Array of input coordinates: x0,
76
* y0, x1, y1, etc.. */
77
int numPoints; /* Number of points at pointPtr. */
78
int numSteps; /* Number of steps to use for each
79
* spline segments (determines
80
* smoothness of curve). */
81
XPoint xPoints[]; /* Array of XPoints to fill in (e.g.
82
* for display. NULL means don't
83
* fill in any XPoints. */
84
double dblPoints[]; /* Array of points to fill in as
85
* doubles, in the form x0, y0,
86
* x1, y1, .... NULL means don't
87
* fill in anything in this form.
88
* Caller must make sure that this
89
* array has enough space. */
93
/* if the number of points is invalid, use the old function */
94
if ((numPoints < 4) || (numPoints % 3 != 1)) {
95
return TkMakeBezierCurve(canvas, pointPtr, numPoints, numSteps,
98
/* if pointPtr == NULL, just return a maximum for the number of
99
* points to be calculated */
101
return (1 + (numPoints/3)*numSteps);
104
if (xPoints != NULL) {
105
Tk_CanvasDrawableCoords(canvas, pointPtr[0], pointPtr[1],
106
&xPoints->x, &xPoints->y);
109
if (dblPoints != NULL) {
110
dblPoints[0] = pointPtr[0];
111
dblPoints[1] = pointPtr[1];
116
for (i = 2; i < numPoints; i += 3, pointPtr += 6) {
117
if (xPoints != NULL) {
118
TkBezierScreenPoints(canvas, pointPtr, numSteps, xPoints);
121
if (dblPoints != NULL) {
122
TkBezierPoints(pointPtr, numSteps, dblPoints);
123
dblPoints += 2*numSteps;
125
outputPoints += numSteps;
131
*--------------------------------------------------------------
133
* SplineCurvePostscript --
135
* This procedure generates Postscript commands that create
136
* a path corresponding to a given Bezier curve.
139
* None. Postscript commands to generate the path are appended
145
*--------------------------------------------------------------
149
SplineCurvePostscript(interp, canvas, pointPtr, numPoints, numSteps)
150
Tcl_Interp *interp; /* Interpreter in whose result the
151
* Postscript is to be stored. */
152
Tk_Canvas canvas; /* Canvas widget for which the
153
* Postscript is being generated. */
154
double *pointPtr; /* Array of input coordinates: x0,
155
* y0, x1, y1, etc.. */
156
int numPoints; /* Number of points at pointPtr. */
157
#if (TK_MAJOR_VERSION < 8) || ((TK_MAJOR_VERSION == 8) && (TK_MAJOR_VERSION < 3))
158
int numSteps; /* Not Used */
164
/* if the number of points is invalid, use the old function */
165
if ((numPoints < 4) || (numPoints % 3 != 1)) {
166
#if (TK_MAJOR_VERSION < 8) || ((TK_MAJOR_VERSION == 8) && (TK_MAJOR_VERSION < 3))
167
TkMakeBezierPostscript(interp, canvas, pointPtr, numPoints, numSteps);
169
TkMakeBezierPostscript(interp, canvas, pointPtr, numPoints);
174
sprintf(buffer, "%.15g %.15g moveto\n",
175
pointPtr[0], Tk_CanvasPsY(canvas, pointPtr[1]));
176
Tcl_AppendResult(interp, buffer, (char *) NULL);
179
* Cycle through all the remaining points in the curve, generating
180
* a curve section for each vertex in the linear path.
183
for (i = numPoints-2, pointPtr += 2; i > 0; i -= 3, pointPtr += 6) {
184
sprintf(buffer, "%.15g %.15g %.15g %.15g %.15g %.15g curveto\n",
185
pointPtr[0], Tk_CanvasPsY(canvas, pointPtr[1]),
186
pointPtr[2], Tk_CanvasPsY(canvas, pointPtr[3]),
187
pointPtr[4], Tk_CanvasPsY(canvas, pointPtr[5]));
188
Tcl_AppendResult(interp, buffer, (char *) NULL);
193
*--------------------------------------------------------------
195
* Tkspline_Init -- Function to call on loading the Tkspline DLL
197
* Results: Returns TCL_OK, or TCL_ERROR if unable to load.
199
* Side effects: Package Tkspline added to package list
200
* lines and polygons have a new "spline" smooth method.
202
*--------------------------------------------------------------
205
int Tkspline_Init(interp)
209
if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) {
212
if (Tk_InitStubs(interp, TK_VERSION, 0) == NULL) {
216
if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 0) != TCL_OK) {
219
if (Tcl_PkgRequire(interp, "Tk", TK_VERSION, 0) != TCL_OK) {
224
Tk_CreateSmoothMethod(interp, &splineSmoothMethod);
226
return Tcl_PkgProvide(interp, "Tkspline", VERSION);
229
int Tkspline_SafeInit(Tcl_Interp * interp)
231
return Tkspline_Init(interp);