/[dtapublic]/projs/ets/trunk/src/c_tk_base_7_5_w_mods/tkcanvarc.c
ViewVC logotype

Diff of /projs/ets/trunk/src/c_tk_base_7_5_w_mods/tkcanvarc.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 69 by dashley, Sat Nov 5 10:54:17 2016 UTC revision 71 by dashley, Sat Nov 5 11:07:06 2016 UTC
# Line 1  Line 1 
1  /* $Header$ */  /* $Header$ */
2    
3  /*  /*
4   * tkCanvArc.c --   * tkCanvArc.c --
5   *   *
6   *      This file implements arc items for canvas widgets.   *      This file implements arc items for canvas widgets.
7   *   *
8   * Copyright (c) 1992-1994 The Regents of the University of California.   * Copyright (c) 1992-1994 The Regents of the University of California.
9   * Copyright (c) 1994-1997 Sun Microsystems, Inc.   * Copyright (c) 1994-1997 Sun Microsystems, Inc.
10   *   *
11   * See the file "license.terms" for information on usage and redistribution   * See the file "license.terms" for information on usage and redistribution
12   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13   *   *
14   * RCS: @(#) $Id: tkcanvarc.c,v 1.1.1.1 2001/06/13 04:55:11 dtashley Exp $   * RCS: @(#) $Id: tkcanvarc.c,v 1.1.1.1 2001/06/13 04:55:11 dtashley Exp $
15   */   */
16    
17  #include <stdio.h>  #include <stdio.h>
18  #include "tkPort.h"  #include "tkPort.h"
19  #include "tkInt.h"  #include "tkInt.h"
20  #include "tkCanvas.h"  #include "tkCanvas.h"
21  /*  /*
22   * The structure below defines the record for each arc item.   * The structure below defines the record for each arc item.
23   */   */
24    
25  typedef enum {  typedef enum {
26      PIESLICE_STYLE, CHORD_STYLE, ARC_STYLE      PIESLICE_STYLE, CHORD_STYLE, ARC_STYLE
27  } Style;  } Style;
28    
29  typedef struct ArcItem  {  typedef struct ArcItem  {
30      Tk_Item header;             /* Generic stuff that's the same for all      Tk_Item header;             /* Generic stuff that's the same for all
31                                   * types.  MUST BE FIRST IN STRUCTURE. */                                   * types.  MUST BE FIRST IN STRUCTURE. */
32      Tk_Outline outline;         /* Outline structure */      Tk_Outline outline;         /* Outline structure */
33      double bbox[4];             /* Coordinates (x1, y1, x2, y2) of bounding      double bbox[4];             /* Coordinates (x1, y1, x2, y2) of bounding
34                                   * box for oval of which arc is a piece. */                                   * box for oval of which arc is a piece. */
35      double start;               /* Angle at which arc begins, in degrees      double start;               /* Angle at which arc begins, in degrees
36                                   * between 0 and 360. */                                   * between 0 and 360. */
37      double extent;              /* Extent of arc (angular distance from      double extent;              /* Extent of arc (angular distance from
38                                   * start to end of arc) in degrees between                                   * start to end of arc) in degrees between
39                                   * -360 and 360. */                                   * -360 and 360. */
40      double *outlinePtr;         /* Points to (x,y) coordinates for points      double *outlinePtr;         /* Points to (x,y) coordinates for points
41                                   * that define one or two closed polygons                                   * that define one or two closed polygons
42                                   * representing the portion of the outline                                   * representing the portion of the outline
43                                   * that isn't part of the arc (the V-shape                                   * that isn't part of the arc (the V-shape
44                                   * for a pie slice or a line-like segment                                   * for a pie slice or a line-like segment
45                                   * for a chord).  Malloc'ed. */                                   * for a chord).  Malloc'ed. */
46      int numOutlinePoints;       /* Number of points at outlinePtr.  Zero      int numOutlinePoints;       /* Number of points at outlinePtr.  Zero
47                                   * means no space allocated. */                                   * means no space allocated. */
48      Tk_TSOffset tsoffset;      Tk_TSOffset tsoffset;
49      XColor *fillColor;          /* Color for filling arc (used for drawing      XColor *fillColor;          /* Color for filling arc (used for drawing
50                                   * outline too when style is "arc").  NULL                                   * outline too when style is "arc").  NULL
51                                   * means don't fill arc. */                                   * means don't fill arc. */
52      XColor *activeFillColor;    /* Color for filling arc (used for drawing      XColor *activeFillColor;    /* Color for filling arc (used for drawing
53                                   * outline too when style is "arc" and state                                   * outline too when style is "arc" and state
54                                   * is "active").  NULL means use fillColor. */                                   * is "active").  NULL means use fillColor. */
55      XColor *disabledFillColor;  /* Color for filling arc (used for drawing      XColor *disabledFillColor;  /* Color for filling arc (used for drawing
56                                   * outline too when style is "arc" and state                                   * outline too when style is "arc" and state
57                                   * is "disabled". NULL means use fillColor */                                   * is "disabled". NULL means use fillColor */
58      Pixmap fillStipple;         /* Stipple bitmap for filling item. */      Pixmap fillStipple;         /* Stipple bitmap for filling item. */
59      Pixmap activeFillStipple;   /* Stipple bitmap for filling item if state      Pixmap activeFillStipple;   /* Stipple bitmap for filling item if state
60                                   * is active. */                                   * is active. */
61      Pixmap disabledFillStipple; /* Stipple bitmap for filling item if state      Pixmap disabledFillStipple; /* Stipple bitmap for filling item if state
62                                   * is disabled. */                                   * is disabled. */
63      Style style;                /* How to draw arc: arc, chord, or pieslice. */      Style style;                /* How to draw arc: arc, chord, or pieslice. */
64      GC fillGC;                  /* Graphics context for filling item. */      GC fillGC;                  /* Graphics context for filling item. */
65      double center1[2];          /* Coordinates of center of arc outline at      double center1[2];          /* Coordinates of center of arc outline at
66                                   * start (see ComputeArcOutline). */                                   * start (see ComputeArcOutline). */
67      double center2[2];          /* Coordinates of center of arc outline at      double center2[2];          /* Coordinates of center of arc outline at
68                                   * start+extent (see ComputeArcOutline). */                                   * start+extent (see ComputeArcOutline). */
69  } ArcItem;  } ArcItem;
70    
71  /*  /*
72   * The definitions below define the sizes of the polygons used to   * The definitions below define the sizes of the polygons used to
73   * display outline information for various styles of arcs:   * display outline information for various styles of arcs:
74   */   */
75    
76  #define CHORD_OUTLINE_PTS       7  #define CHORD_OUTLINE_PTS       7
77  #define PIE_OUTLINE1_PTS        6  #define PIE_OUTLINE1_PTS        6
78  #define PIE_OUTLINE2_PTS        7  #define PIE_OUTLINE2_PTS        7
79    
80  /*  /*
81   * Information used for parsing configuration specs:   * Information used for parsing configuration specs:
82   */   */
83    
84  static int      StyleParseProc _ANSI_ARGS_((  static int      StyleParseProc _ANSI_ARGS_((
85                      ClientData clientData, Tcl_Interp *interp,                      ClientData clientData, Tcl_Interp *interp,
86                      Tk_Window tkwin, CONST char *value,                      Tk_Window tkwin, CONST char *value,
87                      char *widgRec, int offset));                      char *widgRec, int offset));
88  static char *   StylePrintProc _ANSI_ARGS_((  static char *   StylePrintProc _ANSI_ARGS_((
89                      ClientData clientData, Tk_Window tkwin,                      ClientData clientData, Tk_Window tkwin,
90                      char *widgRec, int offset,                      char *widgRec, int offset,
91                      Tcl_FreeProc **freeProcPtr));                      Tcl_FreeProc **freeProcPtr));
92    
93  static Tk_CustomOption stateOption = {  static Tk_CustomOption stateOption = {
94      (Tk_OptionParseProc *) TkStateParseProc,      (Tk_OptionParseProc *) TkStateParseProc,
95      TkStatePrintProc, (ClientData) 2      TkStatePrintProc, (ClientData) 2
96  };  };
97  static Tk_CustomOption styleOption = {  static Tk_CustomOption styleOption = {
98      (Tk_OptionParseProc *) StyleParseProc,      (Tk_OptionParseProc *) StyleParseProc,
99      StylePrintProc, (ClientData) NULL      StylePrintProc, (ClientData) NULL
100  };  };
101  static Tk_CustomOption tagsOption = {  static Tk_CustomOption tagsOption = {
102      (Tk_OptionParseProc *) Tk_CanvasTagsParseProc,      (Tk_OptionParseProc *) Tk_CanvasTagsParseProc,
103      Tk_CanvasTagsPrintProc, (ClientData) NULL      Tk_CanvasTagsPrintProc, (ClientData) NULL
104  };  };
105  static Tk_CustomOption dashOption = {  static Tk_CustomOption dashOption = {
106      (Tk_OptionParseProc *) TkCanvasDashParseProc,      (Tk_OptionParseProc *) TkCanvasDashParseProc,
107      TkCanvasDashPrintProc, (ClientData) NULL      TkCanvasDashPrintProc, (ClientData) NULL
108  };  };
109  static Tk_CustomOption offsetOption = {  static Tk_CustomOption offsetOption = {
110      (Tk_OptionParseProc *) TkOffsetParseProc,      (Tk_OptionParseProc *) TkOffsetParseProc,
111      TkOffsetPrintProc, (ClientData) (TK_OFFSET_RELATIVE)      TkOffsetPrintProc, (ClientData) (TK_OFFSET_RELATIVE)
112  };  };
113  static Tk_CustomOption pixelOption = {  static Tk_CustomOption pixelOption = {
114      (Tk_OptionParseProc *) TkPixelParseProc,      (Tk_OptionParseProc *) TkPixelParseProc,
115      TkPixelPrintProc, (ClientData) NULL      TkPixelPrintProc, (ClientData) NULL
116  };  };
117    
118  static Tk_ConfigSpec configSpecs[] = {  static Tk_ConfigSpec configSpecs[] = {
119      {TK_CONFIG_CUSTOM, "-activedash", (char *) NULL, (char *) NULL,      {TK_CONFIG_CUSTOM, "-activedash", (char *) NULL, (char *) NULL,
120          (char *) NULL, Tk_Offset(ArcItem, outline.activeDash),          (char *) NULL, Tk_Offset(ArcItem, outline.activeDash),
121          TK_CONFIG_NULL_OK, &dashOption},          TK_CONFIG_NULL_OK, &dashOption},
122      {TK_CONFIG_COLOR, "-activefill", (char *) NULL, (char *) NULL,      {TK_CONFIG_COLOR, "-activefill", (char *) NULL, (char *) NULL,
123          (char *) NULL, Tk_Offset(ArcItem, activeFillColor),          (char *) NULL, Tk_Offset(ArcItem, activeFillColor),
124          TK_CONFIG_NULL_OK},          TK_CONFIG_NULL_OK},
125      {TK_CONFIG_COLOR, "-activeoutline", (char *) NULL, (char *) NULL,      {TK_CONFIG_COLOR, "-activeoutline", (char *) NULL, (char *) NULL,
126          (char *) NULL, Tk_Offset(ArcItem, outline.activeColor),          (char *) NULL, Tk_Offset(ArcItem, outline.activeColor),
127          TK_CONFIG_NULL_OK},          TK_CONFIG_NULL_OK},
128      {TK_CONFIG_BITMAP, "-activeoutlinestipple", (char *) NULL, (char *) NULL,      {TK_CONFIG_BITMAP, "-activeoutlinestipple", (char *) NULL, (char *) NULL,
129          (char *) NULL, Tk_Offset(ArcItem, outline.activeStipple),          (char *) NULL, Tk_Offset(ArcItem, outline.activeStipple),
130          TK_CONFIG_NULL_OK},          TK_CONFIG_NULL_OK},
131      {TK_CONFIG_BITMAP, "-activestipple", (char *) NULL, (char *) NULL,      {TK_CONFIG_BITMAP, "-activestipple", (char *) NULL, (char *) NULL,
132          (char *) NULL, Tk_Offset(ArcItem, activeFillStipple),          (char *) NULL, Tk_Offset(ArcItem, activeFillStipple),
133          TK_CONFIG_NULL_OK},          TK_CONFIG_NULL_OK},
134      {TK_CONFIG_CUSTOM, "-activewidth", (char *) NULL, (char *) NULL,      {TK_CONFIG_CUSTOM, "-activewidth", (char *) NULL, (char *) NULL,
135          "0.0", Tk_Offset(ArcItem, outline.activeWidth),          "0.0", Tk_Offset(ArcItem, outline.activeWidth),
136          TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},          TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
137      {TK_CONFIG_CUSTOM, "-dash", (char *) NULL, (char *) NULL,      {TK_CONFIG_CUSTOM, "-dash", (char *) NULL, (char *) NULL,
138          (char *) NULL, Tk_Offset(ArcItem, outline.dash),          (char *) NULL, Tk_Offset(ArcItem, outline.dash),
139          TK_CONFIG_NULL_OK, &dashOption},          TK_CONFIG_NULL_OK, &dashOption},
140      {TK_CONFIG_PIXELS, "-dashoffset", (char *) NULL, (char *) NULL,      {TK_CONFIG_PIXELS, "-dashoffset", (char *) NULL, (char *) NULL,
141          "0", Tk_Offset(ArcItem, outline.offset), TK_CONFIG_DONT_SET_DEFAULT},          "0", Tk_Offset(ArcItem, outline.offset), TK_CONFIG_DONT_SET_DEFAULT},
142      {TK_CONFIG_CUSTOM, "-disableddash", (char *) NULL, (char *) NULL,      {TK_CONFIG_CUSTOM, "-disableddash", (char *) NULL, (char *) NULL,
143          (char *) NULL, Tk_Offset(ArcItem, outline.disabledDash),          (char *) NULL, Tk_Offset(ArcItem, outline.disabledDash),
144          TK_CONFIG_NULL_OK, &dashOption},          TK_CONFIG_NULL_OK, &dashOption},
145      {TK_CONFIG_COLOR, "-disabledfill", (char *) NULL, (char *) NULL,      {TK_CONFIG_COLOR, "-disabledfill", (char *) NULL, (char *) NULL,
146          (char *) NULL, Tk_Offset(ArcItem, disabledFillColor),          (char *) NULL, Tk_Offset(ArcItem, disabledFillColor),
147          TK_CONFIG_NULL_OK},          TK_CONFIG_NULL_OK},
148      {TK_CONFIG_COLOR, "-disabledoutline", (char *) NULL, (char *) NULL,      {TK_CONFIG_COLOR, "-disabledoutline", (char *) NULL, (char *) NULL,
149          (char *) NULL, Tk_Offset(ArcItem, outline.disabledColor),          (char *) NULL, Tk_Offset(ArcItem, outline.disabledColor),
150          TK_CONFIG_NULL_OK},          TK_CONFIG_NULL_OK},
151      {TK_CONFIG_BITMAP, "-disabledoutlinestipple", (char *) NULL, (char *) NULL,      {TK_CONFIG_BITMAP, "-disabledoutlinestipple", (char *) NULL, (char *) NULL,
152          (char *) NULL, Tk_Offset(ArcItem, outline.disabledStipple),          (char *) NULL, Tk_Offset(ArcItem, outline.disabledStipple),
153          TK_CONFIG_NULL_OK},          TK_CONFIG_NULL_OK},
154      {TK_CONFIG_BITMAP, "-disabledstipple", (char *) NULL, (char *) NULL,      {TK_CONFIG_BITMAP, "-disabledstipple", (char *) NULL, (char *) NULL,
155          (char *) NULL, Tk_Offset(ArcItem, disabledFillStipple),          (char *) NULL, Tk_Offset(ArcItem, disabledFillStipple),
156          TK_CONFIG_NULL_OK},          TK_CONFIG_NULL_OK},
157      {TK_CONFIG_CUSTOM, "-disabledwidth", (char *) NULL, (char *) NULL,      {TK_CONFIG_CUSTOM, "-disabledwidth", (char *) NULL, (char *) NULL,
158          "0.0", Tk_Offset(ArcItem, outline.disabledWidth),          "0.0", Tk_Offset(ArcItem, outline.disabledWidth),
159          TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},          TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
160      {TK_CONFIG_DOUBLE, "-extent", (char *) NULL, (char *) NULL,      {TK_CONFIG_DOUBLE, "-extent", (char *) NULL, (char *) NULL,
161          "90", Tk_Offset(ArcItem, extent), TK_CONFIG_DONT_SET_DEFAULT},          "90", Tk_Offset(ArcItem, extent), TK_CONFIG_DONT_SET_DEFAULT},
162      {TK_CONFIG_COLOR, "-fill", (char *) NULL, (char *) NULL,      {TK_CONFIG_COLOR, "-fill", (char *) NULL, (char *) NULL,
163          (char *) NULL, Tk_Offset(ArcItem, fillColor), TK_CONFIG_NULL_OK},          (char *) NULL, Tk_Offset(ArcItem, fillColor), TK_CONFIG_NULL_OK},
164      {TK_CONFIG_CUSTOM, "-offset", (char *) NULL, (char *) NULL,      {TK_CONFIG_CUSTOM, "-offset", (char *) NULL, (char *) NULL,
165          "0,0", Tk_Offset(ArcItem, tsoffset),          "0,0", Tk_Offset(ArcItem, tsoffset),
166          TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},          TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
167      {TK_CONFIG_COLOR, "-outline", (char *) NULL, (char *) NULL,      {TK_CONFIG_COLOR, "-outline", (char *) NULL, (char *) NULL,
168          "black", Tk_Offset(ArcItem, outline.color), TK_CONFIG_NULL_OK},          "black", Tk_Offset(ArcItem, outline.color), TK_CONFIG_NULL_OK},
169      {TK_CONFIG_CUSTOM, "-outlineoffset", (char *) NULL, (char *) NULL,      {TK_CONFIG_CUSTOM, "-outlineoffset", (char *) NULL, (char *) NULL,
170          "0,0", Tk_Offset(ArcItem, outline.tsoffset),          "0,0", Tk_Offset(ArcItem, outline.tsoffset),
171          TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},          TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
172      {TK_CONFIG_BITMAP, "-outlinestipple", (char *) NULL, (char *) NULL,      {TK_CONFIG_BITMAP, "-outlinestipple", (char *) NULL, (char *) NULL,
173          (char *) NULL, Tk_Offset(ArcItem, outline.stipple),          (char *) NULL, Tk_Offset(ArcItem, outline.stipple),
174          TK_CONFIG_NULL_OK},          TK_CONFIG_NULL_OK},
175      {TK_CONFIG_DOUBLE, "-start", (char *) NULL, (char *) NULL,      {TK_CONFIG_DOUBLE, "-start", (char *) NULL, (char *) NULL,
176          "0", Tk_Offset(ArcItem, start), TK_CONFIG_DONT_SET_DEFAULT},          "0", Tk_Offset(ArcItem, start), TK_CONFIG_DONT_SET_DEFAULT},
177      {TK_CONFIG_CUSTOM, "-state", (char *) NULL, (char *) NULL,      {TK_CONFIG_CUSTOM, "-state", (char *) NULL, (char *) NULL,
178          (char *) NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK,          (char *) NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK,
179          &stateOption},          &stateOption},
180      {TK_CONFIG_BITMAP, "-stipple", (char *) NULL, (char *) NULL,      {TK_CONFIG_BITMAP, "-stipple", (char *) NULL, (char *) NULL,
181          (char *) NULL, Tk_Offset(ArcItem, fillStipple), TK_CONFIG_NULL_OK},          (char *) NULL, Tk_Offset(ArcItem, fillStipple), TK_CONFIG_NULL_OK},
182      {TK_CONFIG_CUSTOM, "-style", (char *) NULL, (char *) NULL,      {TK_CONFIG_CUSTOM, "-style", (char *) NULL, (char *) NULL,
183          (char *) NULL, Tk_Offset(ArcItem, style), TK_CONFIG_DONT_SET_DEFAULT,          (char *) NULL, Tk_Offset(ArcItem, style), TK_CONFIG_DONT_SET_DEFAULT,
184          &styleOption},          &styleOption},
185      {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,      {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
186          (char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},          (char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
187      {TK_CONFIG_CUSTOM, "-width", (char *) NULL, (char *) NULL,      {TK_CONFIG_CUSTOM, "-width", (char *) NULL, (char *) NULL,
188          "1.0", Tk_Offset(ArcItem, outline.width), TK_CONFIG_DONT_SET_DEFAULT,          "1.0", Tk_Offset(ArcItem, outline.width), TK_CONFIG_DONT_SET_DEFAULT,
189          &pixelOption},          &pixelOption},
190      {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,      {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
191          (char *) NULL, 0, 0}          (char *) NULL, 0, 0}
192  };  };
193    
194  /*  /*
195   * Prototypes for procedures defined in this file:   * Prototypes for procedures defined in this file:
196   */   */
197    
198  static void             ComputeArcBbox _ANSI_ARGS_((Tk_Canvas canvas,  static void             ComputeArcBbox _ANSI_ARGS_((Tk_Canvas canvas,
199                              ArcItem *arcPtr));                              ArcItem *arcPtr));
200  static int              ConfigureArc _ANSI_ARGS_((Tcl_Interp *interp,  static int              ConfigureArc _ANSI_ARGS_((Tcl_Interp *interp,
201                              Tk_Canvas canvas, Tk_Item *itemPtr, int argc,                              Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
202                              Tcl_Obj *CONST argv[], int flags));                              Tcl_Obj *CONST argv[], int flags));
203  static int              CreateArc _ANSI_ARGS_((Tcl_Interp *interp,  static int              CreateArc _ANSI_ARGS_((Tcl_Interp *interp,
204                              Tk_Canvas canvas, struct Tk_Item *itemPtr,                              Tk_Canvas canvas, struct Tk_Item *itemPtr,
205                              int argc, Tcl_Obj *CONST argv[]));                              int argc, Tcl_Obj *CONST argv[]));
206  static void             DeleteArc _ANSI_ARGS_((Tk_Canvas canvas,  static void             DeleteArc _ANSI_ARGS_((Tk_Canvas canvas,
207                              Tk_Item *itemPtr, Display *display));                              Tk_Item *itemPtr, Display *display));
208  static void             DisplayArc _ANSI_ARGS_((Tk_Canvas canvas,  static void             DisplayArc _ANSI_ARGS_((Tk_Canvas canvas,
209                              Tk_Item *itemPtr, Display *display, Drawable dst,                              Tk_Item *itemPtr, Display *display, Drawable dst,
210                              int x, int y, int width, int height));                              int x, int y, int width, int height));
211  static int              ArcCoords _ANSI_ARGS_((Tcl_Interp *interp,  static int              ArcCoords _ANSI_ARGS_((Tcl_Interp *interp,
212                              Tk_Canvas canvas, Tk_Item *itemPtr, int argc,                              Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
213                              Tcl_Obj *CONST argv[]));                              Tcl_Obj *CONST argv[]));
214  static int              ArcToArea _ANSI_ARGS_((Tk_Canvas canvas,  static int              ArcToArea _ANSI_ARGS_((Tk_Canvas canvas,
215                              Tk_Item *itemPtr, double *rectPtr));                              Tk_Item *itemPtr, double *rectPtr));
216  static double           ArcToPoint _ANSI_ARGS_((Tk_Canvas canvas,  static double           ArcToPoint _ANSI_ARGS_((Tk_Canvas canvas,
217                              Tk_Item *itemPtr, double *coordPtr));                              Tk_Item *itemPtr, double *coordPtr));
218  static int              ArcToPostscript _ANSI_ARGS_((Tcl_Interp *interp,  static int              ArcToPostscript _ANSI_ARGS_((Tcl_Interp *interp,
219                              Tk_Canvas canvas, Tk_Item *itemPtr, int prepass));                              Tk_Canvas canvas, Tk_Item *itemPtr, int prepass));
220  static void             ScaleArc _ANSI_ARGS_((Tk_Canvas canvas,  static void             ScaleArc _ANSI_ARGS_((Tk_Canvas canvas,
221                              Tk_Item *itemPtr, double originX, double originY,                              Tk_Item *itemPtr, double originX, double originY,
222                              double scaleX, double scaleY));                              double scaleX, double scaleY));
223  static void             TranslateArc _ANSI_ARGS_((Tk_Canvas canvas,  static void             TranslateArc _ANSI_ARGS_((Tk_Canvas canvas,
224                              Tk_Item *itemPtr, double deltaX, double deltaY));                              Tk_Item *itemPtr, double deltaX, double deltaY));
225  static int              AngleInRange _ANSI_ARGS_((double x, double y,  static int              AngleInRange _ANSI_ARGS_((double x, double y,
226                              double start, double extent));                              double start, double extent));
227  static void             ComputeArcOutline _ANSI_ARGS_((Tk_Canvas canvas,  static void             ComputeArcOutline _ANSI_ARGS_((Tk_Canvas canvas,
228                              ArcItem *arcPtr));                              ArcItem *arcPtr));
229  static int              HorizLineToArc _ANSI_ARGS_((double x1, double x2,  static int              HorizLineToArc _ANSI_ARGS_((double x1, double x2,
230                              double y, double rx, double ry,                              double y, double rx, double ry,
231                              double start, double extent));                              double start, double extent));
232  static int              VertLineToArc _ANSI_ARGS_((double x, double y1,  static int              VertLineToArc _ANSI_ARGS_((double x, double y1,
233                              double y2, double rx, double ry,                              double y2, double rx, double ry,
234                              double start, double extent));                              double start, double extent));
235    
236  /*  /*
237   * The structures below defines the arc item types by means of procedures   * The structures below defines the arc item types by means of procedures
238   * that can be invoked by generic item code.   * that can be invoked by generic item code.
239   */   */
240    
241  Tk_ItemType tkArcType = {  Tk_ItemType tkArcType = {
242      "arc",                              /* name */      "arc",                              /* name */
243      sizeof(ArcItem),                    /* itemSize */      sizeof(ArcItem),                    /* itemSize */
244      CreateArc,                          /* createProc */      CreateArc,                          /* createProc */
245      configSpecs,                        /* configSpecs */      configSpecs,                        /* configSpecs */
246      ConfigureArc,                       /* configureProc */      ConfigureArc,                       /* configureProc */
247      ArcCoords,                          /* coordProc */      ArcCoords,                          /* coordProc */
248      DeleteArc,                          /* deleteProc */      DeleteArc,                          /* deleteProc */
249      DisplayArc,                         /* displayProc */      DisplayArc,                         /* displayProc */
250      TK_CONFIG_OBJS,                     /* flags */      TK_CONFIG_OBJS,                     /* flags */
251      ArcToPoint,                         /* pointProc */      ArcToPoint,                         /* pointProc */
252      ArcToArea,                          /* areaProc */      ArcToArea,                          /* areaProc */
253      ArcToPostscript,                    /* postscriptProc */      ArcToPostscript,                    /* postscriptProc */
254      ScaleArc,                           /* scaleProc */      ScaleArc,                           /* scaleProc */
255      TranslateArc,                       /* translateProc */      TranslateArc,                       /* translateProc */
256      (Tk_ItemIndexProc *) NULL,          /* indexProc */      (Tk_ItemIndexProc *) NULL,          /* indexProc */
257      (Tk_ItemCursorProc *) NULL,         /* icursorProc */      (Tk_ItemCursorProc *) NULL,         /* icursorProc */
258      (Tk_ItemSelectionProc *) NULL,      /* selectionProc */      (Tk_ItemSelectionProc *) NULL,      /* selectionProc */
259      (Tk_ItemInsertProc *) NULL,         /* insertProc */      (Tk_ItemInsertProc *) NULL,         /* insertProc */
260      (Tk_ItemDCharsProc *) NULL,         /* dTextProc */      (Tk_ItemDCharsProc *) NULL,         /* dTextProc */
261      (Tk_ItemType *) NULL,               /* nextPtr */      (Tk_ItemType *) NULL,               /* nextPtr */
262  };  };
263    
264  #ifndef PI  #ifndef PI
265  #    define PI 3.14159265358979323846  #    define PI 3.14159265358979323846
266  #endif  #endif
267    
268    
269  /*  /*
270   *--------------------------------------------------------------   *--------------------------------------------------------------
271   *   *
272   * CreateArc --   * CreateArc --
273   *   *
274   *      This procedure is invoked to create a new arc item in   *      This procedure is invoked to create a new arc item in
275   *      a canvas.   *      a canvas.
276   *   *
277   * Results:   * Results:
278   *      A standard Tcl return value.  If an error occurred in   *      A standard Tcl return value.  If an error occurred in
279   *      creating the item, then an error message is left in   *      creating the item, then an error message is left in
280   *      the interp's result;  in this case itemPtr is   *      the interp's result;  in this case itemPtr is
281   *      left uninitialized, so it can be safely freed by the   *      left uninitialized, so it can be safely freed by the
282   *      caller.   *      caller.
283   *   *
284   * Side effects:   * Side effects:
285   *      A new arc item is created.   *      A new arc item is created.
286   *   *
287   *--------------------------------------------------------------   *--------------------------------------------------------------
288   */   */
289    
290  static int  static int
291  CreateArc(interp, canvas, itemPtr, argc, argv)  CreateArc(interp, canvas, itemPtr, argc, argv)
292      Tcl_Interp *interp;                 /* Interpreter for error reporting. */      Tcl_Interp *interp;                 /* Interpreter for error reporting. */
293      Tk_Canvas canvas;                   /* Canvas to hold new item. */      Tk_Canvas canvas;                   /* Canvas to hold new item. */
294      Tk_Item *itemPtr;                   /* Record to hold new item;  header      Tk_Item *itemPtr;                   /* Record to hold new item;  header
295                                           * has been initialized by caller. */                                           * has been initialized by caller. */
296      int argc;                           /* Number of arguments in argv. */      int argc;                           /* Number of arguments in argv. */
297      Tcl_Obj *CONST argv[];              /* Arguments describing arc. */      Tcl_Obj *CONST argv[];              /* Arguments describing arc. */
298  {  {
299      ArcItem *arcPtr = (ArcItem *) itemPtr;      ArcItem *arcPtr = (ArcItem *) itemPtr;
300      int i;      int i;
301    
302      if (argc==1) {      if (argc==1) {
303          i = 1;          i = 1;
304      } else {      } else {
305          char *arg = Tcl_GetStringFromObj(argv[1], NULL);          char *arg = Tcl_GetStringFromObj(argv[1], NULL);
306          if ((argc>1) && (arg[0] == '-')          if ((argc>1) && (arg[0] == '-')
307                  && (arg[1] >= 'a') && (arg[1] <= 'z')) {                  && (arg[1] >= 'a') && (arg[1] <= 'z')) {
308              i = 1;              i = 1;
309          } else {          } else {
310              i = 4;              i = 4;
311          }          }
312      }      }
313      if (argc < i) {      if (argc < i) {
314          Tcl_AppendResult(interp, "wrong # args: should be \"",          Tcl_AppendResult(interp, "wrong # args: should be \"",
315                  Tk_PathName(Tk_CanvasTkwin(canvas)), " create ",                  Tk_PathName(Tk_CanvasTkwin(canvas)), " create ",
316                  itemPtr->typePtr->name, " x1 y1 x2 y2 ?options?\"",                  itemPtr->typePtr->name, " x1 y1 x2 y2 ?options?\"",
317                  (char *) NULL);                  (char *) NULL);
318          return TCL_ERROR;          return TCL_ERROR;
319      }      }
320    
321      /*      /*
322       * Carry out initialization that is needed in order to clean       * Carry out initialization that is needed in order to clean
323       * up after errors during the the remainder of this procedure.       * up after errors during the the remainder of this procedure.
324       */       */
325    
326      Tk_CreateOutline(&(arcPtr->outline));      Tk_CreateOutline(&(arcPtr->outline));
327      arcPtr->start = 0;      arcPtr->start = 0;
328      arcPtr->extent = 90;      arcPtr->extent = 90;
329      arcPtr->outlinePtr = NULL;      arcPtr->outlinePtr = NULL;
330      arcPtr->numOutlinePoints = 0;      arcPtr->numOutlinePoints = 0;
331      arcPtr->tsoffset.flags = 0;      arcPtr->tsoffset.flags = 0;
332      arcPtr->tsoffset.xoffset = 0;      arcPtr->tsoffset.xoffset = 0;
333      arcPtr->tsoffset.yoffset = 0;      arcPtr->tsoffset.yoffset = 0;
334      arcPtr->fillColor = NULL;      arcPtr->fillColor = NULL;
335      arcPtr->activeFillColor = NULL;      arcPtr->activeFillColor = NULL;
336      arcPtr->disabledFillColor = NULL;      arcPtr->disabledFillColor = NULL;
337      arcPtr->fillStipple = None;      arcPtr->fillStipple = None;
338      arcPtr->activeFillStipple = None;      arcPtr->activeFillStipple = None;
339      arcPtr->disabledFillStipple = None;      arcPtr->disabledFillStipple = None;
340      arcPtr->style = PIESLICE_STYLE;      arcPtr->style = PIESLICE_STYLE;
341      arcPtr->fillGC = None;      arcPtr->fillGC = None;
342    
343      /*      /*
344       * Process the arguments to fill in the item record.       * Process the arguments to fill in the item record.
345       */       */
346    
347      if ((ArcCoords(interp, canvas, itemPtr, i, argv) != TCL_OK)) {      if ((ArcCoords(interp, canvas, itemPtr, i, argv) != TCL_OK)) {
348          goto error;          goto error;
349      }      }
350      if (ConfigureArc(interp, canvas, itemPtr, argc-4, argv+4, 0) == TCL_OK) {      if (ConfigureArc(interp, canvas, itemPtr, argc-4, argv+4, 0) == TCL_OK) {
351          return TCL_OK;          return TCL_OK;
352      }      }
353      error:      error:
354      DeleteArc(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));      DeleteArc(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas)));
355      return TCL_ERROR;      return TCL_ERROR;
356  }  }
357    
358  /*  /*
359   *--------------------------------------------------------------   *--------------------------------------------------------------
360   *   *
361   * ArcCoords --   * ArcCoords --
362   *   *
363   *      This procedure is invoked to process the "coords" widget   *      This procedure is invoked to process the "coords" widget
364   *      command on arcs.  See the user documentation for details   *      command on arcs.  See the user documentation for details
365   *      on what it does.   *      on what it does.
366   *   *
367   * Results:   * Results:
368   *      Returns TCL_OK or TCL_ERROR, and sets the interp's result.   *      Returns TCL_OK or TCL_ERROR, and sets the interp's result.
369   *   *
370   * Side effects:   * Side effects:
371   *      The coordinates for the given item may be changed.   *      The coordinates for the given item may be changed.
372   *   *
373   *--------------------------------------------------------------   *--------------------------------------------------------------
374   */   */
375    
376  static int  static int
377  ArcCoords(interp, canvas, itemPtr, argc, argv)  ArcCoords(interp, canvas, itemPtr, argc, argv)
378      Tcl_Interp *interp;                 /* Used for error reporting. */      Tcl_Interp *interp;                 /* Used for error reporting. */
379      Tk_Canvas canvas;                   /* Canvas containing item. */      Tk_Canvas canvas;                   /* Canvas containing item. */
380      Tk_Item *itemPtr;                   /* Item whose coordinates are to be      Tk_Item *itemPtr;                   /* Item whose coordinates are to be
381                                           * read or modified. */                                           * read or modified. */
382      int argc;                           /* Number of coordinates supplied in      int argc;                           /* Number of coordinates supplied in
383                                           * argv. */                                           * argv. */
384      Tcl_Obj *CONST argv[];              /* Array of coordinates: x1, y1,      Tcl_Obj *CONST argv[];              /* Array of coordinates: x1, y1,
385                                           * x2, y2, ... */                                           * x2, y2, ... */
386  {  {
387      ArcItem *arcPtr = (ArcItem *) itemPtr;      ArcItem *arcPtr = (ArcItem *) itemPtr;
388    
389      if (argc == 0) {      if (argc == 0) {
390          Tcl_Obj *obj = Tcl_NewObj();          Tcl_Obj *obj = Tcl_NewObj();
391          Tcl_Obj *subobj = Tcl_NewDoubleObj(arcPtr->bbox[0]);          Tcl_Obj *subobj = Tcl_NewDoubleObj(arcPtr->bbox[0]);
392          Tcl_ListObjAppendElement(interp, obj, subobj);          Tcl_ListObjAppendElement(interp, obj, subobj);
393          subobj = Tcl_NewDoubleObj(arcPtr->bbox[1]);          subobj = Tcl_NewDoubleObj(arcPtr->bbox[1]);
394          Tcl_ListObjAppendElement(interp, obj, subobj);          Tcl_ListObjAppendElement(interp, obj, subobj);
395          subobj = Tcl_NewDoubleObj(arcPtr->bbox[2]);          subobj = Tcl_NewDoubleObj(arcPtr->bbox[2]);
396          Tcl_ListObjAppendElement(interp, obj, subobj);          Tcl_ListObjAppendElement(interp, obj, subobj);
397          subobj = Tcl_NewDoubleObj(arcPtr->bbox[3]);          subobj = Tcl_NewDoubleObj(arcPtr->bbox[3]);
398          Tcl_ListObjAppendElement(interp, obj, subobj);          Tcl_ListObjAppendElement(interp, obj, subobj);
399          Tcl_SetObjResult(interp, obj);          Tcl_SetObjResult(interp, obj);
400      } else if ((argc == 1)||(argc == 4)) {      } else if ((argc == 1)||(argc == 4)) {
401          if (argc==1) {          if (argc==1) {
402              if (Tcl_ListObjGetElements(interp, argv[0], &argc,              if (Tcl_ListObjGetElements(interp, argv[0], &argc,
403                      (Tcl_Obj ***) &argv) != TCL_OK) {                      (Tcl_Obj ***) &argv) != TCL_OK) {
404                  return TCL_ERROR;                  return TCL_ERROR;
405              } else if (argc != 4) {              } else if (argc != 4) {
406                  char buf[64 + TCL_INTEGER_SPACE];                  char buf[64 + TCL_INTEGER_SPACE];
407                    
408                  sprintf(buf, "wrong # coordinates: expected 4, got %d", argc);                  sprintf(buf, "wrong # coordinates: expected 4, got %d", argc);
409                  Tcl_SetResult(interp, buf, TCL_VOLATILE);                  Tcl_SetResult(interp, buf, TCL_VOLATILE);
410                  return TCL_ERROR;                  return TCL_ERROR;
411              }              }
412          }          }
413          if ((Tk_CanvasGetCoordFromObj(interp, canvas, argv[0],          if ((Tk_CanvasGetCoordFromObj(interp, canvas, argv[0],
414                      &arcPtr->bbox[0]) != TCL_OK)                      &arcPtr->bbox[0]) != TCL_OK)
415                  || (Tk_CanvasGetCoordFromObj(interp, canvas, argv[1],                  || (Tk_CanvasGetCoordFromObj(interp, canvas, argv[1],
416                      &arcPtr->bbox[1]) != TCL_OK)                      &arcPtr->bbox[1]) != TCL_OK)
417                  || (Tk_CanvasGetCoordFromObj(interp, canvas, argv[2],                  || (Tk_CanvasGetCoordFromObj(interp, canvas, argv[2],
418                          &arcPtr->bbox[2]) != TCL_OK)                          &arcPtr->bbox[2]) != TCL_OK)
419                  || (Tk_CanvasGetCoordFromObj(interp, canvas, argv[3],                  || (Tk_CanvasGetCoordFromObj(interp, canvas, argv[3],
420                          &arcPtr->bbox[3]) != TCL_OK)) {                          &arcPtr->bbox[3]) != TCL_OK)) {
421              return TCL_ERROR;              return TCL_ERROR;
422          }          }
423          ComputeArcBbox(canvas, arcPtr);          ComputeArcBbox(canvas, arcPtr);
424      } else {      } else {
425          char buf[64 + TCL_INTEGER_SPACE];          char buf[64 + TCL_INTEGER_SPACE];
426                    
427          sprintf(buf, "wrong # coordinates: expected 0 or 4, got %d", argc);          sprintf(buf, "wrong # coordinates: expected 0 or 4, got %d", argc);
428          Tcl_SetResult(interp, buf, TCL_VOLATILE);          Tcl_SetResult(interp, buf, TCL_VOLATILE);
429          return TCL_ERROR;          return TCL_ERROR;
430      }      }
431      return TCL_OK;      return TCL_OK;
432  }  }
433    
434  /*  /*
435   *--------------------------------------------------------------   *--------------------------------------------------------------
436   *   *
437   * ConfigureArc --   * ConfigureArc --
438   *   *
439   *      This procedure is invoked to configure various aspects   *      This procedure is invoked to configure various aspects
440   *      of a arc item, such as its outline and fill colors.   *      of a arc item, such as its outline and fill colors.
441   *   *
442   * Results:   * Results:
443   *      A standard Tcl result code.  If an error occurs, then   *      A standard Tcl result code.  If an error occurs, then
444   *      an error message is left in the interp's result.   *      an error message is left in the interp's result.
445   *   *
446   * Side effects:   * Side effects:
447   *      Configuration information, such as colors and stipple   *      Configuration information, such as colors and stipple
448   *      patterns, may be set for itemPtr.   *      patterns, may be set for itemPtr.
449   *   *
450   *--------------------------------------------------------------   *--------------------------------------------------------------
451   */   */
452    
453  static int  static int
454  ConfigureArc(interp, canvas, itemPtr, argc, argv, flags)  ConfigureArc(interp, canvas, itemPtr, argc, argv, flags)
455      Tcl_Interp *interp;         /* Used for error reporting. */      Tcl_Interp *interp;         /* Used for error reporting. */
456      Tk_Canvas canvas;           /* Canvas containing itemPtr. */      Tk_Canvas canvas;           /* Canvas containing itemPtr. */
457      Tk_Item *itemPtr;           /* Arc item to reconfigure. */      Tk_Item *itemPtr;           /* Arc item to reconfigure. */
458      int argc;                   /* Number of elements in argv.  */      int argc;                   /* Number of elements in argv.  */
459      Tcl_Obj *CONST argv[];      /* Arguments describing things to configure. */      Tcl_Obj *CONST argv[];      /* Arguments describing things to configure. */
460      int flags;                  /* Flags to pass to Tk_ConfigureWidget. */      int flags;                  /* Flags to pass to Tk_ConfigureWidget. */
461  {  {
462      ArcItem *arcPtr = (ArcItem *) itemPtr;      ArcItem *arcPtr = (ArcItem *) itemPtr;
463      XGCValues gcValues;      XGCValues gcValues;
464      GC newGC;      GC newGC;
465      unsigned long mask;      unsigned long mask;
466      int i;      int i;
467      Tk_Window tkwin;      Tk_Window tkwin;
468      Tk_TSOffset *tsoffset;      Tk_TSOffset *tsoffset;
469      XColor *color;      XColor *color;
470      Pixmap stipple;      Pixmap stipple;
471      Tk_State state;      Tk_State state;
472    
473      tkwin = Tk_CanvasTkwin(canvas);      tkwin = Tk_CanvasTkwin(canvas);
474      if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, (char **) argv,      if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, (char **) argv,
475              (char *) arcPtr, flags|TK_CONFIG_OBJS) != TCL_OK) {              (char *) arcPtr, flags|TK_CONFIG_OBJS) != TCL_OK) {
476          return TCL_ERROR;          return TCL_ERROR;
477      }      }
478    
479      state = itemPtr->state;      state = itemPtr->state;
480    
481      /*      /*
482       * A few of the options require additional processing, such as       * A few of the options require additional processing, such as
483       * style and graphics contexts.       * style and graphics contexts.
484       */       */
485    
486      if (arcPtr->outline.activeWidth > arcPtr->outline.width ||      if (arcPtr->outline.activeWidth > arcPtr->outline.width ||
487              arcPtr->outline.activeDash.number != 0 ||              arcPtr->outline.activeDash.number != 0 ||
488              arcPtr->outline.activeColor != NULL ||              arcPtr->outline.activeColor != NULL ||
489              arcPtr->outline.activeStipple != None ||              arcPtr->outline.activeStipple != None ||
490              arcPtr->activeFillColor != NULL ||              arcPtr->activeFillColor != NULL ||
491              arcPtr->activeFillStipple != None) {              arcPtr->activeFillStipple != None) {
492          itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;          itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
493      } else {      } else {
494          itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;          itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
495      }      }
496    
497      tsoffset = &arcPtr->outline.tsoffset;      tsoffset = &arcPtr->outline.tsoffset;
498      flags = tsoffset->flags;      flags = tsoffset->flags;
499      if (flags & TK_OFFSET_LEFT) {      if (flags & TK_OFFSET_LEFT) {
500          tsoffset->xoffset = (int) (arcPtr->bbox[0] + 0.5);          tsoffset->xoffset = (int) (arcPtr->bbox[0] + 0.5);
501      } else if (flags & TK_OFFSET_CENTER) {      } else if (flags & TK_OFFSET_CENTER) {
502          tsoffset->xoffset = (int) ((arcPtr->bbox[0]+arcPtr->bbox[2]+1)/2);          tsoffset->xoffset = (int) ((arcPtr->bbox[0]+arcPtr->bbox[2]+1)/2);
503      } else if (flags & TK_OFFSET_RIGHT) {      } else if (flags & TK_OFFSET_RIGHT) {
504          tsoffset->xoffset = (int) (arcPtr->bbox[2] + 0.5);          tsoffset->xoffset = (int) (arcPtr->bbox[2] + 0.5);
505      }      }
506      if (flags & TK_OFFSET_TOP) {      if (flags & TK_OFFSET_TOP) {
507          tsoffset->yoffset = (int) (arcPtr->bbox[1] + 0.5);          tsoffset->yoffset = (int) (arcPtr->bbox[1] + 0.5);
508      } else if (flags & TK_OFFSET_MIDDLE) {      } else if (flags & TK_OFFSET_MIDDLE) {
509          tsoffset->yoffset = (int) ((arcPtr->bbox[1]+arcPtr->bbox[3]+1)/2);          tsoffset->yoffset = (int) ((arcPtr->bbox[1]+arcPtr->bbox[3]+1)/2);
510      } else if (flags & TK_OFFSET_BOTTOM) {      } else if (flags & TK_OFFSET_BOTTOM) {
511          tsoffset->yoffset = (int) (arcPtr->bbox[2] + 0.5);          tsoffset->yoffset = (int) (arcPtr->bbox[2] + 0.5);
512      }      }
513    
514      i = (int) (arcPtr->start/360.0);      i = (int) (arcPtr->start/360.0);
515      arcPtr->start -= i*360.0;      arcPtr->start -= i*360.0;
516      if (arcPtr->start < 0) {      if (arcPtr->start < 0) {
517          arcPtr->start += 360.0;          arcPtr->start += 360.0;
518      }      }
519      i = (int) (arcPtr->extent/360.0);      i = (int) (arcPtr->extent/360.0);
520      arcPtr->extent -= i*360.0;      arcPtr->extent -= i*360.0;
521    
522      mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr,      mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr,
523              &(arcPtr->outline));              &(arcPtr->outline));
524      if (mask) {      if (mask) {
525          gcValues.cap_style = CapButt;          gcValues.cap_style = CapButt;
526          mask |= GCCapStyle;          mask |= GCCapStyle;
527          newGC = Tk_GetGC(tkwin, mask, &gcValues);          newGC = Tk_GetGC(tkwin, mask, &gcValues);
528      } else {      } else {
529          newGC = None;          newGC = None;
530      }      }
531      if (arcPtr->outline.gc != None) {      if (arcPtr->outline.gc != None) {
532          Tk_FreeGC(Tk_Display(tkwin), arcPtr->outline.gc);          Tk_FreeGC(Tk_Display(tkwin), arcPtr->outline.gc);
533      }      }
534      arcPtr->outline.gc = newGC;      arcPtr->outline.gc = newGC;
535    
536      if(state == TK_STATE_NULL) {      if(state == TK_STATE_NULL) {
537          state = ((TkCanvas *)canvas)->canvas_state;          state = ((TkCanvas *)canvas)->canvas_state;
538      }      }
539      if (state==TK_STATE_HIDDEN) {      if (state==TK_STATE_HIDDEN) {
540          ComputeArcBbox(canvas, arcPtr);          ComputeArcBbox(canvas, arcPtr);
541          return TCL_OK;          return TCL_OK;
542      }      }
543    
544      color = arcPtr->fillColor;      color = arcPtr->fillColor;
545      stipple = arcPtr->fillStipple;      stipple = arcPtr->fillStipple;
546      if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {      if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
547          if (arcPtr->activeFillColor!=NULL) {          if (arcPtr->activeFillColor!=NULL) {
548              color = arcPtr->activeFillColor;              color = arcPtr->activeFillColor;
549          }          }
550          if (arcPtr->activeFillStipple!=None) {          if (arcPtr->activeFillStipple!=None) {
551              stipple = arcPtr->activeFillStipple;              stipple = arcPtr->activeFillStipple;
552          }          }
553      } else if (state==TK_STATE_DISABLED) {      } else if (state==TK_STATE_DISABLED) {
554          if (arcPtr->disabledFillColor!=NULL) {          if (arcPtr->disabledFillColor!=NULL) {
555              color = arcPtr->disabledFillColor;              color = arcPtr->disabledFillColor;
556          }          }
557          if (arcPtr->disabledFillStipple!=None) {          if (arcPtr->disabledFillStipple!=None) {
558              stipple = arcPtr->disabledFillStipple;              stipple = arcPtr->disabledFillStipple;
559          }          }
560        }        }
561    
562      if (arcPtr->style == ARC_STYLE) {      if (arcPtr->style == ARC_STYLE) {
563          newGC = None;          newGC = None;
564      } else if (color == NULL) {      } else if (color == NULL) {
565          newGC = None;          newGC = None;
566      } else {      } else {
567          gcValues.foreground = color->pixel;          gcValues.foreground = color->pixel;
568          if (arcPtr->style == CHORD_STYLE) {          if (arcPtr->style == CHORD_STYLE) {
569              gcValues.arc_mode = ArcChord;              gcValues.arc_mode = ArcChord;
570          } else {          } else {
571              gcValues.arc_mode = ArcPieSlice;              gcValues.arc_mode = ArcPieSlice;
572          }          }
573          mask = GCForeground|GCArcMode;          mask = GCForeground|GCArcMode;
574          if (stipple != None) {          if (stipple != None) {
575              gcValues.stipple = stipple;              gcValues.stipple = stipple;
576              gcValues.fill_style = FillStippled;              gcValues.fill_style = FillStippled;
577              mask |= GCStipple|GCFillStyle;              mask |= GCStipple|GCFillStyle;
578          }          }
579          newGC = Tk_GetGC(tkwin, mask, &gcValues);          newGC = Tk_GetGC(tkwin, mask, &gcValues);
580      }      }
581      if (arcPtr->fillGC != None) {      if (arcPtr->fillGC != None) {
582          Tk_FreeGC(Tk_Display(tkwin), arcPtr->fillGC);          Tk_FreeGC(Tk_Display(tkwin), arcPtr->fillGC);
583      }      }
584      arcPtr->fillGC = newGC;      arcPtr->fillGC = newGC;
585    
586      tsoffset = &arcPtr->tsoffset;      tsoffset = &arcPtr->tsoffset;
587      flags = tsoffset->flags;      flags = tsoffset->flags;
588      if (flags & TK_OFFSET_LEFT) {      if (flags & TK_OFFSET_LEFT) {
589          tsoffset->xoffset = (int) (arcPtr->bbox[0] + 0.5);          tsoffset->xoffset = (int) (arcPtr->bbox[0] + 0.5);
590      } else if (flags & TK_OFFSET_CENTER) {      } else if (flags & TK_OFFSET_CENTER) {
591          tsoffset->xoffset = (int) ((arcPtr->bbox[0]+arcPtr->bbox[2]+1)/2);          tsoffset->xoffset = (int) ((arcPtr->bbox[0]+arcPtr->bbox[2]+1)/2);
592      } else if (flags & TK_OFFSET_RIGHT) {      } else if (flags & TK_OFFSET_RIGHT) {
593          tsoffset->xoffset = (int) (arcPtr->bbox[2] + 0.5);          tsoffset->xoffset = (int) (arcPtr->bbox[2] + 0.5);
594      }      }
595      if (flags & TK_OFFSET_TOP) {      if (flags & TK_OFFSET_TOP) {
596          tsoffset->yoffset = (int) (arcPtr->bbox[1] + 0.5);          tsoffset->yoffset = (int) (arcPtr->bbox[1] + 0.5);
597      } else if (flags & TK_OFFSET_MIDDLE) {      } else if (flags & TK_OFFSET_MIDDLE) {
598          tsoffset->yoffset = (int) ((arcPtr->bbox[1]+arcPtr->bbox[3]+1)/2);          tsoffset->yoffset = (int) ((arcPtr->bbox[1]+arcPtr->bbox[3]+1)/2);
599      } else if (flags & TK_OFFSET_BOTTOM) {      } else if (flags & TK_OFFSET_BOTTOM) {
600          tsoffset->yoffset = (int) (arcPtr->bbox[3] + 0.5);          tsoffset->yoffset = (int) (arcPtr->bbox[3] + 0.5);
601      }      }
602    
603      ComputeArcBbox(canvas, arcPtr);      ComputeArcBbox(canvas, arcPtr);
604      return TCL_OK;      return TCL_OK;
605  }  }
606    
607  /*  /*
608   *--------------------------------------------------------------   *--------------------------------------------------------------
609   *   *
610   * DeleteArc --   * DeleteArc --
611   *   *
612   *      This procedure is called to clean up the data structure   *      This procedure is called to clean up the data structure
613   *      associated with a arc item.   *      associated with a arc item.
614   *   *
615   * Results:   * Results:
616   *      None.   *      None.
617   *   *
618   * Side effects:   * Side effects:
619   *      Resources associated with itemPtr are released.   *      Resources associated with itemPtr are released.
620   *   *
621   *--------------------------------------------------------------   *--------------------------------------------------------------
622   */   */
623    
624  static void  static void
625  DeleteArc(canvas, itemPtr, display)  DeleteArc(canvas, itemPtr, display)
626      Tk_Canvas canvas;                   /* Info about overall canvas. */      Tk_Canvas canvas;                   /* Info about overall canvas. */
627      Tk_Item *itemPtr;                   /* Item that is being deleted. */      Tk_Item *itemPtr;                   /* Item that is being deleted. */
628      Display *display;                   /* Display containing window for      Display *display;                   /* Display containing window for
629                                           * canvas. */                                           * canvas. */
630  {  {
631      ArcItem *arcPtr = (ArcItem *) itemPtr;      ArcItem *arcPtr = (ArcItem *) itemPtr;
632    
633      Tk_DeleteOutline(display, &(arcPtr->outline));      Tk_DeleteOutline(display, &(arcPtr->outline));
634      if (arcPtr->numOutlinePoints != 0) {      if (arcPtr->numOutlinePoints != 0) {
635          ckfree((char *) arcPtr->outlinePtr);          ckfree((char *) arcPtr->outlinePtr);
636      }      }
637      if (arcPtr->fillColor != NULL) {      if (arcPtr->fillColor != NULL) {
638          Tk_FreeColor(arcPtr->fillColor);          Tk_FreeColor(arcPtr->fillColor);
639      }      }
640      if (arcPtr->activeFillColor != NULL) {      if (arcPtr->activeFillColor != NULL) {
641          Tk_FreeColor(arcPtr->activeFillColor);          Tk_FreeColor(arcPtr->activeFillColor);
642      }      }
643      if (arcPtr->disabledFillColor != NULL) {      if (arcPtr->disabledFillColor != NULL) {
644          Tk_FreeColor(arcPtr->disabledFillColor);          Tk_FreeColor(arcPtr->disabledFillColor);
645      }      }
646      if (arcPtr->fillStipple != None) {      if (arcPtr->fillStipple != None) {
647          Tk_FreeBitmap(display, arcPtr->fillStipple);          Tk_FreeBitmap(display, arcPtr->fillStipple);
648      }      }
649      if (arcPtr->activeFillStipple != None) {      if (arcPtr->activeFillStipple != None) {
650          Tk_FreeBitmap(display, arcPtr->activeFillStipple);          Tk_FreeBitmap(display, arcPtr->activeFillStipple);
651      }      }
652      if (arcPtr->disabledFillStipple != None) {      if (arcPtr->disabledFillStipple != None) {
653          Tk_FreeBitmap(display, arcPtr->disabledFillStipple);          Tk_FreeBitmap(display, arcPtr->disabledFillStipple);
654      }      }
655      if (arcPtr->fillGC != None) {      if (arcPtr->fillGC != None) {
656          Tk_FreeGC(display, arcPtr->fillGC);          Tk_FreeGC(display, arcPtr->fillGC);
657      }      }
658  }  }
659    
660  /*  /*
661   *--------------------------------------------------------------   *--------------------------------------------------------------
662   *   *
663   * ComputeArcBbox --   * ComputeArcBbox --
664   *   *
665   *      This procedure is invoked to compute the bounding box of   *      This procedure is invoked to compute the bounding box of
666   *      all the pixels that may be drawn as part of an arc.   *      all the pixels that may be drawn as part of an arc.
667   *   *
668   * Results:   * Results:
669   *      None.   *      None.
670   *   *
671   * Side effects:   * Side effects:
672   *      The fields x1, y1, x2, and y2 are updated in the header   *      The fields x1, y1, x2, and y2 are updated in the header
673   *      for itemPtr.   *      for itemPtr.
674   *   *
675   *--------------------------------------------------------------   *--------------------------------------------------------------
676   */   */
677    
678          /* ARGSUSED */          /* ARGSUSED */
679  static void  static void
680  ComputeArcBbox(canvas, arcPtr)  ComputeArcBbox(canvas, arcPtr)
681      Tk_Canvas canvas;                   /* Canvas that contains item. */      Tk_Canvas canvas;                   /* Canvas that contains item. */
682      ArcItem *arcPtr;                    /* Item whose bbox is to be      ArcItem *arcPtr;                    /* Item whose bbox is to be
683                                           * recomputed. */                                           * recomputed. */
684  {  {
685      double tmp, center[2], point[2];      double tmp, center[2], point[2];
686      double width;      double width;
687      Tk_State state = arcPtr->header.state;      Tk_State state = arcPtr->header.state;
688    
689      if(state == TK_STATE_NULL) {      if(state == TK_STATE_NULL) {
690          state = ((TkCanvas *)canvas)->canvas_state;          state = ((TkCanvas *)canvas)->canvas_state;
691      }      }
692    
693      width = arcPtr->outline.width;      width = arcPtr->outline.width;
694      if (width < 1.0) {      if (width < 1.0) {
695          width = 1.0;          width = 1.0;
696      }      }
697      if (state==TK_STATE_HIDDEN) {      if (state==TK_STATE_HIDDEN) {
698          arcPtr->header.x1 = arcPtr->header.x2 =          arcPtr->header.x1 = arcPtr->header.x2 =
699          arcPtr->header.y1 = arcPtr->header.y2 = -1;          arcPtr->header.y1 = arcPtr->header.y2 = -1;
700          return;          return;
701      } else if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *) arcPtr) {      } else if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *) arcPtr) {
702          if (arcPtr->outline.activeWidth>width) {          if (arcPtr->outline.activeWidth>width) {
703              width = arcPtr->outline.activeWidth;              width = arcPtr->outline.activeWidth;
704          }          }
705      } else if (state==TK_STATE_DISABLED) {      } else if (state==TK_STATE_DISABLED) {
706          if (arcPtr->outline.disabledWidth>0) {          if (arcPtr->outline.disabledWidth>0) {
707              width = arcPtr->outline.disabledWidth;              width = arcPtr->outline.disabledWidth;
708          }          }
709      }      }
710    
711      /*      /*
712       * Make sure that the first coordinates are the lowest ones.       * Make sure that the first coordinates are the lowest ones.
713       */       */
714    
715      if (arcPtr->bbox[1] > arcPtr->bbox[3]) {      if (arcPtr->bbox[1] > arcPtr->bbox[3]) {
716          double tmp;          double tmp;
717          tmp = arcPtr->bbox[3];          tmp = arcPtr->bbox[3];
718          arcPtr->bbox[3] = arcPtr->bbox[1];          arcPtr->bbox[3] = arcPtr->bbox[1];
719          arcPtr->bbox[1] = tmp;          arcPtr->bbox[1] = tmp;
720      }      }
721      if (arcPtr->bbox[0] > arcPtr->bbox[2]) {      if (arcPtr->bbox[0] > arcPtr->bbox[2]) {
722          double tmp;          double tmp;
723          tmp = arcPtr->bbox[2];          tmp = arcPtr->bbox[2];
724          arcPtr->bbox[2] = arcPtr->bbox[0];          arcPtr->bbox[2] = arcPtr->bbox[0];
725          arcPtr->bbox[0] = tmp;          arcPtr->bbox[0] = tmp;
726      }      }
727    
728      ComputeArcOutline(canvas,arcPtr);      ComputeArcOutline(canvas,arcPtr);
729    
730      /*      /*
731       * To compute the bounding box, start with the the bbox formed       * To compute the bounding box, start with the the bbox formed
732       * by the two endpoints of the arc.  Then add in the center of       * by the two endpoints of the arc.  Then add in the center of
733       * the arc's oval (if relevant) and the 3-o'clock, 6-o'clock,       * the arc's oval (if relevant) and the 3-o'clock, 6-o'clock,
734       * 9-o'clock, and 12-o'clock positions, if they are relevant.       * 9-o'clock, and 12-o'clock positions, if they are relevant.
735       */       */
736    
737      arcPtr->header.x1 = arcPtr->header.x2 = (int) arcPtr->center1[0];      arcPtr->header.x1 = arcPtr->header.x2 = (int) arcPtr->center1[0];
738      arcPtr->header.y1 = arcPtr->header.y2 = (int) arcPtr->center1[1];      arcPtr->header.y1 = arcPtr->header.y2 = (int) arcPtr->center1[1];
739      TkIncludePoint((Tk_Item *) arcPtr, arcPtr->center2);      TkIncludePoint((Tk_Item *) arcPtr, arcPtr->center2);
740      center[0] = (arcPtr->bbox[0] + arcPtr->bbox[2])/2;      center[0] = (arcPtr->bbox[0] + arcPtr->bbox[2])/2;
741      center[1] = (arcPtr->bbox[1] + arcPtr->bbox[3])/2;      center[1] = (arcPtr->bbox[1] + arcPtr->bbox[3])/2;
742      if (arcPtr->style == PIESLICE_STYLE) {      if (arcPtr->style == PIESLICE_STYLE) {
743          TkIncludePoint((Tk_Item *) arcPtr, center);          TkIncludePoint((Tk_Item *) arcPtr, center);
744      }      }
745    
746      tmp = -arcPtr->start;      tmp = -arcPtr->start;
747      if (tmp < 0) {      if (tmp < 0) {
748          tmp += 360.0;          tmp += 360.0;
749      }      }
750      if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {      if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {
751          point[0] = arcPtr->bbox[2];          point[0] = arcPtr->bbox[2];
752          point[1] = center[1];          point[1] = center[1];
753          TkIncludePoint((Tk_Item *) arcPtr, point);          TkIncludePoint((Tk_Item *) arcPtr, point);
754      }      }
755      tmp = 90.0 - arcPtr->start;      tmp = 90.0 - arcPtr->start;
756      if (tmp < 0) {      if (tmp < 0) {
757          tmp += 360.0;          tmp += 360.0;
758      }      }
759      if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {      if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {
760          point[0] = center[0];          point[0] = center[0];
761          point[1] = arcPtr->bbox[1];          point[1] = arcPtr->bbox[1];
762          TkIncludePoint((Tk_Item *) arcPtr, point);          TkIncludePoint((Tk_Item *) arcPtr, point);
763      }      }
764      tmp = 180.0 - arcPtr->start;      tmp = 180.0 - arcPtr->start;
765      if (tmp < 0) {      if (tmp < 0) {
766          tmp += 360.0;          tmp += 360.0;
767      }      }
768      if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {      if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {
769          point[0] = arcPtr->bbox[0];          point[0] = arcPtr->bbox[0];
770          point[1] = center[1];          point[1] = center[1];
771          TkIncludePoint((Tk_Item *) arcPtr, point);          TkIncludePoint((Tk_Item *) arcPtr, point);
772      }      }
773      tmp = 270.0 - arcPtr->start;      tmp = 270.0 - arcPtr->start;
774      if (tmp < 0) {      if (tmp < 0) {
775          tmp += 360.0;          tmp += 360.0;
776      }      }
777      if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {      if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {
778          point[0] = center[0];          point[0] = center[0];
779          point[1] = arcPtr->bbox[3];          point[1] = arcPtr->bbox[3];
780          TkIncludePoint((Tk_Item *) arcPtr, point);          TkIncludePoint((Tk_Item *) arcPtr, point);
781      }      }
782    
783      /*      /*
784       * Lastly, expand by the width of the arc (if the arc's outline is       * Lastly, expand by the width of the arc (if the arc's outline is
785       * being drawn) and add one extra pixel just for safety.       * being drawn) and add one extra pixel just for safety.
786       */       */
787    
788      if (arcPtr->outline.gc == None) {      if (arcPtr->outline.gc == None) {
789          tmp = 1;          tmp = 1;
790      } else {      } else {
791          tmp = (int) ((width + 1.0)/2.0 + 1);          tmp = (int) ((width + 1.0)/2.0 + 1);
792      }      }
793      arcPtr->header.x1 -= (int) tmp;      arcPtr->header.x1 -= (int) tmp;
794      arcPtr->header.y1 -= (int) tmp;      arcPtr->header.y1 -= (int) tmp;
795      arcPtr->header.x2 += (int) tmp;      arcPtr->header.x2 += (int) tmp;
796      arcPtr->header.y2 += (int) tmp;      arcPtr->header.y2 += (int) tmp;
797  }  }
798    
799  /*  /*
800   *--------------------------------------------------------------   *--------------------------------------------------------------
801   *   *
802   * DisplayArc --   * DisplayArc --
803   *   *
804   *      This procedure is invoked to draw an arc item in a given   *      This procedure is invoked to draw an arc item in a given
805   *      drawable.   *      drawable.
806   *   *
807   * Results:   * Results:
808   *      None.   *      None.
809   *   *
810   * Side effects:   * Side effects:
811   *      ItemPtr is drawn in drawable using the transformation   *      ItemPtr is drawn in drawable using the transformation
812   *      information in canvas.   *      information in canvas.
813   *   *
814   *--------------------------------------------------------------   *--------------------------------------------------------------
815   */   */
816    
817  static void  static void
818  DisplayArc(canvas, itemPtr, display, drawable, x, y, width, height)  DisplayArc(canvas, itemPtr, display, drawable, x, y, width, height)
819      Tk_Canvas canvas;                   /* Canvas that contains item. */      Tk_Canvas canvas;                   /* Canvas that contains item. */
820      Tk_Item *itemPtr;                   /* Item to be displayed. */      Tk_Item *itemPtr;                   /* Item to be displayed. */
821      Display *display;                   /* Display on which to draw item. */      Display *display;                   /* Display on which to draw item. */
822      Drawable drawable;                  /* Pixmap or window in which to draw      Drawable drawable;                  /* Pixmap or window in which to draw
823                                           * item. */                                           * item. */
824      int x, y, width, height;            /* Describes region of canvas that      int x, y, width, height;            /* Describes region of canvas that
825                                           * must be redisplayed (not used). */                                           * must be redisplayed (not used). */
826  {  {
827      ArcItem *arcPtr = (ArcItem *) itemPtr;      ArcItem *arcPtr = (ArcItem *) itemPtr;
828      short x1, y1, x2, y2;      short x1, y1, x2, y2;
829      int start, extent, dashnumber;      int start, extent, dashnumber;
830      double lineWidth;      double lineWidth;
831      Tk_State state = itemPtr->state;      Tk_State state = itemPtr->state;
832      Pixmap stipple;      Pixmap stipple;
833    
834      if(state == TK_STATE_NULL) {      if(state == TK_STATE_NULL) {
835          state = ((TkCanvas *)canvas)->canvas_state;          state = ((TkCanvas *)canvas)->canvas_state;
836      }      }
837      lineWidth = arcPtr->outline.width;      lineWidth = arcPtr->outline.width;
838      if (lineWidth < 1.0) {      if (lineWidth < 1.0) {
839          lineWidth = 1.0;          lineWidth = 1.0;
840      }      }
841      dashnumber = arcPtr->outline.dash.number;      dashnumber = arcPtr->outline.dash.number;
842      stipple = arcPtr->fillStipple;      stipple = arcPtr->fillStipple;
843      if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {      if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
844          if (arcPtr->outline.activeWidth>lineWidth) {          if (arcPtr->outline.activeWidth>lineWidth) {
845              lineWidth = arcPtr->outline.activeWidth;              lineWidth = arcPtr->outline.activeWidth;
846          }          }
847          if (arcPtr->outline.activeDash.number != 0) {          if (arcPtr->outline.activeDash.number != 0) {
848              dashnumber = arcPtr->outline.activeDash.number;              dashnumber = arcPtr->outline.activeDash.number;
849          }          }
850          if (arcPtr->activeFillStipple != None) {          if (arcPtr->activeFillStipple != None) {
851              stipple = arcPtr->activeFillStipple;              stipple = arcPtr->activeFillStipple;
852          }          }
853      } else if (state==TK_STATE_DISABLED) {      } else if (state==TK_STATE_DISABLED) {
854          if (arcPtr->outline.disabledWidth > 0) {          if (arcPtr->outline.disabledWidth > 0) {
855              lineWidth = arcPtr->outline.disabledWidth;              lineWidth = arcPtr->outline.disabledWidth;
856          }          }
857          if (arcPtr->outline.disabledDash.number != 0) {          if (arcPtr->outline.disabledDash.number != 0) {
858              dashnumber = arcPtr->outline.disabledDash.number;              dashnumber = arcPtr->outline.disabledDash.number;
859          }          }
860          if (arcPtr->disabledFillStipple != None) {          if (arcPtr->disabledFillStipple != None) {
861              stipple = arcPtr->disabledFillStipple;              stipple = arcPtr->disabledFillStipple;
862          }          }
863      }      }
864    
865      /*      /*
866       * Compute the screen coordinates of the bounding box for the item,       * Compute the screen coordinates of the bounding box for the item,
867       * plus integer values for the angles.       * plus integer values for the angles.
868       */       */
869    
870      Tk_CanvasDrawableCoords(canvas, arcPtr->bbox[0], arcPtr->bbox[1],      Tk_CanvasDrawableCoords(canvas, arcPtr->bbox[0], arcPtr->bbox[1],
871              &x1, &y1);              &x1, &y1);
872      Tk_CanvasDrawableCoords(canvas, arcPtr->bbox[2], arcPtr->bbox[3],      Tk_CanvasDrawableCoords(canvas, arcPtr->bbox[2], arcPtr->bbox[3],
873              &x2, &y2);              &x2, &y2);
874      if (x2 <= x1) {      if (x2 <= x1) {
875          x2 = x1+1;          x2 = x1+1;
876      }      }
877      if (y2 <= y1) {      if (y2 <= y1) {
878          y2 = y1+1;          y2 = y1+1;
879      }      }
880      start = (int) ((64*arcPtr->start) + 0.5);      start = (int) ((64*arcPtr->start) + 0.5);
881      extent = (int) ((64*arcPtr->extent) + 0.5);      extent = (int) ((64*arcPtr->extent) + 0.5);
882    
883      /*      /*
884       * Display filled arc first (if wanted), then outline.  If the extent       * Display filled arc first (if wanted), then outline.  If the extent
885       * is zero then don't invoke XFillArc or XDrawArc, since this causes       * is zero then don't invoke XFillArc or XDrawArc, since this causes
886       * some window servers to crash and should be a no-op anyway.       * some window servers to crash and should be a no-op anyway.
887       */       */
888    
889      if ((arcPtr->fillGC != None) && (extent != 0)) {      if ((arcPtr->fillGC != None) && (extent != 0)) {
890          if (stipple != None) {          if (stipple != None) {
891              int w=0; int h=0;              int w=0; int h=0;
892              Tk_TSOffset *tsoffset = &arcPtr->tsoffset;              Tk_TSOffset *tsoffset = &arcPtr->tsoffset;
893              int flags = tsoffset->flags;              int flags = tsoffset->flags;
894              if (flags & (TK_OFFSET_CENTER|TK_OFFSET_MIDDLE)) {              if (flags & (TK_OFFSET_CENTER|TK_OFFSET_MIDDLE)) {
895                  Tk_SizeOfBitmap(display, stipple, &w, &h);                  Tk_SizeOfBitmap(display, stipple, &w, &h);
896                  if (flags & TK_OFFSET_CENTER) {                  if (flags & TK_OFFSET_CENTER) {
897                      w /= 2;                      w /= 2;
898                  } else {                  } else {
899                      w = 0;                      w = 0;
900                  }                  }
901                  if (flags & TK_OFFSET_MIDDLE) {                  if (flags & TK_OFFSET_MIDDLE) {
902                      h /= 2;                      h /= 2;
903                  } else {                  } else {
904                      h = 0;                      h = 0;
905                  }                  }
906              }              }
907              tsoffset->xoffset -= w;              tsoffset->xoffset -= w;
908              tsoffset->yoffset -= h;              tsoffset->yoffset -= h;
909              Tk_CanvasSetOffset(canvas, arcPtr->fillGC, tsoffset);              Tk_CanvasSetOffset(canvas, arcPtr->fillGC, tsoffset);
910              if (tsoffset) {              if (tsoffset) {
911                  tsoffset->xoffset += w;                  tsoffset->xoffset += w;
912                  tsoffset->yoffset += h;                  tsoffset->yoffset += h;
913              }              }
914          }          }
915          XFillArc(display, drawable, arcPtr->fillGC, x1, y1, (unsigned) (x2-x1),          XFillArc(display, drawable, arcPtr->fillGC, x1, y1, (unsigned) (x2-x1),
916                  (unsigned) (y2-y1), start, extent);                  (unsigned) (y2-y1), start, extent);
917          if (stipple != None) {          if (stipple != None) {
918              XSetTSOrigin(display, arcPtr->fillGC, 0, 0);              XSetTSOrigin(display, arcPtr->fillGC, 0, 0);
919          }          }
920      }      }
921      if (arcPtr->outline.gc != None) {      if (arcPtr->outline.gc != None) {
922          Tk_ChangeOutlineGC(canvas, itemPtr, &(arcPtr->outline));          Tk_ChangeOutlineGC(canvas, itemPtr, &(arcPtr->outline));
923    
924          if (extent != 0) {          if (extent != 0) {
925              XDrawArc(display, drawable, arcPtr->outline.gc, x1, y1,              XDrawArc(display, drawable, arcPtr->outline.gc, x1, y1,
926                      (unsigned) (x2-x1), (unsigned) (y2-y1), start, extent);                      (unsigned) (x2-x1), (unsigned) (y2-y1), start, extent);
927          }          }
928    
929          /*          /*
930           * If the outline width is very thin, don't use polygons to draw           * If the outline width is very thin, don't use polygons to draw
931           * the linear parts of the outline (this often results in nothing           * the linear parts of the outline (this often results in nothing
932           * being displayed); just draw lines instead. The same is done if           * being displayed); just draw lines instead. The same is done if
933           * the outline is dashed, because then polygons don't work.           * the outline is dashed, because then polygons don't work.
934           */           */
935    
936          if (lineWidth < 1.5 || dashnumber != 0) {          if (lineWidth < 1.5 || dashnumber != 0) {
937              Tk_CanvasDrawableCoords(canvas, arcPtr->center1[0],              Tk_CanvasDrawableCoords(canvas, arcPtr->center1[0],
938                      arcPtr->center1[1], &x1, &y1);                      arcPtr->center1[1], &x1, &y1);
939              Tk_CanvasDrawableCoords(canvas, arcPtr->center2[0],              Tk_CanvasDrawableCoords(canvas, arcPtr->center2[0],
940                      arcPtr->center2[1], &x2, &y2);                      arcPtr->center2[1], &x2, &y2);
941    
942              if (arcPtr->style == CHORD_STYLE) {              if (arcPtr->style == CHORD_STYLE) {
943                  XDrawLine(display, drawable, arcPtr->outline.gc,                  XDrawLine(display, drawable, arcPtr->outline.gc,
944                          x1, y1, x2, y2);                          x1, y1, x2, y2);
945              } else if (arcPtr->style == PIESLICE_STYLE) {              } else if (arcPtr->style == PIESLICE_STYLE) {
946                  short cx, cy;                  short cx, cy;
947    
948                  Tk_CanvasDrawableCoords(canvas,                  Tk_CanvasDrawableCoords(canvas,
949                          (arcPtr->bbox[0] + arcPtr->bbox[2])/2.0,                          (arcPtr->bbox[0] + arcPtr->bbox[2])/2.0,
950                          (arcPtr->bbox[1] + arcPtr->bbox[3])/2.0, &cx, &cy);                          (arcPtr->bbox[1] + arcPtr->bbox[3])/2.0, &cx, &cy);
951                  XDrawLine(display, drawable, arcPtr->outline.gc,                  XDrawLine(display, drawable, arcPtr->outline.gc,
952                          cx, cy, x1, y1);                          cx, cy, x1, y1);
953                  XDrawLine(display, drawable, arcPtr->outline.gc,                  XDrawLine(display, drawable, arcPtr->outline.gc,
954                          cx, cy, x2, y2);                          cx, cy, x2, y2);
955              }              }
956          } else {          } else {
957              if (arcPtr->style == CHORD_STYLE) {              if (arcPtr->style == CHORD_STYLE) {
958                  TkFillPolygon(canvas, arcPtr->outlinePtr, CHORD_OUTLINE_PTS,                  TkFillPolygon(canvas, arcPtr->outlinePtr, CHORD_OUTLINE_PTS,
959                          display, drawable, arcPtr->outline.gc, None);                          display, drawable, arcPtr->outline.gc, None);
960              } else if (arcPtr->style == PIESLICE_STYLE) {              } else if (arcPtr->style == PIESLICE_STYLE) {
961                  TkFillPolygon(canvas, arcPtr->outlinePtr, PIE_OUTLINE1_PTS,                  TkFillPolygon(canvas, arcPtr->outlinePtr, PIE_OUTLINE1_PTS,
962                          display, drawable, arcPtr->outline.gc, None);                          display, drawable, arcPtr->outline.gc, None);
963                  TkFillPolygon(canvas, arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,                  TkFillPolygon(canvas, arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,
964                          PIE_OUTLINE2_PTS, display, drawable, arcPtr->outline.gc,                          PIE_OUTLINE2_PTS, display, drawable, arcPtr->outline.gc,
965                          None);                          None);
966              }              }
967          }          }
968    
969          Tk_ResetOutlineGC(canvas, itemPtr, &(arcPtr->outline));          Tk_ResetOutlineGC(canvas, itemPtr, &(arcPtr->outline));
970      }      }
971  }  }
972    
973  /*  /*
974   *--------------------------------------------------------------   *--------------------------------------------------------------
975   *   *
976   * ArcToPoint --   * ArcToPoint --
977   *   *
978   *      Computes the distance from a given point to a given   *      Computes the distance from a given point to a given
979   *      arc, in canvas units.   *      arc, in canvas units.
980   *   *
981   * Results:   * Results:
982   *      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
983   *      are coordPtr[0] and coordPtr[1] is inside the arc.  If the   *      are coordPtr[0] and coordPtr[1] is inside the arc.  If the
984   *      point isn't inside the arc then the return value is the   *      point isn't inside the arc then the return value is the
985   *      distance from the point to the arc.  If itemPtr is filled,   *      distance from the point to the arc.  If itemPtr is filled,
986   *      then anywhere in the interior is considered "inside"; if   *      then anywhere in the interior is considered "inside"; if
987   *      itemPtr isn't filled, then "inside" means only the area   *      itemPtr isn't filled, then "inside" means only the area
988   *      occupied by the outline.   *      occupied by the outline.
989   *   *
990   * Side effects:   * Side effects:
991   *      None.   *      None.
992   *   *
993   *--------------------------------------------------------------   *--------------------------------------------------------------
994   */   */
995    
996          /* ARGSUSED */          /* ARGSUSED */
997  static double  static double
998  ArcToPoint(canvas, itemPtr, pointPtr)  ArcToPoint(canvas, itemPtr, pointPtr)
999      Tk_Canvas canvas;           /* Canvas containing item. */      Tk_Canvas canvas;           /* Canvas containing item. */
1000      Tk_Item *itemPtr;           /* Item to check against point. */      Tk_Item *itemPtr;           /* Item to check against point. */
1001      double *pointPtr;           /* Pointer to x and y coordinates. */      double *pointPtr;           /* Pointer to x and y coordinates. */
1002  {  {
1003      ArcItem *arcPtr = (ArcItem *) itemPtr;      ArcItem *arcPtr = (ArcItem *) itemPtr;
1004      double vertex[2], pointAngle, diff, dist, newDist;      double vertex[2], pointAngle, diff, dist, newDist;
1005      double poly[8], polyDist, width, t1, t2;      double poly[8], polyDist, width, t1, t2;
1006      int filled, angleInRange;      int filled, angleInRange;
1007      Tk_State state = itemPtr->state;      Tk_State state = itemPtr->state;
1008    
1009      if(state == TK_STATE_NULL) {      if(state == TK_STATE_NULL) {
1010          state = ((TkCanvas *)canvas)->canvas_state;          state = ((TkCanvas *)canvas)->canvas_state;
1011      }      }
1012    
1013      width = (double) arcPtr->outline.width;      width = (double) arcPtr->outline.width;
1014      if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {      if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
1015          if (arcPtr->outline.activeWidth>width) {          if (arcPtr->outline.activeWidth>width) {
1016              width = (double) arcPtr->outline.activeWidth;              width = (double) arcPtr->outline.activeWidth;
1017          }          }
1018      } else if (state == TK_STATE_DISABLED) {      } else if (state == TK_STATE_DISABLED) {
1019          if (arcPtr->outline.disabledWidth>0) {          if (arcPtr->outline.disabledWidth>0) {
1020              width = (double) arcPtr->outline.disabledWidth;              width = (double) arcPtr->outline.disabledWidth;
1021          }          }
1022      }      }
1023    
1024      /*      /*
1025       * See if the point is within the angular range of the arc.       * See if the point is within the angular range of the arc.
1026       * Remember, X angles are backwards from the way we'd normally       * Remember, X angles are backwards from the way we'd normally
1027       * think of them.  Also, compensate for any eccentricity of       * think of them.  Also, compensate for any eccentricity of
1028       * the oval.       * the oval.
1029       */       */
1030    
1031      vertex[0] = (arcPtr->bbox[0] + arcPtr->bbox[2])/2.0;      vertex[0] = (arcPtr->bbox[0] + arcPtr->bbox[2])/2.0;
1032      vertex[1] = (arcPtr->bbox[1] + arcPtr->bbox[3])/2.0;      vertex[1] = (arcPtr->bbox[1] + arcPtr->bbox[3])/2.0;
1033      t1 = arcPtr->bbox[3] - arcPtr->bbox[1];      t1 = arcPtr->bbox[3] - arcPtr->bbox[1];
1034      if (t1 != 0.0) {      if (t1 != 0.0) {
1035          t1 = (pointPtr[1] - vertex[1]) / t1;          t1 = (pointPtr[1] - vertex[1]) / t1;
1036      }      }
1037      t2 = arcPtr->bbox[2] - arcPtr->bbox[0];      t2 = arcPtr->bbox[2] - arcPtr->bbox[0];
1038      if (t2 != 0.0) {      if (t2 != 0.0) {
1039          t2 = (pointPtr[0] - vertex[0]) / t2;          t2 = (pointPtr[0] - vertex[0]) / t2;
1040      }      }
1041      if ((t1 == 0.0) && (t2 == 0.0)) {      if ((t1 == 0.0) && (t2 == 0.0)) {
1042          pointAngle = 0;          pointAngle = 0;
1043      } else {      } else {
1044          pointAngle = -atan2(t1, t2)*180/PI;          pointAngle = -atan2(t1, t2)*180/PI;
1045      }      }
1046      diff = pointAngle - arcPtr->start;      diff = pointAngle - arcPtr->start;
1047      diff -= ((int) (diff/360.0) * 360.0);      diff -= ((int) (diff/360.0) * 360.0);
1048      if (diff < 0) {      if (diff < 0) {
1049          diff += 360.0;          diff += 360.0;
1050      }      }
1051      angleInRange = (diff <= arcPtr->extent) ||      angleInRange = (diff <= arcPtr->extent) ||
1052              ((arcPtr->extent < 0) && ((diff - 360.0) >= arcPtr->extent));              ((arcPtr->extent < 0) && ((diff - 360.0) >= arcPtr->extent));
1053    
1054      /*      /*
1055       * Now perform different tests depending on what kind of arc       * Now perform different tests depending on what kind of arc
1056       * we're dealing with.       * we're dealing with.
1057       */       */
1058    
1059      if (arcPtr->style == ARC_STYLE) {      if (arcPtr->style == ARC_STYLE) {
1060          if (angleInRange) {          if (angleInRange) {
1061              return TkOvalToPoint(arcPtr->bbox, width,              return TkOvalToPoint(arcPtr->bbox, width,
1062                      0, pointPtr);                      0, pointPtr);
1063          }          }
1064          dist = hypot(pointPtr[0] - arcPtr->center1[0],          dist = hypot(pointPtr[0] - arcPtr->center1[0],
1065                  pointPtr[1] - arcPtr->center1[1]);                  pointPtr[1] - arcPtr->center1[1]);
1066          newDist = hypot(pointPtr[0] - arcPtr->center2[0],          newDist = hypot(pointPtr[0] - arcPtr->center2[0],
1067                  pointPtr[1] - arcPtr->center2[1]);                  pointPtr[1] - arcPtr->center2[1]);
1068          if (newDist < dist) {          if (newDist < dist) {
1069              return newDist;              return newDist;
1070          }          }
1071          return dist;          return dist;
1072      }      }
1073    
1074      if ((arcPtr->fillGC != None) || (arcPtr->outline.gc == None)) {      if ((arcPtr->fillGC != None) || (arcPtr->outline.gc == None)) {
1075          filled = 1;          filled = 1;
1076      } else {      } else {
1077          filled = 0;          filled = 0;
1078      }      }
1079      if (arcPtr->outline.gc == None) {      if (arcPtr->outline.gc == None) {
1080          width = 0.0;          width = 0.0;
1081      }      }
1082    
1083      if (arcPtr->style == PIESLICE_STYLE) {      if (arcPtr->style == PIESLICE_STYLE) {
1084          if (width > 1.0) {          if (width > 1.0) {
1085              dist = TkPolygonToPoint(arcPtr->outlinePtr, PIE_OUTLINE1_PTS,              dist = TkPolygonToPoint(arcPtr->outlinePtr, PIE_OUTLINE1_PTS,
1086                      pointPtr);                      pointPtr);
1087              newDist = TkPolygonToPoint(arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,              newDist = TkPolygonToPoint(arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,
1088                          PIE_OUTLINE2_PTS, pointPtr);                          PIE_OUTLINE2_PTS, pointPtr);
1089          } else {          } else {
1090              dist = TkLineToPoint(vertex, arcPtr->center1, pointPtr);              dist = TkLineToPoint(vertex, arcPtr->center1, pointPtr);
1091              newDist = TkLineToPoint(vertex, arcPtr->center2, pointPtr);              newDist = TkLineToPoint(vertex, arcPtr->center2, pointPtr);
1092          }          }
1093          if (newDist < dist) {          if (newDist < dist) {
1094              dist = newDist;              dist = newDist;
1095          }          }
1096          if (angleInRange) {          if (angleInRange) {
1097              newDist = TkOvalToPoint(arcPtr->bbox, width, filled, pointPtr);              newDist = TkOvalToPoint(arcPtr->bbox, width, filled, pointPtr);
1098              if (newDist < dist) {              if (newDist < dist) {
1099                  dist = newDist;                  dist = newDist;
1100              }              }
1101          }          }
1102          return dist;          return dist;
1103      }      }
1104    
1105      /*      /*
1106       * This is a chord-style arc.  We have to deal specially with the       * This is a chord-style arc.  We have to deal specially with the
1107       * triangular piece that represents the difference between a       * triangular piece that represents the difference between a
1108       * chord-style arc and a pie-slice arc (for small angles this piece       * chord-style arc and a pie-slice arc (for small angles this piece
1109       * is excluded here where it would be included for pie slices;       * is excluded here where it would be included for pie slices;
1110       * for large angles the piece is included here but would be       * for large angles the piece is included here but would be
1111       * excluded for pie slices).       * excluded for pie slices).
1112       */       */
1113    
1114      if (width > 1.0) {      if (width > 1.0) {
1115          dist = TkPolygonToPoint(arcPtr->outlinePtr, CHORD_OUTLINE_PTS,          dist = TkPolygonToPoint(arcPtr->outlinePtr, CHORD_OUTLINE_PTS,
1116                      pointPtr);                      pointPtr);
1117      } else {      } else {
1118          dist = TkLineToPoint(arcPtr->center1, arcPtr->center2, pointPtr);          dist = TkLineToPoint(arcPtr->center1, arcPtr->center2, pointPtr);
1119      }      }
1120      poly[0] = poly[6] = vertex[0];      poly[0] = poly[6] = vertex[0];
1121      poly[1] = poly[7] = vertex[1];      poly[1] = poly[7] = vertex[1];
1122      poly[2] = arcPtr->center1[0];      poly[2] = arcPtr->center1[0];
1123      poly[3] = arcPtr->center1[1];      poly[3] = arcPtr->center1[1];
1124      poly[4] = arcPtr->center2[0];      poly[4] = arcPtr->center2[0];
1125      poly[5] = arcPtr->center2[1];      poly[5] = arcPtr->center2[1];
1126      polyDist = TkPolygonToPoint(poly, 4, pointPtr);      polyDist = TkPolygonToPoint(poly, 4, pointPtr);
1127      if (angleInRange) {      if (angleInRange) {
1128          if ((arcPtr->extent < -180.0) || (arcPtr->extent > 180.0)          if ((arcPtr->extent < -180.0) || (arcPtr->extent > 180.0)
1129                  || (polyDist > 0.0)) {                  || (polyDist > 0.0)) {
1130              newDist = TkOvalToPoint(arcPtr->bbox, width, filled, pointPtr);              newDist = TkOvalToPoint(arcPtr->bbox, width, filled, pointPtr);
1131              if (newDist < dist) {              if (newDist < dist) {
1132                  dist = newDist;                  dist = newDist;
1133              }              }
1134          }          }
1135      } else {      } else {
1136          if ((arcPtr->extent < -180.0) || (arcPtr->extent > 180.0)) {          if ((arcPtr->extent < -180.0) || (arcPtr->extent > 180.0)) {
1137              if (filled && (polyDist < dist)) {              if (filled && (polyDist < dist)) {
1138                  dist = polyDist;                  dist = polyDist;
1139              }              }
1140          }          }
1141      }      }
1142      return dist;      return dist;
1143  }  }
1144    
1145  /*  /*
1146   *--------------------------------------------------------------   *--------------------------------------------------------------
1147   *   *
1148   * ArcToArea --   * ArcToArea --
1149   *   *
1150   *      This procedure is called to determine whether an item   *      This procedure is called to determine whether an item
1151   *      lies entirely inside, entirely outside, or overlapping   *      lies entirely inside, entirely outside, or overlapping
1152   *      a given area.   *      a given area.
1153   *   *
1154   * Results:   * Results:
1155   *      -1 is returned if the item is entirely outside the area   *      -1 is returned if the item is entirely outside the area
1156   *      given by rectPtr, 0 if it overlaps, and 1 if it is entirely   *      given by rectPtr, 0 if it overlaps, and 1 if it is entirely
1157   *      inside the given area.   *      inside the given area.
1158   *   *
1159   * Side effects:   * Side effects:
1160   *      None.   *      None.
1161   *   *
1162   *--------------------------------------------------------------   *--------------------------------------------------------------
1163   */   */
1164    
1165          /* ARGSUSED */          /* ARGSUSED */
1166  static int  static int
1167  ArcToArea(canvas, itemPtr, rectPtr)  ArcToArea(canvas, itemPtr, rectPtr)
1168      Tk_Canvas canvas;           /* Canvas containing item. */      Tk_Canvas canvas;           /* Canvas containing item. */
1169      Tk_Item *itemPtr;           /* Item to check against arc. */      Tk_Item *itemPtr;           /* Item to check against arc. */
1170      double *rectPtr;            /* Pointer to array of four coordinates      double *rectPtr;            /* Pointer to array of four coordinates
1171                                   * (x1, y1, x2, y2) describing rectangular                                   * (x1, y1, x2, y2) describing rectangular
1172                                   * area.  */                                   * area.  */
1173  {  {
1174      ArcItem *arcPtr = (ArcItem *) itemPtr;      ArcItem *arcPtr = (ArcItem *) itemPtr;
1175      double rx, ry;              /* Radii for transformed oval:  these define      double rx, ry;              /* Radii for transformed oval:  these define
1176                                   * an oval centered at the origin. */                                   * an oval centered at the origin. */
1177      double tRect[4];            /* Transformed version of x1, y1, x2, y2,      double tRect[4];            /* Transformed version of x1, y1, x2, y2,
1178                                   * for coord. system where arc is centered                                   * for coord. system where arc is centered
1179                                   * on the origin. */                                   * on the origin. */
1180      double center[2], width, angle, tmp;      double center[2], width, angle, tmp;
1181      double points[20], *pointPtr;      double points[20], *pointPtr;
1182      int numPoints, filled;      int numPoints, filled;
1183      int inside;                 /* Non-zero means every test so far suggests      int inside;                 /* Non-zero means every test so far suggests
1184                                   * that arc is inside rectangle.  0 means                                   * that arc is inside rectangle.  0 means
1185                                   * every test so far shows arc to be outside                                   * every test so far shows arc to be outside
1186                                   * of rectangle. */                                   * of rectangle. */
1187      int newInside;      int newInside;
1188      Tk_State state = itemPtr->state;      Tk_State state = itemPtr->state;
1189    
1190      if(state == TK_STATE_NULL) {      if(state == TK_STATE_NULL) {
1191          state = ((TkCanvas *)canvas)->canvas_state;          state = ((TkCanvas *)canvas)->canvas_state;
1192      }      }
1193      width = (double) arcPtr->outline.width;      width = (double) arcPtr->outline.width;
1194      if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {      if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
1195          if (arcPtr->outline.activeWidth>width) {          if (arcPtr->outline.activeWidth>width) {
1196              width = (double) arcPtr->outline.activeWidth;              width = (double) arcPtr->outline.activeWidth;
1197          }          }
1198      } else if (state==TK_STATE_DISABLED) {      } else if (state==TK_STATE_DISABLED) {
1199          if (arcPtr->outline.disabledWidth>0) {          if (arcPtr->outline.disabledWidth>0) {
1200              width = (double) arcPtr->outline.disabledWidth;              width = (double) arcPtr->outline.disabledWidth;
1201          }          }
1202      }      }
1203    
1204      if ((arcPtr->fillGC != None) || (arcPtr->outline.gc == None)) {      if ((arcPtr->fillGC != None) || (arcPtr->outline.gc == None)) {
1205          filled = 1;          filled = 1;
1206      } else {      } else {
1207          filled = 0;          filled = 0;
1208      }      }
1209      if (arcPtr->outline.gc == None) {      if (arcPtr->outline.gc == None) {
1210          width = 0.0;          width = 0.0;
1211      }      }
1212    
1213      /*      /*
1214       * Transform both the arc and the rectangle so that the arc's oval       * Transform both the arc and the rectangle so that the arc's oval
1215       * is centered on the origin.       * is centered on the origin.
1216       */       */
1217    
1218      center[0] = (arcPtr->bbox[0] + arcPtr->bbox[2])/2.0;      center[0] = (arcPtr->bbox[0] + arcPtr->bbox[2])/2.0;
1219      center[1] = (arcPtr->bbox[1] + arcPtr->bbox[3])/2.0;      center[1] = (arcPtr->bbox[1] + arcPtr->bbox[3])/2.0;
1220      tRect[0] = rectPtr[0] - center[0];      tRect[0] = rectPtr[0] - center[0];
1221      tRect[1] = rectPtr[1] - center[1];      tRect[1] = rectPtr[1] - center[1];
1222      tRect[2] = rectPtr[2] - center[0];      tRect[2] = rectPtr[2] - center[0];
1223      tRect[3] = rectPtr[3] - center[1];      tRect[3] = rectPtr[3] - center[1];
1224      rx = arcPtr->bbox[2] - center[0] + width/2.0;      rx = arcPtr->bbox[2] - center[0] + width/2.0;
1225      ry = arcPtr->bbox[3] - center[1] + width/2.0;      ry = arcPtr->bbox[3] - center[1] + width/2.0;
1226    
1227      /*      /*
1228       * Find the extreme points of the arc and see whether these are all       * Find the extreme points of the arc and see whether these are all
1229       * inside the rectangle (in which case we're done), partly in and       * inside the rectangle (in which case we're done), partly in and
1230       * partly out (in which case we're done), or all outside (in which       * partly out (in which case we're done), or all outside (in which
1231       * case we have more work to do).  The extreme points include the       * case we have more work to do).  The extreme points include the
1232       * following, which are checked in order:       * following, which are checked in order:
1233       *       *
1234       * 1. The outside points of the arc, corresponding to start and       * 1. The outside points of the arc, corresponding to start and
1235       *    extent.       *    extent.
1236       * 2. The center of the arc (but only in pie-slice mode).       * 2. The center of the arc (but only in pie-slice mode).
1237       * 3. The 12, 3, 6, and 9-o'clock positions (but only if the arc       * 3. The 12, 3, 6, and 9-o'clock positions (but only if the arc
1238       *    includes those angles).       *    includes those angles).
1239       */       */
1240    
1241      pointPtr = points;      pointPtr = points;
1242      angle = -arcPtr->start*(PI/180.0);      angle = -arcPtr->start*(PI/180.0);
1243      pointPtr[0] = rx*cos(angle);      pointPtr[0] = rx*cos(angle);
1244      pointPtr[1] = ry*sin(angle);      pointPtr[1] = ry*sin(angle);
1245      angle += -arcPtr->extent*(PI/180.0);      angle += -arcPtr->extent*(PI/180.0);
1246      pointPtr[2] = rx*cos(angle);      pointPtr[2] = rx*cos(angle);
1247      pointPtr[3] = ry*sin(angle);      pointPtr[3] = ry*sin(angle);
1248      numPoints = 2;      numPoints = 2;
1249      pointPtr += 4;      pointPtr += 4;
1250    
1251      if ((arcPtr->style == PIESLICE_STYLE) && (arcPtr->extent < 180.0)) {      if ((arcPtr->style == PIESLICE_STYLE) && (arcPtr->extent < 180.0)) {
1252          pointPtr[0] = 0.0;          pointPtr[0] = 0.0;
1253          pointPtr[1] = 0.0;          pointPtr[1] = 0.0;
1254          numPoints++;          numPoints++;
1255          pointPtr += 2;          pointPtr += 2;
1256      }      }
1257    
1258      tmp = -arcPtr->start;      tmp = -arcPtr->start;
1259      if (tmp < 0) {      if (tmp < 0) {
1260          tmp += 360.0;          tmp += 360.0;
1261      }      }
1262      if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {      if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {
1263          pointPtr[0] = rx;          pointPtr[0] = rx;
1264          pointPtr[1] = 0.0;          pointPtr[1] = 0.0;
1265          numPoints++;          numPoints++;
1266          pointPtr += 2;          pointPtr += 2;
1267      }      }
1268      tmp = 90.0 - arcPtr->start;      tmp = 90.0 - arcPtr->start;
1269      if (tmp < 0) {      if (tmp < 0) {
1270          tmp += 360.0;          tmp += 360.0;
1271      }      }
1272      if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {      if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {
1273          pointPtr[0] = 0.0;          pointPtr[0] = 0.0;
1274          pointPtr[1] = -ry;          pointPtr[1] = -ry;
1275          numPoints++;          numPoints++;
1276          pointPtr += 2;          pointPtr += 2;
1277      }      }
1278      tmp = 180.0 - arcPtr->start;      tmp = 180.0 - arcPtr->start;
1279      if (tmp < 0) {      if (tmp < 0) {
1280          tmp += 360.0;          tmp += 360.0;
1281      }      }
1282      if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {      if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {
1283          pointPtr[0] = -rx;          pointPtr[0] = -rx;
1284          pointPtr[1] = 0.0;          pointPtr[1] = 0.0;
1285          numPoints++;          numPoints++;
1286          pointPtr += 2;          pointPtr += 2;
1287      }      }
1288      tmp = 270.0 - arcPtr->start;      tmp = 270.0 - arcPtr->start;
1289      if (tmp < 0) {      if (tmp < 0) {
1290          tmp += 360.0;          tmp += 360.0;
1291      }      }
1292      if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {      if ((tmp < arcPtr->extent) || ((tmp-360) > arcPtr->extent)) {
1293          pointPtr[0] = 0.0;          pointPtr[0] = 0.0;
1294          pointPtr[1] = ry;          pointPtr[1] = ry;
1295          numPoints++;          numPoints++;
1296      }      }
1297    
1298      /*      /*
1299       * Now that we've located the extreme points, loop through them all       * Now that we've located the extreme points, loop through them all
1300       * to see which are inside the rectangle.       * to see which are inside the rectangle.
1301       */       */
1302    
1303      inside = (points[0] > tRect[0]) && (points[0] < tRect[2])      inside = (points[0] > tRect[0]) && (points[0] < tRect[2])
1304              && (points[1] > tRect[1]) && (points[1] < tRect[3]);              && (points[1] > tRect[1]) && (points[1] < tRect[3]);
1305      for (pointPtr = points+2; numPoints > 1; pointPtr += 2, numPoints--) {      for (pointPtr = points+2; numPoints > 1; pointPtr += 2, numPoints--) {
1306          newInside = (pointPtr[0] > tRect[0]) && (pointPtr[0] < tRect[2])          newInside = (pointPtr[0] > tRect[0]) && (pointPtr[0] < tRect[2])
1307                  && (pointPtr[1] > tRect[1]) && (pointPtr[1] < tRect[3]);                  && (pointPtr[1] > tRect[1]) && (pointPtr[1] < tRect[3]);
1308          if (newInside != inside) {          if (newInside != inside) {
1309              return 0;              return 0;
1310          }          }
1311      }      }
1312    
1313      if (inside) {      if (inside) {
1314          return 1;          return 1;
1315      }      }
1316    
1317      /*      /*
1318       * So far, oval appears to be outside rectangle, but can't yet tell       * So far, oval appears to be outside rectangle, but can't yet tell
1319       * for sure.  Next, test each of the four sides of the rectangle       * for sure.  Next, test each of the four sides of the rectangle
1320       * against the bounding region for the arc.  If any intersections       * against the bounding region for the arc.  If any intersections
1321       * are found, then return "overlapping".  First, test against the       * are found, then return "overlapping".  First, test against the
1322       * polygon(s) forming the sides of a chord or pie-slice.       * polygon(s) forming the sides of a chord or pie-slice.
1323       */       */
1324    
1325      if (arcPtr->style == PIESLICE_STYLE) {      if (arcPtr->style == PIESLICE_STYLE) {
1326          if (width >= 1.0) {          if (width >= 1.0) {
1327              if (TkPolygonToArea(arcPtr->outlinePtr, PIE_OUTLINE1_PTS,              if (TkPolygonToArea(arcPtr->outlinePtr, PIE_OUTLINE1_PTS,
1328                      rectPtr) != -1)  {                      rectPtr) != -1)  {
1329                  return 0;                  return 0;
1330              }              }
1331              if (TkPolygonToArea(arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,              if (TkPolygonToArea(arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,
1332                      PIE_OUTLINE2_PTS, rectPtr) != -1) {                      PIE_OUTLINE2_PTS, rectPtr) != -1) {
1333                  return 0;                  return 0;
1334              }              }
1335          } else {          } else {
1336              if ((TkLineToArea(center, arcPtr->center1, rectPtr) != -1) ||              if ((TkLineToArea(center, arcPtr->center1, rectPtr) != -1) ||
1337                      (TkLineToArea(center, arcPtr->center2, rectPtr) != -1)) {                      (TkLineToArea(center, arcPtr->center2, rectPtr) != -1)) {
1338                  return 0;                  return 0;
1339              }              }
1340          }          }
1341      } else if (arcPtr->style == CHORD_STYLE) {      } else if (arcPtr->style == CHORD_STYLE) {
1342          if (width >= 1.0) {          if (width >= 1.0) {
1343              if (TkPolygonToArea(arcPtr->outlinePtr, CHORD_OUTLINE_PTS,              if (TkPolygonToArea(arcPtr->outlinePtr, CHORD_OUTLINE_PTS,
1344                      rectPtr) != -1) {                      rectPtr) != -1) {
1345                  return 0;                  return 0;
1346              }              }
1347          } else {          } else {
1348              if (TkLineToArea(arcPtr->center1, arcPtr->center2,              if (TkLineToArea(arcPtr->center1, arcPtr->center2,
1349                      rectPtr) != -1) {                      rectPtr) != -1) {
1350                  return 0;                  return 0;
1351              }              }
1352          }          }
1353      }      }
1354    
1355      /*      /*
1356       * Next check for overlap between each of the four sides and the       * Next check for overlap between each of the four sides and the
1357       * outer perimiter of the arc.  If the arc isn't filled, then also       * outer perimiter of the arc.  If the arc isn't filled, then also
1358       * check the inner perimeter of the arc.       * check the inner perimeter of the arc.
1359       */       */
1360    
1361      if (HorizLineToArc(tRect[0], tRect[2], tRect[1], rx, ry, arcPtr->start,      if (HorizLineToArc(tRect[0], tRect[2], tRect[1], rx, ry, arcPtr->start,
1362                  arcPtr->extent)                  arcPtr->extent)
1363              || HorizLineToArc(tRect[0], tRect[2], tRect[3], rx, ry,              || HorizLineToArc(tRect[0], tRect[2], tRect[3], rx, ry,
1364                  arcPtr->start, arcPtr->extent)                  arcPtr->start, arcPtr->extent)
1365              || VertLineToArc(tRect[0], tRect[1], tRect[3], rx, ry,              || VertLineToArc(tRect[0], tRect[1], tRect[3], rx, ry,
1366                  arcPtr->start, arcPtr->extent)                  arcPtr->start, arcPtr->extent)
1367              || VertLineToArc(tRect[2], tRect[1], tRect[3], rx, ry,              || VertLineToArc(tRect[2], tRect[1], tRect[3], rx, ry,
1368                  arcPtr->start, arcPtr->extent)) {                  arcPtr->start, arcPtr->extent)) {
1369          return 0;          return 0;
1370      }      }
1371      if ((width > 1.0) && !filled) {      if ((width > 1.0) && !filled) {
1372          rx -= width;          rx -= width;
1373          ry -= width;          ry -= width;
1374          if (HorizLineToArc(tRect[0], tRect[2], tRect[1], rx, ry, arcPtr->start,          if (HorizLineToArc(tRect[0], tRect[2], tRect[1], rx, ry, arcPtr->start,
1375                      arcPtr->extent)                      arcPtr->extent)
1376                  || HorizLineToArc(tRect[0], tRect[2], tRect[3], rx, ry,                  || HorizLineToArc(tRect[0], tRect[2], tRect[3], rx, ry,
1377                      arcPtr->start, arcPtr->extent)                      arcPtr->start, arcPtr->extent)
1378                  || VertLineToArc(tRect[0], tRect[1], tRect[3], rx, ry,                  || VertLineToArc(tRect[0], tRect[1], tRect[3], rx, ry,
1379                      arcPtr->start, arcPtr->extent)                      arcPtr->start, arcPtr->extent)
1380                  || VertLineToArc(tRect[2], tRect[1], tRect[3], rx, ry,                  || VertLineToArc(tRect[2], tRect[1], tRect[3], rx, ry,
1381                      arcPtr->start, arcPtr->extent)) {                      arcPtr->start, arcPtr->extent)) {
1382              return 0;              return 0;
1383          }          }
1384      }      }
1385    
1386      /*      /*
1387       * The arc still appears to be totally disjoint from the rectangle,       * The arc still appears to be totally disjoint from the rectangle,
1388       * but it's also possible that the rectangle is totally inside the arc.       * but it's also possible that the rectangle is totally inside the arc.
1389       * Do one last check, which is to check one point of the rectangle       * Do one last check, which is to check one point of the rectangle
1390       * to see if it's inside the arc.  If it is, we've got overlap.  If       * to see if it's inside the arc.  If it is, we've got overlap.  If
1391       * it isn't, the arc's really outside the rectangle.       * it isn't, the arc's really outside the rectangle.
1392       */       */
1393    
1394      if (ArcToPoint(canvas, itemPtr, rectPtr) == 0.0) {      if (ArcToPoint(canvas, itemPtr, rectPtr) == 0.0) {
1395          return 0;          return 0;
1396      }      }
1397      return -1;      return -1;
1398  }  }
1399    
1400  /*  /*
1401   *--------------------------------------------------------------   *--------------------------------------------------------------
1402   *   *
1403   * ScaleArc --   * ScaleArc --
1404   *   *
1405   *      This procedure is invoked to rescale an arc item.   *      This procedure is invoked to rescale an arc item.
1406   *   *
1407   * Results:   * Results:
1408   *      None.   *      None.
1409   *   *
1410   * Side effects:   * Side effects:
1411   *      The arc referred to by itemPtr is rescaled so that the   *      The arc referred to by itemPtr is rescaled so that the
1412   *      following transformation is applied to all point   *      following transformation is applied to all point
1413   *      coordinates:   *      coordinates:
1414   *              x' = originX + scaleX*(x-originX)   *              x' = originX + scaleX*(x-originX)
1415   *              y' = originY + scaleY*(y-originY)   *              y' = originY + scaleY*(y-originY)
1416   *   *
1417   *--------------------------------------------------------------   *--------------------------------------------------------------
1418   */   */
1419    
1420  static void  static void
1421  ScaleArc(canvas, itemPtr, originX, originY, scaleX, scaleY)  ScaleArc(canvas, itemPtr, originX, originY, scaleX, scaleY)
1422      Tk_Canvas canvas;                   /* Canvas containing arc. */      Tk_Canvas canvas;                   /* Canvas containing arc. */
1423      Tk_Item *itemPtr;                   /* Arc to be scaled. */      Tk_Item *itemPtr;                   /* Arc to be scaled. */
1424      double originX, originY;            /* Origin about which to scale rect. */      double originX, originY;            /* Origin about which to scale rect. */
1425      double scaleX;                      /* Amount to scale in X direction. */      double scaleX;                      /* Amount to scale in X direction. */
1426      double scaleY;                      /* Amount to scale in Y direction. */      double scaleY;                      /* Amount to scale in Y direction. */
1427  {  {
1428      ArcItem *arcPtr = (ArcItem *) itemPtr;      ArcItem *arcPtr = (ArcItem *) itemPtr;
1429    
1430      arcPtr->bbox[0] = originX + scaleX*(arcPtr->bbox[0] - originX);      arcPtr->bbox[0] = originX + scaleX*(arcPtr->bbox[0] - originX);
1431      arcPtr->bbox[1] = originY + scaleY*(arcPtr->bbox[1] - originY);      arcPtr->bbox[1] = originY + scaleY*(arcPtr->bbox[1] - originY);
1432      arcPtr->bbox[2] = originX + scaleX*(arcPtr->bbox[2] - originX);      arcPtr->bbox[2] = originX + scaleX*(arcPtr->bbox[2] - originX);
1433      arcPtr->bbox[3] = originY + scaleY*(arcPtr->bbox[3] - originY);      arcPtr->bbox[3] = originY + scaleY*(arcPtr->bbox[3] - originY);
1434      ComputeArcBbox(canvas, arcPtr);      ComputeArcBbox(canvas, arcPtr);
1435  }  }
1436    
1437  /*  /*
1438   *--------------------------------------------------------------   *--------------------------------------------------------------
1439   *   *
1440   * TranslateArc --   * TranslateArc --
1441   *   *
1442   *      This procedure is called to move an arc by a given amount.   *      This procedure is called to move an arc by a given amount.
1443   *   *
1444   * Results:   * Results:
1445   *      None.   *      None.
1446   *   *
1447   * Side effects:   * Side effects:
1448   *      The position of the arc is offset by (xDelta, yDelta), and   *      The position of the arc is offset by (xDelta, yDelta), and
1449   *      the bounding box is updated in the generic part of the item   *      the bounding box is updated in the generic part of the item
1450   *      structure.   *      structure.
1451   *   *
1452   *--------------------------------------------------------------   *--------------------------------------------------------------
1453   */   */
1454    
1455  static void  static void
1456  TranslateArc(canvas, itemPtr, deltaX, deltaY)  TranslateArc(canvas, itemPtr, deltaX, deltaY)
1457      Tk_Canvas canvas;                   /* Canvas containing item. */      Tk_Canvas canvas;                   /* Canvas containing item. */
1458      Tk_Item *itemPtr;                   /* Item that is being moved. */      Tk_Item *itemPtr;                   /* Item that is being moved. */
1459      double deltaX, deltaY;              /* Amount by which item is to be      double deltaX, deltaY;              /* Amount by which item is to be
1460                                           * moved. */                                           * moved. */
1461  {  {
1462      ArcItem *arcPtr = (ArcItem *) itemPtr;      ArcItem *arcPtr = (ArcItem *) itemPtr;
1463    
1464      arcPtr->bbox[0] += deltaX;      arcPtr->bbox[0] += deltaX;
1465      arcPtr->bbox[1] += deltaY;      arcPtr->bbox[1] += deltaY;
1466      arcPtr->bbox[2] += deltaX;      arcPtr->bbox[2] += deltaX;
1467      arcPtr->bbox[3] += deltaY;      arcPtr->bbox[3] += deltaY;
1468      ComputeArcBbox(canvas, arcPtr);      ComputeArcBbox(canvas, arcPtr);
1469  }  }
1470    
1471  /*  /*
1472   *--------------------------------------------------------------   *--------------------------------------------------------------
1473   *   *
1474   * ComputeArcOutline --   * ComputeArcOutline --
1475   *   *
1476   *      This procedure creates a polygon describing everything in   *      This procedure creates a polygon describing everything in
1477   *      the outline for an arc except what's in the curved part.   *      the outline for an arc except what's in the curved part.
1478   *      For a "pie slice" arc this is a V-shaped chunk, and for   *      For a "pie slice" arc this is a V-shaped chunk, and for
1479   *      a "chord" arc this is a linear chunk (with cutaway corners).   *      a "chord" arc this is a linear chunk (with cutaway corners).
1480   *      For "arc" arcs, this stuff isn't relevant.   *      For "arc" arcs, this stuff isn't relevant.
1481   *   *
1482   * Results:   * Results:
1483   *      None.   *      None.
1484   *   *
1485   * Side effects:   * Side effects:
1486   *      The information at arcPtr->outlinePtr gets modified, and   *      The information at arcPtr->outlinePtr gets modified, and
1487   *      storage for arcPtr->outlinePtr may be allocated or freed.   *      storage for arcPtr->outlinePtr may be allocated or freed.
1488   *   *
1489   *--------------------------------------------------------------   *--------------------------------------------------------------
1490   */   */
1491    
1492  static void  static void
1493  ComputeArcOutline(canvas,arcPtr)  ComputeArcOutline(canvas,arcPtr)
1494      Tk_Canvas canvas;                   /* Information about overall canvas. */      Tk_Canvas canvas;                   /* Information about overall canvas. */
1495      ArcItem *arcPtr;                    /* Information about arc. */      ArcItem *arcPtr;                    /* Information about arc. */
1496  {  {
1497      double sin1, cos1, sin2, cos2, angle, width, halfWidth;      double sin1, cos1, sin2, cos2, angle, width, halfWidth;
1498      double boxWidth, boxHeight;      double boxWidth, boxHeight;
1499      double vertex[2], corner1[2], corner2[2];      double vertex[2], corner1[2], corner2[2];
1500      double *outlinePtr;      double *outlinePtr;
1501      Tk_State state = arcPtr->header.state;      Tk_State state = arcPtr->header.state;
1502    
1503    
1504      /*      /*
1505       * Make sure that the outlinePtr array is large enough to hold       * Make sure that the outlinePtr array is large enough to hold
1506       * either a chord or pie-slice outline.       * either a chord or pie-slice outline.
1507       */       */
1508    
1509      if (arcPtr->numOutlinePoints == 0) {      if (arcPtr->numOutlinePoints == 0) {
1510          arcPtr->outlinePtr = (double *) ckalloc((unsigned)          arcPtr->outlinePtr = (double *) ckalloc((unsigned)
1511                  (26 * sizeof(double)));                  (26 * sizeof(double)));
1512          arcPtr->numOutlinePoints = 22;          arcPtr->numOutlinePoints = 22;
1513      }      }
1514      outlinePtr = arcPtr->outlinePtr;      outlinePtr = arcPtr->outlinePtr;
1515    
1516      if(state == TK_STATE_NULL) {      if(state == TK_STATE_NULL) {
1517          state = ((TkCanvas *)canvas)->canvas_state;          state = ((TkCanvas *)canvas)->canvas_state;
1518      }      }
1519    
1520      /*      /*
1521       * First compute the two points that lie at the centers of       * First compute the two points that lie at the centers of
1522       * the ends of the curved arc segment, which are marked with       * the ends of the curved arc segment, which are marked with
1523       * X's in the figure below:       * X's in the figure below:
1524       *       *
1525       *       *
1526       *                            * * *       *                            * * *
1527       *                        *          *       *                        *          *
1528       *                     *      * *      *       *                     *      * *      *
1529       *                   *    *         *    *       *                   *    *         *    *
1530       *                  *   *             *   *       *                  *   *             *   *
1531       *                   X *               * X       *                   X *               * X
1532       *       *
1533       * The code is tricky because the arc can be ovular in shape.       * The code is tricky because the arc can be ovular in shape.
1534       * It computes the position for a unit circle, and then       * It computes the position for a unit circle, and then
1535       * scales to fit the shape of the arc's bounding box.       * scales to fit the shape of the arc's bounding box.
1536       *       *
1537       * Also, watch out because angles go counter-clockwise like you       * Also, watch out because angles go counter-clockwise like you
1538       * might expect, but the y-coordinate system is inverted.  To       * might expect, but the y-coordinate system is inverted.  To
1539       * handle this, just negate the angles in all the computations.       * handle this, just negate the angles in all the computations.
1540       */       */
1541    
1542      boxWidth = arcPtr->bbox[2] - arcPtr->bbox[0];      boxWidth = arcPtr->bbox[2] - arcPtr->bbox[0];
1543      boxHeight = arcPtr->bbox[3] - arcPtr->bbox[1];      boxHeight = arcPtr->bbox[3] - arcPtr->bbox[1];
1544      angle = -arcPtr->start*PI/180.0;      angle = -arcPtr->start*PI/180.0;
1545      sin1 = sin(angle);      sin1 = sin(angle);
1546      cos1 = cos(angle);      cos1 = cos(angle);
1547      angle -= arcPtr->extent*PI/180.0;      angle -= arcPtr->extent*PI/180.0;
1548      sin2 = sin(angle);      sin2 = sin(angle);
1549      cos2 = cos(angle);      cos2 = cos(angle);
1550      vertex[0] = (arcPtr->bbox[0] + arcPtr->bbox[2])/2.0;      vertex[0] = (arcPtr->bbox[0] + arcPtr->bbox[2])/2.0;
1551      vertex[1] = (arcPtr->bbox[1] + arcPtr->bbox[3])/2.0;      vertex[1] = (arcPtr->bbox[1] + arcPtr->bbox[3])/2.0;
1552      arcPtr->center1[0] = vertex[0] + cos1*boxWidth/2.0;      arcPtr->center1[0] = vertex[0] + cos1*boxWidth/2.0;
1553      arcPtr->center1[1] = vertex[1] + sin1*boxHeight/2.0;      arcPtr->center1[1] = vertex[1] + sin1*boxHeight/2.0;
1554      arcPtr->center2[0] = vertex[0] + cos2*boxWidth/2.0;      arcPtr->center2[0] = vertex[0] + cos2*boxWidth/2.0;
1555      arcPtr->center2[1] = vertex[1] + sin2*boxHeight/2.0;      arcPtr->center2[1] = vertex[1] + sin2*boxHeight/2.0;
1556    
1557      /*      /*
1558       * Next compute the "outermost corners" of the arc, which are       * Next compute the "outermost corners" of the arc, which are
1559       * marked with X's in the figure below:       * marked with X's in the figure below:
1560       *       *
1561       *                            * * *       *                            * * *
1562       *                        *          *       *                        *          *
1563       *                     *      * *      *       *                     *      * *      *
1564       *                   *    *         *    *       *                   *    *         *    *
1565       *                  X   *             *   X       *                  X   *             *   X
1566       *                     *               *       *                     *               *
1567       *       *
1568       * The code below is tricky because it has to handle eccentricity       * The code below is tricky because it has to handle eccentricity
1569       * in the shape of the oval.  The key in the code below is to       * in the shape of the oval.  The key in the code below is to
1570       * realize that the slope of the line from arcPtr->center1 to corner1       * realize that the slope of the line from arcPtr->center1 to corner1
1571       * is (boxWidth*sin1)/(boxHeight*cos1), and similarly for arcPtr->center2       * is (boxWidth*sin1)/(boxHeight*cos1), and similarly for arcPtr->center2
1572       * and corner2.  These formulas can be computed from the formula for       * and corner2.  These formulas can be computed from the formula for
1573       * the oval.       * the oval.
1574       */       */
1575    
1576      width = arcPtr->outline.width;      width = arcPtr->outline.width;
1577      if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *) arcPtr) {      if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *) arcPtr) {
1578          if (arcPtr->outline.activeWidth>arcPtr->outline.width) {          if (arcPtr->outline.activeWidth>arcPtr->outline.width) {
1579              width = arcPtr->outline.activeWidth;              width = arcPtr->outline.activeWidth;
1580          }          }
1581      } else if (state==TK_STATE_DISABLED) {      } else if (state==TK_STATE_DISABLED) {
1582          if (arcPtr->outline.disabledWidth>arcPtr->outline.width) {          if (arcPtr->outline.disabledWidth>arcPtr->outline.width) {
1583              width = arcPtr->outline.disabledWidth;              width = arcPtr->outline.disabledWidth;
1584          }          }
1585      }      }
1586      halfWidth = width/2.0;      halfWidth = width/2.0;
1587    
1588      if (((boxWidth*sin1) == 0.0) && ((boxHeight*cos1) == 0.0)) {      if (((boxWidth*sin1) == 0.0) && ((boxHeight*cos1) == 0.0)) {
1589          angle = 0.0;          angle = 0.0;
1590      } else {      } else {
1591          angle = atan2(boxWidth*sin1, boxHeight*cos1);          angle = atan2(boxWidth*sin1, boxHeight*cos1);
1592      }      }
1593      corner1[0] = arcPtr->center1[0] + cos(angle)*halfWidth;      corner1[0] = arcPtr->center1[0] + cos(angle)*halfWidth;
1594      corner1[1] = arcPtr->center1[1] + sin(angle)*halfWidth;      corner1[1] = arcPtr->center1[1] + sin(angle)*halfWidth;
1595      if (((boxWidth*sin2) == 0.0) && ((boxHeight*cos2) == 0.0)) {      if (((boxWidth*sin2) == 0.0) && ((boxHeight*cos2) == 0.0)) {
1596          angle = 0.0;          angle = 0.0;
1597      } else {      } else {
1598          angle = atan2(boxWidth*sin2, boxHeight*cos2);          angle = atan2(boxWidth*sin2, boxHeight*cos2);
1599      }      }
1600      corner2[0] = arcPtr->center2[0] + cos(angle)*halfWidth;      corner2[0] = arcPtr->center2[0] + cos(angle)*halfWidth;
1601      corner2[1] = arcPtr->center2[1] + sin(angle)*halfWidth;      corner2[1] = arcPtr->center2[1] + sin(angle)*halfWidth;
1602    
1603      /*      /*
1604       * For a chord outline, generate a six-sided polygon with three       * For a chord outline, generate a six-sided polygon with three
1605       * points for each end of the chord.  The first and third points       * points for each end of the chord.  The first and third points
1606       * for each end are butt points generated on either side of the       * for each end are butt points generated on either side of the
1607       * center point.  The second point is the corner point.       * center point.  The second point is the corner point.
1608       */       */
1609    
1610      if (arcPtr->style == CHORD_STYLE) {      if (arcPtr->style == CHORD_STYLE) {
1611          outlinePtr[0] = outlinePtr[12] = corner1[0];          outlinePtr[0] = outlinePtr[12] = corner1[0];
1612          outlinePtr[1] = outlinePtr[13] = corner1[1];          outlinePtr[1] = outlinePtr[13] = corner1[1];
1613          TkGetButtPoints(arcPtr->center2, arcPtr->center1,          TkGetButtPoints(arcPtr->center2, arcPtr->center1,
1614                  width, 0, outlinePtr+10, outlinePtr+2);                  width, 0, outlinePtr+10, outlinePtr+2);
1615          outlinePtr[4] = arcPtr->center2[0] + outlinePtr[2]          outlinePtr[4] = arcPtr->center2[0] + outlinePtr[2]
1616                  - arcPtr->center1[0];                  - arcPtr->center1[0];
1617          outlinePtr[5] = arcPtr->center2[1] + outlinePtr[3]          outlinePtr[5] = arcPtr->center2[1] + outlinePtr[3]
1618                  - arcPtr->center1[1];                  - arcPtr->center1[1];
1619          outlinePtr[6] = corner2[0];          outlinePtr[6] = corner2[0];
1620          outlinePtr[7] = corner2[1];          outlinePtr[7] = corner2[1];
1621          outlinePtr[8] = arcPtr->center2[0] + outlinePtr[10]          outlinePtr[8] = arcPtr->center2[0] + outlinePtr[10]
1622                  - arcPtr->center1[0];                  - arcPtr->center1[0];
1623          outlinePtr[9] = arcPtr->center2[1] + outlinePtr[11]          outlinePtr[9] = arcPtr->center2[1] + outlinePtr[11]
1624                  - arcPtr->center1[1];                  - arcPtr->center1[1];
1625      } else if (arcPtr->style == PIESLICE_STYLE) {      } else if (arcPtr->style == PIESLICE_STYLE) {
1626          /*          /*
1627           * For pie slices, generate two polygons, one for each side           * For pie slices, generate two polygons, one for each side
1628           * of the pie slice.  The first arm has a shape like this,           * of the pie slice.  The first arm has a shape like this,
1629           * where the center of the oval is X, arcPtr->center1 is at Y, and           * where the center of the oval is X, arcPtr->center1 is at Y, and
1630           * corner1 is at Z:           * corner1 is at Z:
1631           *           *
1632           *       _____________________           *       _____________________
1633           *      |                     \           *      |                     \
1634           *      |                      \           *      |                      \
1635           *      X                    Y  Z           *      X                    Y  Z
1636           *      |                      /           *      |                      /
1637           *      |_____________________/           *      |_____________________/
1638           *           *
1639           */           */
1640    
1641          TkGetButtPoints(arcPtr->center1, vertex, width, 0,          TkGetButtPoints(arcPtr->center1, vertex, width, 0,
1642                  outlinePtr, outlinePtr+2);                  outlinePtr, outlinePtr+2);
1643          outlinePtr[4] = arcPtr->center1[0] + outlinePtr[2] - vertex[0];          outlinePtr[4] = arcPtr->center1[0] + outlinePtr[2] - vertex[0];
1644          outlinePtr[5] = arcPtr->center1[1] + outlinePtr[3] - vertex[1];          outlinePtr[5] = arcPtr->center1[1] + outlinePtr[3] - vertex[1];
1645          outlinePtr[6] = corner1[0];          outlinePtr[6] = corner1[0];
1646          outlinePtr[7] = corner1[1];          outlinePtr[7] = corner1[1];
1647          outlinePtr[8] = arcPtr->center1[0] + outlinePtr[0] - vertex[0];          outlinePtr[8] = arcPtr->center1[0] + outlinePtr[0] - vertex[0];
1648          outlinePtr[9] = arcPtr->center1[1] + outlinePtr[1] - vertex[1];          outlinePtr[9] = arcPtr->center1[1] + outlinePtr[1] - vertex[1];
1649          outlinePtr[10] = outlinePtr[0];          outlinePtr[10] = outlinePtr[0];
1650          outlinePtr[11] = outlinePtr[1];          outlinePtr[11] = outlinePtr[1];
1651    
1652          /*          /*
1653           * The second arm has a shape like this:           * The second arm has a shape like this:
1654           *           *
1655           *           *
1656           *         ______________________           *         ______________________
1657           *        /                       \           *        /                       \
1658           *       /                         \           *       /                         \
1659           *      Z  Y                    X  /           *      Z  Y                    X  /
1660           *       \                        /           *       \                        /
1661           *        \______________________/           *        \______________________/
1662           *           *
1663           * Similar to above X is the center of the oval/circle, Y is           * Similar to above X is the center of the oval/circle, Y is
1664           * arcPtr->center2, and Z is corner2.  The extra jog out to the left           * arcPtr->center2, and Z is corner2.  The extra jog out to the left
1665           * of X is needed in or to produce a butted joint with the           * of X is needed in or to produce a butted joint with the
1666           * first arm;  the corner to the right of X is one of the           * first arm;  the corner to the right of X is one of the
1667           * first two points of the first arm, depending on extent.           * first two points of the first arm, depending on extent.
1668           */           */
1669    
1670          TkGetButtPoints(arcPtr->center2, vertex, width, 0,          TkGetButtPoints(arcPtr->center2, vertex, width, 0,
1671                  outlinePtr+12, outlinePtr+16);                  outlinePtr+12, outlinePtr+16);
1672          if ((arcPtr->extent > 180) ||          if ((arcPtr->extent > 180) ||
1673                  ((arcPtr->extent < 0) && (arcPtr->extent > -180))) {                  ((arcPtr->extent < 0) && (arcPtr->extent > -180))) {
1674              outlinePtr[14] = outlinePtr[0];              outlinePtr[14] = outlinePtr[0];
1675              outlinePtr[15] = outlinePtr[1];              outlinePtr[15] = outlinePtr[1];
1676          } else {          } else {
1677              outlinePtr[14] = outlinePtr[2];              outlinePtr[14] = outlinePtr[2];
1678              outlinePtr[15] = outlinePtr[3];              outlinePtr[15] = outlinePtr[3];
1679          }          }
1680          outlinePtr[18] = arcPtr->center2[0] + outlinePtr[16] - vertex[0];          outlinePtr[18] = arcPtr->center2[0] + outlinePtr[16] - vertex[0];
1681          outlinePtr[19] = arcPtr->center2[1] + outlinePtr[17] - vertex[1];          outlinePtr[19] = arcPtr->center2[1] + outlinePtr[17] - vertex[1];
1682          outlinePtr[20] = corner2[0];          outlinePtr[20] = corner2[0];
1683          outlinePtr[21] = corner2[1];          outlinePtr[21] = corner2[1];
1684          outlinePtr[22] = arcPtr->center2[0] + outlinePtr[12] - vertex[0];          outlinePtr[22] = arcPtr->center2[0] + outlinePtr[12] - vertex[0];
1685          outlinePtr[23] = arcPtr->center2[1] + outlinePtr[13] - vertex[1];          outlinePtr[23] = arcPtr->center2[1] + outlinePtr[13] - vertex[1];
1686          outlinePtr[24] = outlinePtr[12];          outlinePtr[24] = outlinePtr[12];
1687          outlinePtr[25] = outlinePtr[13];          outlinePtr[25] = outlinePtr[13];
1688      }      }
1689  }  }
1690    
1691  /*  /*
1692   *--------------------------------------------------------------   *--------------------------------------------------------------
1693   *   *
1694   * HorizLineToArc --   * HorizLineToArc --
1695   *   *
1696   *      Determines whether a horizontal line segment intersects   *      Determines whether a horizontal line segment intersects
1697   *      a given arc.   *      a given arc.
1698   *   *
1699   * Results:   * Results:
1700   *      The return value is 1 if the given line intersects the   *      The return value is 1 if the given line intersects the
1701   *      infinitely-thin arc section defined by rx, ry, start,   *      infinitely-thin arc section defined by rx, ry, start,
1702   *      and extent, and 0 otherwise.  Only the perimeter of the   *      and extent, and 0 otherwise.  Only the perimeter of the
1703   *      arc is checked: interior areas (e.g. pie-slice or chord)   *      arc is checked: interior areas (e.g. pie-slice or chord)
1704   *      are not checked.   *      are not checked.
1705   *   *
1706   * Side effects:   * Side effects:
1707   *      None.   *      None.
1708   *   *
1709   *--------------------------------------------------------------   *--------------------------------------------------------------
1710   */   */
1711    
1712  static int  static int
1713  HorizLineToArc(x1, x2, y, rx, ry, start, extent)  HorizLineToArc(x1, x2, y, rx, ry, start, extent)
1714      double x1, x2;              /* X-coords of endpoints of line segment.      double x1, x2;              /* X-coords of endpoints of line segment.
1715                                   * X1 must be <= x2. */                                   * X1 must be <= x2. */
1716      double y;                   /* Y-coordinate of line segment. */      double y;                   /* Y-coordinate of line segment. */
1717      double rx, ry;              /* These x- and y-radii define an oval      double rx, ry;              /* These x- and y-radii define an oval
1718                                   * centered at the origin. */                                   * centered at the origin. */
1719      double start, extent;       /* Angles that define extent of arc, in      double start, extent;       /* Angles that define extent of arc, in
1720                                   * the standard fashion for this module. */                                   * the standard fashion for this module. */
1721  {  {
1722      double tmp;      double tmp;
1723      double tx, ty;              /* Coordinates of intersection point in      double tx, ty;              /* Coordinates of intersection point in
1724                                   * transformed coordinate system. */                                   * transformed coordinate system. */
1725      double x;      double x;
1726    
1727      /*      /*
1728       * Compute the x-coordinate of one possible intersection point       * Compute the x-coordinate of one possible intersection point
1729       * between the arc and the line.  Use a transformed coordinate       * between the arc and the line.  Use a transformed coordinate
1730       * system where the oval is a unit circle centered at the origin.       * system where the oval is a unit circle centered at the origin.
1731       * Then scale back to get actual x-coordinate.       * Then scale back to get actual x-coordinate.
1732       */       */
1733    
1734      ty = y/ry;      ty = y/ry;
1735      tmp = 1 - ty*ty;      tmp = 1 - ty*ty;
1736      if (tmp < 0) {      if (tmp < 0) {
1737          return 0;          return 0;
1738      }      }
1739      tx = sqrt(tmp);      tx = sqrt(tmp);
1740      x = tx*rx;      x = tx*rx;
1741    
1742      /*      /*
1743       * Test both intersection points.       * Test both intersection points.
1744       */       */
1745    
1746      if ((x >= x1) && (x <= x2) && AngleInRange(tx, ty, start, extent)) {      if ((x >= x1) && (x <= x2) && AngleInRange(tx, ty, start, extent)) {
1747          return 1;          return 1;
1748      }      }
1749      if ((-x >= x1) && (-x <= x2) && AngleInRange(-tx, ty, start, extent)) {      if ((-x >= x1) && (-x <= x2) && AngleInRange(-tx, ty, start, extent)) {
1750          return 1;          return 1;
1751      }      }
1752      return 0;      return 0;
1753  }  }
1754    
1755  /*  /*
1756   *--------------------------------------------------------------   *--------------------------------------------------------------
1757   *   *
1758   * VertLineToArc --   * VertLineToArc --
1759   *   *
1760   *      Determines whether a vertical line segment intersects   *      Determines whether a vertical line segment intersects
1761   *      a given arc.   *      a given arc.
1762   *   *
1763   * Results:   * Results:
1764   *      The return value is 1 if the given line intersects the   *      The return value is 1 if the given line intersects the
1765   *      infinitely-thin arc section defined by rx, ry, start,   *      infinitely-thin arc section defined by rx, ry, start,
1766   *      and extent, and 0 otherwise.  Only the perimeter of the   *      and extent, and 0 otherwise.  Only the perimeter of the
1767   *      arc is checked: interior areas (e.g. pie-slice or chord)   *      arc is checked: interior areas (e.g. pie-slice or chord)
1768   *      are not checked.   *      are not checked.
1769   *   *
1770   * Side effects:   * Side effects:
1771   *      None.   *      None.
1772   *   *
1773   *--------------------------------------------------------------   *--------------------------------------------------------------
1774   */   */
1775    
1776  static int  static int
1777  VertLineToArc(x, y1, y2, rx, ry, start, extent)  VertLineToArc(x, y1, y2, rx, ry, start, extent)
1778      double x;                   /* X-coordinate of line segment. */      double x;                   /* X-coordinate of line segment. */
1779      double y1, y2;              /* Y-coords of endpoints of line segment.      double y1, y2;              /* Y-coords of endpoints of line segment.
1780                                   * Y1 must be <= y2. */                                   * Y1 must be <= y2. */
1781      double rx, ry;              /* These x- and y-radii define an oval      double rx, ry;              /* These x- and y-radii define an oval
1782                                   * centered at the origin. */                                   * centered at the origin. */
1783      double start, extent;       /* Angles that define extent of arc, in      double start, extent;       /* Angles that define extent of arc, in
1784                                   * the standard fashion for this module. */                                   * the standard fashion for this module. */
1785  {  {
1786      double tmp;      double tmp;
1787      double tx, ty;              /* Coordinates of intersection point in      double tx, ty;              /* Coordinates of intersection point in
1788                                   * transformed coordinate system. */                                   * transformed coordinate system. */
1789      double y;      double y;
1790    
1791      /*      /*
1792       * Compute the y-coordinate of one possible intersection point       * Compute the y-coordinate of one possible intersection point
1793       * between the arc and the line.  Use a transformed coordinate       * between the arc and the line.  Use a transformed coordinate
1794       * system where the oval is a unit circle centered at the origin.       * system where the oval is a unit circle centered at the origin.
1795       * Then scale back to get actual y-coordinate.       * Then scale back to get actual y-coordinate.
1796       */       */
1797    
1798      tx = x/rx;      tx = x/rx;
1799      tmp = 1 - tx*tx;      tmp = 1 - tx*tx;
1800      if (tmp < 0) {      if (tmp < 0) {
1801          return 0;          return 0;
1802      }      }
1803      ty = sqrt(tmp);      ty = sqrt(tmp);
1804      y = ty*ry;      y = ty*ry;
1805    
1806      /*      /*
1807       * Test both intersection points.       * Test both intersection points.
1808       */       */
1809    
1810      if ((y > y1) && (y < y2) && AngleInRange(tx, ty, start, extent)) {      if ((y > y1) && (y < y2) && AngleInRange(tx, ty, start, extent)) {
1811          return 1;          return 1;
1812      }      }
1813      if ((-y > y1) && (-y < y2) && AngleInRange(tx, -ty, start, extent)) {      if ((-y > y1) && (-y < y2) && AngleInRange(tx, -ty, start, extent)) {
1814          return 1;          return 1;
1815      }      }
1816      return 0;      return 0;
1817  }  }
1818    
1819  /*  /*
1820   *--------------------------------------------------------------   *--------------------------------------------------------------
1821   *   *
1822   * AngleInRange --   * AngleInRange --
1823   *   *
1824   *      Determine whether the angle from the origin to a given   *      Determine whether the angle from the origin to a given
1825   *      point is within a given range.   *      point is within a given range.
1826   *   *
1827   * Results:   * Results:
1828   *      The return value is 1 if the angle from (0,0) to (x,y)   *      The return value is 1 if the angle from (0,0) to (x,y)
1829   *      is in the range given by start and extent, where angles   *      is in the range given by start and extent, where angles
1830   *      are interpreted in the standard way for ovals (meaning   *      are interpreted in the standard way for ovals (meaning
1831   *      backwards from normal interpretation).  Otherwise the   *      backwards from normal interpretation).  Otherwise the
1832   *      return value is 0.   *      return value is 0.
1833   *   *
1834   * Side effects:   * Side effects:
1835   *      None.   *      None.
1836   *   *
1837   *--------------------------------------------------------------   *--------------------------------------------------------------
1838   */   */
1839    
1840  static int  static int
1841  AngleInRange(x, y, start, extent)  AngleInRange(x, y, start, extent)
1842      double x, y;                /* Coordinate of point;  angle measured      double x, y;                /* Coordinate of point;  angle measured
1843                                   * from origin to here, relative to x-axis. */                                   * from origin to here, relative to x-axis. */
1844      double start;               /* First angle, degrees, >=0, <=360. */      double start;               /* First angle, degrees, >=0, <=360. */
1845      double extent;              /* Size of arc in degrees >=-360, <=360. */      double extent;              /* Size of arc in degrees >=-360, <=360. */
1846  {  {
1847      double diff;      double diff;
1848    
1849      if ((x == 0.0) && (y == 0.0)) {      if ((x == 0.0) && (y == 0.0)) {
1850          return 1;          return 1;
1851      }      }
1852      diff = -atan2(y, x);      diff = -atan2(y, x);
1853      diff = diff*(180.0/PI) - start;      diff = diff*(180.0/PI) - start;
1854      while (diff > 360.0) {      while (diff > 360.0) {
1855          diff -= 360.0;          diff -= 360.0;
1856      }      }
1857      while (diff < 0.0) {      while (diff < 0.0) {
1858          diff += 360.0;          diff += 360.0;
1859      }      }
1860      if (extent >= 0) {      if (extent >= 0) {
1861          return diff <= extent;          return diff <= extent;
1862      }      }
1863      return (diff-360.0) >= extent;      return (diff-360.0) >= extent;
1864  }  }
1865    
1866  /*  /*
1867   *--------------------------------------------------------------   *--------------------------------------------------------------
1868   *   *
1869   * ArcToPostscript --   * ArcToPostscript --
1870   *   *
1871   *      This procedure is called to generate Postscript for   *      This procedure is called to generate Postscript for
1872   *      arc items.   *      arc items.
1873   *   *
1874   * Results:   * Results:
1875   *      The return value is a standard Tcl result.  If an error   *      The return value is a standard Tcl result.  If an error
1876   *      occurs in generating Postscript then an error message is   *      occurs in generating Postscript then an error message is
1877   *      left in the interp's result, replacing whatever used   *      left in the interp's result, replacing whatever used
1878   *      to be there.  If no error occurs, then Postscript for the   *      to be there.  If no error occurs, then Postscript for the
1879   *      item is appended to the result.   *      item is appended to the result.
1880   *   *
1881   * Side effects:   * Side effects:
1882   *      None.   *      None.
1883   *   *
1884   *--------------------------------------------------------------   *--------------------------------------------------------------
1885   */   */
1886    
1887  static int  static int
1888  ArcToPostscript(interp, canvas, itemPtr, prepass)  ArcToPostscript(interp, canvas, itemPtr, prepass)
1889      Tcl_Interp *interp;                 /* Leave Postscript or error message      Tcl_Interp *interp;                 /* Leave Postscript or error message
1890                                           * here. */                                           * here. */
1891      Tk_Canvas canvas;                   /* Information about overall canvas. */      Tk_Canvas canvas;                   /* Information about overall canvas. */
1892      Tk_Item *itemPtr;                   /* Item for which Postscript is      Tk_Item *itemPtr;                   /* Item for which Postscript is
1893                                           * wanted. */                                           * wanted. */
1894      int prepass;                        /* 1 means this is a prepass to      int prepass;                        /* 1 means this is a prepass to
1895                                           * collect font information;  0 means                                           * collect font information;  0 means
1896                                           * final Postscript is being created. */                                           * final Postscript is being created. */
1897  {  {
1898      ArcItem *arcPtr = (ArcItem *) itemPtr;      ArcItem *arcPtr = (ArcItem *) itemPtr;
1899      char buffer[400];      char buffer[400];
1900      double y1, y2, ang1, ang2;      double y1, y2, ang1, ang2;
1901      XColor *color;      XColor *color;
1902      Pixmap stipple;      Pixmap stipple;
1903      XColor *fillColor;      XColor *fillColor;
1904      Pixmap fillStipple;      Pixmap fillStipple;
1905      Tk_State state = itemPtr->state;      Tk_State state = itemPtr->state;
1906    
1907      y1 = Tk_CanvasPsY(canvas, arcPtr->bbox[1]);      y1 = Tk_CanvasPsY(canvas, arcPtr->bbox[1]);
1908      y2 = Tk_CanvasPsY(canvas, arcPtr->bbox[3]);      y2 = Tk_CanvasPsY(canvas, arcPtr->bbox[3]);
1909      ang1 = arcPtr->start;      ang1 = arcPtr->start;
1910      ang2 = ang1 + arcPtr->extent;      ang2 = ang1 + arcPtr->extent;
1911      if (ang2 < ang1) {      if (ang2 < ang1) {
1912          ang1 = ang2;          ang1 = ang2;
1913          ang2 = arcPtr->start;          ang2 = arcPtr->start;
1914      }      }
1915    
1916      if(state == TK_STATE_NULL) {      if(state == TK_STATE_NULL) {
1917          state = ((TkCanvas *)canvas)->canvas_state;          state = ((TkCanvas *)canvas)->canvas_state;
1918      }      }
1919      color = arcPtr->outline.color;      color = arcPtr->outline.color;
1920      stipple = arcPtr->outline.stipple;      stipple = arcPtr->outline.stipple;
1921      fillColor = arcPtr->fillColor;      fillColor = arcPtr->fillColor;
1922      fillStipple = arcPtr->fillStipple;      fillStipple = arcPtr->fillStipple;
1923      if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {      if (((TkCanvas *)canvas)->currentItemPtr == itemPtr) {
1924          if (arcPtr->outline.activeColor!=NULL) {          if (arcPtr->outline.activeColor!=NULL) {
1925              color = arcPtr->outline.activeColor;              color = arcPtr->outline.activeColor;
1926          }          }
1927          if (arcPtr->outline.activeStipple!=None) {          if (arcPtr->outline.activeStipple!=None) {
1928              stipple = arcPtr->outline.activeStipple;              stipple = arcPtr->outline.activeStipple;
1929          }          }
1930          if (arcPtr->activeFillColor!=NULL) {          if (arcPtr->activeFillColor!=NULL) {
1931              fillColor = arcPtr->activeFillColor;              fillColor = arcPtr->activeFillColor;
1932          }          }
1933          if (arcPtr->activeFillStipple!=None) {          if (arcPtr->activeFillStipple!=None) {
1934              fillStipple = arcPtr->activeFillStipple;              fillStipple = arcPtr->activeFillStipple;
1935          }          }
1936      } else if (state==TK_STATE_DISABLED) {      } else if (state==TK_STATE_DISABLED) {
1937          if (arcPtr->outline.disabledColor!=NULL) {          if (arcPtr->outline.disabledColor!=NULL) {
1938              color = arcPtr->outline.disabledColor;              color = arcPtr->outline.disabledColor;
1939          }          }
1940          if (arcPtr->outline.disabledStipple!=None) {          if (arcPtr->outline.disabledStipple!=None) {
1941              stipple = arcPtr->outline.disabledStipple;              stipple = arcPtr->outline.disabledStipple;
1942          }          }
1943          if (arcPtr->disabledFillColor!=NULL) {          if (arcPtr->disabledFillColor!=NULL) {
1944              fillColor = arcPtr->disabledFillColor;              fillColor = arcPtr->disabledFillColor;
1945          }          }
1946          if (arcPtr->disabledFillStipple!=None) {          if (arcPtr->disabledFillStipple!=None) {
1947              fillStipple = arcPtr->disabledFillStipple;              fillStipple = arcPtr->disabledFillStipple;
1948          }          }
1949      }      }
1950    
1951      /*      /*
1952       * If the arc is filled, output Postscript for the interior region       * If the arc is filled, output Postscript for the interior region
1953       * of the arc.       * of the arc.
1954       */       */
1955    
1956      if (arcPtr->fillGC != None) {      if (arcPtr->fillGC != None) {
1957          sprintf(buffer, "matrix currentmatrix\n%.15g %.15g translate %.15g %.15g scale\n",          sprintf(buffer, "matrix currentmatrix\n%.15g %.15g translate %.15g %.15g scale\n",
1958                  (arcPtr->bbox[0] + arcPtr->bbox[2])/2, (y1 + y2)/2,                  (arcPtr->bbox[0] + arcPtr->bbox[2])/2, (y1 + y2)/2,
1959                  (arcPtr->bbox[2] - arcPtr->bbox[0])/2, (y1 - y2)/2);                  (arcPtr->bbox[2] - arcPtr->bbox[0])/2, (y1 - y2)/2);
1960          Tcl_AppendResult(interp, buffer, (char *) NULL);          Tcl_AppendResult(interp, buffer, (char *) NULL);
1961          if (arcPtr->style == CHORD_STYLE) {          if (arcPtr->style == CHORD_STYLE) {
1962              sprintf(buffer, "0 0 1 %.15g %.15g arc closepath\nsetmatrix\n",              sprintf(buffer, "0 0 1 %.15g %.15g arc closepath\nsetmatrix\n",
1963                      ang1, ang2);                      ang1, ang2);
1964          } else {          } else {
1965              sprintf(buffer,              sprintf(buffer,
1966                      "0 0 moveto 0 0 1 %.15g %.15g arc closepath\nsetmatrix\n",                      "0 0 moveto 0 0 1 %.15g %.15g arc closepath\nsetmatrix\n",
1967                      ang1, ang2);                      ang1, ang2);
1968          }          }
1969          Tcl_AppendResult(interp, buffer, (char *) NULL);          Tcl_AppendResult(interp, buffer, (char *) NULL);
1970          if (Tk_CanvasPsColor(interp, canvas, fillColor) != TCL_OK) {          if (Tk_CanvasPsColor(interp, canvas, fillColor) != TCL_OK) {
1971              return TCL_ERROR;              return TCL_ERROR;
1972          };          };
1973          if (fillStipple != None) {          if (fillStipple != None) {
1974              Tcl_AppendResult(interp, "clip ", (char *) NULL);              Tcl_AppendResult(interp, "clip ", (char *) NULL);
1975              if (Tk_CanvasPsStipple(interp, canvas, fillStipple)              if (Tk_CanvasPsStipple(interp, canvas, fillStipple)
1976                      != TCL_OK) {                      != TCL_OK) {
1977                  return TCL_ERROR;                  return TCL_ERROR;
1978              }              }
1979              if (arcPtr->outline.gc != None) {              if (arcPtr->outline.gc != None) {
1980                  Tcl_AppendResult(interp, "grestore gsave\n", (char *) NULL);                  Tcl_AppendResult(interp, "grestore gsave\n", (char *) NULL);
1981              }              }
1982          } else {          } else {
1983              Tcl_AppendResult(interp, "fill\n", (char *) NULL);              Tcl_AppendResult(interp, "fill\n", (char *) NULL);
1984          }          }
1985      }      }
1986    
1987      /*      /*
1988       * If there's an outline for the arc, draw it.       * If there's an outline for the arc, draw it.
1989       */       */
1990    
1991      if (arcPtr->outline.gc != None) {      if (arcPtr->outline.gc != None) {
1992          sprintf(buffer, "matrix currentmatrix\n%.15g %.15g translate %.15g %.15g scale\n",          sprintf(buffer, "matrix currentmatrix\n%.15g %.15g translate %.15g %.15g scale\n",
1993                  (arcPtr->bbox[0] + arcPtr->bbox[2])/2, (y1 + y2)/2,                  (arcPtr->bbox[0] + arcPtr->bbox[2])/2, (y1 + y2)/2,
1994                  (arcPtr->bbox[2] - arcPtr->bbox[0])/2, (y1 - y2)/2);                  (arcPtr->bbox[2] - arcPtr->bbox[0])/2, (y1 - y2)/2);
1995          Tcl_AppendResult(interp, buffer, (char *) NULL);          Tcl_AppendResult(interp, buffer, (char *) NULL);
1996          sprintf(buffer, "0 0 1 %.15g %.15g", ang1, ang2);          sprintf(buffer, "0 0 1 %.15g %.15g", ang1, ang2);
1997          Tcl_AppendResult(interp, buffer,          Tcl_AppendResult(interp, buffer,
1998                  " arc\nsetmatrix\n0 setlinecap\n", (char *) NULL);                  " arc\nsetmatrix\n0 setlinecap\n", (char *) NULL);
1999          if (Tk_CanvasPsOutline(canvas, itemPtr,          if (Tk_CanvasPsOutline(canvas, itemPtr,
2000                  &(arcPtr->outline)) != TCL_OK) {                  &(arcPtr->outline)) != TCL_OK) {
2001              return TCL_ERROR;              return TCL_ERROR;
2002          }          }
2003          if (arcPtr->style != ARC_STYLE) {          if (arcPtr->style != ARC_STYLE) {
2004              Tcl_AppendResult(interp, "grestore gsave\n", (char *) NULL);              Tcl_AppendResult(interp, "grestore gsave\n", (char *) NULL);
2005              if (arcPtr->style == CHORD_STYLE) {              if (arcPtr->style == CHORD_STYLE) {
2006                  Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr,                  Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr,
2007                          CHORD_OUTLINE_PTS);                          CHORD_OUTLINE_PTS);
2008              } else {              } else {
2009                  Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr,                  Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr,
2010                          PIE_OUTLINE1_PTS);                          PIE_OUTLINE1_PTS);
2011                  if (Tk_CanvasPsColor(interp, canvas, color)                  if (Tk_CanvasPsColor(interp, canvas, color)
2012                          != TCL_OK) {                          != TCL_OK) {
2013                      return TCL_ERROR;                      return TCL_ERROR;
2014                  }                  }
2015                  if (stipple != None) {                  if (stipple != None) {
2016                      Tcl_AppendResult(interp, "clip ", (char *) NULL);                      Tcl_AppendResult(interp, "clip ", (char *) NULL);
2017                      if (Tk_CanvasPsStipple(interp, canvas,                      if (Tk_CanvasPsStipple(interp, canvas,
2018                              stipple) != TCL_OK) {                              stipple) != TCL_OK) {
2019                          return TCL_ERROR;                          return TCL_ERROR;
2020                      }                      }
2021                  } else {                  } else {
2022                      Tcl_AppendResult(interp, "fill\n", (char *) NULL);                      Tcl_AppendResult(interp, "fill\n", (char *) NULL);
2023                  }                  }
2024                  Tcl_AppendResult(interp, "grestore gsave\n", (char *) NULL);                  Tcl_AppendResult(interp, "grestore gsave\n", (char *) NULL);
2025                  Tk_CanvasPsPath(interp, canvas,                  Tk_CanvasPsPath(interp, canvas,
2026                          arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,                          arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,
2027                          PIE_OUTLINE2_PTS);                          PIE_OUTLINE2_PTS);
2028              }              }
2029              if (Tk_CanvasPsColor(interp, canvas, color)              if (Tk_CanvasPsColor(interp, canvas, color)
2030                      != TCL_OK) {                      != TCL_OK) {
2031                  return TCL_ERROR;                  return TCL_ERROR;
2032              }              }
2033              if (stipple != None) {              if (stipple != None) {
2034                  Tcl_AppendResult(interp, "clip ", (char *) NULL);                  Tcl_AppendResult(interp, "clip ", (char *) NULL);
2035                  if (Tk_CanvasPsStipple(interp, canvas,                  if (Tk_CanvasPsStipple(interp, canvas,
2036                          stipple) != TCL_OK) {                          stipple) != TCL_OK) {
2037                      return TCL_ERROR;                      return TCL_ERROR;
2038                  }                  }
2039              } else {              } else {
2040                  Tcl_AppendResult(interp, "fill\n", (char *) NULL);                  Tcl_AppendResult(interp, "fill\n", (char *) NULL);
2041              }              }
2042          }          }
2043      }      }
2044    
2045      return TCL_OK;      return TCL_OK;
2046  }  }
2047    
2048  /*  /*
2049   *--------------------------------------------------------------   *--------------------------------------------------------------
2050   *   *
2051   * StyleParseProc --   * StyleParseProc --
2052   *   *
2053   *      This procedure is invoked during option processing to handle   *      This procedure is invoked during option processing to handle
2054   *      the "-style" option.   *      the "-style" option.
2055   *   *
2056   * Results:   * Results:
2057   *      A standard Tcl return value.   *      A standard Tcl return value.
2058   *   *
2059   * Side effects:   * Side effects:
2060   *      The state for a given item gets replaced by the state   *      The state for a given item gets replaced by the state
2061   *      indicated in the value argument.   *      indicated in the value argument.
2062   *   *
2063   *--------------------------------------------------------------   *--------------------------------------------------------------
2064   */   */
2065    
2066  static int  static int
2067  StyleParseProc(clientData, interp, tkwin, value, widgRec, offset)  StyleParseProc(clientData, interp, tkwin, value, widgRec, offset)
2068      ClientData clientData;              /* some flags.*/      ClientData clientData;              /* some flags.*/
2069      Tcl_Interp *interp;                 /* Used for reporting errors. */      Tcl_Interp *interp;                 /* Used for reporting errors. */
2070      Tk_Window tkwin;                    /* Window containing canvas widget. */      Tk_Window tkwin;                    /* Window containing canvas widget. */
2071      CONST char *value;                  /* Value of option. */      CONST char *value;                  /* Value of option. */
2072      char *widgRec;                      /* Pointer to record for item. */      char *widgRec;                      /* Pointer to record for item. */
2073      int offset;                         /* Offset into item. */      int offset;                         /* Offset into item. */
2074  {  {
2075      int c;      int c;
2076      size_t length;      size_t length;
2077    
2078      register Style *stylePtr = (Style *) (widgRec + offset);      register Style *stylePtr = (Style *) (widgRec + offset);
2079    
2080      if(value == NULL || *value == 0) {      if(value == NULL || *value == 0) {
2081          *stylePtr = PIESLICE_STYLE;          *stylePtr = PIESLICE_STYLE;
2082          return TCL_OK;          return TCL_OK;
2083      }      }
2084    
2085      c = value[0];      c = value[0];
2086      length = strlen(value);      length = strlen(value);
2087    
2088      if ((c == 'a') && (strncmp(value, "arc", length) == 0)) {      if ((c == 'a') && (strncmp(value, "arc", length) == 0)) {
2089          *stylePtr = ARC_STYLE;          *stylePtr = ARC_STYLE;
2090          return TCL_OK;          return TCL_OK;
2091      }      }
2092      if ((c == 'c') && (strncmp(value, "chord", length) == 0)) {      if ((c == 'c') && (strncmp(value, "chord", length) == 0)) {
2093          *stylePtr = CHORD_STYLE;          *stylePtr = CHORD_STYLE;
2094          return TCL_OK;          return TCL_OK;
2095      }      }
2096      if ((c == 'p') && (strncmp(value, "pieslice", length) == 0)) {      if ((c == 'p') && (strncmp(value, "pieslice", length) == 0)) {
2097          *stylePtr = PIESLICE_STYLE;          *stylePtr = PIESLICE_STYLE;
2098          return TCL_OK;          return TCL_OK;
2099      }      }
2100    
2101      Tcl_AppendResult(interp, "bad -style option \"",      Tcl_AppendResult(interp, "bad -style option \"",
2102              value, "\": must be arc, chord, or pieslice",              value, "\": must be arc, chord, or pieslice",
2103              (char *) NULL);              (char *) NULL);
2104      *stylePtr = PIESLICE_STYLE;      *stylePtr = PIESLICE_STYLE;
2105      return TCL_ERROR;      return TCL_ERROR;
2106  }  }
2107    
2108  /*  /*
2109   *--------------------------------------------------------------   *--------------------------------------------------------------
2110   *   *
2111   * StylePrintProc --   * StylePrintProc --
2112   *   *
2113   *      This procedure is invoked by the Tk configuration code   *      This procedure is invoked by the Tk configuration code
2114   *      to produce a printable string for the "-style"   *      to produce a printable string for the "-style"
2115   *      configuration option.   *      configuration option.
2116   *   *
2117   * Results:   * Results:
2118   *      The return value is a string describing the state for   *      The return value is a string describing the state for
2119   *      the item referred to by "widgRec".  In addition, *freeProcPtr   *      the item referred to by "widgRec".  In addition, *freeProcPtr
2120   *      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
2121   *      the result string when it's no longer needed (or NULL to   *      the result string when it's no longer needed (or NULL to
2122   *      indicate that the string doesn't need to be freed).   *      indicate that the string doesn't need to be freed).
2123   *   *
2124   * Side effects:   * Side effects:
2125   *      None.   *      None.
2126   *   *
2127   *--------------------------------------------------------------   *--------------------------------------------------------------
2128   */   */
2129    
2130  static char *  static char *
2131  StylePrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)  StylePrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
2132      ClientData clientData;              /* Ignored. */      ClientData clientData;              /* Ignored. */
2133      Tk_Window tkwin;                    /* Ignored. */      Tk_Window tkwin;                    /* Ignored. */
2134      char *widgRec;                      /* Pointer to record for item. */      char *widgRec;                      /* Pointer to record for item. */
2135      int offset;                         /* Offset into item. */      int offset;                         /* Offset into item. */
2136      Tcl_FreeProc **freeProcPtr;         /* Pointer to variable to fill in with      Tcl_FreeProc **freeProcPtr;         /* Pointer to variable to fill in with
2137                                           * information about how to reclaim                                           * information about how to reclaim
2138                                           * storage for return string. */                                           * storage for return string. */
2139  {  {
2140      register Style *stylePtr = (Style *) (widgRec + offset);      register Style *stylePtr = (Style *) (widgRec + offset);
2141    
2142      if (*stylePtr==ARC_STYLE) {      if (*stylePtr==ARC_STYLE) {
2143          return "arc";          return "arc";
2144      } else if (*stylePtr==CHORD_STYLE) {      } else if (*stylePtr==CHORD_STYLE) {
2145          return "chord";          return "chord";
2146      } else {      } else {
2147          return "pieslice";          return "pieslice";
2148      }      }
2149  }  }
2150    
2151  /* End of tkcanvarc.c */  /* End of tkcanvarc.c */

Legend:
Removed from v.69  
changed lines
  Added in v.71

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25