1 |
/* $Header$ */ |
/* $Header$ */ |
2 |
|
|
3 |
/* |
/* |
4 |
* tkCanvLine.c -- |
* tkCanvLine.c -- |
5 |
* |
* |
6 |
* This file implements line items for canvas widgets. |
* This file implements line items for canvas widgets. |
7 |
* |
* |
8 |
* Copyright (c) 1991-1994 The Regents of the University of California. |
* Copyright (c) 1991-1994 The Regents of the University of California. |
9 |
* Copyright (c) 1994-1997 Sun Microsystems, Inc. |
* Copyright (c) 1994-1997 Sun Microsystems, Inc. |
10 |
* Copyright (c) 1998-1999 by Scriptics Corporation. |
* Copyright (c) 1998-1999 by Scriptics Corporation. |
11 |
* |
* |
12 |
* See the file "license.terms" for information on usage and redistribution |
* See the file "license.terms" for information on usage and redistribution |
13 |
* of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
* of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
14 |
* |
* |
15 |
* RCS: @(#) $Id: tkcanvline.c,v 1.1.1.1 2001/06/13 04:56:46 dtashley Exp $ |
* RCS: @(#) $Id: tkcanvline.c,v 1.1.1.1 2001/06/13 04:56:46 dtashley Exp $ |
16 |
*/ |
*/ |
17 |
|
|
18 |
#include <stdio.h> |
#include <stdio.h> |
19 |
#include "tkInt.h" |
#include "tkInt.h" |
20 |
#include "tkPort.h" |
#include "tkPort.h" |
21 |
#include "tkCanvas.h" |
#include "tkCanvas.h" |
22 |
|
|
23 |
/* |
/* |
24 |
* The structure below defines the record for each line item. |
* The structure below defines the record for each line item. |
25 |
*/ |
*/ |
26 |
|
|
27 |
typedef enum { |
typedef enum { |
28 |
ARROWS_NONE, ARROWS_FIRST, ARROWS_LAST, ARROWS_BOTH |
ARROWS_NONE, ARROWS_FIRST, ARROWS_LAST, ARROWS_BOTH |
29 |
} Arrows; |
} Arrows; |
30 |
|
|
31 |
typedef struct LineItem { |
typedef struct LineItem { |
32 |
Tk_Item header; /* Generic stuff that's the same for all |
Tk_Item header; /* Generic stuff that's the same for all |
33 |
* types. MUST BE FIRST IN STRUCTURE. */ |
* types. MUST BE FIRST IN STRUCTURE. */ |
34 |
Tk_Outline outline; /* Outline structure */ |
Tk_Outline outline; /* Outline structure */ |
35 |
Tk_Canvas canvas; /* Canvas containing item. Needed for |
Tk_Canvas canvas; /* Canvas containing item. Needed for |
36 |
* parsing arrow shapes. */ |
* parsing arrow shapes. */ |
37 |
int numPoints; /* Number of points in line (always >= 0). */ |
int numPoints; /* Number of points in line (always >= 0). */ |
38 |
double *coordPtr; /* Pointer to malloc-ed array containing |
double *coordPtr; /* Pointer to malloc-ed array containing |
39 |
* x- and y-coords of all points in line. |
* x- and y-coords of all points in line. |
40 |
* X-coords are even-valued indices, y-coords |
* X-coords are even-valued indices, y-coords |
41 |
* are corresponding odd-valued indices. If |
* are corresponding odd-valued indices. If |
42 |
* the line has arrowheads then the first |
* the line has arrowheads then the first |
43 |
* and last points have been adjusted to refer |
* and last points have been adjusted to refer |
44 |
* to the necks of the arrowheads rather than |
* to the necks of the arrowheads rather than |
45 |
* their tips. The actual endpoints are |
* their tips. The actual endpoints are |
46 |
* stored in the *firstArrowPtr and |
* stored in the *firstArrowPtr and |
47 |
* *lastArrowPtr, if they exist. */ |
* *lastArrowPtr, if they exist. */ |
48 |
int capStyle; /* Cap style for line. */ |
int capStyle; /* Cap style for line. */ |
49 |
int joinStyle; /* Join style for line. */ |
int joinStyle; /* Join style for line. */ |
50 |
GC arrowGC; /* Graphics context for drawing arrowheads. */ |
GC arrowGC; /* Graphics context for drawing arrowheads. */ |
51 |
Arrows arrow; /* Indicates whether or not to draw arrowheads: |
Arrows arrow; /* Indicates whether or not to draw arrowheads: |
52 |
* "none", "first", "last", or "both". */ |
* "none", "first", "last", or "both". */ |
53 |
float arrowShapeA; /* Distance from tip of arrowhead to center. */ |
float arrowShapeA; /* Distance from tip of arrowhead to center. */ |
54 |
float arrowShapeB; /* Distance from tip of arrowhead to trailing |
float arrowShapeB; /* Distance from tip of arrowhead to trailing |
55 |
* point, measured along shaft. */ |
* point, measured along shaft. */ |
56 |
float arrowShapeC; /* Distance of trailing points from outside |
float arrowShapeC; /* Distance of trailing points from outside |
57 |
* edge of shaft. */ |
* edge of shaft. */ |
58 |
double *firstArrowPtr; /* Points to array of PTS_IN_ARROW points |
double *firstArrowPtr; /* Points to array of PTS_IN_ARROW points |
59 |
* describing polygon for arrowhead at first |
* describing polygon for arrowhead at first |
60 |
* point in line. First point of arrowhead |
* point in line. First point of arrowhead |
61 |
* is tip. Malloc'ed. NULL means no arrowhead |
* is tip. Malloc'ed. NULL means no arrowhead |
62 |
* at first point. */ |
* at first point. */ |
63 |
double *lastArrowPtr; /* Points to polygon for arrowhead at last |
double *lastArrowPtr; /* Points to polygon for arrowhead at last |
64 |
* point in line (PTS_IN_ARROW points, first |
* point in line (PTS_IN_ARROW points, first |
65 |
* of which is tip). Malloc'ed. NULL means |
* of which is tip). Malloc'ed. NULL means |
66 |
* no arrowhead at last point. */ |
* no arrowhead at last point. */ |
67 |
Tk_SmoothMethod *smooth; /* Non-zero means draw line smoothed (i.e. |
Tk_SmoothMethod *smooth; /* Non-zero means draw line smoothed (i.e. |
68 |
* with Bezier splines). */ |
* with Bezier splines). */ |
69 |
int splineSteps; /* Number of steps in each spline segment. */ |
int splineSteps; /* Number of steps in each spline segment. */ |
70 |
} LineItem; |
} LineItem; |
71 |
|
|
72 |
/* |
/* |
73 |
* Number of points in an arrowHead: |
* Number of points in an arrowHead: |
74 |
*/ |
*/ |
75 |
|
|
76 |
#define PTS_IN_ARROW 6 |
#define PTS_IN_ARROW 6 |
77 |
|
|
78 |
/* |
/* |
79 |
* Prototypes for procedures defined in this file: |
* Prototypes for procedures defined in this file: |
80 |
*/ |
*/ |
81 |
|
|
82 |
static int ArrowheadPostscript _ANSI_ARGS_((Tcl_Interp *interp, |
static int ArrowheadPostscript _ANSI_ARGS_((Tcl_Interp *interp, |
83 |
Tk_Canvas canvas, LineItem *linePtr, |
Tk_Canvas canvas, LineItem *linePtr, |
84 |
double *arrowPtr)); |
double *arrowPtr)); |
85 |
static void ComputeLineBbox _ANSI_ARGS_((Tk_Canvas canvas, |
static void ComputeLineBbox _ANSI_ARGS_((Tk_Canvas canvas, |
86 |
LineItem *linePtr)); |
LineItem *linePtr)); |
87 |
static int ConfigureLine _ANSI_ARGS_((Tcl_Interp *interp, |
static int ConfigureLine _ANSI_ARGS_((Tcl_Interp *interp, |
88 |
Tk_Canvas canvas, Tk_Item *itemPtr, int argc, |
Tk_Canvas canvas, Tk_Item *itemPtr, int argc, |
89 |
Tcl_Obj *CONST argv[], int flags)); |
Tcl_Obj *CONST argv[], int flags)); |
90 |
static int ConfigureArrows _ANSI_ARGS_((Tk_Canvas canvas, |
static int ConfigureArrows _ANSI_ARGS_((Tk_Canvas canvas, |
91 |
LineItem *linePtr)); |
LineItem *linePtr)); |
92 |
static int CreateLine _ANSI_ARGS_((Tcl_Interp *interp, |
static int CreateLine _ANSI_ARGS_((Tcl_Interp *interp, |
93 |
Tk_Canvas canvas, struct Tk_Item *itemPtr, |
Tk_Canvas canvas, struct Tk_Item *itemPtr, |
94 |
int argc, Tcl_Obj *CONST argv[])); |
int argc, Tcl_Obj *CONST argv[])); |
95 |
static void DeleteLine _ANSI_ARGS_((Tk_Canvas canvas, |
static void DeleteLine _ANSI_ARGS_((Tk_Canvas canvas, |
96 |
Tk_Item *itemPtr, Display *display)); |
Tk_Item *itemPtr, Display *display)); |
97 |
static void DisplayLine _ANSI_ARGS_((Tk_Canvas canvas, |
static void DisplayLine _ANSI_ARGS_((Tk_Canvas canvas, |
98 |
Tk_Item *itemPtr, Display *display, Drawable dst, |
Tk_Item *itemPtr, Display *display, Drawable dst, |
99 |
int x, int y, int width, int height)); |
int x, int y, int width, int height)); |
100 |
static int GetLineIndex _ANSI_ARGS_((Tcl_Interp *interp, |
static int GetLineIndex _ANSI_ARGS_((Tcl_Interp *interp, |
101 |
Tk_Canvas canvas, Tk_Item *itemPtr, |
Tk_Canvas canvas, Tk_Item *itemPtr, |
102 |
Tcl_Obj *obj, int *indexPtr)); |
Tcl_Obj *obj, int *indexPtr)); |
103 |
static int LineCoords _ANSI_ARGS_((Tcl_Interp *interp, |
static int LineCoords _ANSI_ARGS_((Tcl_Interp *interp, |
104 |
Tk_Canvas canvas, Tk_Item *itemPtr, |
Tk_Canvas canvas, Tk_Item *itemPtr, |
105 |
int argc, Tcl_Obj *CONST argv[])); |
int argc, Tcl_Obj *CONST argv[])); |
106 |
static void LineDeleteCoords _ANSI_ARGS_((Tk_Canvas canvas, |
static void LineDeleteCoords _ANSI_ARGS_((Tk_Canvas canvas, |
107 |
Tk_Item *itemPtr, int first, int last)); |
Tk_Item *itemPtr, int first, int last)); |
108 |
static void LineInsert _ANSI_ARGS_((Tk_Canvas canvas, |
static void LineInsert _ANSI_ARGS_((Tk_Canvas canvas, |
109 |
Tk_Item *itemPtr, int beforeThis, Tcl_Obj *obj)); |
Tk_Item *itemPtr, int beforeThis, Tcl_Obj *obj)); |
110 |
static int LineToArea _ANSI_ARGS_((Tk_Canvas canvas, |
static int LineToArea _ANSI_ARGS_((Tk_Canvas canvas, |
111 |
Tk_Item *itemPtr, double *rectPtr)); |
Tk_Item *itemPtr, double *rectPtr)); |
112 |
static double LineToPoint _ANSI_ARGS_((Tk_Canvas canvas, |
static double LineToPoint _ANSI_ARGS_((Tk_Canvas canvas, |
113 |
Tk_Item *itemPtr, double *coordPtr)); |
Tk_Item *itemPtr, double *coordPtr)); |
114 |
static int LineToPostscript _ANSI_ARGS_((Tcl_Interp *interp, |
static int LineToPostscript _ANSI_ARGS_((Tcl_Interp *interp, |
115 |
Tk_Canvas canvas, Tk_Item *itemPtr, int prepass)); |
Tk_Canvas canvas, Tk_Item *itemPtr, int prepass)); |
116 |
static int ArrowParseProc _ANSI_ARGS_((ClientData clientData, |
static int ArrowParseProc _ANSI_ARGS_((ClientData clientData, |
117 |
Tcl_Interp *interp, Tk_Window tkwin, |
Tcl_Interp *interp, Tk_Window tkwin, |
118 |
CONST char *value, char *recordPtr, int offset)); |
CONST char *value, char *recordPtr, int offset)); |
119 |
static char * ArrowPrintProc _ANSI_ARGS_((ClientData clientData, |
static char * ArrowPrintProc _ANSI_ARGS_((ClientData clientData, |
120 |
Tk_Window tkwin, char *recordPtr, int offset, |
Tk_Window tkwin, char *recordPtr, int offset, |
121 |
Tcl_FreeProc **freeProcPtr)); |
Tcl_FreeProc **freeProcPtr)); |
122 |
static int ParseArrowShape _ANSI_ARGS_((ClientData clientData, |
static int ParseArrowShape _ANSI_ARGS_((ClientData clientData, |
123 |
Tcl_Interp *interp, Tk_Window tkwin, |
Tcl_Interp *interp, Tk_Window tkwin, |
124 |
CONST char *value, char *recordPtr, int offset)); |
CONST char *value, char *recordPtr, int offset)); |
125 |
static char * PrintArrowShape _ANSI_ARGS_((ClientData clientData, |
static char * PrintArrowShape _ANSI_ARGS_((ClientData clientData, |
126 |
Tk_Window tkwin, char *recordPtr, int offset, |
Tk_Window tkwin, char *recordPtr, int offset, |
127 |
Tcl_FreeProc **freeProcPtr)); |
Tcl_FreeProc **freeProcPtr)); |
128 |
static void ScaleLine _ANSI_ARGS_((Tk_Canvas canvas, |
static void ScaleLine _ANSI_ARGS_((Tk_Canvas canvas, |
129 |
Tk_Item *itemPtr, double originX, double originY, |
Tk_Item *itemPtr, double originX, double originY, |
130 |
double scaleX, double scaleY)); |
double scaleX, double scaleY)); |
131 |
static void TranslateLine _ANSI_ARGS_((Tk_Canvas canvas, |
static void TranslateLine _ANSI_ARGS_((Tk_Canvas canvas, |
132 |
Tk_Item *itemPtr, double deltaX, double deltaY)); |
Tk_Item *itemPtr, double deltaX, double deltaY)); |
133 |
|
|
134 |
/* |
/* |
135 |
* Information used for parsing configuration specs. If you change any |
* Information used for parsing configuration specs. If you change any |
136 |
* of the default strings, be sure to change the corresponding default |
* of the default strings, be sure to change the corresponding default |
137 |
* values in CreateLine. |
* values in CreateLine. |
138 |
*/ |
*/ |
139 |
|
|
140 |
static Tk_CustomOption arrowShapeOption = { |
static Tk_CustomOption arrowShapeOption = { |
141 |
(Tk_OptionParseProc *) ParseArrowShape, |
(Tk_OptionParseProc *) ParseArrowShape, |
142 |
PrintArrowShape, (ClientData) NULL |
PrintArrowShape, (ClientData) NULL |
143 |
}; |
}; |
144 |
static Tk_CustomOption arrowOption = { |
static Tk_CustomOption arrowOption = { |
145 |
(Tk_OptionParseProc *) ArrowParseProc, |
(Tk_OptionParseProc *) ArrowParseProc, |
146 |
ArrowPrintProc, (ClientData) NULL |
ArrowPrintProc, (ClientData) NULL |
147 |
}; |
}; |
148 |
static Tk_CustomOption smoothOption = { |
static Tk_CustomOption smoothOption = { |
149 |
(Tk_OptionParseProc *) TkSmoothParseProc, |
(Tk_OptionParseProc *) TkSmoothParseProc, |
150 |
TkSmoothPrintProc, (ClientData) NULL |
TkSmoothPrintProc, (ClientData) NULL |
151 |
}; |
}; |
152 |
static Tk_CustomOption stateOption = { |
static Tk_CustomOption stateOption = { |
153 |
(Tk_OptionParseProc *) TkStateParseProc, |
(Tk_OptionParseProc *) TkStateParseProc, |
154 |
TkStatePrintProc, (ClientData) 2 |
TkStatePrintProc, (ClientData) 2 |
155 |
}; |
}; |
156 |
static Tk_CustomOption tagsOption = { |
static Tk_CustomOption tagsOption = { |
157 |
(Tk_OptionParseProc *) Tk_CanvasTagsParseProc, |
(Tk_OptionParseProc *) Tk_CanvasTagsParseProc, |
158 |
Tk_CanvasTagsPrintProc, (ClientData) NULL |
Tk_CanvasTagsPrintProc, (ClientData) NULL |
159 |
}; |
}; |
160 |
static Tk_CustomOption dashOption = { |
static Tk_CustomOption dashOption = { |
161 |
(Tk_OptionParseProc *) TkCanvasDashParseProc, |
(Tk_OptionParseProc *) TkCanvasDashParseProc, |
162 |
TkCanvasDashPrintProc, (ClientData) NULL |
TkCanvasDashPrintProc, (ClientData) NULL |
163 |
}; |
}; |
164 |
static Tk_CustomOption offsetOption = { |
static Tk_CustomOption offsetOption = { |
165 |
(Tk_OptionParseProc *) TkOffsetParseProc, |
(Tk_OptionParseProc *) TkOffsetParseProc, |
166 |
TkOffsetPrintProc, |
TkOffsetPrintProc, |
167 |
(ClientData) (TK_OFFSET_RELATIVE|TK_OFFSET_INDEX) |
(ClientData) (TK_OFFSET_RELATIVE|TK_OFFSET_INDEX) |
168 |
}; |
}; |
169 |
static Tk_CustomOption pixelOption = { |
static Tk_CustomOption pixelOption = { |
170 |
(Tk_OptionParseProc *) TkPixelParseProc, |
(Tk_OptionParseProc *) TkPixelParseProc, |
171 |
TkPixelPrintProc, (ClientData) NULL |
TkPixelPrintProc, (ClientData) NULL |
172 |
}; |
}; |
173 |
|
|
174 |
static Tk_ConfigSpec configSpecs[] = { |
static Tk_ConfigSpec configSpecs[] = { |
175 |
{TK_CONFIG_CUSTOM, "-activedash", (char *) NULL, (char *) NULL, |
{TK_CONFIG_CUSTOM, "-activedash", (char *) NULL, (char *) NULL, |
176 |
(char *) NULL, Tk_Offset(LineItem, outline.activeDash), |
(char *) NULL, Tk_Offset(LineItem, outline.activeDash), |
177 |
TK_CONFIG_NULL_OK, &dashOption}, |
TK_CONFIG_NULL_OK, &dashOption}, |
178 |
{TK_CONFIG_COLOR, "-activefill", (char *) NULL, (char *) NULL, |
{TK_CONFIG_COLOR, "-activefill", (char *) NULL, (char *) NULL, |
179 |
(char *) NULL, Tk_Offset(LineItem, outline.activeColor), |
(char *) NULL, Tk_Offset(LineItem, outline.activeColor), |
180 |
TK_CONFIG_NULL_OK}, |
TK_CONFIG_NULL_OK}, |
181 |
{TK_CONFIG_BITMAP, "-activestipple", (char *) NULL, (char *) NULL, |
{TK_CONFIG_BITMAP, "-activestipple", (char *) NULL, (char *) NULL, |
182 |
(char *) NULL, Tk_Offset(LineItem, outline.activeStipple), |
(char *) NULL, Tk_Offset(LineItem, outline.activeStipple), |
183 |
TK_CONFIG_NULL_OK}, |
TK_CONFIG_NULL_OK}, |
184 |
{TK_CONFIG_CUSTOM, "-activewidth", (char *) NULL, (char *) NULL, |
{TK_CONFIG_CUSTOM, "-activewidth", (char *) NULL, (char *) NULL, |
185 |
"0.0", Tk_Offset(LineItem, outline.activeWidth), |
"0.0", Tk_Offset(LineItem, outline.activeWidth), |
186 |
TK_CONFIG_DONT_SET_DEFAULT, &pixelOption}, |
TK_CONFIG_DONT_SET_DEFAULT, &pixelOption}, |
187 |
{TK_CONFIG_CUSTOM, "-arrow", (char *) NULL, (char *) NULL, |
{TK_CONFIG_CUSTOM, "-arrow", (char *) NULL, (char *) NULL, |
188 |
"none", Tk_Offset(LineItem, arrow), TK_CONFIG_DONT_SET_DEFAULT, &arrowOption}, |
"none", Tk_Offset(LineItem, arrow), TK_CONFIG_DONT_SET_DEFAULT, &arrowOption}, |
189 |
{TK_CONFIG_CUSTOM, "-arrowshape", (char *) NULL, (char *) NULL, |
{TK_CONFIG_CUSTOM, "-arrowshape", (char *) NULL, (char *) NULL, |
190 |
"8 10 3", Tk_Offset(LineItem, arrowShapeA), |
"8 10 3", Tk_Offset(LineItem, arrowShapeA), |
191 |
TK_CONFIG_DONT_SET_DEFAULT, &arrowShapeOption}, |
TK_CONFIG_DONT_SET_DEFAULT, &arrowShapeOption}, |
192 |
{TK_CONFIG_CAP_STYLE, "-capstyle", (char *) NULL, (char *) NULL, |
{TK_CONFIG_CAP_STYLE, "-capstyle", (char *) NULL, (char *) NULL, |
193 |
"butt", Tk_Offset(LineItem, capStyle), TK_CONFIG_DONT_SET_DEFAULT}, |
"butt", Tk_Offset(LineItem, capStyle), TK_CONFIG_DONT_SET_DEFAULT}, |
194 |
{TK_CONFIG_COLOR, "-fill", (char *) NULL, (char *) NULL, |
{TK_CONFIG_COLOR, "-fill", (char *) NULL, (char *) NULL, |
195 |
"black", Tk_Offset(LineItem, outline.color), TK_CONFIG_NULL_OK}, |
"black", Tk_Offset(LineItem, outline.color), TK_CONFIG_NULL_OK}, |
196 |
{TK_CONFIG_CUSTOM, "-dash", (char *) NULL, (char *) NULL, |
{TK_CONFIG_CUSTOM, "-dash", (char *) NULL, (char *) NULL, |
197 |
(char *) NULL, Tk_Offset(LineItem, outline.dash), |
(char *) NULL, Tk_Offset(LineItem, outline.dash), |
198 |
TK_CONFIG_NULL_OK, &dashOption}, |
TK_CONFIG_NULL_OK, &dashOption}, |
199 |
{TK_CONFIG_PIXELS, "-dashoffset", (char *) NULL, (char *) NULL, |
{TK_CONFIG_PIXELS, "-dashoffset", (char *) NULL, (char *) NULL, |
200 |
"0", Tk_Offset(LineItem, outline.offset), |
"0", Tk_Offset(LineItem, outline.offset), |
201 |
TK_CONFIG_DONT_SET_DEFAULT}, |
TK_CONFIG_DONT_SET_DEFAULT}, |
202 |
{TK_CONFIG_CUSTOM, "-disableddash", (char *) NULL, (char *) NULL, |
{TK_CONFIG_CUSTOM, "-disableddash", (char *) NULL, (char *) NULL, |
203 |
(char *) NULL, Tk_Offset(LineItem, outline.disabledDash), |
(char *) NULL, Tk_Offset(LineItem, outline.disabledDash), |
204 |
TK_CONFIG_NULL_OK, &dashOption}, |
TK_CONFIG_NULL_OK, &dashOption}, |
205 |
{TK_CONFIG_COLOR, "-disabledfill", (char *) NULL, (char *) NULL, |
{TK_CONFIG_COLOR, "-disabledfill", (char *) NULL, (char *) NULL, |
206 |
(char *) NULL, Tk_Offset(LineItem, outline.disabledColor), |
(char *) NULL, Tk_Offset(LineItem, outline.disabledColor), |
207 |
TK_CONFIG_NULL_OK}, |
TK_CONFIG_NULL_OK}, |
208 |
{TK_CONFIG_BITMAP, "-disabledstipple", (char *) NULL, (char *) NULL, |
{TK_CONFIG_BITMAP, "-disabledstipple", (char *) NULL, (char *) NULL, |
209 |
(char *) NULL, Tk_Offset(LineItem, outline.disabledStipple), |
(char *) NULL, Tk_Offset(LineItem, outline.disabledStipple), |
210 |
TK_CONFIG_NULL_OK}, |
TK_CONFIG_NULL_OK}, |
211 |
{TK_CONFIG_CUSTOM, "-disabledwidth", (char *) NULL, (char *) NULL, |
{TK_CONFIG_CUSTOM, "-disabledwidth", (char *) NULL, (char *) NULL, |
212 |
"0.0", Tk_Offset(LineItem, outline.disabledWidth), |
"0.0", Tk_Offset(LineItem, outline.disabledWidth), |
213 |
TK_CONFIG_DONT_SET_DEFAULT, &pixelOption}, |
TK_CONFIG_DONT_SET_DEFAULT, &pixelOption}, |
214 |
{TK_CONFIG_JOIN_STYLE, "-joinstyle", (char *) NULL, (char *) NULL, |
{TK_CONFIG_JOIN_STYLE, "-joinstyle", (char *) NULL, (char *) NULL, |
215 |
"round", Tk_Offset(LineItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT}, |
"round", Tk_Offset(LineItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT}, |
216 |
{TK_CONFIG_CUSTOM, "-offset", (char *) NULL, (char *) NULL, |
{TK_CONFIG_CUSTOM, "-offset", (char *) NULL, (char *) NULL, |
217 |
"0,0", Tk_Offset(LineItem, outline.tsoffset), |
"0,0", Tk_Offset(LineItem, outline.tsoffset), |
218 |
TK_CONFIG_DONT_SET_DEFAULT, &offsetOption}, |
TK_CONFIG_DONT_SET_DEFAULT, &offsetOption}, |
219 |
{TK_CONFIG_CUSTOM, "-smooth", (char *) NULL, (char *) NULL, |
{TK_CONFIG_CUSTOM, "-smooth", (char *) NULL, (char *) NULL, |
220 |
"0", Tk_Offset(LineItem, smooth), |
"0", Tk_Offset(LineItem, smooth), |
221 |
TK_CONFIG_DONT_SET_DEFAULT, &smoothOption}, |
TK_CONFIG_DONT_SET_DEFAULT, &smoothOption}, |
222 |
{TK_CONFIG_INT, "-splinesteps", (char *) NULL, (char *) NULL, |
{TK_CONFIG_INT, "-splinesteps", (char *) NULL, (char *) NULL, |
223 |
"12", Tk_Offset(LineItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT}, |
"12", Tk_Offset(LineItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT}, |
224 |
{TK_CONFIG_CUSTOM, "-state", (char *) NULL, (char *) NULL, |
{TK_CONFIG_CUSTOM, "-state", (char *) NULL, (char *) NULL, |
225 |
(char *) NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, |
(char *) NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, |
226 |
&stateOption}, |
&stateOption}, |
227 |
{TK_CONFIG_BITMAP, "-stipple", (char *) NULL, (char *) NULL, |
{TK_CONFIG_BITMAP, "-stipple", (char *) NULL, (char *) NULL, |
228 |
(char *) NULL, Tk_Offset(LineItem, outline.stipple), |
(char *) NULL, Tk_Offset(LineItem, outline.stipple), |
229 |
TK_CONFIG_NULL_OK}, |
TK_CONFIG_NULL_OK}, |
230 |
{TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL, |
{TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL, |
231 |
(char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, |
(char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, |
232 |
{TK_CONFIG_CUSTOM, "-width", (char *) NULL, (char *) NULL, |
{TK_CONFIG_CUSTOM, "-width", (char *) NULL, (char *) NULL, |
233 |
"1.0", Tk_Offset(LineItem, outline.width), |
"1.0", Tk_Offset(LineItem, outline.width), |
234 |
TK_CONFIG_DONT_SET_DEFAULT, &pixelOption}, |
TK_CONFIG_DONT_SET_DEFAULT, &pixelOption}, |
235 |
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, |
{TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, |
236 |
(char *) NULL, 0, 0} |
(char *) NULL, 0, 0} |
237 |
}; |
}; |
238 |
|
|
239 |
/* |
/* |
240 |
* The structures below defines the line item type by means |
* The structures below defines the line item type by means |
241 |
* of procedures that can be invoked by generic item code. |
* of procedures that can be invoked by generic item code. |
242 |
*/ |
*/ |
243 |
|
|
244 |
Tk_ItemType tkLineType = { |
Tk_ItemType tkLineType = { |
245 |
"line", /* name */ |
"line", /* name */ |
246 |
sizeof(LineItem), /* itemSize */ |
sizeof(LineItem), /* itemSize */ |
247 |
CreateLine, /* createProc */ |
CreateLine, /* createProc */ |
248 |
configSpecs, /* configSpecs */ |
configSpecs, /* configSpecs */ |
249 |
ConfigureLine, /* configureProc */ |
ConfigureLine, /* configureProc */ |
250 |
LineCoords, /* coordProc */ |
LineCoords, /* coordProc */ |
251 |
DeleteLine, /* deleteProc */ |
DeleteLine, /* deleteProc */ |
252 |
DisplayLine, /* displayProc */ |
DisplayLine, /* displayProc */ |
253 |
TK_CONFIG_OBJS, /* flags */ |
TK_CONFIG_OBJS, /* flags */ |
254 |
LineToPoint, /* pointProc */ |
LineToPoint, /* pointProc */ |
255 |
LineToArea, /* areaProc */ |
LineToArea, /* areaProc */ |
256 |
LineToPostscript, /* postscriptProc */ |
LineToPostscript, /* postscriptProc */ |
257 |
ScaleLine, /* scaleProc */ |
ScaleLine, /* scaleProc */ |
258 |
TranslateLine, /* translateProc */ |
TranslateLine, /* translateProc */ |
259 |
(Tk_ItemIndexProc *) GetLineIndex, /* indexProc */ |
(Tk_ItemIndexProc *) GetLineIndex, /* indexProc */ |
260 |
(Tk_ItemCursorProc *) NULL, /* icursorProc */ |
(Tk_ItemCursorProc *) NULL, /* icursorProc */ |
261 |
(Tk_ItemSelectionProc *) NULL, /* selectionProc */ |
(Tk_ItemSelectionProc *) NULL, /* selectionProc */ |
262 |
(Tk_ItemInsertProc *) LineInsert, /* insertProc */ |
(Tk_ItemInsertProc *) LineInsert, /* insertProc */ |
263 |
LineDeleteCoords, /* dTextProc */ |
LineDeleteCoords, /* dTextProc */ |
264 |
(Tk_ItemType *) NULL, /* nextPtr */ |
(Tk_ItemType *) NULL, /* nextPtr */ |
265 |
}; |
}; |
266 |
|
|
267 |
/* |
/* |
268 |
* The definition below determines how large are static arrays |
* The definition below determines how large are static arrays |
269 |
* used to hold spline points (splines larger than this have to |
* used to hold spline points (splines larger than this have to |
270 |
* have their arrays malloc-ed). |
* have their arrays malloc-ed). |
271 |
*/ |
*/ |
272 |
|
|
273 |
#define MAX_STATIC_POINTS 200 |
#define MAX_STATIC_POINTS 200 |
274 |
|
|
275 |
/* |
/* |
276 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
277 |
* |
* |
278 |
* CreateLine -- |
* CreateLine -- |
279 |
* |
* |
280 |
* This procedure is invoked to create a new line item in |
* This procedure is invoked to create a new line item in |
281 |
* a canvas. |
* a canvas. |
282 |
* |
* |
283 |
* Results: |
* Results: |
284 |
* A standard Tcl return value. If an error occurred in |
* A standard Tcl return value. If an error occurred in |
285 |
* creating the item, then an error message is left in |
* creating the item, then an error message is left in |
286 |
* the interp's result; in this case itemPtr is left uninitialized, |
* the interp's result; in this case itemPtr is left uninitialized, |
287 |
* so it can be safely freed by the caller. |
* so it can be safely freed by the caller. |
288 |
* |
* |
289 |
* Side effects: |
* Side effects: |
290 |
* A new line item is created. |
* A new line item is created. |
291 |
* |
* |
292 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
293 |
*/ |
*/ |
294 |
|
|
295 |
static int |
static int |
296 |
CreateLine(interp, canvas, itemPtr, argc, argv) |
CreateLine(interp, canvas, itemPtr, argc, argv) |
297 |
Tcl_Interp *interp; /* Interpreter for error reporting. */ |
Tcl_Interp *interp; /* Interpreter for error reporting. */ |
298 |
Tk_Canvas canvas; /* Canvas to hold new item. */ |
Tk_Canvas canvas; /* Canvas to hold new item. */ |
299 |
Tk_Item *itemPtr; /* Record to hold new item; header |
Tk_Item *itemPtr; /* Record to hold new item; header |
300 |
* has been initialized by caller. */ |
* has been initialized by caller. */ |
301 |
int argc; /* Number of arguments in argv. */ |
int argc; /* Number of arguments in argv. */ |
302 |
Tcl_Obj *CONST argv[]; /* Arguments describing line. */ |
Tcl_Obj *CONST argv[]; /* Arguments describing line. */ |
303 |
{ |
{ |
304 |
LineItem *linePtr = (LineItem *) itemPtr; |
LineItem *linePtr = (LineItem *) itemPtr; |
305 |
int i; |
int i; |
306 |
|
|
307 |
/* |
/* |
308 |
* Carry out initialization that is needed to set defaults and to |
* Carry out initialization that is needed to set defaults and to |
309 |
* allow proper cleanup after errors during the the remainder of |
* allow proper cleanup after errors during the the remainder of |
310 |
* this procedure. |
* this procedure. |
311 |
*/ |
*/ |
312 |
|
|
313 |
Tk_CreateOutline(&(linePtr->outline)); |
Tk_CreateOutline(&(linePtr->outline)); |
314 |
linePtr->canvas = canvas; |
linePtr->canvas = canvas; |
315 |
linePtr->numPoints = 0; |
linePtr->numPoints = 0; |
316 |
linePtr->coordPtr = NULL; |
linePtr->coordPtr = NULL; |
317 |
linePtr->capStyle = CapButt; |
linePtr->capStyle = CapButt; |
318 |
linePtr->joinStyle = JoinRound; |
linePtr->joinStyle = JoinRound; |
319 |
linePtr->arrowGC = None; |
linePtr->arrowGC = None; |
320 |
linePtr->arrow = ARROWS_NONE; |
linePtr->arrow = ARROWS_NONE; |
321 |
linePtr->arrowShapeA = (float)8.0; |
linePtr->arrowShapeA = (float)8.0; |
322 |
linePtr->arrowShapeB = (float)10.0; |
linePtr->arrowShapeB = (float)10.0; |
323 |
linePtr->arrowShapeC = (float)3.0; |
linePtr->arrowShapeC = (float)3.0; |
324 |
linePtr->firstArrowPtr = NULL; |
linePtr->firstArrowPtr = NULL; |
325 |
linePtr->lastArrowPtr = NULL; |
linePtr->lastArrowPtr = NULL; |
326 |
linePtr->smooth = (Tk_SmoothMethod *) NULL; |
linePtr->smooth = (Tk_SmoothMethod *) NULL; |
327 |
linePtr->splineSteps = 12; |
linePtr->splineSteps = 12; |
328 |
|
|
329 |
/* |
/* |
330 |
* Count the number of points and then parse them into a point |
* Count the number of points and then parse them into a point |
331 |
* array. Leading arguments are assumed to be points if they |
* array. Leading arguments are assumed to be points if they |
332 |
* start with a digit or a minus sign followed by a digit. |
* start with a digit or a minus sign followed by a digit. |
333 |
*/ |
*/ |
334 |
|
|
335 |
for (i = 0; i < argc; i++) { |
for (i = 0; i < argc; i++) { |
336 |
char *arg = Tcl_GetStringFromObj(argv[i], NULL); |
char *arg = Tcl_GetStringFromObj(argv[i], NULL); |
337 |
if ((arg[0] == '-') && (arg[1] >= 'a') |
if ((arg[0] == '-') && (arg[1] >= 'a') |
338 |
&& (arg[1] <= 'z')) { |
&& (arg[1] <= 'z')) { |
339 |
break; |
break; |
340 |
} |
} |
341 |
} |
} |
342 |
if (i && (LineCoords(interp, canvas, itemPtr, i, argv) != TCL_OK)) { |
if (i && (LineCoords(interp, canvas, itemPtr, i, argv) != TCL_OK)) { |
343 |
goto error; |
goto error; |
344 |
} |
} |
345 |
if (ConfigureLine(interp, canvas, itemPtr, argc-i, argv+i, 0) == TCL_OK) { |
if (ConfigureLine(interp, canvas, itemPtr, argc-i, argv+i, 0) == TCL_OK) { |
346 |
return TCL_OK; |
return TCL_OK; |
347 |
} |
} |
348 |
|
|
349 |
error: |
error: |
350 |
DeleteLine(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas))); |
DeleteLine(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas))); |
351 |
return TCL_ERROR; |
return TCL_ERROR; |
352 |
} |
} |
353 |
|
|
354 |
/* |
/* |
355 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
356 |
* |
* |
357 |
* LineCoords -- |
* LineCoords -- |
358 |
* |
* |
359 |
* This procedure is invoked to process the "coords" widget |
* This procedure is invoked to process the "coords" widget |
360 |
* command on lines. See the user documentation for details |
* command on lines. See the user documentation for details |
361 |
* on what it does. |
* on what it does. |
362 |
* |
* |
363 |
* Results: |
* Results: |
364 |
* Returns TCL_OK or TCL_ERROR, and sets the interp's result. |
* Returns TCL_OK or TCL_ERROR, and sets the interp's result. |
365 |
* |
* |
366 |
* Side effects: |
* Side effects: |
367 |
* The coordinates for the given item may be changed. |
* The coordinates for the given item may be changed. |
368 |
* |
* |
369 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
370 |
*/ |
*/ |
371 |
|
|
372 |
static int |
static int |
373 |
LineCoords(interp, canvas, itemPtr, argc, argv) |
LineCoords(interp, canvas, itemPtr, argc, argv) |
374 |
Tcl_Interp *interp; /* Used for error reporting. */ |
Tcl_Interp *interp; /* Used for error reporting. */ |
375 |
Tk_Canvas canvas; /* Canvas containing item. */ |
Tk_Canvas canvas; /* Canvas containing item. */ |
376 |
Tk_Item *itemPtr; /* Item whose coordinates are to be |
Tk_Item *itemPtr; /* Item whose coordinates are to be |
377 |
* read or modified. */ |
* read or modified. */ |
378 |
int argc; /* Number of coordinates supplied in |
int argc; /* Number of coordinates supplied in |
379 |
* argv. */ |
* argv. */ |
380 |
Tcl_Obj *CONST argv[]; /* Array of coordinates: x1, y1, |
Tcl_Obj *CONST argv[]; /* Array of coordinates: x1, y1, |
381 |
* x2, y2, ... */ |
* x2, y2, ... */ |
382 |
{ |
{ |
383 |
LineItem *linePtr = (LineItem *) itemPtr; |
LineItem *linePtr = (LineItem *) itemPtr; |
384 |
int i, numPoints; |
int i, numPoints; |
385 |
double *coordPtr; |
double *coordPtr; |
386 |
|
|
387 |
if (argc == 0) { |
if (argc == 0) { |
388 |
int numCoords; |
int numCoords; |
389 |
Tcl_Obj *subobj, *obj = Tcl_NewObj(); |
Tcl_Obj *subobj, *obj = Tcl_NewObj(); |
390 |
|
|
391 |
numCoords = 2*linePtr->numPoints; |
numCoords = 2*linePtr->numPoints; |
392 |
if (linePtr->firstArrowPtr != NULL) { |
if (linePtr->firstArrowPtr != NULL) { |
393 |
coordPtr = linePtr->firstArrowPtr; |
coordPtr = linePtr->firstArrowPtr; |
394 |
} else { |
} else { |
395 |
coordPtr = linePtr->coordPtr; |
coordPtr = linePtr->coordPtr; |
396 |
} |
} |
397 |
for (i = 0; i < numCoords; i++, coordPtr++) { |
for (i = 0; i < numCoords; i++, coordPtr++) { |
398 |
if (i == 2) { |
if (i == 2) { |
399 |
coordPtr = linePtr->coordPtr+2; |
coordPtr = linePtr->coordPtr+2; |
400 |
} |
} |
401 |
if ((linePtr->lastArrowPtr != NULL) && (i == (numCoords-2))) { |
if ((linePtr->lastArrowPtr != NULL) && (i == (numCoords-2))) { |
402 |
coordPtr = linePtr->lastArrowPtr; |
coordPtr = linePtr->lastArrowPtr; |
403 |
} |
} |
404 |
subobj = Tcl_NewDoubleObj(*coordPtr); |
subobj = Tcl_NewDoubleObj(*coordPtr); |
405 |
Tcl_ListObjAppendElement(interp, obj, subobj); |
Tcl_ListObjAppendElement(interp, obj, subobj); |
406 |
} |
} |
407 |
Tcl_SetObjResult(interp, obj); |
Tcl_SetObjResult(interp, obj); |
408 |
return TCL_OK; |
return TCL_OK; |
409 |
} |
} |
410 |
if (argc == 1) { |
if (argc == 1) { |
411 |
if (Tcl_ListObjGetElements(interp, argv[0], &argc, |
if (Tcl_ListObjGetElements(interp, argv[0], &argc, |
412 |
(Tcl_Obj ***) &argv) != TCL_OK) { |
(Tcl_Obj ***) &argv) != TCL_OK) { |
413 |
return TCL_ERROR; |
return TCL_ERROR; |
414 |
} |
} |
415 |
} |
} |
416 |
if (argc & 1) { |
if (argc & 1) { |
417 |
Tcl_AppendResult(interp, |
Tcl_AppendResult(interp, |
418 |
"odd number of coordinates specified for line", |
"odd number of coordinates specified for line", |
419 |
(char *) NULL); |
(char *) NULL); |
420 |
return TCL_ERROR; |
return TCL_ERROR; |
421 |
} else if (argc < 4) { |
} else if (argc < 4) { |
422 |
Tcl_AppendResult(interp, |
Tcl_AppendResult(interp, |
423 |
"too few coordinates specified for line", |
"too few coordinates specified for line", |
424 |
(char *) NULL); |
(char *) NULL); |
425 |
return TCL_ERROR; |
return TCL_ERROR; |
426 |
} else { |
} else { |
427 |
numPoints = argc/2; |
numPoints = argc/2; |
428 |
if (linePtr->numPoints != numPoints) { |
if (linePtr->numPoints != numPoints) { |
429 |
coordPtr = (double *) ckalloc((unsigned) |
coordPtr = (double *) ckalloc((unsigned) |
430 |
(sizeof(double) * argc)); |
(sizeof(double) * argc)); |
431 |
if (linePtr->coordPtr != NULL) { |
if (linePtr->coordPtr != NULL) { |
432 |
ckfree((char *) linePtr->coordPtr); |
ckfree((char *) linePtr->coordPtr); |
433 |
} |
} |
434 |
linePtr->coordPtr = coordPtr; |
linePtr->coordPtr = coordPtr; |
435 |
linePtr->numPoints = numPoints; |
linePtr->numPoints = numPoints; |
436 |
} |
} |
437 |
coordPtr = linePtr->coordPtr; |
coordPtr = linePtr->coordPtr; |
438 |
for (i = 0; i <argc; i++) { |
for (i = 0; i <argc; i++) { |
439 |
if (Tk_CanvasGetCoordFromObj(interp, canvas, argv[i], |
if (Tk_CanvasGetCoordFromObj(interp, canvas, argv[i], |
440 |
coordPtr++) != TCL_OK) { |
coordPtr++) != TCL_OK) { |
441 |
return TCL_ERROR; |
return TCL_ERROR; |
442 |
} |
} |
443 |
} |
} |
444 |
|
|
445 |
/* |
/* |
446 |
* Update arrowheads by throwing away any existing arrow-head |
* Update arrowheads by throwing away any existing arrow-head |
447 |
* information and calling ConfigureArrows to recompute it. |
* information and calling ConfigureArrows to recompute it. |
448 |
*/ |
*/ |
449 |
|
|
450 |
if (linePtr->firstArrowPtr != NULL) { |
if (linePtr->firstArrowPtr != NULL) { |
451 |
ckfree((char *) linePtr->firstArrowPtr); |
ckfree((char *) linePtr->firstArrowPtr); |
452 |
linePtr->firstArrowPtr = NULL; |
linePtr->firstArrowPtr = NULL; |
453 |
} |
} |
454 |
if (linePtr->lastArrowPtr != NULL) { |
if (linePtr->lastArrowPtr != NULL) { |
455 |
ckfree((char *) linePtr->lastArrowPtr); |
ckfree((char *) linePtr->lastArrowPtr); |
456 |
linePtr->lastArrowPtr = NULL; |
linePtr->lastArrowPtr = NULL; |
457 |
} |
} |
458 |
if (linePtr->arrow != ARROWS_NONE) { |
if (linePtr->arrow != ARROWS_NONE) { |
459 |
ConfigureArrows(canvas, linePtr); |
ConfigureArrows(canvas, linePtr); |
460 |
} |
} |
461 |
ComputeLineBbox(canvas, linePtr); |
ComputeLineBbox(canvas, linePtr); |
462 |
} |
} |
463 |
return TCL_OK; |
return TCL_OK; |
464 |
} |
} |
465 |
|
|
466 |
/* |
/* |
467 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
468 |
* |
* |
469 |
* ConfigureLine -- |
* ConfigureLine -- |
470 |
* |
* |
471 |
* This procedure is invoked to configure various aspects |
* This procedure is invoked to configure various aspects |
472 |
* of a line item such as its background color. |
* of a line item such as its background color. |
473 |
* |
* |
474 |
* Results: |
* Results: |
475 |
* A standard Tcl result code. If an error occurs, then |
* A standard Tcl result code. If an error occurs, then |
476 |
* an error message is left in the interp's result. |
* an error message is left in the interp's result. |
477 |
* |
* |
478 |
* Side effects: |
* Side effects: |
479 |
* Configuration information, such as colors and stipple |
* Configuration information, such as colors and stipple |
480 |
* patterns, may be set for itemPtr. |
* patterns, may be set for itemPtr. |
481 |
* |
* |
482 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
483 |
*/ |
*/ |
484 |
|
|
485 |
static int |
static int |
486 |
ConfigureLine(interp, canvas, itemPtr, argc, argv, flags) |
ConfigureLine(interp, canvas, itemPtr, argc, argv, flags) |
487 |
Tcl_Interp *interp; /* Used for error reporting. */ |
Tcl_Interp *interp; /* Used for error reporting. */ |
488 |
Tk_Canvas canvas; /* Canvas containing itemPtr. */ |
Tk_Canvas canvas; /* Canvas containing itemPtr. */ |
489 |
Tk_Item *itemPtr; /* Line item to reconfigure. */ |
Tk_Item *itemPtr; /* Line item to reconfigure. */ |
490 |
int argc; /* Number of elements in argv. */ |
int argc; /* Number of elements in argv. */ |
491 |
Tcl_Obj *CONST argv[]; /* Arguments describing things to configure. */ |
Tcl_Obj *CONST argv[]; /* Arguments describing things to configure. */ |
492 |
int flags; /* Flags to pass to Tk_ConfigureWidget. */ |
int flags; /* Flags to pass to Tk_ConfigureWidget. */ |
493 |
{ |
{ |
494 |
LineItem *linePtr = (LineItem *) itemPtr; |
LineItem *linePtr = (LineItem *) itemPtr; |
495 |
XGCValues gcValues; |
XGCValues gcValues; |
496 |
GC newGC, arrowGC; |
GC newGC, arrowGC; |
497 |
unsigned long mask; |
unsigned long mask; |
498 |
Tk_Window tkwin; |
Tk_Window tkwin; |
499 |
Tk_State state; |
Tk_State state; |
500 |
|
|
501 |
tkwin = Tk_CanvasTkwin(canvas); |
tkwin = Tk_CanvasTkwin(canvas); |
502 |
if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, (char **) argv, |
if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, (char **) argv, |
503 |
(char *) linePtr, flags|TK_CONFIG_OBJS) != TCL_OK) { |
(char *) linePtr, flags|TK_CONFIG_OBJS) != TCL_OK) { |
504 |
return TCL_ERROR; |
return TCL_ERROR; |
505 |
} |
} |
506 |
|
|
507 |
/* |
/* |
508 |
* A few of the options require additional processing, such as |
* A few of the options require additional processing, such as |
509 |
* graphics contexts. |
* graphics contexts. |
510 |
*/ |
*/ |
511 |
|
|
512 |
state = itemPtr->state; |
state = itemPtr->state; |
513 |
|
|
514 |
if(state == TK_STATE_NULL) { |
if(state == TK_STATE_NULL) { |
515 |
state = ((TkCanvas *)canvas)->canvas_state; |
state = ((TkCanvas *)canvas)->canvas_state; |
516 |
} |
} |
517 |
|
|
518 |
if (linePtr->outline.activeWidth > linePtr->outline.width || |
if (linePtr->outline.activeWidth > linePtr->outline.width || |
519 |
linePtr->outline.activeDash.number != 0 || |
linePtr->outline.activeDash.number != 0 || |
520 |
linePtr->outline.activeColor != NULL || |
linePtr->outline.activeColor != NULL || |
521 |
linePtr->outline.activeStipple != None) { |
linePtr->outline.activeStipple != None) { |
522 |
itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT; |
itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT; |
523 |
} else { |
} else { |
524 |
itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT; |
itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT; |
525 |
} |
} |
526 |
mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, |
mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, |
527 |
&(linePtr->outline)); |
&(linePtr->outline)); |
528 |
if (mask) { |
if (mask) { |
529 |
if (linePtr->arrow == ARROWS_NONE) { |
if (linePtr->arrow == ARROWS_NONE) { |
530 |
gcValues.cap_style = linePtr->capStyle; |
gcValues.cap_style = linePtr->capStyle; |
531 |
mask |= GCCapStyle; |
mask |= GCCapStyle; |
532 |
} |
} |
533 |
gcValues.join_style = linePtr->joinStyle; |
gcValues.join_style = linePtr->joinStyle; |
534 |
mask |= GCJoinStyle; |
mask |= GCJoinStyle; |
535 |
newGC = Tk_GetGC(tkwin, mask, &gcValues); |
newGC = Tk_GetGC(tkwin, mask, &gcValues); |
536 |
gcValues.line_width = 0; |
gcValues.line_width = 0; |
537 |
arrowGC = Tk_GetGC(tkwin, mask, &gcValues); |
arrowGC = Tk_GetGC(tkwin, mask, &gcValues); |
538 |
} else { |
} else { |
539 |
newGC = arrowGC = None; |
newGC = arrowGC = None; |
540 |
} |
} |
541 |
if (linePtr->outline.gc != None) { |
if (linePtr->outline.gc != None) { |
542 |
Tk_FreeGC(Tk_Display(tkwin), linePtr->outline.gc); |
Tk_FreeGC(Tk_Display(tkwin), linePtr->outline.gc); |
543 |
} |
} |
544 |
if (linePtr->arrowGC != None) { |
if (linePtr->arrowGC != None) { |
545 |
Tk_FreeGC(Tk_Display(tkwin), linePtr->arrowGC); |
Tk_FreeGC(Tk_Display(tkwin), linePtr->arrowGC); |
546 |
} |
} |
547 |
linePtr->outline.gc = newGC; |
linePtr->outline.gc = newGC; |
548 |
linePtr->arrowGC = arrowGC; |
linePtr->arrowGC = arrowGC; |
549 |
|
|
550 |
/* |
/* |
551 |
* Keep spline parameters within reasonable limits. |
* Keep spline parameters within reasonable limits. |
552 |
*/ |
*/ |
553 |
|
|
554 |
if (linePtr->splineSteps < 1) { |
if (linePtr->splineSteps < 1) { |
555 |
linePtr->splineSteps = 1; |
linePtr->splineSteps = 1; |
556 |
} else if (linePtr->splineSteps > 100) { |
} else if (linePtr->splineSteps > 100) { |
557 |
linePtr->splineSteps = 100; |
linePtr->splineSteps = 100; |
558 |
} |
} |
559 |
|
|
560 |
if ((!linePtr->numPoints) || (state==TK_STATE_HIDDEN)) { |
if ((!linePtr->numPoints) || (state==TK_STATE_HIDDEN)) { |
561 |
ComputeLineBbox(canvas, linePtr); |
ComputeLineBbox(canvas, linePtr); |
562 |
return TCL_OK; |
return TCL_OK; |
563 |
} |
} |
564 |
|
|
565 |
/* |
/* |
566 |
* Setup arrowheads, if needed. If arrowheads are turned off, |
* Setup arrowheads, if needed. If arrowheads are turned off, |
567 |
* restore the line's endpoints (they were shortened when the |
* restore the line's endpoints (they were shortened when the |
568 |
* arrowheads were added). |
* arrowheads were added). |
569 |
*/ |
*/ |
570 |
|
|
571 |
if ((linePtr->firstArrowPtr != NULL) && (linePtr->arrow != ARROWS_FIRST) |
if ((linePtr->firstArrowPtr != NULL) && (linePtr->arrow != ARROWS_FIRST) |
572 |
&& (linePtr->arrow != ARROWS_BOTH)) { |
&& (linePtr->arrow != ARROWS_BOTH)) { |
573 |
linePtr->coordPtr[0] = linePtr->firstArrowPtr[0]; |
linePtr->coordPtr[0] = linePtr->firstArrowPtr[0]; |
574 |
linePtr->coordPtr[1] = linePtr->firstArrowPtr[1]; |
linePtr->coordPtr[1] = linePtr->firstArrowPtr[1]; |
575 |
ckfree((char *) linePtr->firstArrowPtr); |
ckfree((char *) linePtr->firstArrowPtr); |
576 |
linePtr->firstArrowPtr = NULL; |
linePtr->firstArrowPtr = NULL; |
577 |
} |
} |
578 |
if ((linePtr->lastArrowPtr != NULL) && (linePtr->arrow != ARROWS_LAST) |
if ((linePtr->lastArrowPtr != NULL) && (linePtr->arrow != ARROWS_LAST) |
579 |
&& (linePtr->arrow != ARROWS_BOTH)) { |
&& (linePtr->arrow != ARROWS_BOTH)) { |
580 |
int i; |
int i; |
581 |
|
|
582 |
i = 2*(linePtr->numPoints-1); |
i = 2*(linePtr->numPoints-1); |
583 |
linePtr->coordPtr[i] = linePtr->lastArrowPtr[0]; |
linePtr->coordPtr[i] = linePtr->lastArrowPtr[0]; |
584 |
linePtr->coordPtr[i+1] = linePtr->lastArrowPtr[1]; |
linePtr->coordPtr[i+1] = linePtr->lastArrowPtr[1]; |
585 |
ckfree((char *) linePtr->lastArrowPtr); |
ckfree((char *) linePtr->lastArrowPtr); |
586 |
linePtr->lastArrowPtr = NULL; |
linePtr->lastArrowPtr = NULL; |
587 |
} |
} |
588 |
if (linePtr->arrow != ARROWS_NONE) { |
if (linePtr->arrow != ARROWS_NONE) { |
589 |
ConfigureArrows(canvas, linePtr); |
ConfigureArrows(canvas, linePtr); |
590 |
} |
} |
591 |
|
|
592 |
/* |
/* |
593 |
* Recompute bounding box for line. |
* Recompute bounding box for line. |
594 |
*/ |
*/ |
595 |
|
|
596 |
ComputeLineBbox(canvas, linePtr); |
ComputeLineBbox(canvas, linePtr); |
597 |
|
|
598 |
return TCL_OK; |
return TCL_OK; |
599 |
} |
} |
600 |
|
|
601 |
/* |
/* |
602 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
603 |
* |
* |
604 |
* DeleteLine -- |
* DeleteLine -- |
605 |
* |
* |
606 |
* This procedure is called to clean up the data structure |
* This procedure is called to clean up the data structure |
607 |
* associated with a line item. |
* associated with a line item. |
608 |
* |
* |
609 |
* Results: |
* Results: |
610 |
* None. |
* None. |
611 |
* |
* |
612 |
* Side effects: |
* Side effects: |
613 |
* Resources associated with itemPtr are released. |
* Resources associated with itemPtr are released. |
614 |
* |
* |
615 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
616 |
*/ |
*/ |
617 |
|
|
618 |
static void |
static void |
619 |
DeleteLine(canvas, itemPtr, display) |
DeleteLine(canvas, itemPtr, display) |
620 |
Tk_Canvas canvas; /* Info about overall canvas widget. */ |
Tk_Canvas canvas; /* Info about overall canvas widget. */ |
621 |
Tk_Item *itemPtr; /* Item that is being deleted. */ |
Tk_Item *itemPtr; /* Item that is being deleted. */ |
622 |
Display *display; /* Display containing window for |
Display *display; /* Display containing window for |
623 |
* canvas. */ |
* canvas. */ |
624 |
{ |
{ |
625 |
LineItem *linePtr = (LineItem *) itemPtr; |
LineItem *linePtr = (LineItem *) itemPtr; |
626 |
|
|
627 |
Tk_DeleteOutline(display, &(linePtr->outline)); |
Tk_DeleteOutline(display, &(linePtr->outline)); |
628 |
if (linePtr->coordPtr != NULL) { |
if (linePtr->coordPtr != NULL) { |
629 |
ckfree((char *) linePtr->coordPtr); |
ckfree((char *) linePtr->coordPtr); |
630 |
} |
} |
631 |
if (linePtr->arrowGC != None) { |
if (linePtr->arrowGC != None) { |
632 |
Tk_FreeGC(display, linePtr->arrowGC); |
Tk_FreeGC(display, linePtr->arrowGC); |
633 |
} |
} |
634 |
if (linePtr->firstArrowPtr != NULL) { |
if (linePtr->firstArrowPtr != NULL) { |
635 |
ckfree((char *) linePtr->firstArrowPtr); |
ckfree((char *) linePtr->firstArrowPtr); |
636 |
} |
} |
637 |
if (linePtr->lastArrowPtr != NULL) { |
if (linePtr->lastArrowPtr != NULL) { |
638 |
ckfree((char *) linePtr->lastArrowPtr); |
ckfree((char *) linePtr->lastArrowPtr); |
639 |
} |
} |
640 |
} |
} |
641 |
|
|
642 |
/* |
/* |
643 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
644 |
* |
* |
645 |
* ComputeLineBbox -- |
* ComputeLineBbox -- |
646 |
* |
* |
647 |
* This procedure is invoked to compute the bounding box of |
* This procedure is invoked to compute the bounding box of |
648 |
* all the pixels that may be drawn as part of a line. |
* all the pixels that may be drawn as part of a line. |
649 |
* |
* |
650 |
* Results: |
* Results: |
651 |
* None. |
* None. |
652 |
* |
* |
653 |
* Side effects: |
* Side effects: |
654 |
* The fields x1, y1, x2, and y2 are updated in the header |
* The fields x1, y1, x2, and y2 are updated in the header |
655 |
* for itemPtr. |
* for itemPtr. |
656 |
* |
* |
657 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
658 |
*/ |
*/ |
659 |
|
|
660 |
static void |
static void |
661 |
ComputeLineBbox(canvas, linePtr) |
ComputeLineBbox(canvas, linePtr) |
662 |
Tk_Canvas canvas; /* Canvas that contains item. */ |
Tk_Canvas canvas; /* Canvas that contains item. */ |
663 |
LineItem *linePtr; /* Item whose bbos is to be |
LineItem *linePtr; /* Item whose bbos is to be |
664 |
* recomputed. */ |
* recomputed. */ |
665 |
{ |
{ |
666 |
double *coordPtr; |
double *coordPtr; |
667 |
int i, intWidth; |
int i, intWidth; |
668 |
double width; |
double width; |
669 |
Tk_State state = linePtr->header.state; |
Tk_State state = linePtr->header.state; |
670 |
Tk_TSOffset *tsoffset; |
Tk_TSOffset *tsoffset; |
671 |
|
|
672 |
if(state == TK_STATE_NULL) { |
if(state == TK_STATE_NULL) { |
673 |
state = ((TkCanvas *)canvas)->canvas_state; |
state = ((TkCanvas *)canvas)->canvas_state; |
674 |
} |
} |
675 |
|
|
676 |
if (!(linePtr->numPoints) || (state==TK_STATE_HIDDEN)) { |
if (!(linePtr->numPoints) || (state==TK_STATE_HIDDEN)) { |
677 |
linePtr->header.x1 = -1; |
linePtr->header.x1 = -1; |
678 |
linePtr->header.x2 = -1; |
linePtr->header.x2 = -1; |
679 |
linePtr->header.y1 = -1; |
linePtr->header.y1 = -1; |
680 |
linePtr->header.y2 = -1; |
linePtr->header.y2 = -1; |
681 |
return; |
return; |
682 |
} |
} |
683 |
|
|
684 |
width = linePtr->outline.width; |
width = linePtr->outline.width; |
685 |
if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)linePtr) { |
if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)linePtr) { |
686 |
if (linePtr->outline.activeWidth>width) { |
if (linePtr->outline.activeWidth>width) { |
687 |
width = linePtr->outline.activeWidth; |
width = linePtr->outline.activeWidth; |
688 |
} |
} |
689 |
} else if (state==TK_STATE_DISABLED) { |
} else if (state==TK_STATE_DISABLED) { |
690 |
if (linePtr->outline.disabledWidth>0) { |
if (linePtr->outline.disabledWidth>0) { |
691 |
width = linePtr->outline.disabledWidth; |
width = linePtr->outline.disabledWidth; |
692 |
} |
} |
693 |
} |
} |
694 |
|
|
695 |
coordPtr = linePtr->coordPtr; |
coordPtr = linePtr->coordPtr; |
696 |
linePtr->header.x1 = linePtr->header.x2 = (int) *coordPtr; |
linePtr->header.x1 = linePtr->header.x2 = (int) *coordPtr; |
697 |
linePtr->header.y1 = linePtr->header.y2 = (int) coordPtr[1]; |
linePtr->header.y1 = linePtr->header.y2 = (int) coordPtr[1]; |
698 |
|
|
699 |
/* |
/* |
700 |
* Compute the bounding box of all the points in the line, |
* Compute the bounding box of all the points in the line, |
701 |
* then expand in all directions by the line's width to take |
* then expand in all directions by the line's width to take |
702 |
* care of butting or rounded corners and projecting or |
* care of butting or rounded corners and projecting or |
703 |
* rounded caps. This expansion is an overestimate (worst-case |
* rounded caps. This expansion is an overestimate (worst-case |
704 |
* is square root of two over two) but it's simple. Don't do |
* is square root of two over two) but it's simple. Don't do |
705 |
* anything special for curves. This causes an additional |
* anything special for curves. This causes an additional |
706 |
* overestimate in the bounding box, but is faster. |
* overestimate in the bounding box, but is faster. |
707 |
*/ |
*/ |
708 |
|
|
709 |
for (i = 1, coordPtr = linePtr->coordPtr+2; i < linePtr->numPoints; |
for (i = 1, coordPtr = linePtr->coordPtr+2; i < linePtr->numPoints; |
710 |
i++, coordPtr += 2) { |
i++, coordPtr += 2) { |
711 |
TkIncludePoint((Tk_Item *) linePtr, coordPtr); |
TkIncludePoint((Tk_Item *) linePtr, coordPtr); |
712 |
} |
} |
713 |
width = linePtr->outline.width; |
width = linePtr->outline.width; |
714 |
if (width < 1.0) { |
if (width < 1.0) { |
715 |
width = 1.0; |
width = 1.0; |
716 |
} |
} |
717 |
if (linePtr->arrow != ARROWS_NONE) { |
if (linePtr->arrow != ARROWS_NONE) { |
718 |
if (linePtr->arrow != ARROWS_LAST) { |
if (linePtr->arrow != ARROWS_LAST) { |
719 |
TkIncludePoint((Tk_Item *) linePtr, linePtr->firstArrowPtr); |
TkIncludePoint((Tk_Item *) linePtr, linePtr->firstArrowPtr); |
720 |
} |
} |
721 |
if (linePtr->arrow != ARROWS_FIRST) { |
if (linePtr->arrow != ARROWS_FIRST) { |
722 |
TkIncludePoint((Tk_Item *) linePtr, linePtr->lastArrowPtr); |
TkIncludePoint((Tk_Item *) linePtr, linePtr->lastArrowPtr); |
723 |
} |
} |
724 |
} |
} |
725 |
|
|
726 |
tsoffset = &linePtr->outline.tsoffset; |
tsoffset = &linePtr->outline.tsoffset; |
727 |
if (tsoffset->flags & TK_OFFSET_INDEX) { |
if (tsoffset->flags & TK_OFFSET_INDEX) { |
728 |
double *coordPtr = linePtr->coordPtr + (tsoffset->flags & ~TK_OFFSET_INDEX); |
double *coordPtr = linePtr->coordPtr + (tsoffset->flags & ~TK_OFFSET_INDEX); |
729 |
if (tsoffset->flags <= 0) { |
if (tsoffset->flags <= 0) { |
730 |
coordPtr = linePtr->coordPtr; |
coordPtr = linePtr->coordPtr; |
731 |
if ((linePtr->arrow == ARROWS_FIRST) || (linePtr->arrow == ARROWS_BOTH)) { |
if ((linePtr->arrow == ARROWS_FIRST) || (linePtr->arrow == ARROWS_BOTH)) { |
732 |
coordPtr = linePtr->firstArrowPtr; |
coordPtr = linePtr->firstArrowPtr; |
733 |
} |
} |
734 |
} |
} |
735 |
if (tsoffset->flags > (linePtr->numPoints * 2)) { |
if (tsoffset->flags > (linePtr->numPoints * 2)) { |
736 |
coordPtr = linePtr->coordPtr + (linePtr->numPoints * 2); |
coordPtr = linePtr->coordPtr + (linePtr->numPoints * 2); |
737 |
if ((linePtr->arrow == ARROWS_LAST) || (linePtr->arrow == ARROWS_BOTH)) { |
if ((linePtr->arrow == ARROWS_LAST) || (linePtr->arrow == ARROWS_BOTH)) { |
738 |
coordPtr = linePtr->lastArrowPtr; |
coordPtr = linePtr->lastArrowPtr; |
739 |
} |
} |
740 |
} |
} |
741 |
tsoffset->xoffset = (int) (coordPtr[0] + 0.5); |
tsoffset->xoffset = (int) (coordPtr[0] + 0.5); |
742 |
tsoffset->yoffset = (int) (coordPtr[1] + 0.5); |
tsoffset->yoffset = (int) (coordPtr[1] + 0.5); |
743 |
} else { |
} else { |
744 |
if (tsoffset->flags & TK_OFFSET_LEFT) { |
if (tsoffset->flags & TK_OFFSET_LEFT) { |
745 |
tsoffset->xoffset = linePtr->header.x1; |
tsoffset->xoffset = linePtr->header.x1; |
746 |
} else if (tsoffset->flags & TK_OFFSET_CENTER) { |
} else if (tsoffset->flags & TK_OFFSET_CENTER) { |
747 |
tsoffset->xoffset = (linePtr->header.x1 + linePtr->header.x2)/2; |
tsoffset->xoffset = (linePtr->header.x1 + linePtr->header.x2)/2; |
748 |
} else if (tsoffset->flags & TK_OFFSET_RIGHT) { |
} else if (tsoffset->flags & TK_OFFSET_RIGHT) { |
749 |
tsoffset->xoffset = linePtr->header.x2; |
tsoffset->xoffset = linePtr->header.x2; |
750 |
} |
} |
751 |
if (tsoffset->flags & TK_OFFSET_TOP) { |
if (tsoffset->flags & TK_OFFSET_TOP) { |
752 |
tsoffset->yoffset = linePtr->header.y1; |
tsoffset->yoffset = linePtr->header.y1; |
753 |
} else if (tsoffset->flags & TK_OFFSET_MIDDLE) { |
} else if (tsoffset->flags & TK_OFFSET_MIDDLE) { |
754 |
tsoffset->yoffset = (linePtr->header.y1 + linePtr->header.y2)/2; |
tsoffset->yoffset = (linePtr->header.y1 + linePtr->header.y2)/2; |
755 |
} else if (tsoffset->flags & TK_OFFSET_BOTTOM) { |
} else if (tsoffset->flags & TK_OFFSET_BOTTOM) { |
756 |
tsoffset->yoffset = linePtr->header.y2; |
tsoffset->yoffset = linePtr->header.y2; |
757 |
} |
} |
758 |
} |
} |
759 |
|
|
760 |
intWidth = (int) (width + 0.5); |
intWidth = (int) (width + 0.5); |
761 |
linePtr->header.x1 -= intWidth; |
linePtr->header.x1 -= intWidth; |
762 |
linePtr->header.x2 += intWidth; |
linePtr->header.x2 += intWidth; |
763 |
linePtr->header.y1 -= intWidth; |
linePtr->header.y1 -= intWidth; |
764 |
linePtr->header.y2 += intWidth; |
linePtr->header.y2 += intWidth; |
765 |
|
|
766 |
if (linePtr->numPoints==1) { |
if (linePtr->numPoints==1) { |
767 |
linePtr->header.x1 -= 1; |
linePtr->header.x1 -= 1; |
768 |
linePtr->header.x2 += 1; |
linePtr->header.x2 += 1; |
769 |
linePtr->header.y1 -= 1; |
linePtr->header.y1 -= 1; |
770 |
linePtr->header.y2 += 1; |
linePtr->header.y2 += 1; |
771 |
return; |
return; |
772 |
} |
} |
773 |
|
|
774 |
/* |
/* |
775 |
* For mitered lines, make a second pass through all the points. |
* For mitered lines, make a second pass through all the points. |
776 |
* Compute the locations of the two miter vertex points and add |
* Compute the locations of the two miter vertex points and add |
777 |
* those into the bounding box. |
* those into the bounding box. |
778 |
*/ |
*/ |
779 |
|
|
780 |
if (linePtr->joinStyle == JoinMiter) { |
if (linePtr->joinStyle == JoinMiter) { |
781 |
for (i = linePtr->numPoints, coordPtr = linePtr->coordPtr; i >= 3; |
for (i = linePtr->numPoints, coordPtr = linePtr->coordPtr; i >= 3; |
782 |
i--, coordPtr += 2) { |
i--, coordPtr += 2) { |
783 |
double miter[4]; |
double miter[4]; |
784 |
int j; |
int j; |
785 |
|
|
786 |
if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4, |
if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4, |
787 |
width, miter, miter+2)) { |
width, miter, miter+2)) { |
788 |
for (j = 0; j < 4; j += 2) { |
for (j = 0; j < 4; j += 2) { |
789 |
TkIncludePoint((Tk_Item *) linePtr, miter+j); |
TkIncludePoint((Tk_Item *) linePtr, miter+j); |
790 |
} |
} |
791 |
} |
} |
792 |
} |
} |
793 |
} |
} |
794 |
|
|
795 |
/* |
/* |
796 |
* Add in the sizes of arrowheads, if any. |
* Add in the sizes of arrowheads, if any. |
797 |
*/ |
*/ |
798 |
|
|
799 |
if (linePtr->arrow != ARROWS_NONE) { |
if (linePtr->arrow != ARROWS_NONE) { |
800 |
if (linePtr->arrow != ARROWS_LAST) { |
if (linePtr->arrow != ARROWS_LAST) { |
801 |
for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW; |
for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW; |
802 |
i++, coordPtr += 2) { |
i++, coordPtr += 2) { |
803 |
TkIncludePoint((Tk_Item *) linePtr, coordPtr); |
TkIncludePoint((Tk_Item *) linePtr, coordPtr); |
804 |
} |
} |
805 |
} |
} |
806 |
if (linePtr->arrow != ARROWS_FIRST) { |
if (linePtr->arrow != ARROWS_FIRST) { |
807 |
for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW; |
for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW; |
808 |
i++, coordPtr += 2) { |
i++, coordPtr += 2) { |
809 |
TkIncludePoint((Tk_Item *) linePtr, coordPtr); |
TkIncludePoint((Tk_Item *) linePtr, coordPtr); |
810 |
} |
} |
811 |
} |
} |
812 |
} |
} |
813 |
|
|
814 |
/* |
/* |
815 |
* Add one more pixel of fudge factor just to be safe (e.g. |
* Add one more pixel of fudge factor just to be safe (e.g. |
816 |
* X may round differently than we do). |
* X may round differently than we do). |
817 |
*/ |
*/ |
818 |
|
|
819 |
linePtr->header.x1 -= 1; |
linePtr->header.x1 -= 1; |
820 |
linePtr->header.x2 += 1; |
linePtr->header.x2 += 1; |
821 |
linePtr->header.y1 -= 1; |
linePtr->header.y1 -= 1; |
822 |
linePtr->header.y2 += 1; |
linePtr->header.y2 += 1; |
823 |
} |
} |
824 |
|
|
825 |
/* |
/* |
826 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
827 |
* |
* |
828 |
* DisplayLine -- |
* DisplayLine -- |
829 |
* |
* |
830 |
* This procedure is invoked to draw a line item in a given |
* This procedure is invoked to draw a line item in a given |
831 |
* drawable. |
* drawable. |
832 |
* |
* |
833 |
* Results: |
* Results: |
834 |
* None. |
* None. |
835 |
* |
* |
836 |
* Side effects: |
* Side effects: |
837 |
* ItemPtr is drawn in drawable using the transformation |
* ItemPtr is drawn in drawable using the transformation |
838 |
* information in canvas. |
* information in canvas. |
839 |
* |
* |
840 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
841 |
*/ |
*/ |
842 |
|
|
843 |
static void |
static void |
844 |
DisplayLine(canvas, itemPtr, display, drawable, x, y, width, height) |
DisplayLine(canvas, itemPtr, display, drawable, x, y, width, height) |
845 |
Tk_Canvas canvas; /* Canvas that contains item. */ |
Tk_Canvas canvas; /* Canvas that contains item. */ |
846 |
Tk_Item *itemPtr; /* Item to be displayed. */ |
Tk_Item *itemPtr; /* Item to be displayed. */ |
847 |
Display *display; /* Display on which to draw item. */ |
Display *display; /* Display on which to draw item. */ |
848 |
Drawable drawable; /* Pixmap or window in which to draw |
Drawable drawable; /* Pixmap or window in which to draw |
849 |
* item. */ |
* item. */ |
850 |
int x, y, width, height; /* Describes region of canvas that |
int x, y, width, height; /* Describes region of canvas that |
851 |
* must be redisplayed (not used). */ |
* must be redisplayed (not used). */ |
852 |
{ |
{ |
853 |
LineItem *linePtr = (LineItem *) itemPtr; |
LineItem *linePtr = (LineItem *) itemPtr; |
854 |
XPoint staticPoints[MAX_STATIC_POINTS]; |
XPoint staticPoints[MAX_STATIC_POINTS]; |
855 |
XPoint *pointPtr; |
XPoint *pointPtr; |
856 |
XPoint *pPtr; |
XPoint *pPtr; |
857 |
double *coordPtr, linewidth; |
double *coordPtr, linewidth; |
858 |
int i, numPoints; |
int i, numPoints; |
859 |
Tk_State state = itemPtr->state; |
Tk_State state = itemPtr->state; |
860 |
Pixmap stipple = linePtr->outline.stipple; |
Pixmap stipple = linePtr->outline.stipple; |
861 |
|
|
862 |
if ((!linePtr->numPoints)||(linePtr->outline.gc==None)) { |
if ((!linePtr->numPoints)||(linePtr->outline.gc==None)) { |
863 |
return; |
return; |
864 |
} |
} |
865 |
|
|
866 |
if (state == TK_STATE_NULL) { |
if (state == TK_STATE_NULL) { |
867 |
state = ((TkCanvas *)canvas)->canvas_state; |
state = ((TkCanvas *)canvas)->canvas_state; |
868 |
} |
} |
869 |
linewidth = linePtr->outline.width; |
linewidth = linePtr->outline.width; |
870 |
if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { |
if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { |
871 |
if (linePtr->outline.activeStipple!=None) { |
if (linePtr->outline.activeStipple!=None) { |
872 |
stipple = linePtr->outline.activeStipple; |
stipple = linePtr->outline.activeStipple; |
873 |
} |
} |
874 |
if (linePtr->outline.activeWidth>linewidth) { |
if (linePtr->outline.activeWidth>linewidth) { |
875 |
linewidth = linePtr->outline.activeWidth; |
linewidth = linePtr->outline.activeWidth; |
876 |
} |
} |
877 |
} else if (state==TK_STATE_DISABLED) { |
} else if (state==TK_STATE_DISABLED) { |
878 |
if (linePtr->outline.disabledStipple!=None) { |
if (linePtr->outline.disabledStipple!=None) { |
879 |
stipple = linePtr->outline.disabledStipple; |
stipple = linePtr->outline.disabledStipple; |
880 |
} |
} |
881 |
if (linePtr->outline.disabledWidth>linewidth) { |
if (linePtr->outline.disabledWidth>linewidth) { |
882 |
linewidth = linePtr->outline.activeWidth; |
linewidth = linePtr->outline.activeWidth; |
883 |
} |
} |
884 |
} |
} |
885 |
/* |
/* |
886 |
* Build up an array of points in screen coordinates. Use a |
* Build up an array of points in screen coordinates. Use a |
887 |
* static array unless the line has an enormous number of points; |
* static array unless the line has an enormous number of points; |
888 |
* in this case, dynamically allocate an array. For smoothed lines, |
* in this case, dynamically allocate an array. For smoothed lines, |
889 |
* generate the curve points on each redisplay. |
* generate the curve points on each redisplay. |
890 |
*/ |
*/ |
891 |
|
|
892 |
if ((linePtr->smooth) && (linePtr->numPoints > 2)) { |
if ((linePtr->smooth) && (linePtr->numPoints > 2)) { |
893 |
numPoints = linePtr->smooth->coordProc(canvas, (double *) NULL, |
numPoints = linePtr->smooth->coordProc(canvas, (double *) NULL, |
894 |
linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL, |
linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL, |
895 |
(double *) NULL); |
(double *) NULL); |
896 |
} else { |
} else { |
897 |
numPoints = linePtr->numPoints; |
numPoints = linePtr->numPoints; |
898 |
} |
} |
899 |
|
|
900 |
if (numPoints <= MAX_STATIC_POINTS) { |
if (numPoints <= MAX_STATIC_POINTS) { |
901 |
pointPtr = staticPoints; |
pointPtr = staticPoints; |
902 |
} else { |
} else { |
903 |
pointPtr = (XPoint *) ckalloc((unsigned) (numPoints * sizeof(XPoint))); |
pointPtr = (XPoint *) ckalloc((unsigned) (numPoints * sizeof(XPoint))); |
904 |
} |
} |
905 |
|
|
906 |
if ((linePtr->smooth) && (linePtr->numPoints > 2)) { |
if ((linePtr->smooth) && (linePtr->numPoints > 2)) { |
907 |
numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr, |
numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr, |
908 |
linePtr->numPoints, linePtr->splineSteps, pointPtr, |
linePtr->numPoints, linePtr->splineSteps, pointPtr, |
909 |
(double *) NULL); |
(double *) NULL); |
910 |
} else { |
} else { |
911 |
for (i = 0, coordPtr = linePtr->coordPtr, pPtr = pointPtr; |
for (i = 0, coordPtr = linePtr->coordPtr, pPtr = pointPtr; |
912 |
i < linePtr->numPoints; i += 1, coordPtr += 2, pPtr++) { |
i < linePtr->numPoints; i += 1, coordPtr += 2, pPtr++) { |
913 |
Tk_CanvasDrawableCoords(canvas, coordPtr[0], coordPtr[1], |
Tk_CanvasDrawableCoords(canvas, coordPtr[0], coordPtr[1], |
914 |
&pPtr->x, &pPtr->y); |
&pPtr->x, &pPtr->y); |
915 |
} |
} |
916 |
} |
} |
917 |
|
|
918 |
/* |
/* |
919 |
* Display line, the free up line storage if it was dynamically |
* Display line, the free up line storage if it was dynamically |
920 |
* allocated. If we're stippling, then modify the stipple offset |
* allocated. If we're stippling, then modify the stipple offset |
921 |
* in the GC. Be sure to reset the offset when done, since the |
* in the GC. Be sure to reset the offset when done, since the |
922 |
* GC is supposed to be read-only. |
* GC is supposed to be read-only. |
923 |
*/ |
*/ |
924 |
|
|
925 |
if (Tk_ChangeOutlineGC(canvas, itemPtr, &(linePtr->outline))) { |
if (Tk_ChangeOutlineGC(canvas, itemPtr, &(linePtr->outline))) { |
926 |
Tk_CanvasSetOffset(canvas, linePtr->arrowGC, &linePtr->outline.tsoffset); |
Tk_CanvasSetOffset(canvas, linePtr->arrowGC, &linePtr->outline.tsoffset); |
927 |
} |
} |
928 |
if (numPoints>1) { |
if (numPoints>1) { |
929 |
XDrawLines(display, drawable, linePtr->outline.gc, pointPtr, numPoints, |
XDrawLines(display, drawable, linePtr->outline.gc, pointPtr, numPoints, |
930 |
CoordModeOrigin); |
CoordModeOrigin); |
931 |
} else { |
} else { |
932 |
int intwidth = (int) (linewidth + 0.5); |
int intwidth = (int) (linewidth + 0.5); |
933 |
if (intwidth<1) { |
if (intwidth<1) { |
934 |
intwidth=1; |
intwidth=1; |
935 |
} |
} |
936 |
XFillArc(display, drawable, linePtr->outline.gc, |
XFillArc(display, drawable, linePtr->outline.gc, |
937 |
pointPtr->x - intwidth/2, pointPtr->y - intwidth/2, |
pointPtr->x - intwidth/2, pointPtr->y - intwidth/2, |
938 |
(unsigned int)intwidth+1, (unsigned int)intwidth+1, 0, 64*360); |
(unsigned int)intwidth+1, (unsigned int)intwidth+1, 0, 64*360); |
939 |
} |
} |
940 |
if (pointPtr != staticPoints) { |
if (pointPtr != staticPoints) { |
941 |
ckfree((char *) pointPtr); |
ckfree((char *) pointPtr); |
942 |
} |
} |
943 |
|
|
944 |
/* |
/* |
945 |
* Display arrowheads, if they are wanted. |
* Display arrowheads, if they are wanted. |
946 |
*/ |
*/ |
947 |
|
|
948 |
if (linePtr->firstArrowPtr != NULL) { |
if (linePtr->firstArrowPtr != NULL) { |
949 |
TkFillPolygon(canvas, linePtr->firstArrowPtr, PTS_IN_ARROW, |
TkFillPolygon(canvas, linePtr->firstArrowPtr, PTS_IN_ARROW, |
950 |
display, drawable, linePtr->arrowGC, NULL); |
display, drawable, linePtr->arrowGC, NULL); |
951 |
} |
} |
952 |
if (linePtr->lastArrowPtr != NULL) { |
if (linePtr->lastArrowPtr != NULL) { |
953 |
TkFillPolygon(canvas, linePtr->lastArrowPtr, PTS_IN_ARROW, |
TkFillPolygon(canvas, linePtr->lastArrowPtr, PTS_IN_ARROW, |
954 |
display, drawable, linePtr->arrowGC, NULL); |
display, drawable, linePtr->arrowGC, NULL); |
955 |
} |
} |
956 |
if (Tk_ResetOutlineGC(canvas, itemPtr, &(linePtr->outline))) { |
if (Tk_ResetOutlineGC(canvas, itemPtr, &(linePtr->outline))) { |
957 |
XSetTSOrigin(display, linePtr->arrowGC, 0, 0); |
XSetTSOrigin(display, linePtr->arrowGC, 0, 0); |
958 |
} |
} |
959 |
} |
} |
960 |
|
|
961 |
/* |
/* |
962 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
963 |
* |
* |
964 |
* LineInsert -- |
* LineInsert -- |
965 |
* |
* |
966 |
* Insert coords into a line item at a given index. |
* Insert coords into a line item at a given index. |
967 |
* |
* |
968 |
* Results: |
* Results: |
969 |
* None. |
* None. |
970 |
* |
* |
971 |
* Side effects: |
* Side effects: |
972 |
* The coords in the given item is modified. |
* The coords in the given item is modified. |
973 |
* |
* |
974 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
975 |
*/ |
*/ |
976 |
|
|
977 |
static void |
static void |
978 |
LineInsert(canvas, itemPtr, beforeThis, obj) |
LineInsert(canvas, itemPtr, beforeThis, obj) |
979 |
Tk_Canvas canvas; /* Canvas containing text item. */ |
Tk_Canvas canvas; /* Canvas containing text item. */ |
980 |
Tk_Item *itemPtr; /* Line item to be modified. */ |
Tk_Item *itemPtr; /* Line item to be modified. */ |
981 |
int beforeThis; /* Index before which new coordinates |
int beforeThis; /* Index before which new coordinates |
982 |
* are to be inserted. */ |
* are to be inserted. */ |
983 |
Tcl_Obj *obj; /* New coordinates to be inserted. */ |
Tcl_Obj *obj; /* New coordinates to be inserted. */ |
984 |
{ |
{ |
985 |
LineItem *linePtr = (LineItem *) itemPtr; |
LineItem *linePtr = (LineItem *) itemPtr; |
986 |
int length, argc, i; |
int length, argc, i; |
987 |
double *new, *coordPtr; |
double *new, *coordPtr; |
988 |
Tk_State state = itemPtr->state; |
Tk_State state = itemPtr->state; |
989 |
Tcl_Obj **objv; |
Tcl_Obj **objv; |
990 |
|
|
991 |
if(state == TK_STATE_NULL) { |
if(state == TK_STATE_NULL) { |
992 |
state = ((TkCanvas *)canvas)->canvas_state; |
state = ((TkCanvas *)canvas)->canvas_state; |
993 |
} |
} |
994 |
|
|
995 |
if (!obj || (Tcl_ListObjGetElements((Tcl_Interp *) NULL, obj, &argc, &objv) != TCL_OK) |
if (!obj || (Tcl_ListObjGetElements((Tcl_Interp *) NULL, obj, &argc, &objv) != TCL_OK) |
996 |
|| !argc || argc&1) { |
|| !argc || argc&1) { |
997 |
return; |
return; |
998 |
} |
} |
999 |
length = 2*linePtr->numPoints; |
length = 2*linePtr->numPoints; |
1000 |
if (beforeThis < 0) { |
if (beforeThis < 0) { |
1001 |
beforeThis = 0; |
beforeThis = 0; |
1002 |
} |
} |
1003 |
if (beforeThis > length) { |
if (beforeThis > length) { |
1004 |
beforeThis = length; |
beforeThis = length; |
1005 |
} |
} |
1006 |
if (linePtr->firstArrowPtr != NULL) { |
if (linePtr->firstArrowPtr != NULL) { |
1007 |
linePtr->coordPtr[0] = linePtr->firstArrowPtr[0]; |
linePtr->coordPtr[0] = linePtr->firstArrowPtr[0]; |
1008 |
linePtr->coordPtr[1] = linePtr->firstArrowPtr[1]; |
linePtr->coordPtr[1] = linePtr->firstArrowPtr[1]; |
1009 |
} |
} |
1010 |
if (linePtr->lastArrowPtr != NULL) { |
if (linePtr->lastArrowPtr != NULL) { |
1011 |
linePtr->coordPtr[length-2] = linePtr->lastArrowPtr[0]; |
linePtr->coordPtr[length-2] = linePtr->lastArrowPtr[0]; |
1012 |
linePtr->coordPtr[length-1] = linePtr->lastArrowPtr[1]; |
linePtr->coordPtr[length-1] = linePtr->lastArrowPtr[1]; |
1013 |
} |
} |
1014 |
new = (double *) ckalloc((unsigned)(sizeof(double) * (length + argc))); |
new = (double *) ckalloc((unsigned)(sizeof(double) * (length + argc))); |
1015 |
for(i=0; i<beforeThis; i++) { |
for(i=0; i<beforeThis; i++) { |
1016 |
new[i] = linePtr->coordPtr[i]; |
new[i] = linePtr->coordPtr[i]; |
1017 |
} |
} |
1018 |
for(i=0; i<argc; i++) { |
for(i=0; i<argc; i++) { |
1019 |
if (Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,objv[i], |
if (Tcl_GetDoubleFromObj((Tcl_Interp *) NULL,objv[i], |
1020 |
new+(i+beforeThis))!=TCL_OK) { |
new+(i+beforeThis))!=TCL_OK) { |
1021 |
Tcl_ResetResult(((TkCanvas *)canvas)->interp); |
Tcl_ResetResult(((TkCanvas *)canvas)->interp); |
1022 |
ckfree((char *) new); |
ckfree((char *) new); |
1023 |
return; |
return; |
1024 |
} |
} |
1025 |
} |
} |
1026 |
|
|
1027 |
for(i=beforeThis; i<length; i++) { |
for(i=beforeThis; i<length; i++) { |
1028 |
new[i+argc] = linePtr->coordPtr[i]; |
new[i+argc] = linePtr->coordPtr[i]; |
1029 |
} |
} |
1030 |
if(linePtr->coordPtr) ckfree((char *)linePtr->coordPtr); |
if(linePtr->coordPtr) ckfree((char *)linePtr->coordPtr); |
1031 |
linePtr->coordPtr = new; |
linePtr->coordPtr = new; |
1032 |
linePtr->numPoints = (length + argc)/2; |
linePtr->numPoints = (length + argc)/2; |
1033 |
|
|
1034 |
if ((length>3) && (state != TK_STATE_HIDDEN)) { |
if ((length>3) && (state != TK_STATE_HIDDEN)) { |
1035 |
/* |
/* |
1036 |
* This is some optimizing code that will result that only the part |
* This is some optimizing code that will result that only the part |
1037 |
* of the polygon that changed (and the objects that are overlapping |
* of the polygon that changed (and the objects that are overlapping |
1038 |
* with that part) need to be redrawn. A special flag is set that |
* with that part) need to be redrawn. A special flag is set that |
1039 |
* instructs the general canvas code not to redraw the whole |
* instructs the general canvas code not to redraw the whole |
1040 |
* object. If this flag is not set, the canvas will do the redrawing, |
* object. If this flag is not set, the canvas will do the redrawing, |
1041 |
* otherwise I have to do it here. |
* otherwise I have to do it here. |
1042 |
*/ |
*/ |
1043 |
itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW; |
itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW; |
1044 |
|
|
1045 |
if (beforeThis>0) {beforeThis -= 2; argc+=2; } |
if (beforeThis>0) {beforeThis -= 2; argc+=2; } |
1046 |
if ((beforeThis+argc)<length) argc+=2; |
if ((beforeThis+argc)<length) argc+=2; |
1047 |
if (linePtr->smooth) { |
if (linePtr->smooth) { |
1048 |
if(beforeThis>0) { |
if(beforeThis>0) { |
1049 |
beforeThis-=2; argc+=2; |
beforeThis-=2; argc+=2; |
1050 |
} |
} |
1051 |
if((beforeThis+argc+2)<length) { |
if((beforeThis+argc+2)<length) { |
1052 |
argc+=2; |
argc+=2; |
1053 |
} |
} |
1054 |
} |
} |
1055 |
itemPtr->x1 = itemPtr->x2 = (int) linePtr->coordPtr[beforeThis]; |
itemPtr->x1 = itemPtr->x2 = (int) linePtr->coordPtr[beforeThis]; |
1056 |
itemPtr->y1 = itemPtr->y2 = (int) linePtr->coordPtr[beforeThis+1]; |
itemPtr->y1 = itemPtr->y2 = (int) linePtr->coordPtr[beforeThis+1]; |
1057 |
if ((linePtr->firstArrowPtr != NULL) && (beforeThis<1)) { |
if ((linePtr->firstArrowPtr != NULL) && (beforeThis<1)) { |
1058 |
/* include old first arrow */ |
/* include old first arrow */ |
1059 |
for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW; |
for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW; |
1060 |
i++, coordPtr += 2) { |
i++, coordPtr += 2) { |
1061 |
TkIncludePoint(itemPtr, coordPtr); |
TkIncludePoint(itemPtr, coordPtr); |
1062 |
} |
} |
1063 |
} |
} |
1064 |
if ((linePtr->lastArrowPtr != NULL) && ((beforeThis+argc)>=length)) { |
if ((linePtr->lastArrowPtr != NULL) && ((beforeThis+argc)>=length)) { |
1065 |
/* include old last arrow */ |
/* include old last arrow */ |
1066 |
for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW; |
for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW; |
1067 |
i++, coordPtr += 2) { |
i++, coordPtr += 2) { |
1068 |
TkIncludePoint(itemPtr, coordPtr); |
TkIncludePoint(itemPtr, coordPtr); |
1069 |
} |
} |
1070 |
} |
} |
1071 |
coordPtr = linePtr->coordPtr+beforeThis+2; |
coordPtr = linePtr->coordPtr+beforeThis+2; |
1072 |
for(i=2; i<argc; i+=2) { |
for(i=2; i<argc; i+=2) { |
1073 |
TkIncludePoint(itemPtr, coordPtr); |
TkIncludePoint(itemPtr, coordPtr); |
1074 |
coordPtr+=2; |
coordPtr+=2; |
1075 |
} |
} |
1076 |
} |
} |
1077 |
if (linePtr->firstArrowPtr != NULL) { |
if (linePtr->firstArrowPtr != NULL) { |
1078 |
ckfree((char *) linePtr->firstArrowPtr); |
ckfree((char *) linePtr->firstArrowPtr); |
1079 |
linePtr->firstArrowPtr = NULL; |
linePtr->firstArrowPtr = NULL; |
1080 |
} |
} |
1081 |
if (linePtr->lastArrowPtr != NULL) { |
if (linePtr->lastArrowPtr != NULL) { |
1082 |
ckfree((char *) linePtr->lastArrowPtr); |
ckfree((char *) linePtr->lastArrowPtr); |
1083 |
linePtr->lastArrowPtr = NULL; |
linePtr->lastArrowPtr = NULL; |
1084 |
} |
} |
1085 |
if (linePtr->arrow != ARROWS_NONE) { |
if (linePtr->arrow != ARROWS_NONE) { |
1086 |
ConfigureArrows(canvas, linePtr); |
ConfigureArrows(canvas, linePtr); |
1087 |
} |
} |
1088 |
|
|
1089 |
if(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) { |
if(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) { |
1090 |
double width; |
double width; |
1091 |
int intWidth; |
int intWidth; |
1092 |
if ((linePtr->firstArrowPtr != NULL) && (beforeThis>2)) { |
if ((linePtr->firstArrowPtr != NULL) && (beforeThis>2)) { |
1093 |
/* include new first arrow */ |
/* include new first arrow */ |
1094 |
for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW; |
for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW; |
1095 |
i++, coordPtr += 2) { |
i++, coordPtr += 2) { |
1096 |
TkIncludePoint(itemPtr, coordPtr); |
TkIncludePoint(itemPtr, coordPtr); |
1097 |
} |
} |
1098 |
} |
} |
1099 |
if ((linePtr->lastArrowPtr != NULL) && ((beforeThis+argc)<(length-2))) { |
if ((linePtr->lastArrowPtr != NULL) && ((beforeThis+argc)<(length-2))) { |
1100 |
/* include new right arrow */ |
/* include new right arrow */ |
1101 |
for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW; |
for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW; |
1102 |
i++, coordPtr += 2) { |
i++, coordPtr += 2) { |
1103 |
TkIncludePoint(itemPtr, coordPtr); |
TkIncludePoint(itemPtr, coordPtr); |
1104 |
} |
} |
1105 |
} |
} |
1106 |
width = linePtr->outline.width; |
width = linePtr->outline.width; |
1107 |
if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { |
if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { |
1108 |
if (linePtr->outline.activeWidth>width) { |
if (linePtr->outline.activeWidth>width) { |
1109 |
width = linePtr->outline.activeWidth; |
width = linePtr->outline.activeWidth; |
1110 |
} |
} |
1111 |
} else if (state==TK_STATE_DISABLED) { |
} else if (state==TK_STATE_DISABLED) { |
1112 |
if (linePtr->outline.disabledWidth>0) { |
if (linePtr->outline.disabledWidth>0) { |
1113 |
width = linePtr->outline.disabledWidth; |
width = linePtr->outline.disabledWidth; |
1114 |
} |
} |
1115 |
} |
} |
1116 |
intWidth = (int) (width + 0.5); |
intWidth = (int) (width + 0.5); |
1117 |
if (intWidth < 1) { |
if (intWidth < 1) { |
1118 |
intWidth = 1; |
intWidth = 1; |
1119 |
} |
} |
1120 |
itemPtr->x1 -= intWidth; itemPtr->y1 -= intWidth; |
itemPtr->x1 -= intWidth; itemPtr->y1 -= intWidth; |
1121 |
itemPtr->x2 += intWidth; itemPtr->y2 += intWidth; |
itemPtr->x2 += intWidth; itemPtr->y2 += intWidth; |
1122 |
Tk_CanvasEventuallyRedraw(canvas, itemPtr->x1, itemPtr->y1, |
Tk_CanvasEventuallyRedraw(canvas, itemPtr->x1, itemPtr->y1, |
1123 |
itemPtr->x2, itemPtr->y2); |
itemPtr->x2, itemPtr->y2); |
1124 |
} |
} |
1125 |
|
|
1126 |
ComputeLineBbox(canvas, linePtr); |
ComputeLineBbox(canvas, linePtr); |
1127 |
} |
} |
1128 |
|
|
1129 |
/* |
/* |
1130 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
1131 |
* |
* |
1132 |
* LineDeleteCoords -- |
* LineDeleteCoords -- |
1133 |
* |
* |
1134 |
* Delete one or more coordinates from a line item. |
* Delete one or more coordinates from a line item. |
1135 |
* |
* |
1136 |
* Results: |
* Results: |
1137 |
* None. |
* None. |
1138 |
* |
* |
1139 |
* Side effects: |
* Side effects: |
1140 |
* Characters between "first" and "last", inclusive, get |
* Characters between "first" and "last", inclusive, get |
1141 |
* deleted from itemPtr. |
* deleted from itemPtr. |
1142 |
* |
* |
1143 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
1144 |
*/ |
*/ |
1145 |
|
|
1146 |
static void |
static void |
1147 |
LineDeleteCoords(canvas, itemPtr, first, last) |
LineDeleteCoords(canvas, itemPtr, first, last) |
1148 |
Tk_Canvas canvas; /* Canvas containing itemPtr. */ |
Tk_Canvas canvas; /* Canvas containing itemPtr. */ |
1149 |
Tk_Item *itemPtr; /* Item in which to delete characters. */ |
Tk_Item *itemPtr; /* Item in which to delete characters. */ |
1150 |
int first; /* Index of first character to delete. */ |
int first; /* Index of first character to delete. */ |
1151 |
int last; /* Index of last character to delete. */ |
int last; /* Index of last character to delete. */ |
1152 |
{ |
{ |
1153 |
LineItem *linePtr = (LineItem *) itemPtr; |
LineItem *linePtr = (LineItem *) itemPtr; |
1154 |
int count, i, first1, last1; |
int count, i, first1, last1; |
1155 |
int length = 2*linePtr->numPoints; |
int length = 2*linePtr->numPoints; |
1156 |
double *coordPtr; |
double *coordPtr; |
1157 |
Tk_State state = itemPtr->state; |
Tk_State state = itemPtr->state; |
1158 |
|
|
1159 |
if(state == TK_STATE_NULL) { |
if(state == TK_STATE_NULL) { |
1160 |
state = ((TkCanvas *)canvas)->canvas_state; |
state = ((TkCanvas *)canvas)->canvas_state; |
1161 |
} |
} |
1162 |
|
|
1163 |
first &= -2; |
first &= -2; |
1164 |
last &= -2; |
last &= -2; |
1165 |
|
|
1166 |
if (first < 0) { |
if (first < 0) { |
1167 |
first = 0; |
first = 0; |
1168 |
} |
} |
1169 |
if (last >= length) { |
if (last >= length) { |
1170 |
last = length-2; |
last = length-2; |
1171 |
} |
} |
1172 |
if (first > last) { |
if (first > last) { |
1173 |
return; |
return; |
1174 |
} |
} |
1175 |
if (linePtr->firstArrowPtr != NULL) { |
if (linePtr->firstArrowPtr != NULL) { |
1176 |
linePtr->coordPtr[0] = linePtr->firstArrowPtr[0]; |
linePtr->coordPtr[0] = linePtr->firstArrowPtr[0]; |
1177 |
linePtr->coordPtr[1] = linePtr->firstArrowPtr[1]; |
linePtr->coordPtr[1] = linePtr->firstArrowPtr[1]; |
1178 |
} |
} |
1179 |
if (linePtr->lastArrowPtr != NULL) { |
if (linePtr->lastArrowPtr != NULL) { |
1180 |
linePtr->coordPtr[length-2] = linePtr->lastArrowPtr[0]; |
linePtr->coordPtr[length-2] = linePtr->lastArrowPtr[0]; |
1181 |
linePtr->coordPtr[length-1] = linePtr->lastArrowPtr[1]; |
linePtr->coordPtr[length-1] = linePtr->lastArrowPtr[1]; |
1182 |
} |
} |
1183 |
first1 = first; last1 = last; |
first1 = first; last1 = last; |
1184 |
if(first1>0) first1 -= 2; |
if(first1>0) first1 -= 2; |
1185 |
if(last1<length-2) last1 += 2; |
if(last1<length-2) last1 += 2; |
1186 |
if (linePtr->smooth) { |
if (linePtr->smooth) { |
1187 |
if(first1>0) first1 -= 2; |
if(first1>0) first1 -= 2; |
1188 |
if(last1<length-2) last1 += 2; |
if(last1<length-2) last1 += 2; |
1189 |
} |
} |
1190 |
|
|
1191 |
if((first1<2) && (last1 >= length-2)) { |
if((first1<2) && (last1 >= length-2)) { |
1192 |
/* |
/* |
1193 |
* This is some optimizing code that will result that only the part |
* This is some optimizing code that will result that only the part |
1194 |
* of the line that changed (and the objects that are overlapping |
* of the line that changed (and the objects that are overlapping |
1195 |
* with that part) need to be redrawn. A special flag is set that |
* with that part) need to be redrawn. A special flag is set that |
1196 |
* instructs the general canvas code not to redraw the whole |
* instructs the general canvas code not to redraw the whole |
1197 |
* object. If this flag is set, the redrawing has to be done here, |
* object. If this flag is set, the redrawing has to be done here, |
1198 |
* otherwise the general Canvas code will take care of it. |
* otherwise the general Canvas code will take care of it. |
1199 |
*/ |
*/ |
1200 |
|
|
1201 |
itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW; |
itemPtr->redraw_flags |= TK_ITEM_DONT_REDRAW; |
1202 |
itemPtr->x1 = itemPtr->x2 = (int) linePtr->coordPtr[first1]; |
itemPtr->x1 = itemPtr->x2 = (int) linePtr->coordPtr[first1]; |
1203 |
itemPtr->y1 = itemPtr->y2 = (int) linePtr->coordPtr[first1+1]; |
itemPtr->y1 = itemPtr->y2 = (int) linePtr->coordPtr[first1+1]; |
1204 |
if ((linePtr->firstArrowPtr != NULL) && (first1<2)) { |
if ((linePtr->firstArrowPtr != NULL) && (first1<2)) { |
1205 |
/* include old first arrow */ |
/* include old first arrow */ |
1206 |
for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW; |
for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW; |
1207 |
i++, coordPtr += 2) { |
i++, coordPtr += 2) { |
1208 |
TkIncludePoint(itemPtr, coordPtr); |
TkIncludePoint(itemPtr, coordPtr); |
1209 |
} |
} |
1210 |
} |
} |
1211 |
if ((linePtr->lastArrowPtr != NULL) && (last1>=length-2)) { |
if ((linePtr->lastArrowPtr != NULL) && (last1>=length-2)) { |
1212 |
/* include old last arrow */ |
/* include old last arrow */ |
1213 |
for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW; |
for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW; |
1214 |
i++, coordPtr += 2) { |
i++, coordPtr += 2) { |
1215 |
TkIncludePoint(itemPtr, coordPtr); |
TkIncludePoint(itemPtr, coordPtr); |
1216 |
} |
} |
1217 |
} |
} |
1218 |
coordPtr = linePtr->coordPtr+first1+2; |
coordPtr = linePtr->coordPtr+first1+2; |
1219 |
for (i=first1+2; i<=last1; i+=2) { |
for (i=first1+2; i<=last1; i+=2) { |
1220 |
TkIncludePoint(itemPtr, coordPtr); |
TkIncludePoint(itemPtr, coordPtr); |
1221 |
coordPtr+=2; |
coordPtr+=2; |
1222 |
} |
} |
1223 |
} |
} |
1224 |
|
|
1225 |
count = last + 2 - first; |
count = last + 2 - first; |
1226 |
for (i=last+2; i<length; i++) { |
for (i=last+2; i<length; i++) { |
1227 |
linePtr->coordPtr[i-count] = linePtr->coordPtr[i]; |
linePtr->coordPtr[i-count] = linePtr->coordPtr[i]; |
1228 |
} |
} |
1229 |
linePtr->numPoints -= count/2; |
linePtr->numPoints -= count/2; |
1230 |
if (linePtr->firstArrowPtr != NULL) { |
if (linePtr->firstArrowPtr != NULL) { |
1231 |
ckfree((char *) linePtr->firstArrowPtr); |
ckfree((char *) linePtr->firstArrowPtr); |
1232 |
linePtr->firstArrowPtr = NULL; |
linePtr->firstArrowPtr = NULL; |
1233 |
} |
} |
1234 |
if (linePtr->lastArrowPtr != NULL) { |
if (linePtr->lastArrowPtr != NULL) { |
1235 |
ckfree((char *) linePtr->lastArrowPtr); |
ckfree((char *) linePtr->lastArrowPtr); |
1236 |
linePtr->lastArrowPtr = NULL; |
linePtr->lastArrowPtr = NULL; |
1237 |
} |
} |
1238 |
if (linePtr->arrow != ARROWS_NONE) { |
if (linePtr->arrow != ARROWS_NONE) { |
1239 |
ConfigureArrows(canvas, linePtr); |
ConfigureArrows(canvas, linePtr); |
1240 |
} |
} |
1241 |
if(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) { |
if(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) { |
1242 |
double width; |
double width; |
1243 |
int intWidth; |
int intWidth; |
1244 |
if ((linePtr->firstArrowPtr != NULL) && (first1<4)) { |
if ((linePtr->firstArrowPtr != NULL) && (first1<4)) { |
1245 |
/* include new first arrow */ |
/* include new first arrow */ |
1246 |
for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW; |
for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW; |
1247 |
i++, coordPtr += 2) { |
i++, coordPtr += 2) { |
1248 |
TkIncludePoint(itemPtr, coordPtr); |
TkIncludePoint(itemPtr, coordPtr); |
1249 |
} |
} |
1250 |
} |
} |
1251 |
if ((linePtr->lastArrowPtr != NULL) && (last1>(length-4))) { |
if ((linePtr->lastArrowPtr != NULL) && (last1>(length-4))) { |
1252 |
/* include new right arrow */ |
/* include new right arrow */ |
1253 |
for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW; |
for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW; |
1254 |
i++, coordPtr += 2) { |
i++, coordPtr += 2) { |
1255 |
TkIncludePoint(itemPtr, coordPtr); |
TkIncludePoint(itemPtr, coordPtr); |
1256 |
} |
} |
1257 |
} |
} |
1258 |
width = linePtr->outline.width; |
width = linePtr->outline.width; |
1259 |
if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { |
if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { |
1260 |
if (linePtr->outline.activeWidth>width) { |
if (linePtr->outline.activeWidth>width) { |
1261 |
width = linePtr->outline.activeWidth; |
width = linePtr->outline.activeWidth; |
1262 |
} |
} |
1263 |
} else if (state==TK_STATE_DISABLED) { |
} else if (state==TK_STATE_DISABLED) { |
1264 |
if (linePtr->outline.disabledWidth>0) { |
if (linePtr->outline.disabledWidth>0) { |
1265 |
width = linePtr->outline.disabledWidth; |
width = linePtr->outline.disabledWidth; |
1266 |
} |
} |
1267 |
} |
} |
1268 |
intWidth = (int) (width + 0.5); |
intWidth = (int) (width + 0.5); |
1269 |
if (intWidth < 1) { |
if (intWidth < 1) { |
1270 |
intWidth = 1; |
intWidth = 1; |
1271 |
} |
} |
1272 |
itemPtr->x1 -= intWidth; itemPtr->y1 -= intWidth; |
itemPtr->x1 -= intWidth; itemPtr->y1 -= intWidth; |
1273 |
itemPtr->x2 += intWidth; itemPtr->y2 += intWidth; |
itemPtr->x2 += intWidth; itemPtr->y2 += intWidth; |
1274 |
Tk_CanvasEventuallyRedraw(canvas, itemPtr->x1, itemPtr->y1, |
Tk_CanvasEventuallyRedraw(canvas, itemPtr->x1, itemPtr->y1, |
1275 |
itemPtr->x2, itemPtr->y2); |
itemPtr->x2, itemPtr->y2); |
1276 |
} |
} |
1277 |
ComputeLineBbox(canvas, linePtr); |
ComputeLineBbox(canvas, linePtr); |
1278 |
} |
} |
1279 |
|
|
1280 |
/* |
/* |
1281 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
1282 |
* |
* |
1283 |
* LineToPoint -- |
* LineToPoint -- |
1284 |
* |
* |
1285 |
* Computes the distance from a given point to a given |
* Computes the distance from a given point to a given |
1286 |
* line, in canvas units. |
* line, in canvas units. |
1287 |
* |
* |
1288 |
* Results: |
* Results: |
1289 |
* The return value is 0 if the point whose x and y coordinates |
* The return value is 0 if the point whose x and y coordinates |
1290 |
* are pointPtr[0] and pointPtr[1] is inside the line. If the |
* are pointPtr[0] and pointPtr[1] is inside the line. If the |
1291 |
* point isn't inside the line then the return value is the |
* point isn't inside the line then the return value is the |
1292 |
* distance from the point to the line. |
* distance from the point to the line. |
1293 |
* |
* |
1294 |
* Side effects: |
* Side effects: |
1295 |
* None. |
* None. |
1296 |
* |
* |
1297 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
1298 |
*/ |
*/ |
1299 |
|
|
1300 |
/* ARGSUSED */ |
/* ARGSUSED */ |
1301 |
static double |
static double |
1302 |
LineToPoint(canvas, itemPtr, pointPtr) |
LineToPoint(canvas, itemPtr, pointPtr) |
1303 |
Tk_Canvas canvas; /* Canvas containing item. */ |
Tk_Canvas canvas; /* Canvas containing item. */ |
1304 |
Tk_Item *itemPtr; /* Item to check against point. */ |
Tk_Item *itemPtr; /* Item to check against point. */ |
1305 |
double *pointPtr; /* Pointer to x and y coordinates. */ |
double *pointPtr; /* Pointer to x and y coordinates. */ |
1306 |
{ |
{ |
1307 |
Tk_State state = itemPtr->state; |
Tk_State state = itemPtr->state; |
1308 |
LineItem *linePtr = (LineItem *) itemPtr; |
LineItem *linePtr = (LineItem *) itemPtr; |
1309 |
double *coordPtr, *linePoints; |
double *coordPtr, *linePoints; |
1310 |
double staticSpace[2*MAX_STATIC_POINTS]; |
double staticSpace[2*MAX_STATIC_POINTS]; |
1311 |
double poly[10]; |
double poly[10]; |
1312 |
double bestDist, dist, width; |
double bestDist, dist, width; |
1313 |
int numPoints, count; |
int numPoints, count; |
1314 |
int changedMiterToBevel; /* Non-zero means that a mitered corner |
int changedMiterToBevel; /* Non-zero means that a mitered corner |
1315 |
* had to be treated as beveled after all |
* had to be treated as beveled after all |
1316 |
* because the angle was < 11 degrees. */ |
* because the angle was < 11 degrees. */ |
1317 |
|
|
1318 |
bestDist = 1.0e36; |
bestDist = 1.0e36; |
1319 |
|
|
1320 |
/* |
/* |
1321 |
* Handle smoothed lines by generating an expanded set of points |
* Handle smoothed lines by generating an expanded set of points |
1322 |
* against which to do the check. |
* against which to do the check. |
1323 |
*/ |
*/ |
1324 |
|
|
1325 |
if(state == TK_STATE_NULL) { |
if(state == TK_STATE_NULL) { |
1326 |
state = ((TkCanvas *)canvas)->canvas_state; |
state = ((TkCanvas *)canvas)->canvas_state; |
1327 |
} |
} |
1328 |
|
|
1329 |
width = linePtr->outline.width; |
width = linePtr->outline.width; |
1330 |
if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { |
if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { |
1331 |
if (linePtr->outline.activeWidth>width) { |
if (linePtr->outline.activeWidth>width) { |
1332 |
width = linePtr->outline.activeWidth; |
width = linePtr->outline.activeWidth; |
1333 |
} |
} |
1334 |
} else if (state==TK_STATE_DISABLED) { |
} else if (state==TK_STATE_DISABLED) { |
1335 |
if (linePtr->outline.disabledWidth>0) { |
if (linePtr->outline.disabledWidth>0) { |
1336 |
width = linePtr->outline.disabledWidth; |
width = linePtr->outline.disabledWidth; |
1337 |
} |
} |
1338 |
} |
} |
1339 |
|
|
1340 |
if ((linePtr->smooth) && (linePtr->numPoints > 2)) { |
if ((linePtr->smooth) && (linePtr->numPoints > 2)) { |
1341 |
numPoints = linePtr->smooth->coordProc(canvas, (double *) NULL, |
numPoints = linePtr->smooth->coordProc(canvas, (double *) NULL, |
1342 |
linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL, |
linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL, |
1343 |
(double *) NULL); |
(double *) NULL); |
1344 |
if (numPoints <= MAX_STATIC_POINTS) { |
if (numPoints <= MAX_STATIC_POINTS) { |
1345 |
linePoints = staticSpace; |
linePoints = staticSpace; |
1346 |
} else { |
} else { |
1347 |
linePoints = (double *) ckalloc((unsigned) |
linePoints = (double *) ckalloc((unsigned) |
1348 |
(2*numPoints*sizeof(double))); |
(2*numPoints*sizeof(double))); |
1349 |
} |
} |
1350 |
numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr, |
numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr, |
1351 |
linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL, |
linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL, |
1352 |
linePoints); |
linePoints); |
1353 |
} else { |
} else { |
1354 |
numPoints = linePtr->numPoints; |
numPoints = linePtr->numPoints; |
1355 |
linePoints = linePtr->coordPtr; |
linePoints = linePtr->coordPtr; |
1356 |
} |
} |
1357 |
|
|
1358 |
if (width < 1.0) { |
if (width < 1.0) { |
1359 |
width = 1.0; |
width = 1.0; |
1360 |
} |
} |
1361 |
|
|
1362 |
if (!numPoints || itemPtr->state==TK_STATE_HIDDEN) { |
if (!numPoints || itemPtr->state==TK_STATE_HIDDEN) { |
1363 |
return bestDist; |
return bestDist; |
1364 |
} else if (numPoints == 1) { |
} else if (numPoints == 1) { |
1365 |
bestDist = hypot(linePoints[0] - pointPtr[0], linePoints[1] - pointPtr[1]) |
bestDist = hypot(linePoints[0] - pointPtr[0], linePoints[1] - pointPtr[1]) |
1366 |
- width/2.0; |
- width/2.0; |
1367 |
if (bestDist < 0) bestDist = 0; |
if (bestDist < 0) bestDist = 0; |
1368 |
return bestDist; |
return bestDist; |
1369 |
} |
} |
1370 |
|
|
1371 |
/* |
/* |
1372 |
* The overall idea is to iterate through all of the edges of |
* The overall idea is to iterate through all of the edges of |
1373 |
* the line, computing a polygon for each edge and testing the |
* the line, computing a polygon for each edge and testing the |
1374 |
* point against that polygon. In addition, there are additional |
* point against that polygon. In addition, there are additional |
1375 |
* tests to deal with rounded joints and caps. |
* tests to deal with rounded joints and caps. |
1376 |
*/ |
*/ |
1377 |
|
|
1378 |
changedMiterToBevel = 0; |
changedMiterToBevel = 0; |
1379 |
for (count = numPoints, coordPtr = linePoints; count >= 2; |
for (count = numPoints, coordPtr = linePoints; count >= 2; |
1380 |
count--, coordPtr += 2) { |
count--, coordPtr += 2) { |
1381 |
|
|
1382 |
/* |
/* |
1383 |
* If rounding is done around the first point then compute |
* If rounding is done around the first point then compute |
1384 |
* the distance between the point and the point. |
* the distance between the point and the point. |
1385 |
*/ |
*/ |
1386 |
|
|
1387 |
if (((linePtr->capStyle == CapRound) && (count == numPoints)) |
if (((linePtr->capStyle == CapRound) && (count == numPoints)) |
1388 |
|| ((linePtr->joinStyle == JoinRound) |
|| ((linePtr->joinStyle == JoinRound) |
1389 |
&& (count != numPoints))) { |
&& (count != numPoints))) { |
1390 |
dist = hypot(coordPtr[0] - pointPtr[0], coordPtr[1] - pointPtr[1]) |
dist = hypot(coordPtr[0] - pointPtr[0], coordPtr[1] - pointPtr[1]) |
1391 |
- width/2.0; |
- width/2.0; |
1392 |
if (dist <= 0.0) { |
if (dist <= 0.0) { |
1393 |
bestDist = 0.0; |
bestDist = 0.0; |
1394 |
goto done; |
goto done; |
1395 |
} else if (dist < bestDist) { |
} else if (dist < bestDist) { |
1396 |
bestDist = dist; |
bestDist = dist; |
1397 |
} |
} |
1398 |
} |
} |
1399 |
|
|
1400 |
/* |
/* |
1401 |
* Compute the polygonal shape corresponding to this edge, |
* Compute the polygonal shape corresponding to this edge, |
1402 |
* consisting of two points for the first point of the edge |
* consisting of two points for the first point of the edge |
1403 |
* and two points for the last point of the edge. |
* and two points for the last point of the edge. |
1404 |
*/ |
*/ |
1405 |
|
|
1406 |
if (count == numPoints) { |
if (count == numPoints) { |
1407 |
TkGetButtPoints(coordPtr+2, coordPtr, width, |
TkGetButtPoints(coordPtr+2, coordPtr, width, |
1408 |
linePtr->capStyle == CapProjecting, poly, poly+2); |
linePtr->capStyle == CapProjecting, poly, poly+2); |
1409 |
} else if ((linePtr->joinStyle == JoinMiter) && !changedMiterToBevel) { |
} else if ((linePtr->joinStyle == JoinMiter) && !changedMiterToBevel) { |
1410 |
poly[0] = poly[6]; |
poly[0] = poly[6]; |
1411 |
poly[1] = poly[7]; |
poly[1] = poly[7]; |
1412 |
poly[2] = poly[4]; |
poly[2] = poly[4]; |
1413 |
poly[3] = poly[5]; |
poly[3] = poly[5]; |
1414 |
} else { |
} else { |
1415 |
TkGetButtPoints(coordPtr+2, coordPtr, width, 0, |
TkGetButtPoints(coordPtr+2, coordPtr, width, 0, |
1416 |
poly, poly+2); |
poly, poly+2); |
1417 |
|
|
1418 |
/* |
/* |
1419 |
* If this line uses beveled joints, then check the distance |
* If this line uses beveled joints, then check the distance |
1420 |
* to a polygon comprising the last two points of the previous |
* to a polygon comprising the last two points of the previous |
1421 |
* polygon and the first two from this polygon; this checks |
* polygon and the first two from this polygon; this checks |
1422 |
* the wedges that fill the mitered joint. |
* the wedges that fill the mitered joint. |
1423 |
*/ |
*/ |
1424 |
|
|
1425 |
if ((linePtr->joinStyle == JoinBevel) || changedMiterToBevel) { |
if ((linePtr->joinStyle == JoinBevel) || changedMiterToBevel) { |
1426 |
poly[8] = poly[0]; |
poly[8] = poly[0]; |
1427 |
poly[9] = poly[1]; |
poly[9] = poly[1]; |
1428 |
dist = TkPolygonToPoint(poly, 5, pointPtr); |
dist = TkPolygonToPoint(poly, 5, pointPtr); |
1429 |
if (dist <= 0.0) { |
if (dist <= 0.0) { |
1430 |
bestDist = 0.0; |
bestDist = 0.0; |
1431 |
goto done; |
goto done; |
1432 |
} else if (dist < bestDist) { |
} else if (dist < bestDist) { |
1433 |
bestDist = dist; |
bestDist = dist; |
1434 |
} |
} |
1435 |
changedMiterToBevel = 0; |
changedMiterToBevel = 0; |
1436 |
} |
} |
1437 |
} |
} |
1438 |
if (count == 2) { |
if (count == 2) { |
1439 |
TkGetButtPoints(coordPtr, coordPtr+2, width, |
TkGetButtPoints(coordPtr, coordPtr+2, width, |
1440 |
linePtr->capStyle == CapProjecting, poly+4, poly+6); |
linePtr->capStyle == CapProjecting, poly+4, poly+6); |
1441 |
} else if (linePtr->joinStyle == JoinMiter) { |
} else if (linePtr->joinStyle == JoinMiter) { |
1442 |
if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4, |
if (TkGetMiterPoints(coordPtr, coordPtr+2, coordPtr+4, |
1443 |
width, poly+4, poly+6) == 0) { |
width, poly+4, poly+6) == 0) { |
1444 |
changedMiterToBevel = 1; |
changedMiterToBevel = 1; |
1445 |
TkGetButtPoints(coordPtr, coordPtr+2, width, |
TkGetButtPoints(coordPtr, coordPtr+2, width, |
1446 |
0, poly+4, poly+6); |
0, poly+4, poly+6); |
1447 |
} |
} |
1448 |
} else { |
} else { |
1449 |
TkGetButtPoints(coordPtr, coordPtr+2, width, 0, |
TkGetButtPoints(coordPtr, coordPtr+2, width, 0, |
1450 |
poly+4, poly+6); |
poly+4, poly+6); |
1451 |
} |
} |
1452 |
poly[8] = poly[0]; |
poly[8] = poly[0]; |
1453 |
poly[9] = poly[1]; |
poly[9] = poly[1]; |
1454 |
dist = TkPolygonToPoint(poly, 5, pointPtr); |
dist = TkPolygonToPoint(poly, 5, pointPtr); |
1455 |
if (dist <= 0.0) { |
if (dist <= 0.0) { |
1456 |
bestDist = 0.0; |
bestDist = 0.0; |
1457 |
goto done; |
goto done; |
1458 |
} else if (dist < bestDist) { |
} else if (dist < bestDist) { |
1459 |
bestDist = dist; |
bestDist = dist; |
1460 |
} |
} |
1461 |
} |
} |
1462 |
|
|
1463 |
/* |
/* |
1464 |
* If caps are rounded, check the distance to the cap around the |
* If caps are rounded, check the distance to the cap around the |
1465 |
* final end point of the line. |
* final end point of the line. |
1466 |
*/ |
*/ |
1467 |
|
|
1468 |
if (linePtr->capStyle == CapRound) { |
if (linePtr->capStyle == CapRound) { |
1469 |
dist = hypot(coordPtr[0] - pointPtr[0], coordPtr[1] - pointPtr[1]) |
dist = hypot(coordPtr[0] - pointPtr[0], coordPtr[1] - pointPtr[1]) |
1470 |
- width/2.0; |
- width/2.0; |
1471 |
if (dist <= 0.0) { |
if (dist <= 0.0) { |
1472 |
bestDist = 0.0; |
bestDist = 0.0; |
1473 |
goto done; |
goto done; |
1474 |
} else if (dist < bestDist) { |
} else if (dist < bestDist) { |
1475 |
bestDist = dist; |
bestDist = dist; |
1476 |
} |
} |
1477 |
} |
} |
1478 |
|
|
1479 |
/* |
/* |
1480 |
* If there are arrowheads, check the distance to the arrowheads. |
* If there are arrowheads, check the distance to the arrowheads. |
1481 |
*/ |
*/ |
1482 |
|
|
1483 |
if (linePtr->arrow != ARROWS_NONE) { |
if (linePtr->arrow != ARROWS_NONE) { |
1484 |
if (linePtr->arrow != ARROWS_LAST) { |
if (linePtr->arrow != ARROWS_LAST) { |
1485 |
dist = TkPolygonToPoint(linePtr->firstArrowPtr, PTS_IN_ARROW, |
dist = TkPolygonToPoint(linePtr->firstArrowPtr, PTS_IN_ARROW, |
1486 |
pointPtr); |
pointPtr); |
1487 |
if (dist <= 0.0) { |
if (dist <= 0.0) { |
1488 |
bestDist = 0.0; |
bestDist = 0.0; |
1489 |
goto done; |
goto done; |
1490 |
} else if (dist < bestDist) { |
} else if (dist < bestDist) { |
1491 |
bestDist = dist; |
bestDist = dist; |
1492 |
} |
} |
1493 |
} |
} |
1494 |
if (linePtr->arrow != ARROWS_FIRST) { |
if (linePtr->arrow != ARROWS_FIRST) { |
1495 |
dist = TkPolygonToPoint(linePtr->lastArrowPtr, PTS_IN_ARROW, |
dist = TkPolygonToPoint(linePtr->lastArrowPtr, PTS_IN_ARROW, |
1496 |
pointPtr); |
pointPtr); |
1497 |
if (dist <= 0.0) { |
if (dist <= 0.0) { |
1498 |
bestDist = 0.0; |
bestDist = 0.0; |
1499 |
goto done; |
goto done; |
1500 |
} else if (dist < bestDist) { |
} else if (dist < bestDist) { |
1501 |
bestDist = dist; |
bestDist = dist; |
1502 |
} |
} |
1503 |
} |
} |
1504 |
} |
} |
1505 |
|
|
1506 |
done: |
done: |
1507 |
if ((linePoints != staticSpace) && (linePoints != linePtr->coordPtr)) { |
if ((linePoints != staticSpace) && (linePoints != linePtr->coordPtr)) { |
1508 |
ckfree((char *) linePoints); |
ckfree((char *) linePoints); |
1509 |
} |
} |
1510 |
return bestDist; |
return bestDist; |
1511 |
} |
} |
1512 |
|
|
1513 |
/* |
/* |
1514 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
1515 |
* |
* |
1516 |
* LineToArea -- |
* LineToArea -- |
1517 |
* |
* |
1518 |
* This procedure is called to determine whether an item |
* This procedure is called to determine whether an item |
1519 |
* lies entirely inside, entirely outside, or overlapping |
* lies entirely inside, entirely outside, or overlapping |
1520 |
* a given rectangular area. |
* a given rectangular area. |
1521 |
* |
* |
1522 |
* Results: |
* Results: |
1523 |
* -1 is returned if the item is entirely outside the |
* -1 is returned if the item is entirely outside the |
1524 |
* area, 0 if it overlaps, and 1 if it is entirely |
* area, 0 if it overlaps, and 1 if it is entirely |
1525 |
* inside the given area. |
* inside the given area. |
1526 |
* |
* |
1527 |
* Side effects: |
* Side effects: |
1528 |
* None. |
* None. |
1529 |
* |
* |
1530 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
1531 |
*/ |
*/ |
1532 |
|
|
1533 |
/* ARGSUSED */ |
/* ARGSUSED */ |
1534 |
static int |
static int |
1535 |
LineToArea(canvas, itemPtr, rectPtr) |
LineToArea(canvas, itemPtr, rectPtr) |
1536 |
Tk_Canvas canvas; /* Canvas containing item. */ |
Tk_Canvas canvas; /* Canvas containing item. */ |
1537 |
Tk_Item *itemPtr; /* Item to check against line. */ |
Tk_Item *itemPtr; /* Item to check against line. */ |
1538 |
double *rectPtr; |
double *rectPtr; |
1539 |
{ |
{ |
1540 |
LineItem *linePtr = (LineItem *) itemPtr; |
LineItem *linePtr = (LineItem *) itemPtr; |
1541 |
double staticSpace[2*MAX_STATIC_POINTS]; |
double staticSpace[2*MAX_STATIC_POINTS]; |
1542 |
double *linePoints; |
double *linePoints; |
1543 |
int numPoints, result; |
int numPoints, result; |
1544 |
double radius, width; |
double radius, width; |
1545 |
Tk_State state = itemPtr->state; |
Tk_State state = itemPtr->state; |
1546 |
|
|
1547 |
if(state == TK_STATE_NULL) { |
if(state == TK_STATE_NULL) { |
1548 |
state = ((TkCanvas *)canvas)->canvas_state; |
state = ((TkCanvas *)canvas)->canvas_state; |
1549 |
} |
} |
1550 |
width = linePtr->outline.width; |
width = linePtr->outline.width; |
1551 |
if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { |
if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { |
1552 |
if (linePtr->outline.activeWidth>width) { |
if (linePtr->outline.activeWidth>width) { |
1553 |
width = linePtr->outline.activeWidth; |
width = linePtr->outline.activeWidth; |
1554 |
} |
} |
1555 |
} else if (state==TK_STATE_DISABLED) { |
} else if (state==TK_STATE_DISABLED) { |
1556 |
if (linePtr->outline.disabledWidth>0) { |
if (linePtr->outline.disabledWidth>0) { |
1557 |
width = linePtr->outline.disabledWidth; |
width = linePtr->outline.disabledWidth; |
1558 |
} |
} |
1559 |
} |
} |
1560 |
|
|
1561 |
radius = (width+1.0)/2.0; |
radius = (width+1.0)/2.0; |
1562 |
|
|
1563 |
if ((state==TK_STATE_HIDDEN) || !linePtr->numPoints) { |
if ((state==TK_STATE_HIDDEN) || !linePtr->numPoints) { |
1564 |
return -1; |
return -1; |
1565 |
} else if (linePtr->numPoints == 1) { |
} else if (linePtr->numPoints == 1) { |
1566 |
double oval[4]; |
double oval[4]; |
1567 |
oval[0] = linePtr->coordPtr[0]-radius; |
oval[0] = linePtr->coordPtr[0]-radius; |
1568 |
oval[1] = linePtr->coordPtr[1]-radius; |
oval[1] = linePtr->coordPtr[1]-radius; |
1569 |
oval[2] = linePtr->coordPtr[0]+radius; |
oval[2] = linePtr->coordPtr[0]+radius; |
1570 |
oval[3] = linePtr->coordPtr[1]+radius; |
oval[3] = linePtr->coordPtr[1]+radius; |
1571 |
return TkOvalToArea(oval, rectPtr); |
return TkOvalToArea(oval, rectPtr); |
1572 |
} |
} |
1573 |
|
|
1574 |
/* |
/* |
1575 |
* Handle smoothed lines by generating an expanded set of points |
* Handle smoothed lines by generating an expanded set of points |
1576 |
* against which to do the check. |
* against which to do the check. |
1577 |
*/ |
*/ |
1578 |
|
|
1579 |
if ((linePtr->smooth) && (linePtr->numPoints > 2)) { |
if ((linePtr->smooth) && (linePtr->numPoints > 2)) { |
1580 |
numPoints = linePtr->smooth->coordProc(canvas, (double *) NULL, |
numPoints = linePtr->smooth->coordProc(canvas, (double *) NULL, |
1581 |
linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL, |
linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL, |
1582 |
(double *) NULL); |
(double *) NULL); |
1583 |
if (numPoints <= MAX_STATIC_POINTS) { |
if (numPoints <= MAX_STATIC_POINTS) { |
1584 |
linePoints = staticSpace; |
linePoints = staticSpace; |
1585 |
} else { |
} else { |
1586 |
linePoints = (double *) ckalloc((unsigned) |
linePoints = (double *) ckalloc((unsigned) |
1587 |
(2*numPoints*sizeof(double))); |
(2*numPoints*sizeof(double))); |
1588 |
} |
} |
1589 |
numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr, |
numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr, |
1590 |
linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL, |
linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL, |
1591 |
linePoints); |
linePoints); |
1592 |
} else { |
} else { |
1593 |
numPoints = linePtr->numPoints; |
numPoints = linePtr->numPoints; |
1594 |
linePoints = linePtr->coordPtr; |
linePoints = linePtr->coordPtr; |
1595 |
} |
} |
1596 |
|
|
1597 |
/* |
/* |
1598 |
* Check the segments of the line. |
* Check the segments of the line. |
1599 |
*/ |
*/ |
1600 |
|
|
1601 |
if (width < 1.0) { |
if (width < 1.0) { |
1602 |
width = 1.0; |
width = 1.0; |
1603 |
} |
} |
1604 |
|
|
1605 |
result = TkThickPolyLineToArea(linePoints, numPoints, |
result = TkThickPolyLineToArea(linePoints, numPoints, |
1606 |
width, linePtr->capStyle, linePtr->joinStyle, |
width, linePtr->capStyle, linePtr->joinStyle, |
1607 |
rectPtr); |
rectPtr); |
1608 |
if (result == 0) { |
if (result == 0) { |
1609 |
goto done; |
goto done; |
1610 |
} |
} |
1611 |
|
|
1612 |
/* |
/* |
1613 |
* Check arrowheads, if any. |
* Check arrowheads, if any. |
1614 |
*/ |
*/ |
1615 |
|
|
1616 |
if (linePtr->arrow != ARROWS_NONE) { |
if (linePtr->arrow != ARROWS_NONE) { |
1617 |
if (linePtr->arrow != ARROWS_LAST) { |
if (linePtr->arrow != ARROWS_LAST) { |
1618 |
if (TkPolygonToArea(linePtr->firstArrowPtr, PTS_IN_ARROW, |
if (TkPolygonToArea(linePtr->firstArrowPtr, PTS_IN_ARROW, |
1619 |
rectPtr) != result) { |
rectPtr) != result) { |
1620 |
result = 0; |
result = 0; |
1621 |
goto done; |
goto done; |
1622 |
} |
} |
1623 |
} |
} |
1624 |
if (linePtr->arrow != ARROWS_FIRST) { |
if (linePtr->arrow != ARROWS_FIRST) { |
1625 |
if (TkPolygonToArea(linePtr->lastArrowPtr, PTS_IN_ARROW, |
if (TkPolygonToArea(linePtr->lastArrowPtr, PTS_IN_ARROW, |
1626 |
rectPtr) != result) { |
rectPtr) != result) { |
1627 |
result = 0; |
result = 0; |
1628 |
goto done; |
goto done; |
1629 |
} |
} |
1630 |
} |
} |
1631 |
} |
} |
1632 |
|
|
1633 |
done: |
done: |
1634 |
if ((linePoints != staticSpace) && (linePoints != linePtr->coordPtr)) { |
if ((linePoints != staticSpace) && (linePoints != linePtr->coordPtr)) { |
1635 |
ckfree((char *) linePoints); |
ckfree((char *) linePoints); |
1636 |
} |
} |
1637 |
return result; |
return result; |
1638 |
} |
} |
1639 |
|
|
1640 |
/* |
/* |
1641 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
1642 |
* |
* |
1643 |
* ScaleLine -- |
* ScaleLine -- |
1644 |
* |
* |
1645 |
* This procedure is invoked to rescale a line item. |
* This procedure is invoked to rescale a line item. |
1646 |
* |
* |
1647 |
* Results: |
* Results: |
1648 |
* None. |
* None. |
1649 |
* |
* |
1650 |
* Side effects: |
* Side effects: |
1651 |
* The line referred to by itemPtr is rescaled so that the |
* The line referred to by itemPtr is rescaled so that the |
1652 |
* following transformation is applied to all point |
* following transformation is applied to all point |
1653 |
* coordinates: |
* coordinates: |
1654 |
* x' = originX + scaleX*(x-originX) |
* x' = originX + scaleX*(x-originX) |
1655 |
* y' = originY + scaleY*(y-originY) |
* y' = originY + scaleY*(y-originY) |
1656 |
* |
* |
1657 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
1658 |
*/ |
*/ |
1659 |
|
|
1660 |
static void |
static void |
1661 |
ScaleLine(canvas, itemPtr, originX, originY, scaleX, scaleY) |
ScaleLine(canvas, itemPtr, originX, originY, scaleX, scaleY) |
1662 |
Tk_Canvas canvas; /* Canvas containing line. */ |
Tk_Canvas canvas; /* Canvas containing line. */ |
1663 |
Tk_Item *itemPtr; /* Line to be scaled. */ |
Tk_Item *itemPtr; /* Line to be scaled. */ |
1664 |
double originX, originY; /* Origin about which to scale rect. */ |
double originX, originY; /* Origin about which to scale rect. */ |
1665 |
double scaleX; /* Amount to scale in X direction. */ |
double scaleX; /* Amount to scale in X direction. */ |
1666 |
double scaleY; /* Amount to scale in Y direction. */ |
double scaleY; /* Amount to scale in Y direction. */ |
1667 |
{ |
{ |
1668 |
LineItem *linePtr = (LineItem *) itemPtr; |
LineItem *linePtr = (LineItem *) itemPtr; |
1669 |
double *coordPtr; |
double *coordPtr; |
1670 |
int i; |
int i; |
1671 |
|
|
1672 |
/* |
/* |
1673 |
* Delete any arrowheads before scaling all the points (so that |
* Delete any arrowheads before scaling all the points (so that |
1674 |
* the end-points of the line get restored). |
* the end-points of the line get restored). |
1675 |
*/ |
*/ |
1676 |
|
|
1677 |
if (linePtr->firstArrowPtr != NULL) { |
if (linePtr->firstArrowPtr != NULL) { |
1678 |
linePtr->coordPtr[0] = linePtr->firstArrowPtr[0]; |
linePtr->coordPtr[0] = linePtr->firstArrowPtr[0]; |
1679 |
linePtr->coordPtr[1] = linePtr->firstArrowPtr[1]; |
linePtr->coordPtr[1] = linePtr->firstArrowPtr[1]; |
1680 |
ckfree((char *) linePtr->firstArrowPtr); |
ckfree((char *) linePtr->firstArrowPtr); |
1681 |
linePtr->firstArrowPtr = NULL; |
linePtr->firstArrowPtr = NULL; |
1682 |
} |
} |
1683 |
if (linePtr->lastArrowPtr != NULL) { |
if (linePtr->lastArrowPtr != NULL) { |
1684 |
int i; |
int i; |
1685 |
|
|
1686 |
i = 2*(linePtr->numPoints-1); |
i = 2*(linePtr->numPoints-1); |
1687 |
linePtr->coordPtr[i] = linePtr->lastArrowPtr[0]; |
linePtr->coordPtr[i] = linePtr->lastArrowPtr[0]; |
1688 |
linePtr->coordPtr[i+1] = linePtr->lastArrowPtr[1]; |
linePtr->coordPtr[i+1] = linePtr->lastArrowPtr[1]; |
1689 |
ckfree((char *) linePtr->lastArrowPtr); |
ckfree((char *) linePtr->lastArrowPtr); |
1690 |
linePtr->lastArrowPtr = NULL; |
linePtr->lastArrowPtr = NULL; |
1691 |
} |
} |
1692 |
for (i = 0, coordPtr = linePtr->coordPtr; i < linePtr->numPoints; |
for (i = 0, coordPtr = linePtr->coordPtr; i < linePtr->numPoints; |
1693 |
i++, coordPtr += 2) { |
i++, coordPtr += 2) { |
1694 |
coordPtr[0] = originX + scaleX*(*coordPtr - originX); |
coordPtr[0] = originX + scaleX*(*coordPtr - originX); |
1695 |
coordPtr[1] = originY + scaleY*(coordPtr[1] - originY); |
coordPtr[1] = originY + scaleY*(coordPtr[1] - originY); |
1696 |
} |
} |
1697 |
if (linePtr->arrow != ARROWS_NONE) { |
if (linePtr->arrow != ARROWS_NONE) { |
1698 |
ConfigureArrows(canvas, linePtr); |
ConfigureArrows(canvas, linePtr); |
1699 |
} |
} |
1700 |
ComputeLineBbox(canvas, linePtr); |
ComputeLineBbox(canvas, linePtr); |
1701 |
} |
} |
1702 |
|
|
1703 |
/* |
/* |
1704 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
1705 |
* |
* |
1706 |
* GetLineIndex -- |
* GetLineIndex -- |
1707 |
* |
* |
1708 |
* Parse an index into a line item and return either its value |
* Parse an index into a line item and return either its value |
1709 |
* or an error. |
* or an error. |
1710 |
* |
* |
1711 |
* Results: |
* Results: |
1712 |
* A standard Tcl result. If all went well, then *indexPtr is |
* A standard Tcl result. If all went well, then *indexPtr is |
1713 |
* filled in with the index (into itemPtr) corresponding to |
* filled in with the index (into itemPtr) corresponding to |
1714 |
* string. Otherwise an error message is left in |
* string. Otherwise an error message is left in |
1715 |
* interp->result. |
* interp->result. |
1716 |
* |
* |
1717 |
* Side effects: |
* Side effects: |
1718 |
* None. |
* None. |
1719 |
* |
* |
1720 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
1721 |
*/ |
*/ |
1722 |
|
|
1723 |
static int |
static int |
1724 |
GetLineIndex(interp, canvas, itemPtr, obj, indexPtr) |
GetLineIndex(interp, canvas, itemPtr, obj, indexPtr) |
1725 |
Tcl_Interp *interp; /* Used for error reporting. */ |
Tcl_Interp *interp; /* Used for error reporting. */ |
1726 |
Tk_Canvas canvas; /* Canvas containing item. */ |
Tk_Canvas canvas; /* Canvas containing item. */ |
1727 |
Tk_Item *itemPtr; /* Item for which the index is being |
Tk_Item *itemPtr; /* Item for which the index is being |
1728 |
* specified. */ |
* specified. */ |
1729 |
Tcl_Obj *obj; /* Specification of a particular coord |
Tcl_Obj *obj; /* Specification of a particular coord |
1730 |
* in itemPtr's line. */ |
* in itemPtr's line. */ |
1731 |
int *indexPtr; /* Where to store converted index. */ |
int *indexPtr; /* Where to store converted index. */ |
1732 |
{ |
{ |
1733 |
LineItem *linePtr = (LineItem *) itemPtr; |
LineItem *linePtr = (LineItem *) itemPtr; |
1734 |
size_t length; |
size_t length; |
1735 |
char *string = Tcl_GetStringFromObj(obj, (int *) &length); |
char *string = Tcl_GetStringFromObj(obj, (int *) &length); |
1736 |
|
|
1737 |
if (string[0] == 'e') { |
if (string[0] == 'e') { |
1738 |
if (strncmp(string, "end", length) == 0) { |
if (strncmp(string, "end", length) == 0) { |
1739 |
*indexPtr = 2*linePtr->numPoints; |
*indexPtr = 2*linePtr->numPoints; |
1740 |
} else { |
} else { |
1741 |
badIndex: |
badIndex: |
1742 |
|
|
1743 |
/* |
/* |
1744 |
* Some of the paths here leave messages in interp->result, |
* Some of the paths here leave messages in interp->result, |
1745 |
* so we have to clear it out before storing our own message. |
* so we have to clear it out before storing our own message. |
1746 |
*/ |
*/ |
1747 |
|
|
1748 |
Tcl_SetResult(interp, (char *) NULL, TCL_STATIC); |
Tcl_SetResult(interp, (char *) NULL, TCL_STATIC); |
1749 |
Tcl_AppendResult(interp, "bad index \"", string, "\"", |
Tcl_AppendResult(interp, "bad index \"", string, "\"", |
1750 |
(char *) NULL); |
(char *) NULL); |
1751 |
return TCL_ERROR; |
return TCL_ERROR; |
1752 |
} |
} |
1753 |
} else if (string[0] == '@') { |
} else if (string[0] == '@') { |
1754 |
int i; |
int i; |
1755 |
double x ,y, bestDist, dist, *coordPtr; |
double x ,y, bestDist, dist, *coordPtr; |
1756 |
char *end, *p; |
char *end, *p; |
1757 |
|
|
1758 |
p = string+1; |
p = string+1; |
1759 |
x = strtod(p, &end); |
x = strtod(p, &end); |
1760 |
if ((end == p) || (*end != ',')) { |
if ((end == p) || (*end != ',')) { |
1761 |
goto badIndex; |
goto badIndex; |
1762 |
} |
} |
1763 |
p = end+1; |
p = end+1; |
1764 |
y = strtod(p, &end); |
y = strtod(p, &end); |
1765 |
if ((end == p) || (*end != 0)) { |
if ((end == p) || (*end != 0)) { |
1766 |
goto badIndex; |
goto badIndex; |
1767 |
} |
} |
1768 |
bestDist = 1.0e36; |
bestDist = 1.0e36; |
1769 |
coordPtr = linePtr->coordPtr; |
coordPtr = linePtr->coordPtr; |
1770 |
*indexPtr = 0; |
*indexPtr = 0; |
1771 |
for(i=0; i<linePtr->numPoints; i++) { |
for(i=0; i<linePtr->numPoints; i++) { |
1772 |
dist = hypot(coordPtr[0] - x, coordPtr[1] - y); |
dist = hypot(coordPtr[0] - x, coordPtr[1] - y); |
1773 |
if (dist<bestDist) { |
if (dist<bestDist) { |
1774 |
bestDist = dist; |
bestDist = dist; |
1775 |
*indexPtr = 2*i; |
*indexPtr = 2*i; |
1776 |
} |
} |
1777 |
coordPtr += 2; |
coordPtr += 2; |
1778 |
} |
} |
1779 |
} else { |
} else { |
1780 |
if (Tcl_GetIntFromObj(interp, obj, indexPtr) != TCL_OK) { |
if (Tcl_GetIntFromObj(interp, obj, indexPtr) != TCL_OK) { |
1781 |
goto badIndex; |
goto badIndex; |
1782 |
} |
} |
1783 |
*indexPtr &= -2; /* if index is odd, make it even */ |
*indexPtr &= -2; /* if index is odd, make it even */ |
1784 |
if (*indexPtr < 0){ |
if (*indexPtr < 0){ |
1785 |
*indexPtr = 0; |
*indexPtr = 0; |
1786 |
} else if (*indexPtr > (2*linePtr->numPoints)) { |
} else if (*indexPtr > (2*linePtr->numPoints)) { |
1787 |
*indexPtr = (2*linePtr->numPoints); |
*indexPtr = (2*linePtr->numPoints); |
1788 |
} |
} |
1789 |
} |
} |
1790 |
return TCL_OK; |
return TCL_OK; |
1791 |
} |
} |
1792 |
|
|
1793 |
/* |
/* |
1794 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
1795 |
* |
* |
1796 |
* TranslateLine -- |
* TranslateLine -- |
1797 |
* |
* |
1798 |
* This procedure is called to move a line by a given amount. |
* This procedure is called to move a line by a given amount. |
1799 |
* |
* |
1800 |
* Results: |
* Results: |
1801 |
* None. |
* None. |
1802 |
* |
* |
1803 |
* Side effects: |
* Side effects: |
1804 |
* The position of the line is offset by (xDelta, yDelta), and |
* The position of the line is offset by (xDelta, yDelta), and |
1805 |
* the bounding box is updated in the generic part of the item |
* the bounding box is updated in the generic part of the item |
1806 |
* structure. |
* structure. |
1807 |
* |
* |
1808 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
1809 |
*/ |
*/ |
1810 |
|
|
1811 |
static void |
static void |
1812 |
TranslateLine(canvas, itemPtr, deltaX, deltaY) |
TranslateLine(canvas, itemPtr, deltaX, deltaY) |
1813 |
Tk_Canvas canvas; /* Canvas containing item. */ |
Tk_Canvas canvas; /* Canvas containing item. */ |
1814 |
Tk_Item *itemPtr; /* Item that is being moved. */ |
Tk_Item *itemPtr; /* Item that is being moved. */ |
1815 |
double deltaX, deltaY; /* Amount by which item is to be |
double deltaX, deltaY; /* Amount by which item is to be |
1816 |
* moved. */ |
* moved. */ |
1817 |
{ |
{ |
1818 |
LineItem *linePtr = (LineItem *) itemPtr; |
LineItem *linePtr = (LineItem *) itemPtr; |
1819 |
double *coordPtr; |
double *coordPtr; |
1820 |
int i; |
int i; |
1821 |
|
|
1822 |
for (i = 0, coordPtr = linePtr->coordPtr; i < linePtr->numPoints; |
for (i = 0, coordPtr = linePtr->coordPtr; i < linePtr->numPoints; |
1823 |
i++, coordPtr += 2) { |
i++, coordPtr += 2) { |
1824 |
coordPtr[0] += deltaX; |
coordPtr[0] += deltaX; |
1825 |
coordPtr[1] += deltaY; |
coordPtr[1] += deltaY; |
1826 |
} |
} |
1827 |
if (linePtr->firstArrowPtr != NULL) { |
if (linePtr->firstArrowPtr != NULL) { |
1828 |
for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW; |
for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW; |
1829 |
i++, coordPtr += 2) { |
i++, coordPtr += 2) { |
1830 |
coordPtr[0] += deltaX; |
coordPtr[0] += deltaX; |
1831 |
coordPtr[1] += deltaY; |
coordPtr[1] += deltaY; |
1832 |
} |
} |
1833 |
} |
} |
1834 |
if (linePtr->lastArrowPtr != NULL) { |
if (linePtr->lastArrowPtr != NULL) { |
1835 |
for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW; |
for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW; |
1836 |
i++, coordPtr += 2) { |
i++, coordPtr += 2) { |
1837 |
coordPtr[0] += deltaX; |
coordPtr[0] += deltaX; |
1838 |
coordPtr[1] += deltaY; |
coordPtr[1] += deltaY; |
1839 |
} |
} |
1840 |
} |
} |
1841 |
ComputeLineBbox(canvas, linePtr); |
ComputeLineBbox(canvas, linePtr); |
1842 |
} |
} |
1843 |
|
|
1844 |
/* |
/* |
1845 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
1846 |
* |
* |
1847 |
* ParseArrowShape -- |
* ParseArrowShape -- |
1848 |
* |
* |
1849 |
* This procedure is called back during option parsing to |
* This procedure is called back during option parsing to |
1850 |
* parse arrow shape information. |
* parse arrow shape information. |
1851 |
* |
* |
1852 |
* Results: |
* Results: |
1853 |
* The return value is a standard Tcl result: TCL_OK means |
* The return value is a standard Tcl result: TCL_OK means |
1854 |
* that the arrow shape information was parsed ok, and |
* that the arrow shape information was parsed ok, and |
1855 |
* TCL_ERROR means it couldn't be parsed. |
* TCL_ERROR means it couldn't be parsed. |
1856 |
* |
* |
1857 |
* Side effects: |
* Side effects: |
1858 |
* Arrow information in recordPtr is updated. |
* Arrow information in recordPtr is updated. |
1859 |
* |
* |
1860 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
1861 |
*/ |
*/ |
1862 |
|
|
1863 |
/* ARGSUSED */ |
/* ARGSUSED */ |
1864 |
static int |
static int |
1865 |
ParseArrowShape(clientData, interp, tkwin, value, recordPtr, offset) |
ParseArrowShape(clientData, interp, tkwin, value, recordPtr, offset) |
1866 |
ClientData clientData; /* Not used. */ |
ClientData clientData; /* Not used. */ |
1867 |
Tcl_Interp *interp; /* Used for error reporting. */ |
Tcl_Interp *interp; /* Used for error reporting. */ |
1868 |
Tk_Window tkwin; /* Not used. */ |
Tk_Window tkwin; /* Not used. */ |
1869 |
CONST char *value; /* Textual specification of arrow shape. */ |
CONST char *value; /* Textual specification of arrow shape. */ |
1870 |
char *recordPtr; /* Pointer to item record in which to |
char *recordPtr; /* Pointer to item record in which to |
1871 |
* store arrow information. */ |
* store arrow information. */ |
1872 |
int offset; /* Offset of shape information in widget |
int offset; /* Offset of shape information in widget |
1873 |
* record. */ |
* record. */ |
1874 |
{ |
{ |
1875 |
LineItem *linePtr = (LineItem *) recordPtr; |
LineItem *linePtr = (LineItem *) recordPtr; |
1876 |
double a, b, c; |
double a, b, c; |
1877 |
int argc; |
int argc; |
1878 |
char **argv = NULL; |
char **argv = NULL; |
1879 |
|
|
1880 |
if (offset != Tk_Offset(LineItem, arrowShapeA)) { |
if (offset != Tk_Offset(LineItem, arrowShapeA)) { |
1881 |
panic("ParseArrowShape received bogus offset"); |
panic("ParseArrowShape received bogus offset"); |
1882 |
} |
} |
1883 |
|
|
1884 |
if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) { |
if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) { |
1885 |
syntaxError: |
syntaxError: |
1886 |
Tcl_ResetResult(interp); |
Tcl_ResetResult(interp); |
1887 |
Tcl_AppendResult(interp, "bad arrow shape \"", value, |
Tcl_AppendResult(interp, "bad arrow shape \"", value, |
1888 |
"\": must be list with three numbers", (char *) NULL); |
"\": must be list with three numbers", (char *) NULL); |
1889 |
if (argv != NULL) { |
if (argv != NULL) { |
1890 |
ckfree((char *) argv); |
ckfree((char *) argv); |
1891 |
} |
} |
1892 |
return TCL_ERROR; |
return TCL_ERROR; |
1893 |
} |
} |
1894 |
if (argc != 3) { |
if (argc != 3) { |
1895 |
goto syntaxError; |
goto syntaxError; |
1896 |
} |
} |
1897 |
if ((Tk_CanvasGetCoord(interp, linePtr->canvas, argv[0], &a) != TCL_OK) |
if ((Tk_CanvasGetCoord(interp, linePtr->canvas, argv[0], &a) != TCL_OK) |
1898 |
|| (Tk_CanvasGetCoord(interp, linePtr->canvas, argv[1], &b) |
|| (Tk_CanvasGetCoord(interp, linePtr->canvas, argv[1], &b) |
1899 |
!= TCL_OK) |
!= TCL_OK) |
1900 |
|| (Tk_CanvasGetCoord(interp, linePtr->canvas, argv[2], &c) |
|| (Tk_CanvasGetCoord(interp, linePtr->canvas, argv[2], &c) |
1901 |
!= TCL_OK)) { |
!= TCL_OK)) { |
1902 |
goto syntaxError; |
goto syntaxError; |
1903 |
} |
} |
1904 |
linePtr->arrowShapeA = (float)a; |
linePtr->arrowShapeA = (float)a; |
1905 |
linePtr->arrowShapeB = (float)b; |
linePtr->arrowShapeB = (float)b; |
1906 |
linePtr->arrowShapeC = (float)c; |
linePtr->arrowShapeC = (float)c; |
1907 |
ckfree((char *) argv); |
ckfree((char *) argv); |
1908 |
return TCL_OK; |
return TCL_OK; |
1909 |
} |
} |
1910 |
|
|
1911 |
/* |
/* |
1912 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
1913 |
* |
* |
1914 |
* PrintArrowShape -- |
* PrintArrowShape -- |
1915 |
* |
* |
1916 |
* This procedure is a callback invoked by the configuration |
* This procedure is a callback invoked by the configuration |
1917 |
* code to return a printable value describing an arrow shape. |
* code to return a printable value describing an arrow shape. |
1918 |
* |
* |
1919 |
* Results: |
* Results: |
1920 |
* None. |
* None. |
1921 |
* |
* |
1922 |
* Side effects: |
* Side effects: |
1923 |
* None. |
* None. |
1924 |
* |
* |
1925 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
1926 |
*/ |
*/ |
1927 |
|
|
1928 |
/* ARGSUSED */ |
/* ARGSUSED */ |
1929 |
static char * |
static char * |
1930 |
PrintArrowShape(clientData, tkwin, recordPtr, offset, freeProcPtr) |
PrintArrowShape(clientData, tkwin, recordPtr, offset, freeProcPtr) |
1931 |
ClientData clientData; /* Not used. */ |
ClientData clientData; /* Not used. */ |
1932 |
Tk_Window tkwin; /* Window associated with linePtr's widget. */ |
Tk_Window tkwin; /* Window associated with linePtr's widget. */ |
1933 |
char *recordPtr; /* Pointer to item record containing current |
char *recordPtr; /* Pointer to item record containing current |
1934 |
* shape information. */ |
* shape information. */ |
1935 |
int offset; /* Offset of arrow information in record. */ |
int offset; /* Offset of arrow information in record. */ |
1936 |
Tcl_FreeProc **freeProcPtr; /* Store address of procedure to call to |
Tcl_FreeProc **freeProcPtr; /* Store address of procedure to call to |
1937 |
* free string here. */ |
* free string here. */ |
1938 |
{ |
{ |
1939 |
LineItem *linePtr = (LineItem *) recordPtr; |
LineItem *linePtr = (LineItem *) recordPtr; |
1940 |
char *buffer; |
char *buffer; |
1941 |
|
|
1942 |
buffer = (char *) ckalloc(120); |
buffer = (char *) ckalloc(120); |
1943 |
sprintf(buffer, "%.5g %.5g %.5g", linePtr->arrowShapeA, |
sprintf(buffer, "%.5g %.5g %.5g", linePtr->arrowShapeA, |
1944 |
linePtr->arrowShapeB, linePtr->arrowShapeC); |
linePtr->arrowShapeB, linePtr->arrowShapeC); |
1945 |
*freeProcPtr = TCL_DYNAMIC; |
*freeProcPtr = TCL_DYNAMIC; |
1946 |
return buffer; |
return buffer; |
1947 |
} |
} |
1948 |
|
|
1949 |
|
|
1950 |
/* |
/* |
1951 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
1952 |
* |
* |
1953 |
* ArrowParseProc -- |
* ArrowParseProc -- |
1954 |
* |
* |
1955 |
* This procedure is invoked during option processing to handle |
* This procedure is invoked during option processing to handle |
1956 |
* the "-arrow" option. |
* the "-arrow" option. |
1957 |
* |
* |
1958 |
* Results: |
* Results: |
1959 |
* A standard Tcl return value. |
* A standard Tcl return value. |
1960 |
* |
* |
1961 |
* Side effects: |
* Side effects: |
1962 |
* The arrow for a given item gets replaced by the arrow |
* The arrow for a given item gets replaced by the arrow |
1963 |
* indicated in the value argument. |
* indicated in the value argument. |
1964 |
* |
* |
1965 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
1966 |
*/ |
*/ |
1967 |
|
|
1968 |
static int |
static int |
1969 |
ArrowParseProc(clientData, interp, tkwin, value, widgRec, offset) |
ArrowParseProc(clientData, interp, tkwin, value, widgRec, offset) |
1970 |
ClientData clientData; /* some flags.*/ |
ClientData clientData; /* some flags.*/ |
1971 |
Tcl_Interp *interp; /* Used for reporting errors. */ |
Tcl_Interp *interp; /* Used for reporting errors. */ |
1972 |
Tk_Window tkwin; /* Window containing canvas widget. */ |
Tk_Window tkwin; /* Window containing canvas widget. */ |
1973 |
CONST char *value; /* Value of option. */ |
CONST char *value; /* Value of option. */ |
1974 |
char *widgRec; /* Pointer to record for item. */ |
char *widgRec; /* Pointer to record for item. */ |
1975 |
int offset; /* Offset into item. */ |
int offset; /* Offset into item. */ |
1976 |
{ |
{ |
1977 |
int c; |
int c; |
1978 |
size_t length; |
size_t length; |
1979 |
|
|
1980 |
register Arrows *arrowPtr = (Arrows *) (widgRec + offset); |
register Arrows *arrowPtr = (Arrows *) (widgRec + offset); |
1981 |
|
|
1982 |
if(value == NULL || *value == 0) { |
if(value == NULL || *value == 0) { |
1983 |
*arrowPtr = ARROWS_NONE; |
*arrowPtr = ARROWS_NONE; |
1984 |
return TCL_OK; |
return TCL_OK; |
1985 |
} |
} |
1986 |
|
|
1987 |
c = value[0]; |
c = value[0]; |
1988 |
length = strlen(value); |
length = strlen(value); |
1989 |
|
|
1990 |
if ((c == 'n') && (strncmp(value, "none", length) == 0)) { |
if ((c == 'n') && (strncmp(value, "none", length) == 0)) { |
1991 |
*arrowPtr = ARROWS_NONE; |
*arrowPtr = ARROWS_NONE; |
1992 |
return TCL_OK; |
return TCL_OK; |
1993 |
} |
} |
1994 |
if ((c == 'f') && (strncmp(value, "first", length) == 0)) { |
if ((c == 'f') && (strncmp(value, "first", length) == 0)) { |
1995 |
*arrowPtr = ARROWS_FIRST; |
*arrowPtr = ARROWS_FIRST; |
1996 |
return TCL_OK; |
return TCL_OK; |
1997 |
} |
} |
1998 |
if ((c == 'l') && (strncmp(value, "last", length) == 0)) { |
if ((c == 'l') && (strncmp(value, "last", length) == 0)) { |
1999 |
*arrowPtr = ARROWS_LAST; |
*arrowPtr = ARROWS_LAST; |
2000 |
return TCL_OK; |
return TCL_OK; |
2001 |
} |
} |
2002 |
if ((c == 'b') && (strncmp(value, "both", length) == 0)) { |
if ((c == 'b') && (strncmp(value, "both", length) == 0)) { |
2003 |
*arrowPtr = ARROWS_BOTH; |
*arrowPtr = ARROWS_BOTH; |
2004 |
return TCL_OK; |
return TCL_OK; |
2005 |
} |
} |
2006 |
|
|
2007 |
Tcl_AppendResult(interp, "bad arrow spec \"", value, |
Tcl_AppendResult(interp, "bad arrow spec \"", value, |
2008 |
"\": must be none, first, last, or both", |
"\": must be none, first, last, or both", |
2009 |
(char *) NULL); |
(char *) NULL); |
2010 |
*arrowPtr = ARROWS_NONE; |
*arrowPtr = ARROWS_NONE; |
2011 |
return TCL_ERROR; |
return TCL_ERROR; |
2012 |
} |
} |
2013 |
|
|
2014 |
/* |
/* |
2015 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
2016 |
* |
* |
2017 |
* ArrowPrintProc -- |
* ArrowPrintProc -- |
2018 |
* |
* |
2019 |
* This procedure is invoked by the Tk configuration code |
* This procedure is invoked by the Tk configuration code |
2020 |
* to produce a printable string for the "-arrow" |
* to produce a printable string for the "-arrow" |
2021 |
* configuration option. |
* configuration option. |
2022 |
* |
* |
2023 |
* Results: |
* Results: |
2024 |
* The return value is a string describing the arrows for |
* The return value is a string describing the arrows for |
2025 |
* the item referred to by "widgRec". In addition, *freeProcPtr |
* the item referred to by "widgRec". In addition, *freeProcPtr |
2026 |
* is filled in with the address of a procedure to call to free |
* is filled in with the address of a procedure to call to free |
2027 |
* the result string when it's no longer needed (or NULL to |
* the result string when it's no longer needed (or NULL to |
2028 |
* indicate that the string doesn't need to be freed). |
* indicate that the string doesn't need to be freed). |
2029 |
* |
* |
2030 |
* Side effects: |
* Side effects: |
2031 |
* None. |
* None. |
2032 |
* |
* |
2033 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
2034 |
*/ |
*/ |
2035 |
|
|
2036 |
static char * |
static char * |
2037 |
ArrowPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) |
ArrowPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) |
2038 |
ClientData clientData; /* Ignored. */ |
ClientData clientData; /* Ignored. */ |
2039 |
Tk_Window tkwin; /* Window containing canvas widget. */ |
Tk_Window tkwin; /* Window containing canvas widget. */ |
2040 |
char *widgRec; /* Pointer to record for item. */ |
char *widgRec; /* Pointer to record for item. */ |
2041 |
int offset; /* Offset into item. */ |
int offset; /* Offset into item. */ |
2042 |
Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with |
Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with |
2043 |
* information about how to reclaim |
* information about how to reclaim |
2044 |
* storage for return string. */ |
* storage for return string. */ |
2045 |
{ |
{ |
2046 |
register Arrows *arrowPtr = (Arrows *) (widgRec + offset); |
register Arrows *arrowPtr = (Arrows *) (widgRec + offset); |
2047 |
|
|
2048 |
switch (*arrowPtr) { |
switch (*arrowPtr) { |
2049 |
case ARROWS_FIRST: |
case ARROWS_FIRST: |
2050 |
return "first"; |
return "first"; |
2051 |
case ARROWS_LAST: |
case ARROWS_LAST: |
2052 |
return "last"; |
return "last"; |
2053 |
case ARROWS_BOTH: |
case ARROWS_BOTH: |
2054 |
return "both"; |
return "both"; |
2055 |
default: |
default: |
2056 |
return "none"; |
return "none"; |
2057 |
} |
} |
2058 |
} |
} |
2059 |
|
|
2060 |
/* |
/* |
2061 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
2062 |
* |
* |
2063 |
* ConfigureArrows -- |
* ConfigureArrows -- |
2064 |
* |
* |
2065 |
* If arrowheads have been requested for a line, this |
* If arrowheads have been requested for a line, this |
2066 |
* procedure makes arrangements for the arrowheads. |
* procedure makes arrangements for the arrowheads. |
2067 |
* |
* |
2068 |
* Results: |
* Results: |
2069 |
* Always returns TCL_OK. |
* Always returns TCL_OK. |
2070 |
* |
* |
2071 |
* Side effects: |
* Side effects: |
2072 |
* Information in linePtr is set up for one or two arrowheads. |
* Information in linePtr is set up for one or two arrowheads. |
2073 |
* the firstArrowPtr and lastArrowPtr polygons are allocated |
* the firstArrowPtr and lastArrowPtr polygons are allocated |
2074 |
* and initialized, if need be, and the end points of the line |
* and initialized, if need be, and the end points of the line |
2075 |
* are adjusted so that a thick line doesn't stick out past |
* are adjusted so that a thick line doesn't stick out past |
2076 |
* the arrowheads. |
* the arrowheads. |
2077 |
* |
* |
2078 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
2079 |
*/ |
*/ |
2080 |
|
|
2081 |
/* ARGSUSED */ |
/* ARGSUSED */ |
2082 |
static int |
static int |
2083 |
ConfigureArrows(canvas, linePtr) |
ConfigureArrows(canvas, linePtr) |
2084 |
Tk_Canvas canvas; /* Canvas in which arrows will be |
Tk_Canvas canvas; /* Canvas in which arrows will be |
2085 |
* displayed (interp and tkwin |
* displayed (interp and tkwin |
2086 |
* fields are needed). */ |
* fields are needed). */ |
2087 |
LineItem *linePtr; /* Item to configure for arrows. */ |
LineItem *linePtr; /* Item to configure for arrows. */ |
2088 |
{ |
{ |
2089 |
double *poly, *coordPtr; |
double *poly, *coordPtr; |
2090 |
double dx, dy, length, sinTheta, cosTheta, temp; |
double dx, dy, length, sinTheta, cosTheta, temp; |
2091 |
double fracHeight; /* Line width as fraction of |
double fracHeight; /* Line width as fraction of |
2092 |
* arrowhead width. */ |
* arrowhead width. */ |
2093 |
double backup; /* Distance to backup end points |
double backup; /* Distance to backup end points |
2094 |
* so the line ends in the middle |
* so the line ends in the middle |
2095 |
* of the arrowhead. */ |
* of the arrowhead. */ |
2096 |
double vertX, vertY; /* Position of arrowhead vertex. */ |
double vertX, vertY; /* Position of arrowhead vertex. */ |
2097 |
double shapeA, shapeB, shapeC; /* Adjusted coordinates (see |
double shapeA, shapeB, shapeC; /* Adjusted coordinates (see |
2098 |
* explanation below). */ |
* explanation below). */ |
2099 |
double width; |
double width; |
2100 |
Tk_State state = linePtr->header.state; |
Tk_State state = linePtr->header.state; |
2101 |
|
|
2102 |
if (linePtr->numPoints <2) { |
if (linePtr->numPoints <2) { |
2103 |
return TCL_OK; |
return TCL_OK; |
2104 |
} |
} |
2105 |
|
|
2106 |
if(state == TK_STATE_NULL) { |
if(state == TK_STATE_NULL) { |
2107 |
state = ((TkCanvas *)canvas)->canvas_state; |
state = ((TkCanvas *)canvas)->canvas_state; |
2108 |
} |
} |
2109 |
|
|
2110 |
width = linePtr->outline.width; |
width = linePtr->outline.width; |
2111 |
if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)linePtr) { |
if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)linePtr) { |
2112 |
if (linePtr->outline.activeWidth>width) { |
if (linePtr->outline.activeWidth>width) { |
2113 |
width = linePtr->outline.activeWidth; |
width = linePtr->outline.activeWidth; |
2114 |
} |
} |
2115 |
} else if (state==TK_STATE_DISABLED) { |
} else if (state==TK_STATE_DISABLED) { |
2116 |
if (linePtr->outline.disabledWidth>0) { |
if (linePtr->outline.disabledWidth>0) { |
2117 |
width = linePtr->outline.disabledWidth; |
width = linePtr->outline.disabledWidth; |
2118 |
} |
} |
2119 |
} |
} |
2120 |
|
|
2121 |
/* |
/* |
2122 |
* The code below makes a tiny increase in the shape parameters |
* The code below makes a tiny increase in the shape parameters |
2123 |
* for the line. This is a bit of a hack, but it seems to result |
* for the line. This is a bit of a hack, but it seems to result |
2124 |
* in displays that more closely approximate the specified parameters. |
* in displays that more closely approximate the specified parameters. |
2125 |
* Without the adjustment, the arrows come out smaller than expected. |
* Without the adjustment, the arrows come out smaller than expected. |
2126 |
*/ |
*/ |
2127 |
|
|
2128 |
shapeA = linePtr->arrowShapeA + 0.001; |
shapeA = linePtr->arrowShapeA + 0.001; |
2129 |
shapeB = linePtr->arrowShapeB + 0.001; |
shapeB = linePtr->arrowShapeB + 0.001; |
2130 |
shapeC = linePtr->arrowShapeC + width/2.0 + 0.001; |
shapeC = linePtr->arrowShapeC + width/2.0 + 0.001; |
2131 |
|
|
2132 |
/* |
/* |
2133 |
* If there's an arrowhead on the first point of the line, compute |
* If there's an arrowhead on the first point of the line, compute |
2134 |
* its polygon and adjust the first point of the line so that the |
* its polygon and adjust the first point of the line so that the |
2135 |
* line doesn't stick out past the leading edge of the arrowhead. |
* line doesn't stick out past the leading edge of the arrowhead. |
2136 |
*/ |
*/ |
2137 |
|
|
2138 |
fracHeight = (width/2.0)/shapeC; |
fracHeight = (width/2.0)/shapeC; |
2139 |
backup = fracHeight*shapeB + shapeA*(1.0 - fracHeight)/2.0; |
backup = fracHeight*shapeB + shapeA*(1.0 - fracHeight)/2.0; |
2140 |
if (linePtr->arrow != ARROWS_LAST) { |
if (linePtr->arrow != ARROWS_LAST) { |
2141 |
poly = linePtr->firstArrowPtr; |
poly = linePtr->firstArrowPtr; |
2142 |
if (poly == NULL) { |
if (poly == NULL) { |
2143 |
poly = (double *) ckalloc((unsigned) |
poly = (double *) ckalloc((unsigned) |
2144 |
(2*PTS_IN_ARROW*sizeof(double))); |
(2*PTS_IN_ARROW*sizeof(double))); |
2145 |
poly[0] = poly[10] = linePtr->coordPtr[0]; |
poly[0] = poly[10] = linePtr->coordPtr[0]; |
2146 |
poly[1] = poly[11] = linePtr->coordPtr[1]; |
poly[1] = poly[11] = linePtr->coordPtr[1]; |
2147 |
linePtr->firstArrowPtr = poly; |
linePtr->firstArrowPtr = poly; |
2148 |
} |
} |
2149 |
dx = poly[0] - linePtr->coordPtr[2]; |
dx = poly[0] - linePtr->coordPtr[2]; |
2150 |
dy = poly[1] - linePtr->coordPtr[3]; |
dy = poly[1] - linePtr->coordPtr[3]; |
2151 |
length = hypot(dx, dy); |
length = hypot(dx, dy); |
2152 |
if (length == 0) { |
if (length == 0) { |
2153 |
sinTheta = cosTheta = 0.0; |
sinTheta = cosTheta = 0.0; |
2154 |
} else { |
} else { |
2155 |
sinTheta = dy/length; |
sinTheta = dy/length; |
2156 |
cosTheta = dx/length; |
cosTheta = dx/length; |
2157 |
} |
} |
2158 |
vertX = poly[0] - shapeA*cosTheta; |
vertX = poly[0] - shapeA*cosTheta; |
2159 |
vertY = poly[1] - shapeA*sinTheta; |
vertY = poly[1] - shapeA*sinTheta; |
2160 |
temp = shapeC*sinTheta; |
temp = shapeC*sinTheta; |
2161 |
poly[2] = poly[0] - shapeB*cosTheta + temp; |
poly[2] = poly[0] - shapeB*cosTheta + temp; |
2162 |
poly[8] = poly[2] - 2*temp; |
poly[8] = poly[2] - 2*temp; |
2163 |
temp = shapeC*cosTheta; |
temp = shapeC*cosTheta; |
2164 |
poly[3] = poly[1] - shapeB*sinTheta - temp; |
poly[3] = poly[1] - shapeB*sinTheta - temp; |
2165 |
poly[9] = poly[3] + 2*temp; |
poly[9] = poly[3] + 2*temp; |
2166 |
poly[4] = poly[2]*fracHeight + vertX*(1.0-fracHeight); |
poly[4] = poly[2]*fracHeight + vertX*(1.0-fracHeight); |
2167 |
poly[5] = poly[3]*fracHeight + vertY*(1.0-fracHeight); |
poly[5] = poly[3]*fracHeight + vertY*(1.0-fracHeight); |
2168 |
poly[6] = poly[8]*fracHeight + vertX*(1.0-fracHeight); |
poly[6] = poly[8]*fracHeight + vertX*(1.0-fracHeight); |
2169 |
poly[7] = poly[9]*fracHeight + vertY*(1.0-fracHeight); |
poly[7] = poly[9]*fracHeight + vertY*(1.0-fracHeight); |
2170 |
|
|
2171 |
/* |
/* |
2172 |
* Polygon done. Now move the first point towards the second so |
* Polygon done. Now move the first point towards the second so |
2173 |
* that the corners at the end of the line are inside the |
* that the corners at the end of the line are inside the |
2174 |
* arrowhead. |
* arrowhead. |
2175 |
*/ |
*/ |
2176 |
|
|
2177 |
linePtr->coordPtr[0] = poly[0] - backup*cosTheta; |
linePtr->coordPtr[0] = poly[0] - backup*cosTheta; |
2178 |
linePtr->coordPtr[1] = poly[1] - backup*sinTheta; |
linePtr->coordPtr[1] = poly[1] - backup*sinTheta; |
2179 |
} |
} |
2180 |
|
|
2181 |
/* |
/* |
2182 |
* Similar arrowhead calculation for the last point of the line. |
* Similar arrowhead calculation for the last point of the line. |
2183 |
*/ |
*/ |
2184 |
|
|
2185 |
if (linePtr->arrow != ARROWS_FIRST) { |
if (linePtr->arrow != ARROWS_FIRST) { |
2186 |
coordPtr = linePtr->coordPtr + 2*(linePtr->numPoints-2); |
coordPtr = linePtr->coordPtr + 2*(linePtr->numPoints-2); |
2187 |
poly = linePtr->lastArrowPtr; |
poly = linePtr->lastArrowPtr; |
2188 |
if (poly == NULL) { |
if (poly == NULL) { |
2189 |
poly = (double *) ckalloc((unsigned) |
poly = (double *) ckalloc((unsigned) |
2190 |
(2*PTS_IN_ARROW*sizeof(double))); |
(2*PTS_IN_ARROW*sizeof(double))); |
2191 |
poly[0] = poly[10] = coordPtr[2]; |
poly[0] = poly[10] = coordPtr[2]; |
2192 |
poly[1] = poly[11] = coordPtr[3]; |
poly[1] = poly[11] = coordPtr[3]; |
2193 |
linePtr->lastArrowPtr = poly; |
linePtr->lastArrowPtr = poly; |
2194 |
} |
} |
2195 |
dx = poly[0] - coordPtr[0]; |
dx = poly[0] - coordPtr[0]; |
2196 |
dy = poly[1] - coordPtr[1]; |
dy = poly[1] - coordPtr[1]; |
2197 |
length = hypot(dx, dy); |
length = hypot(dx, dy); |
2198 |
if (length == 0) { |
if (length == 0) { |
2199 |
sinTheta = cosTheta = 0.0; |
sinTheta = cosTheta = 0.0; |
2200 |
} else { |
} else { |
2201 |
sinTheta = dy/length; |
sinTheta = dy/length; |
2202 |
cosTheta = dx/length; |
cosTheta = dx/length; |
2203 |
} |
} |
2204 |
vertX = poly[0] - shapeA*cosTheta; |
vertX = poly[0] - shapeA*cosTheta; |
2205 |
vertY = poly[1] - shapeA*sinTheta; |
vertY = poly[1] - shapeA*sinTheta; |
2206 |
temp = shapeC*sinTheta; |
temp = shapeC*sinTheta; |
2207 |
poly[2] = poly[0] - shapeB*cosTheta + temp; |
poly[2] = poly[0] - shapeB*cosTheta + temp; |
2208 |
poly[8] = poly[2] - 2*temp; |
poly[8] = poly[2] - 2*temp; |
2209 |
temp = shapeC*cosTheta; |
temp = shapeC*cosTheta; |
2210 |
poly[3] = poly[1] - shapeB*sinTheta - temp; |
poly[3] = poly[1] - shapeB*sinTheta - temp; |
2211 |
poly[9] = poly[3] + 2*temp; |
poly[9] = poly[3] + 2*temp; |
2212 |
poly[4] = poly[2]*fracHeight + vertX*(1.0-fracHeight); |
poly[4] = poly[2]*fracHeight + vertX*(1.0-fracHeight); |
2213 |
poly[5] = poly[3]*fracHeight + vertY*(1.0-fracHeight); |
poly[5] = poly[3]*fracHeight + vertY*(1.0-fracHeight); |
2214 |
poly[6] = poly[8]*fracHeight + vertX*(1.0-fracHeight); |
poly[6] = poly[8]*fracHeight + vertX*(1.0-fracHeight); |
2215 |
poly[7] = poly[9]*fracHeight + vertY*(1.0-fracHeight); |
poly[7] = poly[9]*fracHeight + vertY*(1.0-fracHeight); |
2216 |
coordPtr[2] = poly[0] - backup*cosTheta; |
coordPtr[2] = poly[0] - backup*cosTheta; |
2217 |
coordPtr[3] = poly[1] - backup*sinTheta; |
coordPtr[3] = poly[1] - backup*sinTheta; |
2218 |
} |
} |
2219 |
|
|
2220 |
return TCL_OK; |
return TCL_OK; |
2221 |
} |
} |
2222 |
|
|
2223 |
/* |
/* |
2224 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
2225 |
* |
* |
2226 |
* LineToPostscript -- |
* LineToPostscript -- |
2227 |
* |
* |
2228 |
* This procedure is called to generate Postscript for |
* This procedure is called to generate Postscript for |
2229 |
* line items. |
* line items. |
2230 |
* |
* |
2231 |
* Results: |
* Results: |
2232 |
* The return value is a standard Tcl result. If an error |
* The return value is a standard Tcl result. If an error |
2233 |
* occurs in generating Postscript then an error message is |
* occurs in generating Postscript then an error message is |
2234 |
* left in the interp's result, replacing whatever used |
* left in the interp's result, replacing whatever used |
2235 |
* to be there. If no error occurs, then Postscript for the |
* to be there. If no error occurs, then Postscript for the |
2236 |
* item is appended to the result. |
* item is appended to the result. |
2237 |
* |
* |
2238 |
* Side effects: |
* Side effects: |
2239 |
* None. |
* None. |
2240 |
* |
* |
2241 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
2242 |
*/ |
*/ |
2243 |
|
|
2244 |
static int |
static int |
2245 |
LineToPostscript(interp, canvas, itemPtr, prepass) |
LineToPostscript(interp, canvas, itemPtr, prepass) |
2246 |
Tcl_Interp *interp; /* Leave Postscript or error message |
Tcl_Interp *interp; /* Leave Postscript or error message |
2247 |
* here. */ |
* here. */ |
2248 |
Tk_Canvas canvas; /* Information about overall canvas. */ |
Tk_Canvas canvas; /* Information about overall canvas. */ |
2249 |
Tk_Item *itemPtr; /* Item for which Postscript is |
Tk_Item *itemPtr; /* Item for which Postscript is |
2250 |
* wanted. */ |
* wanted. */ |
2251 |
int prepass; /* 1 means this is a prepass to |
int prepass; /* 1 means this is a prepass to |
2252 |
* collect font information; 0 means |
* collect font information; 0 means |
2253 |
* final Postscript is being created. */ |
* final Postscript is being created. */ |
2254 |
{ |
{ |
2255 |
LineItem *linePtr = (LineItem *) itemPtr; |
LineItem *linePtr = (LineItem *) itemPtr; |
2256 |
char buffer[64 + TCL_INTEGER_SPACE]; |
char buffer[64 + TCL_INTEGER_SPACE]; |
2257 |
char *style; |
char *style; |
2258 |
|
|
2259 |
double width; |
double width; |
2260 |
XColor *color; |
XColor *color; |
2261 |
Pixmap stipple; |
Pixmap stipple; |
2262 |
Tk_State state = itemPtr->state; |
Tk_State state = itemPtr->state; |
2263 |
|
|
2264 |
if(state == TK_STATE_NULL) { |
if(state == TK_STATE_NULL) { |
2265 |
state = ((TkCanvas *)canvas)->canvas_state; |
state = ((TkCanvas *)canvas)->canvas_state; |
2266 |
} |
} |
2267 |
|
|
2268 |
width = linePtr->outline.width; |
width = linePtr->outline.width; |
2269 |
color = linePtr->outline.color; |
color = linePtr->outline.color; |
2270 |
stipple = linePtr->outline.stipple; |
stipple = linePtr->outline.stipple; |
2271 |
if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { |
if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) { |
2272 |
if (linePtr->outline.activeWidth>width) { |
if (linePtr->outline.activeWidth>width) { |
2273 |
width = linePtr->outline.activeWidth; |
width = linePtr->outline.activeWidth; |
2274 |
} |
} |
2275 |
if (linePtr->outline.activeColor!=NULL) { |
if (linePtr->outline.activeColor!=NULL) { |
2276 |
color = linePtr->outline.activeColor; |
color = linePtr->outline.activeColor; |
2277 |
} |
} |
2278 |
if (linePtr->outline.activeStipple!=None) { |
if (linePtr->outline.activeStipple!=None) { |
2279 |
stipple = linePtr->outline.activeStipple; |
stipple = linePtr->outline.activeStipple; |
2280 |
} |
} |
2281 |
} else if (state==TK_STATE_DISABLED) { |
} else if (state==TK_STATE_DISABLED) { |
2282 |
if (linePtr->outline.disabledWidth>0) { |
if (linePtr->outline.disabledWidth>0) { |
2283 |
width = linePtr->outline.disabledWidth; |
width = linePtr->outline.disabledWidth; |
2284 |
} |
} |
2285 |
if (linePtr->outline.disabledColor!=NULL) { |
if (linePtr->outline.disabledColor!=NULL) { |
2286 |
color = linePtr->outline.disabledColor; |
color = linePtr->outline.disabledColor; |
2287 |
} |
} |
2288 |
if (linePtr->outline.disabledStipple!=None) { |
if (linePtr->outline.disabledStipple!=None) { |
2289 |
stipple = linePtr->outline.disabledStipple; |
stipple = linePtr->outline.disabledStipple; |
2290 |
} |
} |
2291 |
} |
} |
2292 |
|
|
2293 |
if (color == NULL || linePtr->numPoints<1 || linePtr->coordPtr==NULL) { |
if (color == NULL || linePtr->numPoints<1 || linePtr->coordPtr==NULL) { |
2294 |
return TCL_OK; |
return TCL_OK; |
2295 |
} |
} |
2296 |
|
|
2297 |
if (linePtr->numPoints==1) { |
if (linePtr->numPoints==1) { |
2298 |
sprintf(buffer, "%.15g %.15g translate %.15g %.15g", |
sprintf(buffer, "%.15g %.15g translate %.15g %.15g", |
2299 |
linePtr->coordPtr[0], Tk_CanvasPsY(canvas, linePtr->coordPtr[1]), |
linePtr->coordPtr[0], Tk_CanvasPsY(canvas, linePtr->coordPtr[1]), |
2300 |
width/2.0, width/2.0); |
width/2.0, width/2.0); |
2301 |
Tcl_AppendResult(interp, "matrix currentmatrix\n",buffer, |
Tcl_AppendResult(interp, "matrix currentmatrix\n",buffer, |
2302 |
" scale 1 0 moveto 0 0 1 0 360 arc\nsetmatrix\n", (char *) NULL); |
" scale 1 0 moveto 0 0 1 0 360 arc\nsetmatrix\n", (char *) NULL); |
2303 |
if (Tk_CanvasPsColor(interp, canvas, color) |
if (Tk_CanvasPsColor(interp, canvas, color) |
2304 |
!= TCL_OK) { |
!= TCL_OK) { |
2305 |
return TCL_ERROR; |
return TCL_ERROR; |
2306 |
} |
} |
2307 |
if (stipple != None) { |
if (stipple != None) { |
2308 |
Tcl_AppendResult(interp, "clip ", (char *) NULL); |
Tcl_AppendResult(interp, "clip ", (char *) NULL); |
2309 |
if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) { |
if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) { |
2310 |
return TCL_ERROR; |
return TCL_ERROR; |
2311 |
} |
} |
2312 |
} else { |
} else { |
2313 |
Tcl_AppendResult(interp, "fill\n", (char *) NULL); |
Tcl_AppendResult(interp, "fill\n", (char *) NULL); |
2314 |
} |
} |
2315 |
return TCL_OK; |
return TCL_OK; |
2316 |
} |
} |
2317 |
/* |
/* |
2318 |
* Generate a path for the line's center-line (do this differently |
* Generate a path for the line's center-line (do this differently |
2319 |
* for straight lines and smoothed lines). |
* for straight lines and smoothed lines). |
2320 |
*/ |
*/ |
2321 |
|
|
2322 |
if ((!linePtr->smooth) || (linePtr->numPoints < 3)) { |
if ((!linePtr->smooth) || (linePtr->numPoints < 3)) { |
2323 |
Tk_CanvasPsPath(interp, canvas, linePtr->coordPtr, linePtr->numPoints); |
Tk_CanvasPsPath(interp, canvas, linePtr->coordPtr, linePtr->numPoints); |
2324 |
} else { |
} else { |
2325 |
if ((stipple == None) && linePtr->smooth->postscriptProc) { |
if ((stipple == None) && linePtr->smooth->postscriptProc) { |
2326 |
linePtr->smooth->postscriptProc(interp, canvas, |
linePtr->smooth->postscriptProc(interp, canvas, |
2327 |
linePtr->coordPtr, linePtr->numPoints, linePtr->splineSteps); |
linePtr->coordPtr, linePtr->numPoints, linePtr->splineSteps); |
2328 |
} else { |
} else { |
2329 |
/* |
/* |
2330 |
* Special hack: Postscript printers don't appear to be able |
* Special hack: Postscript printers don't appear to be able |
2331 |
* to turn a path drawn with "curveto"s into a clipping path |
* to turn a path drawn with "curveto"s into a clipping path |
2332 |
* without exceeding resource limits, so TkMakeBezierPostscript |
* without exceeding resource limits, so TkMakeBezierPostscript |
2333 |
* won't work for stippled curves. Instead, generate all of |
* won't work for stippled curves. Instead, generate all of |
2334 |
* the intermediate points here and output them into the |
* the intermediate points here and output them into the |
2335 |
* Postscript file with "lineto"s instead. |
* Postscript file with "lineto"s instead. |
2336 |
*/ |
*/ |
2337 |
|
|
2338 |
double staticPoints[2*MAX_STATIC_POINTS]; |
double staticPoints[2*MAX_STATIC_POINTS]; |
2339 |
double *pointPtr; |
double *pointPtr; |
2340 |
int numPoints; |
int numPoints; |
2341 |
|
|
2342 |
numPoints = linePtr->smooth->coordProc(canvas, (double *) NULL, |
numPoints = linePtr->smooth->coordProc(canvas, (double *) NULL, |
2343 |
linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL, |
linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL, |
2344 |
(double *) NULL); |
(double *) NULL); |
2345 |
pointPtr = staticPoints; |
pointPtr = staticPoints; |
2346 |
if (numPoints > MAX_STATIC_POINTS) { |
if (numPoints > MAX_STATIC_POINTS) { |
2347 |
pointPtr = (double *) ckalloc((unsigned) |
pointPtr = (double *) ckalloc((unsigned) |
2348 |
(numPoints * 2 * sizeof(double))); |
(numPoints * 2 * sizeof(double))); |
2349 |
} |
} |
2350 |
numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr, |
numPoints = linePtr->smooth->coordProc(canvas, linePtr->coordPtr, |
2351 |
linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL, |
linePtr->numPoints, linePtr->splineSteps, (XPoint *) NULL, |
2352 |
pointPtr); |
pointPtr); |
2353 |
Tk_CanvasPsPath(interp, canvas, pointPtr, numPoints); |
Tk_CanvasPsPath(interp, canvas, pointPtr, numPoints); |
2354 |
if (pointPtr != staticPoints) { |
if (pointPtr != staticPoints) { |
2355 |
ckfree((char *) pointPtr); |
ckfree((char *) pointPtr); |
2356 |
} |
} |
2357 |
} |
} |
2358 |
} |
} |
2359 |
|
|
2360 |
/* |
/* |
2361 |
* Set other line-drawing parameters and stroke out the line. |
* Set other line-drawing parameters and stroke out the line. |
2362 |
*/ |
*/ |
2363 |
|
|
2364 |
style = "0 setlinecap\n"; |
style = "0 setlinecap\n"; |
2365 |
if (linePtr->capStyle == CapRound) { |
if (linePtr->capStyle == CapRound) { |
2366 |
style = "1 setlinecap\n"; |
style = "1 setlinecap\n"; |
2367 |
} else if (linePtr->capStyle == CapProjecting) { |
} else if (linePtr->capStyle == CapProjecting) { |
2368 |
style = "2 setlinecap\n"; |
style = "2 setlinecap\n"; |
2369 |
} |
} |
2370 |
Tcl_AppendResult(interp, style, (char *) NULL); |
Tcl_AppendResult(interp, style, (char *) NULL); |
2371 |
style = "0 setlinejoin\n"; |
style = "0 setlinejoin\n"; |
2372 |
if (linePtr->joinStyle == JoinRound) { |
if (linePtr->joinStyle == JoinRound) { |
2373 |
style = "1 setlinejoin\n"; |
style = "1 setlinejoin\n"; |
2374 |
} else if (linePtr->joinStyle == JoinBevel) { |
} else if (linePtr->joinStyle == JoinBevel) { |
2375 |
style = "2 setlinejoin\n"; |
style = "2 setlinejoin\n"; |
2376 |
} |
} |
2377 |
Tcl_AppendResult(interp, style, (char *) NULL); |
Tcl_AppendResult(interp, style, (char *) NULL); |
2378 |
|
|
2379 |
if (Tk_CanvasPsOutline(canvas, itemPtr, |
if (Tk_CanvasPsOutline(canvas, itemPtr, |
2380 |
&(linePtr->outline)) != TCL_OK) { |
&(linePtr->outline)) != TCL_OK) { |
2381 |
return TCL_ERROR; |
return TCL_ERROR; |
2382 |
} |
} |
2383 |
|
|
2384 |
/* |
/* |
2385 |
* Output polygons for the arrowheads, if there are any. |
* Output polygons for the arrowheads, if there are any. |
2386 |
*/ |
*/ |
2387 |
|
|
2388 |
if (linePtr->firstArrowPtr != NULL) { |
if (linePtr->firstArrowPtr != NULL) { |
2389 |
if (stipple != None) { |
if (stipple != None) { |
2390 |
Tcl_AppendResult(interp, "grestore gsave\n", |
Tcl_AppendResult(interp, "grestore gsave\n", |
2391 |
(char *) NULL); |
(char *) NULL); |
2392 |
} |
} |
2393 |
if (ArrowheadPostscript(interp, canvas, linePtr, |
if (ArrowheadPostscript(interp, canvas, linePtr, |
2394 |
linePtr->firstArrowPtr) != TCL_OK) { |
linePtr->firstArrowPtr) != TCL_OK) { |
2395 |
return TCL_ERROR; |
return TCL_ERROR; |
2396 |
} |
} |
2397 |
} |
} |
2398 |
if (linePtr->lastArrowPtr != NULL) { |
if (linePtr->lastArrowPtr != NULL) { |
2399 |
if (stipple != None) { |
if (stipple != None) { |
2400 |
Tcl_AppendResult(interp, "grestore gsave\n", (char *) NULL); |
Tcl_AppendResult(interp, "grestore gsave\n", (char *) NULL); |
2401 |
} |
} |
2402 |
if (ArrowheadPostscript(interp, canvas, linePtr, |
if (ArrowheadPostscript(interp, canvas, linePtr, |
2403 |
linePtr->lastArrowPtr) != TCL_OK) { |
linePtr->lastArrowPtr) != TCL_OK) { |
2404 |
return TCL_ERROR; |
return TCL_ERROR; |
2405 |
} |
} |
2406 |
} |
} |
2407 |
return TCL_OK; |
return TCL_OK; |
2408 |
} |
} |
2409 |
|
|
2410 |
/* |
/* |
2411 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
2412 |
* |
* |
2413 |
* ArrowheadPostscript -- |
* ArrowheadPostscript -- |
2414 |
* |
* |
2415 |
* This procedure is called to generate Postscript for |
* This procedure is called to generate Postscript for |
2416 |
* an arrowhead for a line item. |
* an arrowhead for a line item. |
2417 |
* |
* |
2418 |
* Results: |
* Results: |
2419 |
* The return value is a standard Tcl result. If an error |
* The return value is a standard Tcl result. If an error |
2420 |
* occurs in generating Postscript then an error message is |
* occurs in generating Postscript then an error message is |
2421 |
* left in the interp's result, replacing whatever used |
* left in the interp's result, replacing whatever used |
2422 |
* to be there. If no error occurs, then Postscript for the |
* to be there. If no error occurs, then Postscript for the |
2423 |
* arrowhead is appended to the result. |
* arrowhead is appended to the result. |
2424 |
* |
* |
2425 |
* Side effects: |
* Side effects: |
2426 |
* None. |
* None. |
2427 |
* |
* |
2428 |
*-------------------------------------------------------------- |
*-------------------------------------------------------------- |
2429 |
*/ |
*/ |
2430 |
|
|
2431 |
static int |
static int |
2432 |
ArrowheadPostscript(interp, canvas, linePtr, arrowPtr) |
ArrowheadPostscript(interp, canvas, linePtr, arrowPtr) |
2433 |
Tcl_Interp *interp; /* Leave Postscript or error message |
Tcl_Interp *interp; /* Leave Postscript or error message |
2434 |
* here. */ |
* here. */ |
2435 |
Tk_Canvas canvas; /* Information about overall canvas. */ |
Tk_Canvas canvas; /* Information about overall canvas. */ |
2436 |
LineItem *linePtr; /* Line item for which Postscript is |
LineItem *linePtr; /* Line item for which Postscript is |
2437 |
* being generated. */ |
* being generated. */ |
2438 |
double *arrowPtr; /* Pointer to first of five points |
double *arrowPtr; /* Pointer to first of five points |
2439 |
* describing arrowhead polygon. */ |
* describing arrowhead polygon. */ |
2440 |
{ |
{ |
2441 |
Pixmap stipple; |
Pixmap stipple; |
2442 |
Tk_State state = linePtr->header.state; |
Tk_State state = linePtr->header.state; |
2443 |
|
|
2444 |
if(state == TK_STATE_NULL) { |
if(state == TK_STATE_NULL) { |
2445 |
state = ((TkCanvas *)canvas)->canvas_state; |
state = ((TkCanvas *)canvas)->canvas_state; |
2446 |
} |
} |
2447 |
|
|
2448 |
stipple = linePtr->outline.stipple; |
stipple = linePtr->outline.stipple; |
2449 |
if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)linePtr) { |
if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)linePtr) { |
2450 |
if (linePtr->outline.activeStipple!=None) { |
if (linePtr->outline.activeStipple!=None) { |
2451 |
stipple = linePtr->outline.activeStipple; |
stipple = linePtr->outline.activeStipple; |
2452 |
} |
} |
2453 |
} else if (state==TK_STATE_DISABLED) { |
} else if (state==TK_STATE_DISABLED) { |
2454 |
if (linePtr->outline.activeStipple!=None) { |
if (linePtr->outline.activeStipple!=None) { |
2455 |
stipple = linePtr->outline.disabledStipple; |
stipple = linePtr->outline.disabledStipple; |
2456 |
} |
} |
2457 |
} |
} |
2458 |
|
|
2459 |
Tk_CanvasPsPath(interp, canvas, arrowPtr, PTS_IN_ARROW); |
Tk_CanvasPsPath(interp, canvas, arrowPtr, PTS_IN_ARROW); |
2460 |
if (stipple != None) { |
if (stipple != None) { |
2461 |
Tcl_AppendResult(interp, "clip ", (char *) NULL); |
Tcl_AppendResult(interp, "clip ", (char *) NULL); |
2462 |
if (Tk_CanvasPsStipple(interp, canvas, stipple) |
if (Tk_CanvasPsStipple(interp, canvas, stipple) |
2463 |
!= TCL_OK) { |
!= TCL_OK) { |
2464 |
return TCL_ERROR; |
return TCL_ERROR; |
2465 |
} |
} |
2466 |
} else { |
} else { |
2467 |
Tcl_AppendResult(interp, "fill\n", (char *) NULL); |
Tcl_AppendResult(interp, "fill\n", (char *) NULL); |
2468 |
} |
} |
2469 |
return TCL_OK; |
return TCL_OK; |
2470 |
} |
} |
2471 |
|
|
2472 |
/* End of tkcanvline.c */ |
/* End of tkcanvline.c */ |