summaryrefslogtreecommitdiffstats
path: root/generic/tkCanvLine.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkCanvLine.c')
-rw-r--r--generic/tkCanvLine.c1207
1 files changed, 1023 insertions, 184 deletions
diff --git a/generic/tkCanvLine.c b/generic/tkCanvLine.c
index 131b73d..328d184 100644
--- a/generic/tkCanvLine.c
+++ b/generic/tkCanvLine.c
@@ -10,23 +10,29 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkCanvLine.c,v 1.4 1999/04/16 01:51:11 stanton Exp $
+ * RCS: @(#) $Id: tkCanvLine.c,v 1.5 1999/12/14 06:52:26 hobbs Exp $
*/
#include <stdio.h>
#include "tkInt.h"
#include "tkPort.h"
+#include "tkCanvas.h"
/*
* The structure below defines the record for each line item.
*/
+typedef enum {
+ ARROWS_NONE, ARROWS_FIRST, ARROWS_LAST, ARROWS_BOTH
+} Arrows;
+
typedef struct LineItem {
Tk_Item header; /* Generic stuff that's the same for all
* types. MUST BE FIRST IN STRUCTURE. */
+ Tk_Outline outline; /* Outline structure */
Tk_Canvas canvas; /* Canvas containing item. Needed for
* parsing arrow shapes. */
- int numPoints; /* Number of points in line (always >= 2). */
+ int numPoints; /* Number of points in line (always >= 0). */
double *coordPtr; /* Pointer to malloc-ed array containing
* x- and y-coords of all points in line.
* X-coords are even-valued indices, y-coords
@@ -37,14 +43,10 @@ typedef struct LineItem {
* their tips. The actual endpoints are
* stored in the *firstArrowPtr and
* *lastArrowPtr, if they exist. */
- int width; /* Width of line. */
- XColor *fg; /* Foreground color for line. */
- Pixmap fillStipple; /* Stipple bitmap for filling line. */
int capStyle; /* Cap style for line. */
int joinStyle; /* Join style for line. */
- GC gc; /* Graphics context for filling line. */
GC arrowGC; /* Graphics context for drawing arrowheads. */
- Tk_Uid arrow; /* Indicates whether or not to draw arrowheads:
+ Arrows arrow; /* Indicates whether or not to draw arrowheads:
* "none", "first", "last", or "both". */
float arrowShapeA; /* Distance from tip of arrowhead to center. */
float arrowShapeB; /* Distance from tip of arrowhead to trailing
@@ -60,7 +62,7 @@ typedef struct LineItem {
* point in line (PTS_IN_ARROW points, first
* of which is tip). Malloc'ed. NULL means
* no arrowhead at last point. */
- int smooth; /* Non-zero means draw line smoothed (i.e.
+ Tk_SmoothMethod *smooth; /* Non-zero means draw line smoothed (i.e.
* with Bezier splines). */
int splineSteps; /* Number of steps in each spline segment. */
} LineItem;
@@ -82,29 +84,42 @@ static void ComputeLineBbox _ANSI_ARGS_((Tk_Canvas canvas,
LineItem *linePtr));
static int ConfigureLine _ANSI_ARGS_((Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
- char **argv, int flags));
+ Tcl_Obj *CONST argv[], int flags));
static int ConfigureArrows _ANSI_ARGS_((Tk_Canvas canvas,
LineItem *linePtr));
static int CreateLine _ANSI_ARGS_((Tcl_Interp *interp,
Tk_Canvas canvas, struct Tk_Item *itemPtr,
- int argc, char **argv));
+ int argc, Tcl_Obj *CONST argv[]));
static void DeleteLine _ANSI_ARGS_((Tk_Canvas canvas,
Tk_Item *itemPtr, Display *display));
static void DisplayLine _ANSI_ARGS_((Tk_Canvas canvas,
Tk_Item *itemPtr, Display *display, Drawable dst,
int x, int y, int width, int height));
+static int GetLineIndex _ANSI_ARGS_((Tcl_Interp *interp,
+ Tk_Canvas canvas, Tk_Item *itemPtr,
+ Tcl_Obj *obj, int *indexPtr));
static int LineCoords _ANSI_ARGS_((Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr,
- int argc, char **argv));
+ int argc, Tcl_Obj *CONST argv[]));
+static void LineDeleteCoords _ANSI_ARGS_((Tk_Canvas canvas,
+ Tk_Item *itemPtr, int first, int last));
+static void LineInsert _ANSI_ARGS_((Tk_Canvas canvas,
+ Tk_Item *itemPtr, int beforeThis, Tcl_Obj *obj));
static int LineToArea _ANSI_ARGS_((Tk_Canvas canvas,
Tk_Item *itemPtr, double *rectPtr));
static double LineToPoint _ANSI_ARGS_((Tk_Canvas canvas,
Tk_Item *itemPtr, double *coordPtr));
static int LineToPostscript _ANSI_ARGS_((Tcl_Interp *interp,
Tk_Canvas canvas, Tk_Item *itemPtr, int prepass));
+static int ArrowParseProc _ANSI_ARGS_((ClientData clientData,
+ Tcl_Interp *interp, Tk_Window tkwin,
+ CONST char *value, char *recordPtr, int offset));
+static char * ArrowPrintProc _ANSI_ARGS_((ClientData clientData,
+ Tk_Window tkwin, char *recordPtr, int offset,
+ Tcl_FreeProc **freeProcPtr));
static int ParseArrowShape _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, Tk_Window tkwin, char *value,
- char *recordPtr, int offset));
+ Tcl_Interp *interp, Tk_Window tkwin,
+ CONST char *value, char *recordPtr, int offset));
static char * PrintArrowShape _ANSI_ARGS_((ClientData clientData,
Tk_Window tkwin, char *recordPtr, int offset,
Tcl_FreeProc **freeProcPtr));
@@ -120,34 +135,101 @@ static void TranslateLine _ANSI_ARGS_((Tk_Canvas canvas,
* values in CreateLine.
*/
-static Tk_CustomOption arrowShapeOption = {ParseArrowShape,
- PrintArrowShape, (ClientData) NULL};
-static Tk_CustomOption tagsOption = {Tk_CanvasTagsParseProc,
+static Tk_CustomOption arrowShapeOption = {
+ (Tk_OptionParseProc *) ParseArrowShape,
+ PrintArrowShape, (ClientData) NULL
+};
+static Tk_CustomOption arrowOption = {
+ (Tk_OptionParseProc *) ArrowParseProc,
+ ArrowPrintProc, (ClientData) NULL
+};
+static Tk_CustomOption smoothOption = {
+ (Tk_OptionParseProc *) TkSmoothParseProc,
+ TkSmoothPrintProc, (ClientData) NULL
+};
+static Tk_CustomOption stateOption = {
+ (Tk_OptionParseProc *) TkStateParseProc,
+ TkStatePrintProc, (ClientData) 2
+};
+static Tk_CustomOption tagsOption = {
+ (Tk_OptionParseProc *) Tk_CanvasTagsParseProc,
Tk_CanvasTagsPrintProc, (ClientData) NULL
};
+static Tk_CustomOption dashOption = {
+ (Tk_OptionParseProc *) TkCanvasDashParseProc,
+ TkCanvasDashPrintProc, (ClientData) NULL
+};
+static Tk_CustomOption offsetOption = {
+ (Tk_OptionParseProc *) TkOffsetParseProc,
+ TkOffsetPrintProc,
+ (ClientData) (TK_OFFSET_RELATIVE|TK_OFFSET_INDEX)
+};
+static Tk_CustomOption pixelOption = {
+ (Tk_OptionParseProc *) TkPixelParseProc,
+ TkPixelPrintProc, (ClientData) NULL
+};
static Tk_ConfigSpec configSpecs[] = {
- {TK_CONFIG_UID, "-arrow", (char *) NULL, (char *) NULL,
- "none", Tk_Offset(LineItem, arrow), TK_CONFIG_DONT_SET_DEFAULT},
+ {TK_CONFIG_CUSTOM, "-activedash", (char *) NULL, (char *) NULL,
+ (char *) NULL, Tk_Offset(LineItem, outline.activeDash),
+ TK_CONFIG_NULL_OK, &dashOption},
+ {TK_CONFIG_COLOR, "-activefill", (char *) NULL, (char *) NULL,
+ (char *) NULL, Tk_Offset(LineItem, outline.activeColor),
+ TK_CONFIG_NULL_OK},
+ {TK_CONFIG_BITMAP, "-activestipple", (char *) NULL, (char *) NULL,
+ (char *) NULL, Tk_Offset(LineItem, outline.activeStipple),
+ TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-activewidth", (char *) NULL, (char *) NULL,
+ "0.0", Tk_Offset(LineItem, outline.activeWidth),
+ TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
+ {TK_CONFIG_CUSTOM, "-arrow", (char *) NULL, (char *) NULL,
+ "none", Tk_Offset(LineItem, arrow), TK_CONFIG_DONT_SET_DEFAULT, &arrowOption},
{TK_CONFIG_CUSTOM, "-arrowshape", (char *) NULL, (char *) NULL,
"8 10 3", Tk_Offset(LineItem, arrowShapeA),
TK_CONFIG_DONT_SET_DEFAULT, &arrowShapeOption},
{TK_CONFIG_CAP_STYLE, "-capstyle", (char *) NULL, (char *) NULL,
"butt", Tk_Offset(LineItem, capStyle), TK_CONFIG_DONT_SET_DEFAULT},
{TK_CONFIG_COLOR, "-fill", (char *) NULL, (char *) NULL,
- "black", Tk_Offset(LineItem, fg), TK_CONFIG_NULL_OK},
+ "black", Tk_Offset(LineItem, outline.color), TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-dash", (char *) NULL, (char *) NULL,
+ (char *) NULL, Tk_Offset(LineItem, outline.dash),
+ TK_CONFIG_NULL_OK, &dashOption},
+ {TK_CONFIG_PIXELS, "-dashoffset", (char *) NULL, (char *) NULL,
+ "0", Tk_Offset(LineItem, outline.offset),
+ TK_CONFIG_DONT_SET_DEFAULT},
+ {TK_CONFIG_CUSTOM, "-disableddash", (char *) NULL, (char *) NULL,
+ (char *) NULL, Tk_Offset(LineItem, outline.disabledDash),
+ TK_CONFIG_NULL_OK, &dashOption},
+ {TK_CONFIG_COLOR, "-disabledfill", (char *) NULL, (char *) NULL,
+ (char *) NULL, Tk_Offset(LineItem, outline.disabledColor),
+ TK_CONFIG_NULL_OK},
+ {TK_CONFIG_BITMAP, "-disabledstipple", (char *) NULL, (char *) NULL,
+ (char *) NULL, Tk_Offset(LineItem, outline.disabledStipple),
+ TK_CONFIG_NULL_OK},
+ {TK_CONFIG_CUSTOM, "-disabledwidth", (char *) NULL, (char *) NULL,
+ "0.0", Tk_Offset(LineItem, outline.disabledWidth),
+ TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
{TK_CONFIG_JOIN_STYLE, "-joinstyle", (char *) NULL, (char *) NULL,
"round", Tk_Offset(LineItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT},
- {TK_CONFIG_BOOLEAN, "-smooth", (char *) NULL, (char *) NULL,
- "0", Tk_Offset(LineItem, smooth), TK_CONFIG_DONT_SET_DEFAULT},
+ {TK_CONFIG_CUSTOM, "-offset", (char *) NULL, (char *) NULL,
+ "0,0", Tk_Offset(LineItem, outline.tsoffset),
+ TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
+ {TK_CONFIG_CUSTOM, "-smooth", (char *) NULL, (char *) NULL,
+ "0", Tk_Offset(LineItem, smooth),
+ TK_CONFIG_DONT_SET_DEFAULT, &smoothOption},
{TK_CONFIG_INT, "-splinesteps", (char *) NULL, (char *) NULL,
"12", Tk_Offset(LineItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT},
+ {TK_CONFIG_CUSTOM, "-state", (char *) NULL, (char *) NULL,
+ (char *) NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK,
+ &stateOption},
{TK_CONFIG_BITMAP, "-stipple", (char *) NULL, (char *) NULL,
- (char *) NULL, Tk_Offset(LineItem, fillStipple), TK_CONFIG_NULL_OK},
+ (char *) NULL, Tk_Offset(LineItem, outline.stipple),
+ TK_CONFIG_NULL_OK},
{TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
(char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
- {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL,
- "1", Tk_Offset(LineItem, width), TK_CONFIG_DONT_SET_DEFAULT},
+ {TK_CONFIG_CUSTOM, "-width", (char *) NULL, (char *) NULL,
+ "1.0", Tk_Offset(LineItem, outline.width),
+ TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
(char *) NULL, 0, 0}
};
@@ -166,18 +248,18 @@ Tk_ItemType tkLineType = {
LineCoords, /* coordProc */
DeleteLine, /* deleteProc */
DisplayLine, /* displayProc */
- 0, /* alwaysRedraw */
+ TK_CONFIG_OBJS, /* flags */
LineToPoint, /* pointProc */
LineToArea, /* areaProc */
LineToPostscript, /* postscriptProc */
ScaleLine, /* scaleProc */
TranslateLine, /* translateProc */
- (Tk_ItemIndexProc *) NULL, /* indexProc */
+ (Tk_ItemIndexProc *) GetLineIndex, /* indexProc */
(Tk_ItemCursorProc *) NULL, /* icursorProc */
(Tk_ItemSelectionProc *) NULL, /* selectionProc */
- (Tk_ItemInsertProc *) NULL, /* insertProc */
- (Tk_ItemDCharsProc *) NULL, /* dTextProc */
- (Tk_ItemType *) NULL /* nextPtr */
+ (Tk_ItemInsertProc *) LineInsert, /* insertProc */
+ LineDeleteCoords, /* dTextProc */
+ (Tk_ItemType *) NULL, /* nextPtr */
};
/*
@@ -215,42 +297,31 @@ CreateLine(interp, canvas, itemPtr, argc, argv)
Tk_Item *itemPtr; /* Record to hold new item; header
* has been initialized by caller. */
int argc; /* Number of arguments in argv. */
- char **argv; /* Arguments describing line. */
+ Tcl_Obj *CONST argv[]; /* Arguments describing line. */
{
LineItem *linePtr = (LineItem *) itemPtr;
int i;
- if (argc < 4) {
- Tcl_AppendResult(interp, "wrong # args: should be \"",
- Tk_PathName(Tk_CanvasTkwin(canvas)), " create ",
- itemPtr->typePtr->name, " x1 y1 x2 y2 ?x3 y3 ...? ?options?\"",
- (char *) NULL);
- return TCL_ERROR;
- }
-
/*
* Carry out initialization that is needed to set defaults and to
* allow proper cleanup after errors during the the remainder of
* this procedure.
*/
+ Tk_CreateOutline(&(linePtr->outline));
linePtr->canvas = canvas;
linePtr->numPoints = 0;
linePtr->coordPtr = NULL;
- linePtr->width = 1;
- linePtr->fg = None;
- linePtr->fillStipple = None;
linePtr->capStyle = CapButt;
linePtr->joinStyle = JoinRound;
- linePtr->gc = None;
linePtr->arrowGC = None;
- linePtr->arrow = Tk_GetUid("none");
+ linePtr->arrow = ARROWS_NONE;
linePtr->arrowShapeA = (float)8.0;
linePtr->arrowShapeB = (float)10.0;
linePtr->arrowShapeC = (float)3.0;
linePtr->firstArrowPtr = NULL;
linePtr->lastArrowPtr = NULL;
- linePtr->smooth = 0;
+ linePtr->smooth = (Tk_SmoothMethod *) NULL;
linePtr->splineSteps = 12;
/*
@@ -259,14 +330,14 @@ CreateLine(interp, canvas, itemPtr, argc, argv)
* start with a digit or a minus sign followed by a digit.
*/
- for (i = 4; i < (argc-1); i+=2) {
- if ((!isdigit(UCHAR(argv[i][0]))) &&
- ((argv[i][0] != '-')
- || ((argv[i][1] != '.') && !isdigit(UCHAR(argv[i][1]))))) {
+ for (i = 0; i < argc; i++) {
+ char *arg = Tcl_GetStringFromObj(argv[i], NULL);
+ if ((arg[0] == '-') && (arg[1] >= 'a')
+ && (arg[1] <= 'z')) {
break;
}
}
- if (LineCoords(interp, canvas, itemPtr, i, argv) != TCL_OK) {
+ if (i && (LineCoords(interp, canvas, itemPtr, i, argv) != TCL_OK)) {
goto error;
}
if (ConfigureLine(interp, canvas, itemPtr, argc-i, argv+i, 0) == TCL_OK) {
@@ -304,16 +375,16 @@ LineCoords(interp, canvas, itemPtr, argc, argv)
* read or modified. */
int argc; /* Number of coordinates supplied in
* argv. */
- char **argv; /* Array of coordinates: x1, y1,
+ Tcl_Obj *CONST argv[]; /* Array of coordinates: x1, y1,
* x2, y2, ... */
{
LineItem *linePtr = (LineItem *) itemPtr;
- char buffer[TCL_DOUBLE_SPACE];
int i, numPoints;
+ double *coordPtr;
if (argc == 0) {
- double *coordPtr;
int numCoords;
+ Tcl_Obj *subobj, *obj = Tcl_NewObj();
numCoords = 2*linePtr->numPoints;
if (linePtr->firstArrowPtr != NULL) {
@@ -328,15 +399,19 @@ LineCoords(interp, canvas, itemPtr, argc, argv)
if ((linePtr->lastArrowPtr != NULL) && (i == (numCoords-2))) {
coordPtr = linePtr->lastArrowPtr;
}
- Tcl_PrintDouble(interp, *coordPtr, buffer);
- Tcl_AppendElement(interp, buffer);
+ subobj = Tcl_NewDoubleObj(*coordPtr);
+ Tcl_ListObjAppendElement(interp, obj, subobj);
}
- } else if (argc < 4) {
- Tcl_AppendResult(interp,
- "too few coordinates for line: must have at least 4",
- (char *) NULL);
- return TCL_ERROR;
- } else if (argc & 1) {
+ Tcl_SetObjResult(interp, obj);
+ return TCL_OK;
+ }
+ if (argc == 1) {
+ if (Tcl_ListObjGetElements(interp, argv[0], &argc,
+ (Tcl_Obj ***) &argv) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ }
+ if (argc & 1) {
Tcl_AppendResult(interp,
"odd number of coordinates specified for line",
(char *) NULL);
@@ -344,19 +419,21 @@ LineCoords(interp, canvas, itemPtr, argc, argv)
} else {
numPoints = argc/2;
if (linePtr->numPoints != numPoints) {
+ coordPtr = (double *) ckalloc((unsigned)
+ (sizeof(double) * argc));
if (linePtr->coordPtr != NULL) {
ckfree((char *) linePtr->coordPtr);
}
- linePtr->coordPtr = (double *) ckalloc((unsigned)
- (sizeof(double) * argc));
+ linePtr->coordPtr = coordPtr;
linePtr->numPoints = numPoints;
}
- for (i = argc-1; i >= 0; i--) {
- if (Tk_CanvasGetCoord(interp, canvas, argv[i],
- &linePtr->coordPtr[i]) != TCL_OK) {
- return TCL_ERROR;
- }
- }
+ coordPtr = linePtr->coordPtr;
+ for (i = 0; i <argc; i++) {
+ if (Tk_CanvasGetCoordFromObj(interp, canvas, argv[i],
+ coordPtr++) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ }
/*
* Update arrowheads by throwing away any existing arrow-head
@@ -371,7 +448,7 @@ LineCoords(interp, canvas, itemPtr, argc, argv)
ckfree((char *) linePtr->lastArrowPtr);
linePtr->lastArrowPtr = NULL;
}
- if (linePtr->arrow != Tk_GetUid("none")) {
+ if (linePtr->arrow != ARROWS_NONE) {
ConfigureArrows(canvas, linePtr);
}
ComputeLineBbox(canvas, linePtr);
@@ -404,7 +481,7 @@ ConfigureLine(interp, canvas, itemPtr, argc, argv, flags)
Tk_Canvas canvas; /* Canvas containing itemPtr. */
Tk_Item *itemPtr; /* Line item to reconfigure. */
int argc; /* Number of elements in argv. */
- char **argv; /* Arguments describing things to configure. */
+ Tcl_Obj *CONST argv[]; /* Arguments describing things to configure. */
int flags; /* Flags to pass to Tk_ConfigureWidget. */
{
LineItem *linePtr = (LineItem *) itemPtr;
@@ -412,14 +489,11 @@ ConfigureLine(interp, canvas, itemPtr, argc, argv, flags)
GC newGC, arrowGC;
unsigned long mask;
Tk_Window tkwin;
- Tk_Uid noneUid = Tk_GetUid("none");
- Tk_Uid bothUid = Tk_GetUid("both");
- Tk_Uid firstUid = Tk_GetUid("first");
- Tk_Uid lastUid = Tk_GetUid("last");
+ Tk_State state;
tkwin = Tk_CanvasTkwin(canvas);
- if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, argv,
- (char *) linePtr, flags) != TCL_OK) {
+ if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, (char **) argv,
+ (char *) linePtr, flags|TK_CONFIG_OBJS) != TCL_OK) {
return TCL_ERROR;
}
@@ -428,36 +502,42 @@ ConfigureLine(interp, canvas, itemPtr, argc, argv, flags)
* graphics contexts.
*/
- if (linePtr->fg == NULL) {
- newGC = arrowGC = None;
+ state = itemPtr->state;
+
+ if(state == TK_STATE_NULL) {
+ state = ((TkCanvas *)canvas)->canvas_state;
+ }
+
+ if (linePtr->outline.activeWidth > linePtr->outline.width ||
+ linePtr->outline.activeDash.number > 0 ||
+ linePtr->outline.activeColor != NULL ||
+ linePtr->outline.activeStipple != None) {
+ itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
} else {
- gcValues.foreground = linePtr->fg->pixel;
- gcValues.join_style = linePtr->joinStyle;
- if (linePtr->width < 0) {
- linePtr->width = 1;
- }
- gcValues.line_width = linePtr->width;
- mask = GCForeground|GCJoinStyle|GCLineWidth;
- if (linePtr->fillStipple != None) {
- gcValues.stipple = linePtr->fillStipple;
- gcValues.fill_style = FillStippled;
- mask |= GCStipple|GCFillStyle;
- }
- if (linePtr->arrow == noneUid) {
+ itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
+ }
+ mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr,
+ &(linePtr->outline));
+ if (mask) {
+ if (linePtr->arrow == ARROWS_NONE) {
gcValues.cap_style = linePtr->capStyle;
mask |= GCCapStyle;
}
+ gcValues.join_style = linePtr->joinStyle;
+ mask |= GCJoinStyle;
newGC = Tk_GetGC(tkwin, mask, &gcValues);
gcValues.line_width = 0;
arrowGC = Tk_GetGC(tkwin, mask, &gcValues);
+ } else {
+ newGC = arrowGC = None;
}
- if (linePtr->gc != None) {
- Tk_FreeGC(Tk_Display(tkwin), linePtr->gc);
+ if (linePtr->outline.gc != None) {
+ Tk_FreeGC(Tk_Display(tkwin), linePtr->outline.gc);
}
if (linePtr->arrowGC != None) {
Tk_FreeGC(Tk_Display(tkwin), linePtr->arrowGC);
}
- linePtr->gc = newGC;
+ linePtr->outline.gc = newGC;
linePtr->arrowGC = arrowGC;
/*
@@ -470,21 +550,26 @@ ConfigureLine(interp, canvas, itemPtr, argc, argv, flags)
linePtr->splineSteps = 100;
}
+ if ((!linePtr->numPoints) || (state==TK_STATE_HIDDEN)) {
+ ComputeLineBbox(canvas, linePtr);
+ return TCL_OK;
+ }
+
/*
* Setup arrowheads, if needed. If arrowheads are turned off,
* restore the line's endpoints (they were shortened when the
* arrowheads were added).
*/
- if ((linePtr->firstArrowPtr != NULL) && (linePtr->arrow != firstUid)
- && (linePtr->arrow != bothUid)) {
+ if ((linePtr->firstArrowPtr != NULL) && (linePtr->arrow != ARROWS_FIRST)
+ && (linePtr->arrow != ARROWS_BOTH)) {
linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];
linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];
ckfree((char *) linePtr->firstArrowPtr);
linePtr->firstArrowPtr = NULL;
}
- if ((linePtr->lastArrowPtr != NULL) && (linePtr->arrow != lastUid)
- && (linePtr->arrow != bothUid)) {
+ if ((linePtr->lastArrowPtr != NULL) && (linePtr->arrow != ARROWS_LAST)
+ && (linePtr->arrow != ARROWS_BOTH)) {
int i;
i = 2*(linePtr->numPoints-1);
@@ -493,15 +578,7 @@ ConfigureLine(interp, canvas, itemPtr, argc, argv, flags)
ckfree((char *) linePtr->lastArrowPtr);
linePtr->lastArrowPtr = NULL;
}
- if (linePtr->arrow != noneUid) {
- if ((linePtr->arrow != firstUid) && (linePtr->arrow != lastUid)
- && (linePtr->arrow != bothUid)) {
- Tcl_AppendResult(interp, "bad arrow spec \"",
- linePtr->arrow, "\": must be none, first, last, or both",
- (char *) NULL);
- linePtr->arrow = noneUid;
- return TCL_ERROR;
- }
+ if (linePtr->arrow != ARROWS_NONE) {
ConfigureArrows(canvas, linePtr);
}
@@ -540,18 +617,10 @@ DeleteLine(canvas, itemPtr, display)
{
LineItem *linePtr = (LineItem *) itemPtr;
+ Tk_DeleteOutline(display, &(linePtr->outline));
if (linePtr->coordPtr != NULL) {
ckfree((char *) linePtr->coordPtr);
}
- if (linePtr->fg != NULL) {
- Tk_FreeColor(linePtr->fg);
- }
- if (linePtr->fillStipple != None) {
- Tk_FreeBitmap(display, linePtr->fillStipple);
- }
- if (linePtr->gc != None) {
- Tk_FreeGC(display, linePtr->gc);
- }
if (linePtr->arrowGC != None) {
Tk_FreeGC(display, linePtr->arrowGC);
}
@@ -588,7 +657,33 @@ ComputeLineBbox(canvas, linePtr)
* recomputed. */
{
double *coordPtr;
- int i, width;
+ int i, intWidth;
+ double width;
+ Tk_State state = linePtr->header.state;
+ Tk_TSOffset *tsoffset;
+
+ if(state == TK_STATE_NULL) {
+ state = ((TkCanvas *)canvas)->canvas_state;
+ }
+
+ if (!(linePtr->numPoints) || (state==TK_STATE_HIDDEN)) {
+ linePtr->header.x1 = -1;
+ linePtr->header.x2 = -1;
+ linePtr->header.y1 = -1;
+ linePtr->header.y2 = -1;
+ return;
+ }
+
+ width = linePtr->outline.width;
+ if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)linePtr) {
+ if (linePtr->outline.activeWidth>width) {
+ width = linePtr->outline.activeWidth;
+ }
+ } else if (state==TK_STATE_DISABLED) {
+ if (linePtr->outline.disabledWidth>0) {
+ width = linePtr->outline.disabledWidth;
+ }
+ }
coordPtr = linePtr->coordPtr;
linePtr->header.x1 = linePtr->header.x2 = (int) *coordPtr;
@@ -608,14 +703,66 @@ ComputeLineBbox(canvas, linePtr)
i++, coordPtr += 2) {
TkIncludePoint((Tk_Item *) linePtr, coordPtr);
}
- width = linePtr->width;
- if (width < 1) {
- width = 1;
+ width = linePtr->outline.width;
+ if (width < 1.0) {
+ width = 1.0;
+ }
+ if (linePtr->arrow != ARROWS_NONE) {
+ if (linePtr->arrow != ARROWS_LAST) {
+ TkIncludePoint((Tk_Item *) linePtr, linePtr->firstArrowPtr);
+ }
+ if (linePtr->arrow != ARROWS_FIRST) {
+ TkIncludePoint((Tk_Item *) linePtr, linePtr->lastArrowPtr);
+ }
+ }
+
+ tsoffset = &linePtr->outline.tsoffset;
+ if (tsoffset->flags & TK_OFFSET_INDEX) {
+ double *coordPtr = linePtr->coordPtr + (tsoffset->flags & ~TK_OFFSET_INDEX);
+ if (tsoffset->flags <= 0) {
+ coordPtr = linePtr->coordPtr;
+ if ((linePtr->arrow == ARROWS_FIRST) || (linePtr->arrow == ARROWS_BOTH)) {
+ coordPtr = linePtr->firstArrowPtr;
+ }
+ }
+ if (tsoffset->flags > (linePtr->numPoints * 2)) {
+ coordPtr = linePtr->coordPtr + (linePtr->numPoints * 2);
+ if ((linePtr->arrow == ARROWS_LAST) || (linePtr->arrow == ARROWS_BOTH)) {
+ coordPtr = linePtr->lastArrowPtr;
+ }
+ }
+ tsoffset->xoffset = (int) (coordPtr[0] + 0.5);
+ tsoffset->yoffset = (int) (coordPtr[1] + 0.5);
+ } else {
+ if (tsoffset->flags & TK_OFFSET_LEFT) {
+ tsoffset->xoffset = linePtr->header.x1;
+ } else if (tsoffset->flags & TK_OFFSET_CENTER) {
+ tsoffset->xoffset = (linePtr->header.x1 + linePtr->header.x2)/2;
+ } else if (tsoffset->flags & TK_OFFSET_RIGHT) {
+ tsoffset->xoffset = linePtr->header.x2;
+ }
+ if (tsoffset->flags & TK_OFFSET_TOP) {
+ tsoffset->yoffset = linePtr->header.y1;
+ } else if (tsoffset->flags & TK_OFFSET_MIDDLE) {
+ tsoffset->yoffset = (linePtr->header.y1 + linePtr->header.y2)/2;
+ } else if (tsoffset->flags & TK_OFFSET_BOTTOM) {
+ tsoffset->yoffset = linePtr->header.y2;
+ }
+ }
+
+ intWidth = (int) (width + 0.5);
+ linePtr->header.x1 -= intWidth;
+ linePtr->header.x2 += intWidth;
+ linePtr->header.y1 -= intWidth;
+ linePtr->header.y2 += intWidth;
+
+ if (linePtr->numPoints==1) {
+ linePtr->header.x1 -= 1;
+ linePtr->header.x2 += 1;
+ linePtr->header.y1 -= 1;
+ linePtr->header.y2 += 1;
+ return;
}
- linePtr->header.x1 -= width;
- linePtr->header.x2 += width;
- linePtr->header.y1 -= width;
- linePtr->header.y2 += width;
/*
* For mitered lines, make a second pass through all the points.
@@ -630,7 +777,7 @@ ComputeLineBbox(canvas, linePtr)
int j;
if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4,
- (double) width, miter, miter+2)) {
+ width, miter, miter+2)) {
for (j = 0; j < 4; j += 2) {
TkIncludePoint((Tk_Item *) linePtr, miter+j);
}
@@ -642,14 +789,14 @@ ComputeLineBbox(canvas, linePtr)
* Add in the sizes of arrowheads, if any.
*/
- if (linePtr->arrow != Tk_GetUid("none")) {
- if (linePtr->arrow != Tk_GetUid("last")) {
+ if (linePtr->arrow != ARROWS_NONE) {
+ if (linePtr->arrow != ARROWS_LAST) {
for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
i++, coordPtr += 2) {
TkIncludePoint((Tk_Item *) linePtr, coordPtr);
}
}
- if (linePtr->arrow != Tk_GetUid("first")) {
+ if (linePtr->arrow != ARROWS_FIRST) {
for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
i++, coordPtr += 2) {
TkIncludePoint((Tk_Item *) linePtr, coordPtr);
@@ -700,13 +847,34 @@ DisplayLine(canvas, itemPtr, display, drawable, x, y, width, height)
XPoint staticPoints[MAX_STATIC_POINTS];
XPoint *pointPtr;
XPoint *pPtr;
- double *coordPtr;
+ double *coordPtr, linewidth;
int i, numPoints;
+ Tk_State state = itemPtr->state;
+ Pixmap stipple = linePtr->outline.stipple;
- if (linePtr->gc == None) {
+ if ((!linePtr->numPoints)||(linePtr->outline.gc==None)) {
return;
}
+ if (state == TK_STATE_NULL) {
+ state = ((TkCanvas *)canvas)->canvas_state;
+ }
+ linewidth = linePtr->outline.width;
+ if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
+ if (linePtr->outline.activeStipple!=None) {
+ stipple = linePtr->outline.activeStipple;
+ }
+ if (linePtr->outline.activeWidth>linewidth) {
+ linewidth = linePtr->outline.activeWidth;
+ }
+ } else if (state==TK_STATE_DISABLED) {
+ if (linePtr->outline.disabledStipple!=None) {
+ stipple = linePtr->outline.disabledStipple;
+ }
+ if (linePtr->outline.disabledWidth>linewidth) {
+ linewidth = linePtr->outline.activeWidth;
+ }
+ }
/*
* Build up an array of points in screen coordinates. Use a
* static array unless the line has an enormous number of points;
@@ -715,7 +883,9 @@ DisplayLine(canvas, itemPtr, display, drawable, x, y, width, height)
*/
if ((linePtr->smooth) && (linePtr->numPoints > 2)) {
- numPoints = 1 + linePtr->numPoints*linePtr->splineSteps;
+ numPoints = linePtr->smooth->coordProc(canvas, (double *) NULL,
+ linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL,
+ (double *) NULL);
} else {
numPoints = linePtr->numPoints;
}
@@ -727,7 +897,7 @@ DisplayLine(canvas, itemPtr, display, drawable, x, y, width, height)
}
if ((linePtr->smooth) && (linePtr->numPoints > 2)) {
- numPoints = TkMakeBezierCurve(canvas, linePtr->coordPtr,
+ numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr,
linePtr->numPoints, linePtr->splineSteps, pointPtr,
(double *) NULL);
} else {
@@ -745,12 +915,21 @@ DisplayLine(canvas, itemPtr, display, drawable, x, y, width, height)
* GC is supposed to be read-only.
*/
- if (linePtr->fillStipple != None) {
- Tk_CanvasSetStippleOrigin(canvas, linePtr->gc);
- Tk_CanvasSetStippleOrigin(canvas, linePtr->arrowGC);
+ if (Tk_ChangeOutlineGC(canvas, itemPtr, &(linePtr->outline))) {
+ Tk_CanvasSetOffset(canvas, linePtr->arrowGC, &linePtr->outline.tsoffset);
}
- XDrawLines(display, drawable, linePtr->gc, pointPtr, numPoints,
+ if (numPoints>1) {
+ XDrawLines(display, drawable, linePtr->outline.gc, pointPtr, numPoints,
CoordModeOrigin);
+ } else {
+ int intwidth = (int) (linewidth + 0.5);
+ if (intwidth<1) {
+ intwidth=1;
+ }
+ XFillArc(display, drawable, linePtr->outline.gc,
+ pointPtr->x - intwidth/2, pointPtr->y - intwidth/2,
+ (unsigned int)intwidth+1, (unsigned int)intwidth+1, 0, 64*360);
+ }
if (pointPtr != staticPoints) {
ckfree((char *) pointPtr);
}
@@ -761,14 +940,13 @@ DisplayLine(canvas, itemPtr, display, drawable, x, y, width, height)
if (linePtr->firstArrowPtr != NULL) {
TkFillPolygon(canvas, linePtr->firstArrowPtr, PTS_IN_ARROW,
- display, drawable, linePtr->gc, NULL);
+ display, drawable, linePtr->arrowGC, NULL);
}
if (linePtr->lastArrowPtr != NULL) {
TkFillPolygon(canvas, linePtr->lastArrowPtr, PTS_IN_ARROW,
- display, drawable, linePtr->gc, NULL);
+ display, drawable, linePtr->arrowGC, NULL);
}
- if (linePtr->fillStipple != None) {
- XSetTSOrigin(display, linePtr->gc, 0, 0);
+ if (Tk_ResetOutlineGC(canvas, itemPtr, &(linePtr->outline))) {
XSetTSOrigin(display, linePtr->arrowGC, 0, 0);
}
}
@@ -776,6 +954,325 @@ DisplayLine(canvas, itemPtr, display, drawable, x, y, width, height)
/*
*--------------------------------------------------------------
*
+ * LineInsert --
+ *
+ * Insert coords into a line item at a given index.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The coords in the given item is modified.
+ *
+ *--------------------------------------------------------------
+ */
+
+static void
+LineInsert(canvas, itemPtr, beforeThis, obj)
+ Tk_Canvas canvas; /* Canvas containing text item. */
+ Tk_Item *itemPtr; /* Line item to be modified. */
+ int beforeThis; /* Index before which new coordinates
+ * are to be inserted. */
+ Tcl_Obj *obj; /* New coordinates to be inserted. */
+{
+ LineItem *linePtr = (LineItem *) itemPtr;
+ int length, argc, i;
+ double *new, *coordPtr;
+ Tk_State state = itemPtr->state;
+ Tcl_Obj **objv;
+
+ if(state == TK_STATE_NULL) {
+ state = ((TkCanvas *)canvas)->canvas_state;
+ }
+
+ if (!obj || (Tcl_ListObjGetElements((Tcl_Interp *) NULL, obj, &argc, &objv) != TCL_OK)
+ || !argc || argc&1) {
+ return;
+ }
+ length = 2*linePtr->numPoints;
+ if (beforeThis < 0) {
+ beforeThis = 0;
+ }
+ if (beforeThis > length) {
+ beforeThis = length;
+ }
+ if (linePtr->firstArrowPtr != NULL) {
+ linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];
+ linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];
+ }
+ if (linePtr->lastArrowPtr != NULL) {
+ linePtr->coordPtr[length-2] = linePtr->lastArrowPtr[0];
+ linePtr->coordPtr[length-1] = linePtr->lastArrowPtr[1];
+ }
+ new = (double *) ckalloc((unsigned)(sizeof(double) * (length + argc)));
+ for(i=0; i<beforeThis; i++) {
+ new[i] = linePtr->coordPtr[i];
+ }
+ for(i=0; i<argc; i++) {
+ if (Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,objv[i],
+ new+(i+beforeThis))!=TCL_OK) {
+ Tcl_ResetResult(((TkCanvas *)canvas)->interp);
+ ckfree((char *) new);
+ return;
+ }
+ }
+
+ for(i=beforeThis; i<length; i++) {
+ new[i+argc] = linePtr->coordPtr[i];
+ }
+ if(linePtr->coordPtr) ckfree((char *)linePtr->coordPtr);
+ linePtr->coordPtr = new;
+ linePtr->numPoints = (length + argc)/2;
+
+ if ((length>3) && (state != TK_STATE_HIDDEN)) {
+ /*
+ * This is some optimizing code that will result that only the part
+ * of the polygon that changed (and the objects that are overlapping
+ * with that part) need to be redrawn. A special flag is set that
+ * instructs the general canvas code not to redraw the whole
+ * object. If this flag is not set, the canvas will do the redrawing,
+ * otherwise I have to do it here.
+ */
+ itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW;
+
+ if (beforeThis>0) {beforeThis -= 2; argc+=2; }
+ if ((beforeThis+argc)<length) argc+=2;
+ if (linePtr->smooth) {
+ if(beforeThis>0) {
+ beforeThis-=2; argc+=2;
+ }
+ if((beforeThis+argc+2)<length) {
+ argc+=2;
+ }
+ }
+ itemPtr->x1 = itemPtr->x2 = (int) linePtr->coordPtr[beforeThis];
+ itemPtr->y1 = itemPtr->y2 = (int) linePtr->coordPtr[beforeThis+1];
+ if ((linePtr->firstArrowPtr != NULL) && (beforeThis<1)) {
+ /* include old first arrow */
+ for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
+ i++, coordPtr += 2) {
+ TkIncludePoint(itemPtr, coordPtr);
+ }
+ }
+ if ((linePtr->lastArrowPtr != NULL) && ((beforeThis+argc)>=length)) {
+ /* include old last arrow */
+ for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
+ i++, coordPtr += 2) {
+ TkIncludePoint(itemPtr, coordPtr);
+ }
+ }
+ coordPtr = linePtr->coordPtr+beforeThis+2;
+ for(i=2; i<argc; i+=2) {
+ TkIncludePoint(itemPtr, coordPtr);
+ coordPtr+=2;
+ }
+ }
+ if (linePtr->firstArrowPtr != NULL) {
+ ckfree((char *) linePtr->firstArrowPtr);
+ linePtr->firstArrowPtr = NULL;
+ }
+ if (linePtr->lastArrowPtr != NULL) {
+ ckfree((char *) linePtr->lastArrowPtr);
+ linePtr->lastArrowPtr = NULL;
+ }
+ if (linePtr->arrow != ARROWS_NONE) {
+ ConfigureArrows(canvas, linePtr);
+ }
+
+ if(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
+ double width;
+ int intWidth;
+ if ((linePtr->firstArrowPtr != NULL) && (beforeThis>2)) {
+ /* include new first arrow */
+ for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
+ i++, coordPtr += 2) {
+ TkIncludePoint(itemPtr, coordPtr);
+ }
+ }
+ if ((linePtr->lastArrowPtr != NULL) && ((beforeThis+argc)<(length-2))) {
+ /* include new right arrow */
+ for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
+ i++, coordPtr += 2) {
+ TkIncludePoint(itemPtr, coordPtr);
+ }
+ }
+ width = linePtr->outline.width;
+ if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
+ if (linePtr->outline.activeWidth>width) {
+ width = linePtr->outline.activeWidth;
+ }
+ } else if (state==TK_STATE_DISABLED) {
+ if (linePtr->outline.disabledWidth>0) {
+ width = linePtr->outline.disabledWidth;
+ }
+ }
+ intWidth = (int) (width + 0.5);
+ if (intWidth < 1) {
+ intWidth = 1;
+ }
+ itemPtr->x1 -= intWidth; itemPtr->y1 -= intWidth;
+ itemPtr->x2 += intWidth; itemPtr->y2 += intWidth;
+ Tk_CanvasEventuallyRedraw(canvas, itemPtr->x1, itemPtr->y1,
+ itemPtr->x2, itemPtr->y2);
+ }
+
+ ComputeLineBbox(canvas, linePtr);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * LineDeleteCoords --
+ *
+ * Delete one or more coordinates from a line item.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Characters between "first" and "last", inclusive, get
+ * deleted from itemPtr.
+ *
+ *--------------------------------------------------------------
+ */
+
+static void
+LineDeleteCoords(canvas, itemPtr, first, last)
+ Tk_Canvas canvas; /* Canvas containing itemPtr. */
+ Tk_Item *itemPtr; /* Item in which to delete characters. */
+ int first; /* Index of first character to delete. */
+ int last; /* Index of last character to delete. */
+{
+ LineItem *linePtr = (LineItem *) itemPtr;
+ int count, i, first1, last1;
+ int length = 2*linePtr->numPoints;
+ double *coordPtr;
+ Tk_State state = itemPtr->state;
+
+ if(state == TK_STATE_NULL) {
+ state = ((TkCanvas *)canvas)->canvas_state;
+ }
+
+ first &= -2;
+ last &= -2;
+
+ if (first < 0) {
+ first = 0;
+ }
+ if (last >= length) {
+ last = length-2;
+ }
+ if (first > last) {
+ return;
+ }
+ if (linePtr->firstArrowPtr != NULL) {
+ linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];
+ linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];
+ }
+ if (linePtr->lastArrowPtr != NULL) {
+ linePtr->coordPtr[length-2] = linePtr->lastArrowPtr[0];
+ linePtr->coordPtr[length-1] = linePtr->lastArrowPtr[1];
+ }
+ first1 = first; last1 = last;
+ if(first1>0) first1 -= 2;
+ if(last1<length-2) last1 += 2;
+ if (linePtr->smooth) {
+ if(first1>0) first1 -= 2;
+ if(last1<length-2) last1 += 2;
+ }
+
+ if((first1<2) && (last1 >= length-2)) {
+ /*
+ * This is some optimizing code that will result that only the part
+ * of the line that changed (and the objects that are overlapping
+ * with that part) need to be redrawn. A special flag is set that
+ * instructs the general canvas code not to redraw the whole
+ * object. If this flag is set, the redrawing has to be done here,
+ * otherwise the general Canvas code will take care of it.
+ */
+
+ itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW;
+ itemPtr->x1 = itemPtr->x2 = (int) linePtr->coordPtr[first1];
+ itemPtr->y1 = itemPtr->y2 = (int) linePtr->coordPtr[first1+1];
+ if ((linePtr->firstArrowPtr != NULL) && (first1<2)) {
+ /* include old first arrow */
+ for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
+ i++, coordPtr += 2) {
+ TkIncludePoint(itemPtr, coordPtr);
+ }
+ }
+ if ((linePtr->lastArrowPtr != NULL) && (last1>=length-2)) {
+ /* include old last arrow */
+ for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
+ i++, coordPtr += 2) {
+ TkIncludePoint(itemPtr, coordPtr);
+ }
+ }
+ coordPtr = linePtr->coordPtr+first1+2;
+ for (i=first1+2; i<=last1; i+=2) {
+ TkIncludePoint(itemPtr, coordPtr);
+ coordPtr+=2;
+ }
+ }
+
+ count = last + 2 - first;
+ for (i=last+2; i<length; i++) {
+ linePtr->coordPtr[i-count] = linePtr->coordPtr[i];
+ }
+ linePtr->numPoints -= count/2;
+ if (linePtr->firstArrowPtr != NULL) {
+ ckfree((char *) linePtr->firstArrowPtr);
+ linePtr->firstArrowPtr = NULL;
+ }
+ if (linePtr->lastArrowPtr != NULL) {
+ ckfree((char *) linePtr->lastArrowPtr);
+ linePtr->lastArrowPtr = NULL;
+ }
+ if (linePtr->arrow != ARROWS_NONE) {
+ ConfigureArrows(canvas, linePtr);
+ }
+ if(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
+ double width;
+ int intWidth;
+ if ((linePtr->firstArrowPtr != NULL) && (first1<4)) {
+ /* include new first arrow */
+ for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
+ i++, coordPtr += 2) {
+ TkIncludePoint(itemPtr, coordPtr);
+ }
+ }
+ if ((linePtr->lastArrowPtr != NULL) && (last1>(length-4))) {
+ /* include new right arrow */
+ for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
+ i++, coordPtr += 2) {
+ TkIncludePoint(itemPtr, coordPtr);
+ }
+ }
+ width = linePtr->outline.width;
+ if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
+ if (linePtr->outline.activeWidth>width) {
+ width = linePtr->outline.activeWidth;
+ }
+ } else if (state==TK_STATE_DISABLED) {
+ if (linePtr->outline.disabledWidth>0) {
+ width = linePtr->outline.disabledWidth;
+ }
+ }
+ intWidth = (int) (width + 0.5);
+ if (intWidth < 1) {
+ intWidth = 1;
+ }
+ itemPtr->x1 -= intWidth; itemPtr->y1 -= intWidth;
+ itemPtr->x2 += intWidth; itemPtr->y2 += intWidth;
+ Tk_CanvasEventuallyRedraw(canvas, itemPtr->x1, itemPtr->y1,
+ itemPtr->x2, itemPtr->y2);
+ }
+ ComputeLineBbox(canvas, linePtr);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
* LineToPoint --
*
* Computes the distance from a given point to a given
@@ -800,6 +1297,7 @@ LineToPoint(canvas, itemPtr, pointPtr)
Tk_Item *itemPtr; /* Item to check against point. */
double *pointPtr; /* Pointer to x and y coordinates. */
{
+ Tk_State state = itemPtr->state;
LineItem *linePtr = (LineItem *) itemPtr;
double *coordPtr, *linePoints;
double staticSpace[2*MAX_STATIC_POINTS];
@@ -817,15 +1315,32 @@ LineToPoint(canvas, itemPtr, pointPtr)
* against which to do the check.
*/
+ if(state == TK_STATE_NULL) {
+ state = ((TkCanvas *)canvas)->canvas_state;
+ }
+
+ width = linePtr->outline.width;
+ if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
+ if (linePtr->outline.activeWidth>width) {
+ width = linePtr->outline.activeWidth;
+ }
+ } else if (state==TK_STATE_DISABLED) {
+ if (linePtr->outline.disabledWidth>0) {
+ width = linePtr->outline.disabledWidth;
+ }
+ }
+
if ((linePtr->smooth) && (linePtr->numPoints > 2)) {
- numPoints = 1 + linePtr->numPoints*linePtr->splineSteps;
+ numPoints = linePtr->smooth->coordProc(canvas, (double *) NULL,
+ linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL,
+ (double *) NULL);
if (numPoints <= MAX_STATIC_POINTS) {
linePoints = staticSpace;
} else {
linePoints = (double *) ckalloc((unsigned)
(2*numPoints*sizeof(double)));
}
- numPoints = TkMakeBezierCurve(canvas, linePtr->coordPtr,
+ numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr,
linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL,
linePoints);
} else {
@@ -833,11 +1348,19 @@ LineToPoint(canvas, itemPtr, pointPtr)
linePoints = linePtr->coordPtr;
}
- width = (double) linePtr->width;
if (width < 1.0) {
width = 1.0;
}
+ if (!numPoints || itemPtr->state==TK_STATE_HIDDEN) {
+ return bestDist;
+ } else if (numPoints == 1) {
+ bestDist = hypot(linePoints[0] - pointPtr[0], linePoints[1] - pointPtr[1])
+ - width/2.0;
+ if (bestDist < 0) bestDist = 0;
+ return bestDist;
+ }
+
/*
* The overall idea is to iterate through all of the edges of
* the line, computing a polygon for each edge and testing the
@@ -950,8 +1473,8 @@ LineToPoint(canvas, itemPtr, pointPtr)
* If there are arrowheads, check the distance to the arrowheads.
*/
- if (linePtr->arrow != Tk_GetUid("none")) {
- if (linePtr->arrow != Tk_GetUid("last")) {
+ if (linePtr->arrow != ARROWS_NONE) {
+ if (linePtr->arrow != ARROWS_LAST) {
dist = TkPolygonToPoint(linePtr->firstArrowPtr, PTS_IN_ARROW,
pointPtr);
if (dist <= 0.0) {
@@ -961,7 +1484,7 @@ LineToPoint(canvas, itemPtr, pointPtr)
bestDist = dist;
}
}
- if (linePtr->arrow != Tk_GetUid("first")) {
+ if (linePtr->arrow != ARROWS_FIRST) {
dist = TkPolygonToPoint(linePtr->lastArrowPtr, PTS_IN_ARROW,
pointPtr);
if (dist <= 0.0) {
@@ -1010,8 +1533,36 @@ LineToArea(canvas, itemPtr, rectPtr)
LineItem *linePtr = (LineItem *) itemPtr;
double staticSpace[2*MAX_STATIC_POINTS];
double *linePoints;
- double width;
int numPoints, result;
+ double radius, width;
+ Tk_State state = itemPtr->state;
+
+ if(state == TK_STATE_NULL) {
+ state = ((TkCanvas *)canvas)->canvas_state;
+ }
+ width = linePtr->outline.width;
+ if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
+ if (linePtr->outline.activeWidth>width) {
+ width = linePtr->outline.activeWidth;
+ }
+ } else if (state==TK_STATE_DISABLED) {
+ if (linePtr->outline.disabledWidth>0) {
+ width = linePtr->outline.disabledWidth;
+ }
+ }
+
+ radius = (width+1.0)/2.0;
+
+ if ((state==TK_STATE_HIDDEN) || !linePtr->numPoints) {
+ return -1;
+ } else if (linePtr->numPoints == 1) {
+ double oval[4];
+ oval[0] = linePtr->coordPtr[0]-radius;
+ oval[1] = linePtr->coordPtr[1]-radius;
+ oval[2] = linePtr->coordPtr[0]+radius;
+ oval[3] = linePtr->coordPtr[1]+radius;
+ return TkOvalToArea(oval, rectPtr);
+ }
/*
* Handle smoothed lines by generating an expanded set of points
@@ -1019,14 +1570,16 @@ LineToArea(canvas, itemPtr, rectPtr)
*/
if ((linePtr->smooth) && (linePtr->numPoints > 2)) {
- numPoints = 1 + linePtr->numPoints*linePtr->splineSteps;
+ numPoints = linePtr->smooth->coordProc(canvas, (double *) NULL,
+ linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL,
+ (double *) NULL);
if (numPoints <= MAX_STATIC_POINTS) {
linePoints = staticSpace;
} else {
linePoints = (double *) ckalloc((unsigned)
(2*numPoints*sizeof(double)));
}
- numPoints = TkMakeBezierCurve(canvas, linePtr->coordPtr,
+ numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr,
linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL,
linePoints);
} else {
@@ -1038,8 +1591,7 @@ LineToArea(canvas, itemPtr, rectPtr)
* Check the segments of the line.
*/
- width = (double) linePtr->width;
- if (width < 1.0) {
+ if (width < 1.0) {
width = 1.0;
}
@@ -1054,15 +1606,15 @@ LineToArea(canvas, itemPtr, rectPtr)
* Check arrowheads, if any.
*/
- if (linePtr->arrow != Tk_GetUid("none")) {
- if (linePtr->arrow != Tk_GetUid("last")) {
+ if (linePtr->arrow != ARROWS_NONE) {
+ if (linePtr->arrow != ARROWS_LAST) {
if (TkPolygonToArea(linePtr->firstArrowPtr, PTS_IN_ARROW,
rectPtr) != result) {
result = 0;
goto done;
}
}
- if (linePtr->arrow != Tk_GetUid("first")) {
+ if (linePtr->arrow != ARROWS_FIRST) {
if (TkPolygonToArea(linePtr->lastArrowPtr, PTS_IN_ARROW,
rectPtr) != result) {
result = 0;
@@ -1135,7 +1687,7 @@ ScaleLine(canvas, itemPtr, originX, originY, scaleX, scaleY)
coordPtr[0] = originX + scaleX*(*coordPtr - originX);
coordPtr[1] = originY + scaleY*(coordPtr[1] - originY);
}
- if (linePtr->arrow != Tk_GetUid("none")) {
+ if (linePtr->arrow != ARROWS_NONE) {
ConfigureArrows(canvas, linePtr);
}
ComputeLineBbox(canvas, linePtr);
@@ -1144,6 +1696,96 @@ ScaleLine(canvas, itemPtr, originX, originY, scaleX, scaleY)
/*
*--------------------------------------------------------------
*
+ * GetLineIndex --
+ *
+ * Parse an index into a line item and return either its value
+ * or an error.
+ *
+ * Results:
+ * A standard Tcl result. If all went well, then *indexPtr is
+ * filled in with the index (into itemPtr) corresponding to
+ * string. Otherwise an error message is left in
+ * interp->result.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+static int
+GetLineIndex(interp, canvas, itemPtr, obj, indexPtr)
+ Tcl_Interp *interp; /* Used for error reporting. */
+ Tk_Canvas canvas; /* Canvas containing item. */
+ Tk_Item *itemPtr; /* Item for which the index is being
+ * specified. */
+ Tcl_Obj *obj; /* Specification of a particular coord
+ * in itemPtr's line. */
+ int *indexPtr; /* Where to store converted index. */
+{
+ LineItem *linePtr = (LineItem *) itemPtr;
+ size_t length;
+ char *string = Tcl_GetStringFromObj(obj, (int *) &length);
+
+ if (string[0] == 'e') {
+ if (strncmp(string, "end", length) == 0) {
+ *indexPtr = 2*linePtr->numPoints;
+ } else {
+ badIndex:
+
+ /*
+ * Some of the paths here leave messages in interp->result,
+ * so we have to clear it out before storing our own message.
+ */
+
+ Tcl_SetResult(interp, (char *) NULL, TCL_STATIC);
+ Tcl_AppendResult(interp, "bad index \"", string, "\"",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ } else if (string[0] == '@') {
+ int i;
+ double x ,y, bestDist, dist, *coordPtr;
+ char *end, *p;
+
+ p = string+1;
+ x = strtod(p, &end);
+ if ((end == p) || (*end != ',')) {
+ goto badIndex;
+ }
+ p = end+1;
+ y = strtod(p, &end);
+ if ((end == p) || (*end != 0)) {
+ goto badIndex;
+ }
+ bestDist = 1.0e36;
+ coordPtr = linePtr->coordPtr;
+ *indexPtr = 0;
+ for(i=0; i<linePtr->numPoints; i++) {
+ dist = hypot(coordPtr[0] - x, coordPtr[1] - y);
+ if (dist<bestDist) {
+ bestDist = dist;
+ *indexPtr = 2*i;
+ }
+ coordPtr += 2;
+ }
+ } else {
+ if (Tcl_GetIntFromObj(interp, obj, indexPtr) != TCL_OK) {
+ goto badIndex;
+ }
+ *indexPtr &= -2; /* if index is odd, make it even */
+ if (*indexPtr < 0){
+ *indexPtr = 0;
+ } else if (*indexPtr > (2*linePtr->numPoints)) {
+ *indexPtr = (2*linePtr->numPoints);
+ }
+ }
+ return TCL_OK;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
* TranslateLine --
*
* This procedure is called to move a line by a given amount.
@@ -1217,7 +1859,7 @@ ParseArrowShape(clientData, interp, tkwin, value, recordPtr, offset)
ClientData clientData; /* Not used. */
Tcl_Interp *interp; /* Used for error reporting. */
Tk_Window tkwin; /* Not used. */
- char *value; /* Textual specification of arrow shape. */
+ CONST char *value; /* Textual specification of arrow shape. */
char *recordPtr; /* Pointer to item record in which to
* store arrow information. */
int offset; /* Offset of shape information in widget
@@ -1232,7 +1874,7 @@ ParseArrowShape(clientData, interp, tkwin, value, recordPtr, offset)
panic("ParseArrowShape received bogus offset");
}
- if (Tcl_SplitList(interp, value, &argc, &argv) != TCL_OK) {
+ if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) {
syntaxError:
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "bad arrow shape \"", value,
@@ -1297,6 +1939,117 @@ PrintArrowShape(clientData, tkwin, recordPtr, offset, freeProcPtr)
return buffer;
}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ArrowParseProc --
+ *
+ * This procedure is invoked during option processing to handle
+ * the "-arrow" option.
+ *
+ * Results:
+ * A standard Tcl return value.
+ *
+ * Side effects:
+ * The arrow for a given item gets replaced by the arrow
+ * indicated in the value argument.
+ *
+ *--------------------------------------------------------------
+ */
+
+static int
+ArrowParseProc(clientData, interp, tkwin, value, widgRec, offset)
+ ClientData clientData; /* some flags.*/
+ Tcl_Interp *interp; /* Used for reporting errors. */
+ Tk_Window tkwin; /* Window containing canvas widget. */
+ CONST char *value; /* Value of option. */
+ char *widgRec; /* Pointer to record for item. */
+ int offset; /* Offset into item. */
+{
+ int c;
+ size_t length;
+
+ register Arrows *arrowPtr = (Arrows *) (widgRec + offset);
+
+ if(value == NULL || *value == 0) {
+ *arrowPtr = ARROWS_NONE;
+ return TCL_OK;
+ }
+
+ c = value[0];
+ length = strlen(value);
+
+ if ((c == 'n') && (strncmp(value, "none", length) == 0)) {
+ *arrowPtr = ARROWS_NONE;
+ return TCL_OK;
+ }
+ if ((c == 'f') && (strncmp(value, "first", length) == 0)) {
+ *arrowPtr = ARROWS_FIRST;
+ return TCL_OK;
+ }
+ if ((c == 'l') && (strncmp(value, "last", length) == 0)) {
+ *arrowPtr = ARROWS_LAST;
+ return TCL_OK;
+ }
+ if ((c == 'b') && (strncmp(value, "both", length) == 0)) {
+ *arrowPtr = ARROWS_BOTH;
+ return TCL_OK;
+ }
+
+ Tcl_AppendResult(interp, "bad arrow spec \"", value,
+ "\": must be none, first, last, or both",
+ (char *) NULL);
+ *arrowPtr = ARROWS_NONE;
+ return TCL_ERROR;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ArrowPrintProc --
+ *
+ * This procedure is invoked by the Tk configuration code
+ * to produce a printable string for the "-arrow"
+ * configuration option.
+ *
+ * Results:
+ * The return value is a string describing the arrows for
+ * the item referred to by "widgRec". In addition, *freeProcPtr
+ * is filled in with the address of a procedure to call to free
+ * the result string when it's no longer needed (or NULL to
+ * indicate that the string doesn't need to be freed).
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+static char *
+ArrowPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
+ ClientData clientData; /* Ignored. */
+ Tk_Window tkwin; /* Window containing canvas widget. */
+ char *widgRec; /* Pointer to record for item. */
+ int offset; /* Offset into item. */
+ Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with
+ * information about how to reclaim
+ * storage for return string. */
+{
+ register Arrows *arrowPtr = (Arrows *) (widgRec + offset);
+
+ switch (*arrowPtr) {
+ case ARROWS_FIRST:
+ return "first";
+ case ARROWS_LAST:
+ return "last";
+ case ARROWS_BOTH:
+ return "both";
+ default:
+ return "none";
+ }
+}
+
/*
*--------------------------------------------------------------
*
@@ -1336,6 +2089,27 @@ ConfigureArrows(canvas, linePtr)
double vertX, vertY; /* Position of arrowhead vertex. */
double shapeA, shapeB, shapeC; /* Adjusted coordinates (see
* explanation below). */
+ double width;
+ Tk_State state = linePtr->header.state;
+
+ if (linePtr->numPoints <2) {
+ return TCL_OK;
+ }
+
+ if(state == TK_STATE_NULL) {
+ state = ((TkCanvas *)canvas)->canvas_state;
+ }
+
+ width = linePtr->outline.width;
+ if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)linePtr) {
+ if (linePtr->outline.activeWidth>width) {
+ width = linePtr->outline.activeWidth;
+ }
+ } else if (state==TK_STATE_DISABLED) {
+ if (linePtr->outline.disabledWidth>0) {
+ width = linePtr->outline.disabledWidth;
+ }
+ }
/*
* The code below makes a tiny increase in the shape parameters
@@ -1346,7 +2120,7 @@ ConfigureArrows(canvas, linePtr)
shapeA = linePtr->arrowShapeA + 0.001;
shapeB = linePtr->arrowShapeB + 0.001;
- shapeC = linePtr->arrowShapeC + linePtr->width/2.0 + 0.001;
+ shapeC = linePtr->arrowShapeC + width/2.0 + 0.001;
/*
* If there's an arrowhead on the first point of the line, compute
@@ -1354,9 +2128,9 @@ ConfigureArrows(canvas, linePtr)
* line doesn't stick out past the leading edge of the arrowhead.
*/
- fracHeight = (linePtr->width/2.0)/shapeC;
+ fracHeight = (width/2.0)/shapeC;
backup = fracHeight*shapeB + shapeA*(1.0 - fracHeight)/2.0;
- if (linePtr->arrow != Tk_GetUid("last")) {
+ if (linePtr->arrow != ARROWS_LAST) {
poly = linePtr->firstArrowPtr;
if (poly == NULL) {
poly = (double *) ckalloc((unsigned)
@@ -1401,7 +2175,7 @@ ConfigureArrows(canvas, linePtr)
* Similar arrowhead calculation for the last point of the line.
*/
- if (linePtr->arrow != Tk_GetUid("first")) {
+ if (linePtr->arrow != ARROWS_FIRST) {
coordPtr = linePtr->coordPtr + 2*(linePtr->numPoints-2);
poly = linePtr->lastArrowPtr;
if (poly == NULL) {
@@ -1475,21 +2249,75 @@ LineToPostscript(interp, canvas, itemPtr, prepass)
char buffer[64 + TCL_INTEGER_SPACE];
char *style;
- if (linePtr->fg == NULL) {
+ double width;
+ XColor *color;
+ Pixmap stipple;
+ Tk_State state = itemPtr->state;
+
+ if(state == TK_STATE_NULL) {
+ state = ((TkCanvas *)canvas)->canvas_state;
+ }
+
+ width = linePtr->outline.width;
+ color = linePtr->outline.color;
+ stipple = linePtr->outline.stipple;
+ if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
+ if (linePtr->outline.activeWidth>width) {
+ width = linePtr->outline.activeWidth;
+ }
+ if (linePtr->outline.activeColor!=NULL) {
+ color = linePtr->outline.activeColor;
+ }
+ if (linePtr->outline.activeStipple!=None) {
+ stipple = linePtr->outline.activeStipple;
+ }
+ } else if (state==TK_STATE_DISABLED) {
+ if (linePtr->outline.disabledWidth>0) {
+ width = linePtr->outline.disabledWidth;
+ }
+ if (linePtr->outline.disabledColor!=NULL) {
+ color = linePtr->outline.disabledColor;
+ }
+ if (linePtr->outline.disabledStipple!=None) {
+ stipple = linePtr->outline.disabledStipple;
+ }
+ }
+
+ if (color == NULL || linePtr->numPoints<1 || linePtr->coordPtr==NULL) {
return TCL_OK;
}
+ if (linePtr->numPoints==1) {
+ sprintf(buffer, "%.15g %.15g translate %.15g %.15g",
+ linePtr->coordPtr[0], Tk_CanvasPsY(canvas, linePtr->coordPtr[1]),
+ width/2.0, width/2.0);
+ Tcl_AppendResult(interp, "matrix currentmatrix\n",buffer,
+ " scale 1 0 moveto 0 0 1 0 360 arc\nsetmatrix\n", (char *) NULL);
+ if (Tk_CanvasPsColor(interp, canvas, color)
+ != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (stipple != None) {
+ Tcl_AppendResult(interp, "clip ", (char *) NULL);
+ if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ } else {
+ Tcl_AppendResult(interp, "fill\n", (char *) NULL);
+ }
+ return TCL_OK;
+ }
/*
* Generate a path for the line's center-line (do this differently
* for straight lines and smoothed lines).
*/
- if ((!linePtr->smooth) || (linePtr->numPoints <= 2)) {
+ if ((!linePtr->smooth) || (linePtr->numPoints < 3)) {
Tk_CanvasPsPath(interp, canvas, linePtr->coordPtr, linePtr->numPoints);
} else {
- if (linePtr->fillStipple == None) {
- TkMakeBezierPostscript(interp, canvas, linePtr->coordPtr,
- linePtr->numPoints);
+ if ((stipple == None) && linePtr->smooth->postscriptProc) {
+ linePtr->smooth->postscriptProc(interp, canvas,
+ linePtr->coordPtr, linePtr->numPoints, linePtr->splineSteps);
} else {
/*
* Special hack: Postscript printers don't appear to be able
@@ -1504,13 +2332,15 @@ LineToPostscript(interp, canvas, itemPtr, prepass)
double *pointPtr;
int numPoints;
- numPoints = 1 + linePtr->numPoints*linePtr->splineSteps;
+ numPoints = linePtr->smooth->coordProc(canvas, (double *) NULL,
+ linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL,
+ (double *) NULL);
pointPtr = staticPoints;
if (numPoints > MAX_STATIC_POINTS) {
pointPtr = (double *) ckalloc((unsigned)
(numPoints * 2 * sizeof(double)));
}
- numPoints = TkMakeBezierCurve(canvas, linePtr->coordPtr,
+ numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr,
linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL,
pointPtr);
Tk_CanvasPsPath(interp, canvas, pointPtr, numPoints);
@@ -1524,8 +2354,6 @@ LineToPostscript(interp, canvas, itemPtr, prepass)
* Set other line-drawing parameters and stroke out the line.
*/
- sprintf(buffer, "%d setlinewidth\n", linePtr->width);
- Tcl_AppendResult(interp, buffer, (char *) NULL);
style = "0 setlinecap\n";
if (linePtr->capStyle == CapRound) {
style = "1 setlinecap\n";
@@ -1540,17 +2368,10 @@ LineToPostscript(interp, canvas, itemPtr, prepass)
style = "2 setlinejoin\n";
}
Tcl_AppendResult(interp, style, (char *) NULL);
- if (Tk_CanvasPsColor(interp, canvas, linePtr->fg) != TCL_OK) {
+
+ if (Tk_CanvasPsOutline(canvas, itemPtr,
+ &(linePtr->outline)) != TCL_OK) {
return TCL_ERROR;
- };
- if (linePtr->fillStipple != None) {
- Tcl_AppendResult(interp, "StrokeClip ", (char *) NULL);
- if (Tk_CanvasPsStipple(interp, canvas, linePtr->fillStipple)
- != TCL_OK) {
- return TCL_ERROR;
- }
- } else {
- Tcl_AppendResult(interp, "stroke\n", (char *) NULL);
}
/*
@@ -1558,7 +2379,7 @@ LineToPostscript(interp, canvas, itemPtr, prepass)
*/
if (linePtr->firstArrowPtr != NULL) {
- if (linePtr->fillStipple != None) {
+ if (stipple != None) {
Tcl_AppendResult(interp, "grestore gsave\n",
(char *) NULL);
}
@@ -1568,7 +2389,7 @@ LineToPostscript(interp, canvas, itemPtr, prepass)
}
}
if (linePtr->lastArrowPtr != NULL) {
- if (linePtr->fillStipple != None) {
+ if (stipple != None) {
Tcl_AppendResult(interp, "grestore gsave\n", (char *) NULL);
}
if (ArrowheadPostscript(interp, canvas, linePtr,
@@ -1610,10 +2431,28 @@ ArrowheadPostscript(interp, canvas, linePtr, arrowPtr)
double *arrowPtr; /* Pointer to first of five points
* describing arrowhead polygon. */
{
+ Pixmap stipple;
+ Tk_State state = linePtr->header.state;
+
+ if(state == TK_STATE_NULL) {
+ state = ((TkCanvas *)canvas)->canvas_state;
+ }
+
+ stipple = linePtr->outline.stipple;
+ if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)linePtr) {
+ if (linePtr->outline.activeStipple!=None) {
+ stipple = linePtr->outline.activeStipple;
+ }
+ } else if (state==TK_STATE_DISABLED) {
+ if (linePtr->outline.activeStipple!=None) {
+ stipple = linePtr->outline.disabledStipple;
+ }
+ }
+
Tk_CanvasPsPath(interp, canvas, arrowPtr, PTS_IN_ARROW);
- if (linePtr->fillStipple != None) {
+ if (stipple != None) {
Tcl_AppendResult(interp, "clip ", (char *) NULL);
- if (Tk_CanvasPsStipple(interp, canvas, linePtr->fillStipple)
+ if (Tk_CanvasPsStipple(interp, canvas, stipple)
!= TCL_OK) {
return TCL_ERROR;
}