From 4e9cc914ae924ff2c51ac4ddfb02bc3181f6f482 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 19 Aug 2004 14:41:50 +0000 Subject: TIP#168 implementation. Based on [Patch 886240] --- ChangeLog | 15 +++ doc/canvas.n | 50 ++++++--- generic/tkCanvUtil.c | 137 ++++++++++++++++++------ generic/tkInt.decls | 15 ++- generic/tkTrig.c | 297 +++++++++++++++++++++++++++++++++++++++++++++++++-- tests/canvas.test | 12 ++- 6 files changed, 470 insertions(+), 56 deletions(-) diff --git a/ChangeLog b/ChangeLog index 949ccfd..0a1180e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2004-08-19 Donal K. Fellows + + TIP#168 IMPLEMENTATION + + * generic/tkTrig.c (TkMakeRawCurve, TkMakeRawCurvePostscript): + * generic/tkInt.decls: New functions to handle the geometry for + "raw" bezier curves. + * generic/tkCanvUtil.c (tkRawSmoothMethod, InitSmoothMethods) + (TkSmoothParseProc): Add new type of smoothing method, simplify + the method initialization, and change the old smoothing method to + be called "true" and just keep "bezier" as an alias. + * tests/canvas.test (canvas-17.1): Basic test of built-in + smoothing method support. + * doc/canvas.n: Documentation updates. + 2004-08-18 Donal K. Fellows * generic/tkPanedWindow.c (optionSpecs): Add missing GEOMETRY flag diff --git a/doc/canvas.n b/doc/canvas.n index a9bee5f..7403907 100644 --- a/doc/canvas.n +++ b/doc/canvas.n @@ -6,7 +6,7 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -'\" RCS: @(#) $Id: canvas.n,v 1.15 2004/08/16 08:24:45 dkf Exp $ +'\" RCS: @(#) $Id: canvas.n,v 1.16 2004/08/19 14:41:52 dkf Exp $ '\" .so man.macros .TH canvas n 8.3 Tk "Tk Built-In Commands" @@ -1396,20 +1396,29 @@ irrelevant. .TP \fB\-smooth \fIsmoothMethod\fR \fIsmoothMethod\fR must have one of the forms accepted by -\fBTk_GetBoolean\fR or a line smoothing method. Only \fBbezier\fR is -supported in the core, but more can be added at runtime. If a boolean +\fBTk_GetBoolean\fR or a line smoothing method. Only \fBtrue\fR and \fBraw\fR are +supported in the core (with \fBbezier\fR being an alias for \fBtrue\fR), but more can be added at runtime. If a boolean false value or empty string is given, no smoothing is applied. A boolean -truth value assumes \fBbezier\fR smoothing. -It indicates whether or not the line should be drawn as a curve. -If so, the line is rendered as a set of parabolic splines: one spline +truth value assumes \fBtrue\fR smoothing. +If the smoothing method is \fBtrue\fR, this indicates that the line +should be drawn as a curve, rendered as a set of quadratic splines: one spline is drawn for the first and second line segments, one for the second and third, and so on. Straight-line segments can be generated within a curve by duplicating the end-points of the desired line segment. +If the smoothing method is \fBraw\fR, this indicates that the line +should also be drawn as a curve but where the list of coordinates is +such that the first coordinate pair (and every third coordinate pair +thereafter) is a knot point on a cubic Bezier curve, and the other +coordinates are control points on the cubic Bezier curve. Straight +line segments can be venerated within a curve by making control points +equal to their neighbouring knot points. If the last point is a +control point and not a knot point, the point is repeated (one or two +times) so that it also becomes a knot point. .TP \fB\-splinesteps \fInumber\fR Specifies the degree of smoothness desired for curves: each spline will be approximated with \fInumber\fR line segments. This -option is ignored unless the \fB\-smooth\fR option is true. +option is ignored unless the \fB\-smooth\fR option is true or \fBraw\fR. .SH "OVAL ITEMS" .PP Items of type \fBoval\fR appear as circular or oval regions on @@ -1516,17 +1525,30 @@ If this option isn't specified then it defaults to \fBmiter\fR. .TP \fB\-smooth \fIboolean\fR \fIBoolean\fR must have one of the forms accepted by \fBTk_GetBoolean\fR -It indicates whether or not the polygon should be drawn with a -curved perimeter. -If so, the outline of the polygon becomes a set of parabolic splines, -one spline for the first and second line segments, one for the second -and third, and so on. Straight-line segments can be generated in a -smoothed polygon by duplicating the end-points of the desired line segment. +or a line smoothing method. Only \fBtrue\fR and \fBraw\fR are +supported in the core (with \fBbezier\fR being an alias for \fBtrue\fR), but more can be added at runtime. If a boolean +false value or empty string is given, no smoothing is applied. A boolean +truth value assumes \fBtrue\fR smoothing. +If the smoothing method is \fBtrue\fR, this indicates that the polygon +should be drawn as a curve, rendered as a set of quadratic splines: one spline +is drawn for the first and second line segments, one for the second +and third, and so on. Straight-line segments can be generated within +a curve by duplicating the end-points of the desired line segment. +If the smoothing method is \fBraw\fR, this indicates that the polygon +should also be drawn as a curve but where the list of coordinates is +such that the first coordinate pair (and every third coordinate pair +thereafter) is a knot point on a cubic Bezier curve, and the other +coordinates are control points on the cubic Bezier curve. Straight +line segments can be venerated within a curve by making control points +equal to their neighbouring knot points. If the last point is not the +second point of a pair of control points, the point is repeated (one or two +times) so that it also becomes the second point of a pair of control +points (the associated knot point will be the first control point). .TP \fB\-splinesteps \fInumber\fR Specifies the degree of smoothness desired for curves: each spline will be approximated with \fInumber\fR line segments. This -option is ignored unless the \fB\-smooth\fR option is true. +option is ignored unless the \fB\-smooth\fR option is true or \fBraw\fR. .PP Polygon items are different from other items such as rectangles, ovals and arcs in that interior points are considered to be ``inside'' a diff --git a/generic/tkCanvUtil.c b/generic/tkCanvUtil.c index ceabca4..ff0d720 100644 --- a/generic/tkCanvUtil.c +++ b/generic/tkCanvUtil.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvUtil.c,v 1.11 2004/03/16 19:53:18 hobbs Exp $ + * RCS: @(#) $Id: tkCanvUtil.c,v 1.12 2004/08/19 14:41:52 dkf Exp $ */ #include "tkInt.h" @@ -18,6 +18,45 @@ #include "tkPort.h" #include +/* + * Structures defined only in this file. + */ + +typedef struct SmoothAssocData { + struct SmoothAssocData *nextPtr; /* pointer to next SmoothAssocData */ + Tk_SmoothMethod smooth; /* name and functions associated with + * this option */ +} SmoothAssocData; + +Tk_SmoothMethod tkBezierSmoothMethod = { + "true", + TkMakeBezierCurve, + (void (*) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, + double *coordPtr, int numPoints, int numSteps))) + TkMakeBezierPostscript, +}; +static Tk_SmoothMethod tkRawSmoothMethod = { + "raw", + TkMakeRawCurve, + (void (*) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, + double *coordPtr, int numPoints, int numSteps))) + TkMakeRawCurvePostscript, +}; + +/* + * Function forward-declarations. + */ + +static void SmoothMethodCleanupProc _ANSI_ARGS_(( + ClientData clientData, Tcl_Interp *interp)); +static SmoothAssocData *InitSmoothMethods _ANSI_ARGS_((Tcl_Interp *interp)); +static int DashConvert _ANSI_ARGS_((char *l, CONST char *p, + int n, double width)); +static void translateAndAppendCoords _ANSI_ARGS_(( + TkCanvas *canvPtr, double x, double y, + XPoint *outArr, int numOut)); + +#define ABS(a) ((a>=0)?(a):(-(a))) /* *---------------------------------------------------------------------- @@ -458,11 +497,6 @@ Tk_CanvasTagsPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) return Tcl_Merge(itemPtr->numTags, (CONST char **) itemPtr->tagPtr); } - -static int DashConvert _ANSI_ARGS_((char *l, CONST char *p, - int n, double width)); -#define ABS(a) ((a>=0)?(a):(-(a))) - /* *-------------------------------------------------------------- * @@ -557,6 +591,49 @@ TkCanvasDashPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) /* *-------------------------------------------------------------- * + * InitSmoothMethods -- + * + * This procedure is invoked to set up the initial state of the + * list of "-smooth" methods. It should only be called when the + * list installed in the interpreter is NULL. + * + * Results: + * Pointer to the start of the list of default smooth methods. + * + * Side effects: + * A linked list of smooth methods is created and attached to the + * interpreter's association key "smoothMethod" + * + *-------------------------------------------------------------- + */ + +static SmoothAssocData * +InitSmoothMethods(interp) + Tcl_Interp *interp; +{ + SmoothAssocData *methods, *ptr; + + methods = (SmoothAssocData *) ckalloc(sizeof(SmoothAssocData)); + methods->smooth.name = tkRawSmoothMethod.name; + methods->smooth.coordProc = tkRawSmoothMethod.coordProc; + methods->smooth.postscriptProc = tkRawSmoothMethod.postscriptProc; + + methods->nextPtr = (SmoothAssocData *) ckalloc(sizeof(SmoothAssocData)); + + ptr = methods->nextPtr; + ptr->smooth.name = tkBezierSmoothMethod.name; + ptr->smooth.coordProc = tkBezierSmoothMethod.coordProc; + ptr->smooth.postscriptProc = tkBezierSmoothMethod.postscriptProc; + ptr->nextPtr = NULL; + + Tcl_SetAssocData(interp, "smoothMethod", SmoothMethodCleanupProc, + (ClientData) methods); + return methods; +} + +/* + *-------------------------------------------------------------- + * * Tk_CreateSmoothMethod -- * * This procedure is invoked to add additional values @@ -572,23 +649,6 @@ TkCanvasDashPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) *-------------------------------------------------------------- */ -Tk_SmoothMethod tkBezierSmoothMethod = { - "bezier", - TkMakeBezierCurve, - (void (*) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas, - double *coordPtr, int numPoints, int numSteps))) - TkMakeBezierPostscript, -}; - -static void SmoothMethodCleanupProc _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp)); - -typedef struct SmoothAssocData { - struct SmoothAssocData *nextPtr; /* pointer to next SmoothAssocData */ - Tk_SmoothMethod smooth; /* name and functions associated with this - * option */ -} SmoothAssocData; - void Tk_CreateSmoothMethod(interp, smooth) Tcl_Interp *interp; @@ -599,6 +659,14 @@ Tk_CreateSmoothMethod(interp, smooth) (Tcl_InterpDeleteProc **) NULL); /* + * Initialize if we were not previously initialized. + */ + + if (methods == NULL) { + methods = InitSmoothMethods(interp); + } + + /* * If there's already a smooth method with the given name, remove it. */ @@ -680,7 +748,7 @@ TkSmoothParseProc(clientData, interp, tkwin, value, widgRec, offset) int offset; /* Offset into item. */ { register Tk_SmoothMethod **smoothPtr = - (Tk_SmoothMethod **) (widgRec + offset); + (Tk_SmoothMethod **) (widgRec + offset); Tk_SmoothMethod *smooth = NULL; int b; size_t length; @@ -693,10 +761,22 @@ TkSmoothParseProc(clientData, interp, tkwin, value, widgRec, offset) length = strlen(value); methods = (SmoothAssocData *) Tcl_GetAssocData(interp, "smoothMethod", (Tcl_InterpDeleteProc **) NULL); + /* + * Not initialized yet; fix that now. + */ + if (methods == NULL) { + methods = InitSmoothMethods(interp); + } + /* + * Backward compatability hack + */ + if (strncmp(value, "bezier", length) == 0) { + smooth = &tkBezierSmoothMethod; + } while (methods != (SmoothAssocData *) NULL) { if (strncmp(value, methods->smooth.name, length) == 0) { if (smooth != (Tk_SmoothMethod *) NULL) { - Tcl_AppendResult(interp, "ambigeous smooth method \"", value, + Tcl_AppendResult(interp, "ambiguous smooth method \"", value, "\"", (char *) NULL); return TCL_ERROR; } @@ -707,15 +787,8 @@ TkSmoothParseProc(clientData, interp, tkwin, value, widgRec, offset) if (smooth) { *smoothPtr = smooth; return TCL_OK; - } else if (strncmp(value, tkBezierSmoothMethod.name, length) == 0) { - /* - * We need to do handle the built-in bezier method. - */ - *smoothPtr = &tkBezierSmoothMethod; - return TCL_OK; } - if (Tcl_GetBoolean(interp, (char *) value, &b) != TCL_OK) { return TCL_ERROR; } diff --git a/generic/tkInt.decls b/generic/tkInt.decls index ebfae12..12a560d 100644 --- a/generic/tkInt.decls +++ b/generic/tkInt.decls @@ -9,7 +9,7 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # -# RCS: @(#) $Id: tkInt.decls,v 1.35 2004/03/17 18:15:43 das Exp $ +# RCS: @(#) $Id: tkInt.decls,v 1.36 2004/08/19 14:41:52 dkf Exp $ library tk @@ -630,7 +630,18 @@ declare 148 generic { declare 149 generic { CONST Tk_OptionSpec * TkGetOptionSpec (CONST char *name, - Tk_OptionTable optionTable) + Tk_OptionTable optionTable) +} + +# TIP#168 +declare 150 generic { + int TkMakeRawCurve (Tk_Canvas canvas, + double *pointPtr, int numPoints, int numSteps, + XPoint xPoints[], double dblPoints[]) +} +declare 151 generic { + void TkMakeRawCurvePostscript (Tcl_Interp *interp, + Tk_Canvas canvas, double *pointPtr, int numPoints) } ############################################################################## diff --git a/generic/tkTrig.c b/generic/tkTrig.c index b8a88e7..f3561b1 100644 --- a/generic/tkTrig.c +++ b/generic/tkTrig.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTrig.c,v 1.4 1999/12/14 06:52:33 hobbs Exp $ + * RCS: @(#) $Id: tkTrig.c,v 1.5 2004/08/19 14:41:52 dkf Exp $ */ #include @@ -918,7 +918,7 @@ TkIncludePoint(itemPtr, pointPtr) * TkBezierScreenPoints -- * * Given four control points, create a larger set of XPoints - * for a Bezier spline based on the points. + * for a Bezier curve based on the points. * * Results: * The array at *xPointPtr gets filled in with numSteps XPoints @@ -969,7 +969,7 @@ TkBezierScreenPoints(canvas, control, numSteps, xPointPtr) * TkBezierPoints -- * * Given four control points, create a larger set of points - * for a Bezier spline based on the points. + * for a Bezier curve based on the points. * * Results: * The array at *coordPtr gets filled in with 2*numSteps @@ -1019,10 +1019,12 @@ TkBezierPoints(control, numSteps, coordPtr) * parabolic splines to the line segments connecting the original * points. Produces output points in either of two forms. * - * Note: in spite of this procedure's name, it does *not* generate - * Bezier curves. Since only three control points are used for - * each curve segment, not four, the curves are actually just - * parabolic. + * Note: the name of this procedure should *not* be taken to + * mean that it interprets the input points as directly defining + * Bezier curves. Rather, it internally computes a Bezier curve + * representation of each parabolic spline segment. (These + * Bezier curves are then flattened to produce the points + * filled into the output arrays.) * * Results: * Either or both of the xPoints or dblPoints arrays are filled @@ -1196,6 +1198,185 @@ TkMakeBezierCurve(canvas, pointPtr, numPoints, numSteps, xPoints, dblPoints) /* *-------------------------------------------------------------- * + * TkMakeRawCurve -- + * + * Interpret the given set of points as the raw knots and + * control points defining a sequence of cubic Bezier curves. + * Create a new set of points that fit these Bezier curves. + * Output points are produced in either of two forms. + * + * Results: + * Either or both of the xPoints or dblPoints arrays are filled + * in. The return value is the number of points placed in the + * arrays. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +int +TkMakeRawCurve(canvas, pointPtr, numPoints, numSteps, xPoints, dblPoints) + Tk_Canvas canvas; /* Canvas in which curve is to be + * drawn. */ + double *pointPtr; /* Array of input coordinates: x0, + * y0, x1, y1, etc.. */ + int numPoints; /* Number of points at pointPtr. */ + int numSteps; /* Number of steps to use for each + * curve segment (determines + * smoothness of curve). */ + XPoint xPoints[]; /* Array of XPoints to fill in (e.g. + * for display. NULL means don't + * fill in any XPoints. */ + double dblPoints[]; /* Array of points to fill in as + * doubles, in the form x0, y0, + * x1, y1, .... NULL means don't + * fill in anything in this form. + * Caller must make sure that this + * array has enough space. */ +{ + int outputPoints, i; + int numSegments = (numPoints+1)/3; + double *segPtr; + + /* + * The input describes a curve with s Bezier curve segments if + * there are 3s+1, 3s, or 3s-1 input points. In the last two + * cases, 1 or 2 initial points from the first curve segment + * are reused as defining points also for the last curve segment. + * In the case of 3s input points, this will automatically close + * the curve. + */ + + if (!pointPtr) { + /* + * If pointPtr == NULL, this function returns an upper limit. + * of the array size to store the coordinates. This can be + * used to allocate storage, before the actual coordinates + * are calculated. + */ + return 1 + numSegments * numSteps; + } + + outputPoints = 0; + if (xPoints != NULL) { + Tk_CanvasDrawableCoords(canvas, pointPtr[0], pointPtr[1], + &xPoints->x, &xPoints->y); + xPoints += 1; + } + if (dblPoints != NULL) { + dblPoints[0] = pointPtr[0]; + dblPoints[1] = pointPtr[1]; + dblPoints += 2; + } + outputPoints += 1; + + /* + * The next loop handles all curve segments except one that + * overlaps the end of the list of coordinates. + */ + + for (i=numPoints,segPtr=pointPtr ; i>=4 ; i-=3,segPtr+=6) { + if (segPtr[0]==segPtr[2] && segPtr[1]==segPtr[3] && + segPtr[4]==segPtr[6] && segPtr[5]==segPtr[7]) { + /* + * The control points on this segment are equal to + * their neighbouring knots, so this segment is just + * a straight line. A single point is sufficient. + */ + if (xPoints != NULL) { + Tk_CanvasDrawableCoords(canvas, segPtr[6], segPtr[7], + &xPoints->x, &xPoints->y); + xPoints += 1; + } + if (dblPoints != NULL) { + dblPoints[0] = segPtr[6]; + dblPoints[1] = segPtr[7]; + dblPoints += 2; + } + outputPoints += 1; + } else { + /* + * This is a generic Bezier curve segment. + */ + if (xPoints != NULL) { + TkBezierScreenPoints(canvas, segPtr, numSteps, xPoints); + xPoints += numSteps; + } + if (dblPoints != NULL) { + TkBezierPoints(segPtr, numSteps, dblPoints); + dblPoints += 2*numSteps; + } + outputPoints += numSteps; + } + } + + /* + * If at this point i>1, then there is some point which has not + * yet been used. Make another curve segment. + */ + + if (i>1) { + int j; + double control[8]; + + /* + * Copy the relevant coordinates to control[], so that + * it can be passed as a unit to e.g. TkBezierPoints. + */ + + for (j=0; j<2*i; j++) { + control[j] = segPtr[j]; + } + for (; j<8; j++) { + control[j] = pointPtr[j-2*i]; + } + + /* + * Then we just do the same things as above. + */ + + if (control[0]==control[2] && control[1]==control[3] && + control[4]==control[6] && control[5]==control[7]) { + /* + * The control points on this segment are equal to + * their neighbouring knots, so this segment is just + * a straight line. A single point is sufficient. + */ + if (xPoints != NULL) { + Tk_CanvasDrawableCoords(canvas, control[6], control[7], + &xPoints->x, &xPoints->y); + xPoints += 1; + } + if (dblPoints != NULL) { + dblPoints[0] = control[6]; + dblPoints[1] = control[7]; + dblPoints += 2; + } + outputPoints += 1; + } else { + /* + * This is a generic Bezier curve segment. + */ + if (xPoints != NULL) { + TkBezierScreenPoints(canvas, control, numSteps, xPoints); + xPoints += numSteps; + } + if (dblPoints != NULL) { + TkBezierPoints(control, numSteps, dblPoints); + dblPoints += 2*numSteps; + } + outputPoints += numSteps; + } + } + + return outputPoints; +} + +/* + *-------------------------------------------------------------- + * * TkMakeBezierPostscript -- * * This procedure generates Postscript commands that create @@ -1293,6 +1474,108 @@ TkMakeBezierPostscript(interp, canvas, pointPtr, numPoints) /* *-------------------------------------------------------------- * + * TkMakeRawCurvePostscript -- + * + * This procedure interprets the input points as the raw knot + * and control points for a curve composed of Bezier curve + * segments, just like TkMakeRawCurve. It generates Postscript + * commands that create a path corresponding to this given curve. + * + * Results: + * None. Postscript commands to generate the path are appended + * to the interp's result. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +void +TkMakeRawCurvePostscript(interp, canvas, pointPtr, numPoints) + Tcl_Interp *interp; /* Interpreter in whose result the + * Postscript is to be stored. */ + Tk_Canvas canvas; /* Canvas widget for which the + * Postscript is being generated. */ + double *pointPtr; /* Array of input coordinates: x0, + * y0, x1, y1, etc.. */ + int numPoints; /* Number of points at pointPtr. */ +{ + int i; + double *segPtr; + char buffer[200]; + + /* + * Put the first point into the path. + */ + + sprintf(buffer, "%.15g %.15g moveto\n", + pointPtr[0], Tk_CanvasPsY(canvas, pointPtr[1])); + Tcl_AppendResult(interp, buffer, (char *) NULL); + + /* + * Loop through all the remaining points in the curve, generating + * a straight line or curve section for every three of them. + */ + + for (i=numPoints-1,segPtr=pointPtr ; i>=3 ; i-=3,segPtr+=6) { + if (segPtr[0]==segPtr[2] && segPtr[1]==segPtr[3] && + segPtr[4]==segPtr[6] && segPtr[5]==segPtr[7]) { + /* + * The control points on this segment are equal to + * their neighbouring knots, so this segment is just + * a straight line. + */ + sprintf(buffer, "%.15g %.15g lineto\n", + segPtr[6], Tk_CanvasPsY(canvas, segPtr[7])); + } else { + /* + * This is a generic Bezier curve segment. + */ + sprintf(buffer, "%.15g %.15g %.15g %.15g %.15g %.15g curveto\n", + segPtr[2], Tk_CanvasPsY(canvas, segPtr[3]), + segPtr[4], Tk_CanvasPsY(canvas, segPtr[5]), + segPtr[6], Tk_CanvasPsY(canvas, segPtr[7])); + } + Tcl_AppendResult(interp, buffer, (char *) NULL); + } + + /* + * If there are any points left that haven't been used, + * then build the last segment and generate Postscript in + * the same way for that. + */ + + if (i>0) { + int j; + double control[8]; + + for (j=0; j<2*i+2; j++) { + control[j] = segPtr[j]; + } + for (; j<8; j++) { + control[j] = pointPtr[j-2*i-2]; + } + + if (control[0]==control[2] && control[1]==control[3] && + control[4]==control[6] && control[5]==control[7]) { + /* Straight line */ + sprintf(buffer, "%.15g %.15g lineto\n", + control[6], Tk_CanvasPsY(canvas, control[7])); + } else { + /* Bezier curve segment */ + sprintf(buffer, "%.15g %.15g %.15g %.15g %.15g %.15g curveto\n", + control[2], Tk_CanvasPsY(canvas, control[3]), + control[4], Tk_CanvasPsY(canvas, control[5]), + control[6], Tk_CanvasPsY(canvas, control[7])); + } + Tcl_AppendResult(interp, buffer, (char *) NULL); + } +} + +/* + *-------------------------------------------------------------- + * * TkGetMiterPoints -- * * Given three points forming an angle, compute the diff --git a/tests/canvas.test b/tests/canvas.test index efa6b16..84f18b3 100644 --- a/tests/canvas.test +++ b/tests/canvas.test @@ -6,7 +6,7 @@ # Copyright (c) 1998-2000 Ajuba Solutions. # All rights reserved. # -# RCS: @(#) $Id: canvas.test,v 1.19 2004/06/15 21:06:40 dkf Exp $ +# RCS: @(#) $Id: canvas.test,v 1.20 2004/08/19 14:41:52 dkf Exp $ package require tcltest 2.1 eval tcltest::configure $argv @@ -476,6 +476,16 @@ test canvas-16.1 {arc coords check} { .c itemcget $id -start } {33.0} +test canvas-17.1 {default smooth method handling} { + destroy .c; canvas .c + set id [.c create line {0 0 1 1 2 2 3 3 4 4 5 5 6 6}] + set result [.c itemcget $id -smooth] + foreach smoother {yes 1 bezier raw r b} { + .c itemconfigure $id -smooth $smoother + lappend result [.c itemcget $id -smooth] + } +} {0 true true true raw raw true} + destroy .c # cleanup -- cgit v0.12