A previous version of this patch was published for tk3.2. This version
is for tk3.3b1.
To install, run ``patch tkCanvLine.c <seg.patch''.
Edit tkAppInit.c and add a call to InitCanvSegType() to
the body of Tcl_AppInit(). Edit the makefile to add tkCanvSeg.c to
the list of canvas objects. Type make.
To test, feed wish the input
canvas .c
pack append . .c top
.c create segments 0 0 100 100 50 0 100 100 -width 5 -fill blue
Known bugs: I left out arrowheads.
*** tkCanvLine.c Sat Jun 26 19:47:02 1993
--- tkCanvSeg.c Tue Jul 13 15:50:36 1993
***************
*** 1,7 ****
/*
! * tkCanvLine.c --
*
! * This file implements line items for canvas widgets.
*
* Copyright (c) 1991-1993 The Regents of the University of California.
* All rights reserved.
--- 1,10 ----
/*
! * tkCanvSeg.c --
*
! * This file implements segment items for canvas widgets.
! *
! * This file is derived from code by John Ousterhout,
! * with changes by Scott Schwartz.
*
* Copyright (c) 1991-1993 The Regents of the University of California.
* All rights reserved.
***************
*** 167,174 ****
* of procedures that can be invoked by generic item code.
*/
! Tk_ItemType TkLineType = {
! "line", /* name */
sizeof(LineItem), /* itemSize */
CreateLine, /* createProc */
configSpecs, /* configSpecs */
--- 170,177 ----
* of procedures that can be invoked by generic item code.
*/
! Tk_ItemType TkSegType = {
! "segments", /* name */
sizeof(LineItem), /* itemSize */
CreateLine, /* createProc */
configSpecs, /* configSpecs */
***************
*** 242,248 ****
if (argc < 4) {
Tcl_AppendResult(canvasPtr->interp, "wrong # args: should be \"",
Tk_PathName(canvasPtr->tkwin),
! "\" create x1 y1 x2 y2 ?x3 y3 ...? ?options?",
(char *) NULL);
return TCL_ERROR;
}
--- 245,252 ----
if (argc < 4) {
Tcl_AppendResult(canvasPtr->interp, "wrong # args: should be \"",
Tk_PathName(canvasPtr->tkwin),
! "\" create ", itemPtr->typePtr->name,
! " x1 y1 x2 y2 ?x3 y3 x4 y4 ...? ?options?",
(char *) NULL);
return TCL_ERROR;
}
***************
*** 358,366 ****
"too few coordinates for line: must have at least 4",
(char *) NULL);
return TCL_ERROR;
! } else if (argc & 1) {
Tcl_AppendResult(canvasPtr->interp,
! "odd number of coordinates specified for line",
(char *) NULL);
return TCL_ERROR;
} else {
--- 362,370 ----
"too few coordinates for line: must have at least 4",
(char *) NULL);
return TCL_ERROR;
! } else if (argc & 3) {
Tcl_AppendResult(canvasPtr->interp,
! "number of coordinates not a multiple of 4",
(char *) NULL);
return TCL_ERROR;
} else {
***************
*** 694,704 ****
* item. */
{
register LineItem *linePtr = (LineItem *) itemPtr;
! XPoint staticPoints[MAX_STATIC_POINTS];
! XPoint *pointPtr;
! register XPoint *pPtr;
register double *coordPtr;
! int i, numPoints;
if (linePtr->gc == None) {
return;
--- 698,708 ----
* item. */
{
register LineItem *linePtr = (LineItem *) itemPtr;
! XSegment staticSegments[MAX_STATIC_POINTS];
! XSegment *segmentPtr;
! register XSegment *sPtr;
register double *coordPtr;
! int i, numSegments;
if (linePtr->gc == None) {
return;
***************
*** 707,738 ****
/*
* Build up an array of points in screen coordinates. Use a
* static array unless the line has an enormous number of points;
! * in this case, dynamically allocate an array. For smoothed lines,
! * generate the curve points on each redisplay.
*/
! if ((linePtr->smooth) && (linePtr->numPoints > 2)) {
! numPoints = 1 + linePtr->numPoints*linePtr->splineSteps;
! } else {
! numPoints = linePtr->numPoints;
! }
! if (numPoints <= MAX_STATIC_POINTS) {
! pointPtr = staticPoints;
} else {
! pointPtr = (XPoint *) ckalloc((unsigned) (numPoints * sizeof(XPoint)));
}
! if (linePtr->smooth) {
! numPoints = TkMakeBezierCurve(canvasPtr, linePtr->coordPtr,
! linePtr->numPoints, linePtr->splineSteps, pointPtr,
! (double *) NULL);
! } else {
! for (i = 0, coordPtr = linePtr->coordPtr, pPtr = pointPtr;
! i < linePtr->numPoints; i += 1, coordPtr += 2, pPtr++) {
! pPtr->x = SCREEN_X(canvasPtr, *coordPtr);
! pPtr->y = SCREEN_Y(canvasPtr, coordPtr[1]);
! }
}
/*
--- 711,735 ----
/*
* Build up an array of points in screen coordinates. Use a
* static array unless the line has an enormous number of points;
! * in this case, dynamically allocate an array.
*/
! numSegments = linePtr->numPoints/2;
! if (numSegments <= MAX_STATIC_POINTS/2) {
! segmentPtr = staticSegments;
} else {
! segmentPtr = (XSegment *)
! ckalloc((unsigned) (numSegments * sizeof(XSegment)));
}
! for (i = 0, coordPtr = linePtr->coordPtr, sPtr = segmentPtr;
! i < numSegments;
! i += 1, coordPtr += 4, sPtr++) {
! sPtr->x1 = SCREEN_X(canvasPtr, coordPtr[0]);
! sPtr->y1 = SCREEN_Y(canvasPtr, coordPtr[1]);
! sPtr->x2 = SCREEN_X(canvasPtr, coordPtr[2]);
! sPtr->y2 = SCREEN_Y(canvasPtr, coordPtr[3]);
}
/*
***************
*** 746,757 ****
XSetTSOrigin(Tk_Display(canvasPtr->tkwin), linePtr->gc,
-canvasPtr->drawableXOrigin, -canvasPtr->drawableYOrigin);
}
! XDrawLines(Tk_Display(canvasPtr->tkwin), drawable, linePtr->gc,
! pointPtr, numPoints, CoordModeOrigin);
! if (pointPtr != staticPoints) {
! ckfree((char *) pointPtr);
}
/*
* Display arrowheads, if they are wanted.
*/
--- 743,755 ----
XSetTSOrigin(Tk_Display(canvasPtr->tkwin), linePtr->gc,
-canvasPtr->drawableXOrigin, -canvasPtr->drawableYOrigin);
}
! XDrawSegments(Tk_Display(canvasPtr->tkwin), drawable, linePtr->gc,
! segmentPtr, numSegments);
! if (segmentPtr != staticSegments) {
! ckfree((char *) segmentPtr);
}
+ #if 0
/*
* Display arrowheads, if they are wanted.
*/
***************
*** 766,771 ****
--- 764,771 ----
drawable, linePtr->gc);
}
}
+ #endif
+
if (linePtr->fillStipple != None) {
XSetTSOrigin(Tk_Display(canvasPtr->tkwin), linePtr->gc, 0, 0);
}
***************
*** 1689,1692 ****
--- 1689,1699 ----
Tcl_AppendResult(canvasPtr->interp, "fill\n", (char *) NULL);
}
return TCL_OK;
+ }
+
+ /* Install the new canvas item. */
+
+ int InitCanvSegType()
+ {
+ Tk_CreateItemType((Tk_ItemType*)&TkSegType);
}