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

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

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

revision 70 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   * tkCanvUtil.c --   * tkCanvUtil.c --
5   *   *
6   *      This procedure contains a collection of utility procedures   *      This procedure contains a collection of utility procedures
7   *      used by the implementations of various canvas item types.   *      used by the implementations of various canvas item types.
8   *   *
9   * Copyright (c) 1994 Sun Microsystems, Inc.   * Copyright (c) 1994 Sun Microsystems, Inc.
10   * Copyright (c) 1994 Sun Microsystems, Inc.   * Copyright (c) 1994 Sun Microsystems, Inc.
11   *   *
12   * See the file "license.terms" for information on usage and redistribution   * See the file "license.terms" for information on usage and redistribution
13   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.   * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14   *   *
15   * RCS: @(#) $Id: tkcanvutil.c,v 1.1.1.1 2001/06/13 04:57:52 dtashley Exp $   * RCS: @(#) $Id: tkcanvutil.c,v 1.1.1.1 2001/06/13 04:57:52 dtashley Exp $
16   */   */
17    
18  #include "tkInt.h"  #include "tkInt.h"
19  #include "tkCanvas.h"  #include "tkCanvas.h"
20  #include "tkPort.h"  #include "tkPort.h"
21    
22    
23  /*  /*
24   *----------------------------------------------------------------------   *----------------------------------------------------------------------
25   *   *
26   * Tk_CanvasTkwin --   * Tk_CanvasTkwin --
27   *   *
28   *      Given a token for a canvas, this procedure returns the   *      Given a token for a canvas, this procedure returns the
29   *      widget that represents the canvas.   *      widget that represents the canvas.
30   *   *
31   * Results:   * Results:
32   *      The return value is a handle for the widget.   *      The return value is a handle for the widget.
33   *   *
34   * Side effects:   * Side effects:
35   *      None.   *      None.
36   *   *
37   *----------------------------------------------------------------------   *----------------------------------------------------------------------
38   */   */
39    
40  Tk_Window  Tk_Window
41  Tk_CanvasTkwin(canvas)  Tk_CanvasTkwin(canvas)
42      Tk_Canvas canvas;                   /* Token for the canvas. */      Tk_Canvas canvas;                   /* Token for the canvas. */
43  {  {
44      TkCanvas *canvasPtr = (TkCanvas *) canvas;      TkCanvas *canvasPtr = (TkCanvas *) canvas;
45      return canvasPtr->tkwin;      return canvasPtr->tkwin;
46  }  }
47    
48  /*  /*
49   *----------------------------------------------------------------------   *----------------------------------------------------------------------
50   *   *
51   * Tk_CanvasDrawableCoords --   * Tk_CanvasDrawableCoords --
52   *   *
53   *      Given an (x,y) coordinate pair within a canvas, this procedure   *      Given an (x,y) coordinate pair within a canvas, this procedure
54   *      returns the corresponding coordinates at which the point should   *      returns the corresponding coordinates at which the point should
55   *      be drawn in the drawable used for display.   *      be drawn in the drawable used for display.
56   *   *
57   * Results:   * Results:
58   *      There is no return value.  The values at *drawableXPtr and   *      There is no return value.  The values at *drawableXPtr and
59   *      *drawableYPtr are filled in with the coordinates at which   *      *drawableYPtr are filled in with the coordinates at which
60   *      x and y should be drawn.  These coordinates are clipped   *      x and y should be drawn.  These coordinates are clipped
61   *      to fit within a "short", since this is what X uses in   *      to fit within a "short", since this is what X uses in
62   *      most cases for drawing.   *      most cases for drawing.
63   *   *
64   * Side effects:   * Side effects:
65   *      None.   *      None.
66   *   *
67   *----------------------------------------------------------------------   *----------------------------------------------------------------------
68   */   */
69    
70  void  void
71  Tk_CanvasDrawableCoords(canvas, x, y, drawableXPtr, drawableYPtr)  Tk_CanvasDrawableCoords(canvas, x, y, drawableXPtr, drawableYPtr)
72      Tk_Canvas canvas;                   /* Token for the canvas. */      Tk_Canvas canvas;                   /* Token for the canvas. */
73      double x, y;                        /* Coordinates in canvas space. */      double x, y;                        /* Coordinates in canvas space. */
74      short *drawableXPtr, *drawableYPtr; /* Screen coordinates are stored      short *drawableXPtr, *drawableYPtr; /* Screen coordinates are stored
75                                           * here. */                                           * here. */
76  {  {
77      TkCanvas *canvasPtr = (TkCanvas *) canvas;      TkCanvas *canvasPtr = (TkCanvas *) canvas;
78      double tmp;      double tmp;
79    
80      tmp = x - canvasPtr->drawableXOrigin;      tmp = x - canvasPtr->drawableXOrigin;
81      if (tmp > 0) {      if (tmp > 0) {
82          tmp += 0.5;          tmp += 0.5;
83      } else {      } else {
84          tmp -= 0.5;          tmp -= 0.5;
85      }      }
86      if (tmp > 32767) {      if (tmp > 32767) {
87          *drawableXPtr = 32767;          *drawableXPtr = 32767;
88      } else if (tmp < -32768) {      } else if (tmp < -32768) {
89          *drawableXPtr = -32768;          *drawableXPtr = -32768;
90      } else {      } else {
91          *drawableXPtr = (short) tmp;          *drawableXPtr = (short) tmp;
92      }      }
93    
94      tmp = y  - canvasPtr->drawableYOrigin;      tmp = y  - canvasPtr->drawableYOrigin;
95      if (tmp > 0) {      if (tmp > 0) {
96          tmp += 0.5;          tmp += 0.5;
97      } else {      } else {
98          tmp -= 0.5;          tmp -= 0.5;
99      }      }
100      if (tmp > 32767) {      if (tmp > 32767) {
101          *drawableYPtr = 32767;          *drawableYPtr = 32767;
102      } else if (tmp < -32768) {      } else if (tmp < -32768) {
103          *drawableYPtr = -32768;          *drawableYPtr = -32768;
104      } else {      } else {
105          *drawableYPtr = (short) tmp;          *drawableYPtr = (short) tmp;
106      }      }
107  }  }
108    
109  /*  /*
110   *----------------------------------------------------------------------   *----------------------------------------------------------------------
111   *   *
112   * Tk_CanvasWindowCoords --   * Tk_CanvasWindowCoords --
113   *   *
114   *      Given an (x,y) coordinate pair within a canvas, this procedure   *      Given an (x,y) coordinate pair within a canvas, this procedure
115   *      returns the corresponding coordinates in the canvas's window.   *      returns the corresponding coordinates in the canvas's window.
116   *   *
117   * Results:   * Results:
118   *      There is no return value.  The values at *screenXPtr and   *      There is no return value.  The values at *screenXPtr and
119   *      *screenYPtr are filled in with the coordinates at which   *      *screenYPtr are filled in with the coordinates at which
120   *      (x,y) appears in the canvas's window.  These coordinates   *      (x,y) appears in the canvas's window.  These coordinates
121   *      are clipped to fit within a "short", since this is what X   *      are clipped to fit within a "short", since this is what X
122   *      uses in most cases for drawing.   *      uses in most cases for drawing.
123   *   *
124   * Side effects:   * Side effects:
125   *      None.   *      None.
126   *   *
127   *----------------------------------------------------------------------   *----------------------------------------------------------------------
128   */   */
129    
130  void  void
131  Tk_CanvasWindowCoords(canvas, x, y, screenXPtr, screenYPtr)  Tk_CanvasWindowCoords(canvas, x, y, screenXPtr, screenYPtr)
132      Tk_Canvas canvas;                   /* Token for the canvas. */      Tk_Canvas canvas;                   /* Token for the canvas. */
133      double x, y;                        /* Coordinates in canvas space. */      double x, y;                        /* Coordinates in canvas space. */
134      short *screenXPtr, *screenYPtr;     /* Screen coordinates are stored      short *screenXPtr, *screenYPtr;     /* Screen coordinates are stored
135                                           * here. */                                           * here. */
136  {  {
137      TkCanvas *canvasPtr = (TkCanvas *) canvas;      TkCanvas *canvasPtr = (TkCanvas *) canvas;
138      double tmp;      double tmp;
139    
140      tmp = x - canvasPtr->xOrigin;      tmp = x - canvasPtr->xOrigin;
141      if (tmp > 0) {      if (tmp > 0) {
142          tmp += 0.5;          tmp += 0.5;
143      } else {      } else {
144          tmp -= 0.5;          tmp -= 0.5;
145      }      }
146      if (tmp > 32767) {      if (tmp > 32767) {
147          *screenXPtr = 32767;          *screenXPtr = 32767;
148      } else if (tmp < -32768) {      } else if (tmp < -32768) {
149          *screenXPtr = -32768;          *screenXPtr = -32768;
150      } else {      } else {
151          *screenXPtr = (short) tmp;          *screenXPtr = (short) tmp;
152      }      }
153    
154      tmp = y  - canvasPtr->yOrigin;      tmp = y  - canvasPtr->yOrigin;
155      if (tmp > 0) {      if (tmp > 0) {
156          tmp += 0.5;          tmp += 0.5;
157      } else {      } else {
158          tmp -= 0.5;          tmp -= 0.5;
159      }      }
160      if (tmp > 32767) {      if (tmp > 32767) {
161          *screenYPtr = 32767;          *screenYPtr = 32767;
162      } else if (tmp < -32768) {      } else if (tmp < -32768) {
163          *screenYPtr = -32768;          *screenYPtr = -32768;
164      } else {      } else {
165          *screenYPtr = (short) tmp;          *screenYPtr = (short) tmp;
166      }      }
167  }  }
168    
169  /*  /*
170   *--------------------------------------------------------------   *--------------------------------------------------------------
171   *   *
172   * Tk_CanvasGetCoord --   * Tk_CanvasGetCoord --
173   *   *
174   *      Given a string, returns a floating-point canvas coordinate   *      Given a string, returns a floating-point canvas coordinate
175   *      corresponding to that string.   *      corresponding to that string.
176   *   *
177   * Results:   * Results:
178   *      The return value is a standard Tcl return result.  If   *      The return value is a standard Tcl return result.  If
179   *      TCL_OK is returned, then everything went well and the   *      TCL_OK is returned, then everything went well and the
180   *      canvas coordinate is stored at *doublePtr;  otherwise   *      canvas coordinate is stored at *doublePtr;  otherwise
181   *      TCL_ERROR is returned and an error message is left in   *      TCL_ERROR is returned and an error message is left in
182   *      the interp's result.   *      the interp's result.
183   *   *
184   * Side effects:   * Side effects:
185   *      None.   *      None.
186   *   *
187   *--------------------------------------------------------------   *--------------------------------------------------------------
188   */   */
189    
190  int  int
191  Tk_CanvasGetCoord(interp, canvas, string, doublePtr)  Tk_CanvasGetCoord(interp, canvas, string, doublePtr)
192      Tcl_Interp *interp;         /* Interpreter for error reporting. */      Tcl_Interp *interp;         /* Interpreter for error reporting. */
193      Tk_Canvas canvas;           /* Canvas to which coordinate applies. */      Tk_Canvas canvas;           /* Canvas to which coordinate applies. */
194      char *string;               /* Describes coordinate (any screen      char *string;               /* Describes coordinate (any screen
195                                   * coordinate form may be used here). */                                   * coordinate form may be used here). */
196      double *doublePtr;          /* Place to store converted coordinate. */      double *doublePtr;          /* Place to store converted coordinate. */
197  {  {
198      TkCanvas *canvasPtr = (TkCanvas *) canvas;      TkCanvas *canvasPtr = (TkCanvas *) canvas;
199      if (Tk_GetScreenMM(canvasPtr->interp, canvasPtr->tkwin, string,      if (Tk_GetScreenMM(canvasPtr->interp, canvasPtr->tkwin, string,
200              doublePtr) != TCL_OK) {              doublePtr) != TCL_OK) {
201          return TCL_ERROR;          return TCL_ERROR;
202      }      }
203      *doublePtr *= canvasPtr->pixelsPerMM;      *doublePtr *= canvasPtr->pixelsPerMM;
204      return TCL_OK;      return TCL_OK;
205  }  }
206    
207  /*  /*
208   *--------------------------------------------------------------   *--------------------------------------------------------------
209   *   *
210   * Tk_CanvasGetCoordFromObj --   * Tk_CanvasGetCoordFromObj --
211   *   *
212   *      Given a string, returns a floating-point canvas coordinate   *      Given a string, returns a floating-point canvas coordinate
213   *      corresponding to that string.   *      corresponding to that string.
214   *   *
215   * Results:   * Results:
216   *      The return value is a standard Tcl return result.  If   *      The return value is a standard Tcl return result.  If
217   *      TCL_OK is returned, then everything went well and the   *      TCL_OK is returned, then everything went well and the
218   *      canvas coordinate is stored at *doublePtr;  otherwise   *      canvas coordinate is stored at *doublePtr;  otherwise
219   *      TCL_ERROR is returned and an error message is left in   *      TCL_ERROR is returned and an error message is left in
220   *      interp->result.   *      interp->result.
221   *   *
222   * Side effects:   * Side effects:
223   *      None.   *      None.
224   *   *
225   *--------------------------------------------------------------   *--------------------------------------------------------------
226   */   */
227    
228  int  int
229  Tk_CanvasGetCoordFromObj(interp, canvas, obj, doublePtr)  Tk_CanvasGetCoordFromObj(interp, canvas, obj, doublePtr)
230      Tcl_Interp *interp;         /* Interpreter for error reporting. */      Tcl_Interp *interp;         /* Interpreter for error reporting. */
231      Tk_Canvas canvas;           /* Canvas to which coordinate applies. */      Tk_Canvas canvas;           /* Canvas to which coordinate applies. */
232      Tcl_Obj *obj;               /* Describes coordinate (any screen      Tcl_Obj *obj;               /* Describes coordinate (any screen
233                                   * coordinate form may be used here). */                                   * coordinate form may be used here). */
234      double *doublePtr;          /* Place to store converted coordinate. */      double *doublePtr;          /* Place to store converted coordinate. */
235  {  {
236      TkCanvas *canvasPtr = (TkCanvas *) canvas;      TkCanvas *canvasPtr = (TkCanvas *) canvas;
237      if (Tk_GetMMFromObj(canvasPtr->interp, canvasPtr->tkwin, obj,      if (Tk_GetMMFromObj(canvasPtr->interp, canvasPtr->tkwin, obj,
238              doublePtr) != TCL_OK) {              doublePtr) != TCL_OK) {
239          return TCL_ERROR;          return TCL_ERROR;
240      }      }
241      *doublePtr *= canvasPtr->pixelsPerMM;      *doublePtr *= canvasPtr->pixelsPerMM;
242      return TCL_OK;      return TCL_OK;
243  }  }
244    
245  /*  /*
246   *----------------------------------------------------------------------   *----------------------------------------------------------------------
247   *   *
248   * Tk_CanvasSetStippleOrigin --   * Tk_CanvasSetStippleOrigin --
249   *   *
250   *      This procedure sets the stipple origin in a graphics context   *      This procedure sets the stipple origin in a graphics context
251   *      so that stipples drawn with the GC will line up with other   *      so that stipples drawn with the GC will line up with other
252   *      stipples previously drawn in the canvas.   *      stipples previously drawn in the canvas.
253   *   *
254   * Results:   * Results:
255   *      None.   *      None.
256   *   *
257   * Side effects:   * Side effects:
258   *      The graphics context is modified.   *      The graphics context is modified.
259   *   *
260   *----------------------------------------------------------------------   *----------------------------------------------------------------------
261   */   */
262    
263  void  void
264  Tk_CanvasSetStippleOrigin(canvas, gc)  Tk_CanvasSetStippleOrigin(canvas, gc)
265      Tk_Canvas canvas;           /* Token for a canvas. */      Tk_Canvas canvas;           /* Token for a canvas. */
266      GC gc;                      /* Graphics context that is about to be      GC gc;                      /* Graphics context that is about to be
267                                   * used to draw a stippled pattern as                                   * used to draw a stippled pattern as
268                                   * part of redisplaying the canvas. */                                   * part of redisplaying the canvas. */
269    
270  {  {
271      TkCanvas *canvasPtr = (TkCanvas *) canvas;      TkCanvas *canvasPtr = (TkCanvas *) canvas;
272    
273      XSetTSOrigin(canvasPtr->display, gc, -canvasPtr->drawableXOrigin,      XSetTSOrigin(canvasPtr->display, gc, -canvasPtr->drawableXOrigin,
274              -canvasPtr->drawableYOrigin);              -canvasPtr->drawableYOrigin);
275  }  }
276    
277  /*  /*
278   *----------------------------------------------------------------------   *----------------------------------------------------------------------
279   *   *
280   * Tk_CanvasSetOffset--   * Tk_CanvasSetOffset--
281   *   *
282   *      This procedure sets the stipple offset in a graphics   *      This procedure sets the stipple offset in a graphics
283   *      context so that stipples drawn with the GC will   *      context so that stipples drawn with the GC will
284   *      line up with other stipples with the same offset.   *      line up with other stipples with the same offset.
285   *   *
286   * Results:   * Results:
287   *      None.   *      None.
288   *   *
289   * Side effects:   * Side effects:
290   *      The graphics context is modified.   *      The graphics context is modified.
291   *   *
292   *----------------------------------------------------------------------   *----------------------------------------------------------------------
293   */   */
294    
295  void  void
296  Tk_CanvasSetOffset(canvas, gc, offset)  Tk_CanvasSetOffset(canvas, gc, offset)
297      Tk_Canvas canvas;           /* Token for a canvas. */      Tk_Canvas canvas;           /* Token for a canvas. */
298      GC gc;                      /* Graphics context that is about to be      GC gc;                      /* Graphics context that is about to be
299                                   * used to draw a stippled pattern as                                   * used to draw a stippled pattern as
300                                   * part of redisplaying the canvas. */                                   * part of redisplaying the canvas. */
301      Tk_TSOffset *offset;        /* offset (may be NULL pointer)*/      Tk_TSOffset *offset;        /* offset (may be NULL pointer)*/
302  {  {
303      TkCanvas *canvasPtr = (TkCanvas *) canvas;      TkCanvas *canvasPtr = (TkCanvas *) canvas;
304      int flags = 0;      int flags = 0;
305      int x = - canvasPtr->drawableXOrigin;      int x = - canvasPtr->drawableXOrigin;
306      int y = - canvasPtr->drawableYOrigin;      int y = - canvasPtr->drawableYOrigin;
307    
308      if (offset != NULL) {      if (offset != NULL) {
309          flags = offset->flags;          flags = offset->flags;
310          x += offset->xoffset;          x += offset->xoffset;
311          y += offset->yoffset;          y += offset->yoffset;
312      }      }
313      if ((flags & TK_OFFSET_RELATIVE) && !(flags & TK_OFFSET_INDEX)) {      if ((flags & TK_OFFSET_RELATIVE) && !(flags & TK_OFFSET_INDEX)) {
314          Tk_SetTSOrigin(canvasPtr->tkwin, gc, x - canvasPtr->xOrigin,          Tk_SetTSOrigin(canvasPtr->tkwin, gc, x - canvasPtr->xOrigin,
315                  y - canvasPtr->yOrigin);                  y - canvasPtr->yOrigin);
316      } else {      } else {
317          XSetTSOrigin(canvasPtr->display, gc, x, y);          XSetTSOrigin(canvasPtr->display, gc, x, y);
318      }      }
319  }  }
320    
321  /*  /*
322   *----------------------------------------------------------------------   *----------------------------------------------------------------------
323   *   *
324   * Tk_CanvasGetTextInfo --   * Tk_CanvasGetTextInfo --
325   *   *
326   *      This procedure returns a pointer to a structure containing   *      This procedure returns a pointer to a structure containing
327   *      information about the selection and insertion cursor for   *      information about the selection and insertion cursor for
328   *      a canvas widget.  Items such as text items save the pointer   *      a canvas widget.  Items such as text items save the pointer
329   *      and use it to share access to the information with the generic   *      and use it to share access to the information with the generic
330   *      canvas code.   *      canvas code.
331   *   *
332   * Results:   * Results:
333   *      The return value is a pointer to the structure holding text   *      The return value is a pointer to the structure holding text
334   *      information for the canvas.  Most of the fields should not   *      information for the canvas.  Most of the fields should not
335   *      be modified outside the generic canvas code;  see the user   *      be modified outside the generic canvas code;  see the user
336   *      documentation for details.   *      documentation for details.
337   *   *
338   * Side effects:   * Side effects:
339   *      None.   *      None.
340   *   *
341   *----------------------------------------------------------------------   *----------------------------------------------------------------------
342   */   */
343    
344  Tk_CanvasTextInfo *  Tk_CanvasTextInfo *
345  Tk_CanvasGetTextInfo(canvas)  Tk_CanvasGetTextInfo(canvas)
346      Tk_Canvas canvas;                   /* Token for the canvas widget. */      Tk_Canvas canvas;                   /* Token for the canvas widget. */
347  {  {
348      return &((TkCanvas *) canvas)->textInfo;      return &((TkCanvas *) canvas)->textInfo;
349  }  }
350    
351  /*  /*
352   *--------------------------------------------------------------   *--------------------------------------------------------------
353   *   *
354   * Tk_CanvasTagsParseProc --   * Tk_CanvasTagsParseProc --
355   *   *
356   *      This procedure is invoked during option processing to handle   *      This procedure is invoked during option processing to handle
357   *      "-tags" options for canvas items.   *      "-tags" options for canvas items.
358   *   *
359   * Results:   * Results:
360   *      A standard Tcl return value.   *      A standard Tcl return value.
361   *   *
362   * Side effects:   * Side effects:
363   *      The tags for a given item get replaced by those indicated   *      The tags for a given item get replaced by those indicated
364   *      in the value argument.   *      in the value argument.
365   *   *
366   *--------------------------------------------------------------   *--------------------------------------------------------------
367   */   */
368    
369  int  int
370  Tk_CanvasTagsParseProc(clientData, interp, tkwin, value, widgRec, offset)  Tk_CanvasTagsParseProc(clientData, interp, tkwin, value, widgRec, offset)
371      ClientData clientData;              /* Not used.*/      ClientData clientData;              /* Not used.*/
372      Tcl_Interp *interp;                 /* Used for reporting errors. */      Tcl_Interp *interp;                 /* Used for reporting errors. */
373      Tk_Window tkwin;                    /* Window containing canvas widget. */      Tk_Window tkwin;                    /* Window containing canvas widget. */
374      char *value;                        /* Value of option (list of tag      char *value;                        /* Value of option (list of tag
375                                           * names). */                                           * names). */
376      char *widgRec;                      /* Pointer to record for item. */      char *widgRec;                      /* Pointer to record for item. */
377      int offset;                         /* Offset into item (ignored). */      int offset;                         /* Offset into item (ignored). */
378  {  {
379      register Tk_Item *itemPtr = (Tk_Item *) widgRec;      register Tk_Item *itemPtr = (Tk_Item *) widgRec;
380      int argc, i;      int argc, i;
381      char **argv;      char **argv;
382      Tk_Uid *newPtr;      Tk_Uid *newPtr;
383    
384      /*      /*
385       * Break the value up into the individual tag names.       * Break the value up into the individual tag names.
386       */       */
387    
388      if (Tcl_SplitList(interp, value, &argc, &argv) != TCL_OK) {      if (Tcl_SplitList(interp, value, &argc, &argv) != TCL_OK) {
389          return TCL_ERROR;          return TCL_ERROR;
390      }      }
391    
392      /*      /*
393       * Make sure that there's enough space in the item to hold the       * Make sure that there's enough space in the item to hold the
394       * tag names.       * tag names.
395       */       */
396    
397      if (itemPtr->tagSpace < argc) {      if (itemPtr->tagSpace < argc) {
398          newPtr = (Tk_Uid *) ckalloc((unsigned) (argc * sizeof(Tk_Uid)));          newPtr = (Tk_Uid *) ckalloc((unsigned) (argc * sizeof(Tk_Uid)));
399          for (i = itemPtr->numTags-1; i >= 0; i--) {          for (i = itemPtr->numTags-1; i >= 0; i--) {
400              newPtr[i] = itemPtr->tagPtr[i];              newPtr[i] = itemPtr->tagPtr[i];
401          }          }
402          if (itemPtr->tagPtr != itemPtr->staticTagSpace) {          if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
403              ckfree((char *) itemPtr->tagPtr);              ckfree((char *) itemPtr->tagPtr);
404          }          }
405          itemPtr->tagPtr = newPtr;          itemPtr->tagPtr = newPtr;
406          itemPtr->tagSpace = argc;          itemPtr->tagSpace = argc;
407      }      }
408      itemPtr->numTags = argc;      itemPtr->numTags = argc;
409      for (i = 0; i < argc; i++) {      for (i = 0; i < argc; i++) {
410          itemPtr->tagPtr[i] = Tk_GetUid(argv[i]);          itemPtr->tagPtr[i] = Tk_GetUid(argv[i]);
411      }      }
412      ckfree((char *) argv);      ckfree((char *) argv);
413      return TCL_OK;      return TCL_OK;
414  }  }
415    
416  /*  /*
417   *--------------------------------------------------------------   *--------------------------------------------------------------
418   *   *
419   * Tk_CanvasTagsPrintProc --   * Tk_CanvasTagsPrintProc --
420   *   *
421   *      This procedure is invoked by the Tk configuration code   *      This procedure is invoked by the Tk configuration code
422   *      to produce a printable string for the "-tags" configuration   *      to produce a printable string for the "-tags" configuration
423   *      option for canvas items.   *      option for canvas items.
424   *   *
425   * Results:   * Results:
426   *      The return value is a string describing all the tags for   *      The return value is a string describing all the tags for
427   *      the item referred to by "widgRec".  In addition, *freeProcPtr   *      the item referred to by "widgRec".  In addition, *freeProcPtr
428   *      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
429   *      the result string when it's no longer needed (or NULL to   *      the result string when it's no longer needed (or NULL to
430   *      indicate that the string doesn't need to be freed).   *      indicate that the string doesn't need to be freed).
431   *   *
432   * Side effects:   * Side effects:
433   *      None.   *      None.
434   *   *
435   *--------------------------------------------------------------   *--------------------------------------------------------------
436   */   */
437    
438  char *  char *
439  Tk_CanvasTagsPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)  Tk_CanvasTagsPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
440      ClientData clientData;              /* Ignored. */      ClientData clientData;              /* Ignored. */
441      Tk_Window tkwin;                    /* Window containing canvas widget. */      Tk_Window tkwin;                    /* Window containing canvas widget. */
442      char *widgRec;                      /* Pointer to record for item. */      char *widgRec;                      /* Pointer to record for item. */
443      int offset;                         /* Ignored. */      int offset;                         /* Ignored. */
444      Tcl_FreeProc **freeProcPtr;         /* Pointer to variable to fill in with      Tcl_FreeProc **freeProcPtr;         /* Pointer to variable to fill in with
445                                           * information about how to reclaim                                           * information about how to reclaim
446                                           * storage for return string. */                                           * storage for return string. */
447  {  {
448      register Tk_Item *itemPtr = (Tk_Item *) widgRec;      register Tk_Item *itemPtr = (Tk_Item *) widgRec;
449    
450      if (itemPtr->numTags == 0) {      if (itemPtr->numTags == 0) {
451          *freeProcPtr = (Tcl_FreeProc *) NULL;          *freeProcPtr = (Tcl_FreeProc *) NULL;
452          return "";          return "";
453      }      }
454      if (itemPtr->numTags == 1) {      if (itemPtr->numTags == 1) {
455          *freeProcPtr = (Tcl_FreeProc *) NULL;          *freeProcPtr = (Tcl_FreeProc *) NULL;
456          return (char *) itemPtr->tagPtr[0];          return (char *) itemPtr->tagPtr[0];
457      }      }
458      *freeProcPtr = TCL_DYNAMIC;      *freeProcPtr = TCL_DYNAMIC;
459      return Tcl_Merge(itemPtr->numTags, (char **) itemPtr->tagPtr);      return Tcl_Merge(itemPtr->numTags, (char **) itemPtr->tagPtr);
460  }  }
461    
462    
463  static int      DashConvert _ANSI_ARGS_((char *l, CONST char *p,  static int      DashConvert _ANSI_ARGS_((char *l, CONST char *p,
464                          int n, double width));                          int n, double width));
465  #define ABS(a) ((a>=0)?(a):(-(a)))  #define ABS(a) ((a>=0)?(a):(-(a)))
466    
467  /*  /*
468   *--------------------------------------------------------------   *--------------------------------------------------------------
469   *   *
470   * TkCanvasDashParseProc --   * TkCanvasDashParseProc --
471   *   *
472   *      This procedure is invoked during option processing to handle   *      This procedure is invoked during option processing to handle
473   *      "-dash", "-activedash" and "-disableddash" options for canvas   *      "-dash", "-activedash" and "-disableddash" options for canvas
474   *      objects.   *      objects.
475   *   *
476   * Results:   * Results:
477   *      A standard Tcl return value.   *      A standard Tcl return value.
478   *   *
479   * Side effects:   * Side effects:
480   *      The dash list for a given canvas object gets replaced by   *      The dash list for a given canvas object gets replaced by
481   *      those indicated in the value argument.   *      those indicated in the value argument.
482   *   *
483   *--------------------------------------------------------------   *--------------------------------------------------------------
484   */   */
485    
486  int  int
487  TkCanvasDashParseProc(clientData, interp, tkwin, value, widgRec, offset)  TkCanvasDashParseProc(clientData, interp, tkwin, value, widgRec, offset)
488      ClientData clientData;              /* Not used.*/      ClientData clientData;              /* Not used.*/
489      Tcl_Interp *interp;                 /* Used for reporting errors. */      Tcl_Interp *interp;                 /* Used for reporting errors. */
490      Tk_Window tkwin;                    /* Window containing canvas widget. */      Tk_Window tkwin;                    /* Window containing canvas widget. */
491      CONST char *value;                  /* Value of option. */      CONST char *value;                  /* Value of option. */
492      char *widgRec;                      /* Pointer to record for item. */      char *widgRec;                      /* Pointer to record for item. */
493      int offset;                         /* Offset into item. */      int offset;                         /* Offset into item. */
494  {  {
495      return Tk_GetDash(interp, value, (Tk_Dash *)(widgRec+offset));      return Tk_GetDash(interp, value, (Tk_Dash *)(widgRec+offset));
496  }  }
497    
498  /*  /*
499   *--------------------------------------------------------------   *--------------------------------------------------------------
500   *   *
501   * TkCanvasDashPrintProc --   * TkCanvasDashPrintProc --
502   *   *
503   *      This procedure is invoked by the Tk configuration code   *      This procedure is invoked by the Tk configuration code
504   *      to produce a printable string for the "-dash", "-activedash"   *      to produce a printable string for the "-dash", "-activedash"
505   *      and "-disableddash" configuration options for canvas items.   *      and "-disableddash" configuration options for canvas items.
506   *   *
507   * Results:   * Results:
508   *      The return value is a string describing all the dash list for   *      The return value is a string describing all the dash list for
509   *      the item referred to by "widgRec"and "offset".  In addition,   *      the item referred to by "widgRec"and "offset".  In addition,
510   *      *freeProcPtr is filled in with the address of a procedure to   *      *freeProcPtr is filled in with the address of a procedure to
511   *      call to free the result string when it's no longer needed (or   *      call to free the result string when it's no longer needed (or
512   *      NULL to indicate that the string doesn't need to be freed).   *      NULL to indicate that the string doesn't need to be freed).
513   *   *
514   * Side effects:   * Side effects:
515   *      None.   *      None.
516   *   *
517   *--------------------------------------------------------------   *--------------------------------------------------------------
518   */   */
519    
520  char *  char *
521  TkCanvasDashPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)  TkCanvasDashPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
522      ClientData clientData;              /* Ignored. */      ClientData clientData;              /* Ignored. */
523      Tk_Window tkwin;                    /* Window containing canvas widget. */      Tk_Window tkwin;                    /* Window containing canvas widget. */
524      char *widgRec;                      /* Pointer to record for item. */      char *widgRec;                      /* Pointer to record for item. */
525      int offset;                         /* Offset in record for item. */      int offset;                         /* Offset in record for item. */
526      Tcl_FreeProc **freeProcPtr;         /* Pointer to variable to fill in with      Tcl_FreeProc **freeProcPtr;         /* Pointer to variable to fill in with
527                                           * information about how to reclaim                                           * information about how to reclaim
528                                           * storage for return string. */                                           * storage for return string. */
529  {  {
530      Tk_Dash *dash = (Tk_Dash *) (widgRec+offset);      Tk_Dash *dash = (Tk_Dash *) (widgRec+offset);
531      char *buffer;      char *buffer;
532      char *p;      char *p;
533      int i = dash->number;      int i = dash->number;
534    
535      if (i < 0) {      if (i < 0) {
536          i = -i;          i = -i;
537          *freeProcPtr = TCL_DYNAMIC;          *freeProcPtr = TCL_DYNAMIC;
538          buffer = (char *) ckalloc((unsigned int) (i+1));          buffer = (char *) ckalloc((unsigned int) (i+1));
539          p = (i > sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;          p = (i > sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
540          memcpy(buffer, p, (unsigned int) i);          memcpy(buffer, p, (unsigned int) i);
541          buffer[i] = 0;          buffer[i] = 0;
542          return buffer;          return buffer;
543      } else if (!i) {      } else if (!i) {
544          *freeProcPtr = (Tcl_FreeProc *) NULL;          *freeProcPtr = (Tcl_FreeProc *) NULL;
545          return "";          return "";
546      }      }
547      buffer = (char *)ckalloc((unsigned int) (4*i));      buffer = (char *)ckalloc((unsigned int) (4*i));
548      *freeProcPtr = TCL_DYNAMIC;      *freeProcPtr = TCL_DYNAMIC;
549    
550      p = (i > sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;      p = (i > sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
551      sprintf(buffer, "%d", *p++ & 0xff);      sprintf(buffer, "%d", *p++ & 0xff);
552      while(--i) {      while(--i) {
553          sprintf(buffer+strlen(buffer), " %d", *p++ & 0xff);          sprintf(buffer+strlen(buffer), " %d", *p++ & 0xff);
554      }      }
555      return buffer;      return buffer;
556  }  }
557    
558  /*  /*
559   *--------------------------------------------------------------   *--------------------------------------------------------------
560   *   *
561   * Tk_CreateSmoothMethod --   * Tk_CreateSmoothMethod --
562   *   *
563   *      This procedure is invoked to add additional values   *      This procedure is invoked to add additional values
564   *      for the "-smooth" option to the list.   *      for the "-smooth" option to the list.
565   *   *
566   * Results:   * Results:
567   *      A standard Tcl return value.   *      A standard Tcl return value.
568   *   *
569   * Side effects:   * Side effects:
570   *      In the future "-smooth <name>" will be accepted as   *      In the future "-smooth <name>" will be accepted as
571   *      smooth method for the line and polygon.   *      smooth method for the line and polygon.
572   *   *
573   *--------------------------------------------------------------   *--------------------------------------------------------------
574   */   */
575    
576  Tk_SmoothMethod tkBezierSmoothMethod = {  Tk_SmoothMethod tkBezierSmoothMethod = {
577      "bezier",      "bezier",
578      TkMakeBezierCurve,      TkMakeBezierCurve,
579      (void (*) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas,      (void (*) _ANSI_ARGS_((Tcl_Interp *interp, Tk_Canvas canvas,
580              double *coordPtr, int numPoints, int numSteps)))              double *coordPtr, int numPoints, int numSteps)))
581                  TkMakeBezierPostscript,                  TkMakeBezierPostscript,
582  };  };
583    
584  static void SmoothMethodCleanupProc _ANSI_ARGS_((ClientData clientData,  static void SmoothMethodCleanupProc _ANSI_ARGS_((ClientData clientData,
585                  Tcl_Interp *interp));                  Tcl_Interp *interp));
586    
587  typedef struct SmoothAssocData {  typedef struct SmoothAssocData {
588      struct SmoothAssocData *nextPtr;    /* pointer to next SmoothAssocData */      struct SmoothAssocData *nextPtr;    /* pointer to next SmoothAssocData */
589      Tk_SmoothMethod smooth;             /* name and functions associated with this      Tk_SmoothMethod smooth;             /* name and functions associated with this
590                                           * option */                                           * option */
591  } SmoothAssocData;  } SmoothAssocData;
592    
593  void  void
594  Tk_CreateSmoothMethod(interp, smooth)  Tk_CreateSmoothMethod(interp, smooth)
595      Tcl_Interp *interp;      Tcl_Interp *interp;
596      Tk_SmoothMethod *smooth;      Tk_SmoothMethod *smooth;
597  {  {
598      SmoothAssocData *methods, *typePtr2, *prevPtr, *ptr;      SmoothAssocData *methods, *typePtr2, *prevPtr, *ptr;
599      methods = (SmoothAssocData *) Tcl_GetAssocData(interp, "smoothMethod",      methods = (SmoothAssocData *) Tcl_GetAssocData(interp, "smoothMethod",
600              (Tcl_InterpDeleteProc **) NULL);              (Tcl_InterpDeleteProc **) NULL);
601    
602      /*      /*
603       * If there's already a smooth method with the given name, remove it.       * If there's already a smooth method with the given name, remove it.
604       */       */
605    
606      for (typePtr2 = methods, prevPtr = NULL; typePtr2 != NULL;      for (typePtr2 = methods, prevPtr = NULL; typePtr2 != NULL;
607              prevPtr = typePtr2, typePtr2 = typePtr2->nextPtr) {              prevPtr = typePtr2, typePtr2 = typePtr2->nextPtr) {
608          if (!strcmp(typePtr2->smooth.name, smooth->name)) {          if (!strcmp(typePtr2->smooth.name, smooth->name)) {
609              if (prevPtr == NULL) {              if (prevPtr == NULL) {
610                  methods = typePtr2->nextPtr;                  methods = typePtr2->nextPtr;
611              } else {              } else {
612                  prevPtr->nextPtr = typePtr2->nextPtr;                  prevPtr->nextPtr = typePtr2->nextPtr;
613              }              }
614              ckfree((char *) typePtr2);              ckfree((char *) typePtr2);
615              break;              break;
616          }          }
617      }      }
618      ptr = (SmoothAssocData *) ckalloc(sizeof(SmoothAssocData));      ptr = (SmoothAssocData *) ckalloc(sizeof(SmoothAssocData));
619      ptr->smooth.name = smooth->name;      ptr->smooth.name = smooth->name;
620      ptr->smooth.coordProc = smooth->coordProc;      ptr->smooth.coordProc = smooth->coordProc;
621      ptr->smooth.postscriptProc = smooth->postscriptProc;      ptr->smooth.postscriptProc = smooth->postscriptProc;
622      ptr->nextPtr = methods;      ptr->nextPtr = methods;
623      Tcl_SetAssocData(interp, "smoothMethod", SmoothMethodCleanupProc,      Tcl_SetAssocData(interp, "smoothMethod", SmoothMethodCleanupProc,
624                  (ClientData) ptr);                  (ClientData) ptr);
625  }  }
626  /*  /*
627   *----------------------------------------------------------------------   *----------------------------------------------------------------------
628   *   *
629   * SmoothMethodCleanupProc --   * SmoothMethodCleanupProc --
630   *   *
631   *      This procedure is invoked whenever an interpreter is deleted   *      This procedure is invoked whenever an interpreter is deleted
632   *      to cleanup the smooth methods.   *      to cleanup the smooth methods.
633   *   *
634   * Results:   * Results:
635   *      None.   *      None.
636   *   *
637   * Side effects:   * Side effects:
638   *      Smooth methods are removed.   *      Smooth methods are removed.
639   *   *
640   *----------------------------------------------------------------------   *----------------------------------------------------------------------
641   */   */
642    
643  static void  static void
644  SmoothMethodCleanupProc(clientData, interp)  SmoothMethodCleanupProc(clientData, interp)
645      ClientData clientData;      /* Points to "smoothMethod" AssocData      ClientData clientData;      /* Points to "smoothMethod" AssocData
646                                   * for the interpreter. */                                   * for the interpreter. */
647      Tcl_Interp *interp;         /* Interpreter that is being deleted. */      Tcl_Interp *interp;         /* Interpreter that is being deleted. */
648  {  {
649      SmoothAssocData *ptr, *methods = (SmoothAssocData *) clientData;      SmoothAssocData *ptr, *methods = (SmoothAssocData *) clientData;
650    
651      while (methods != NULL) {      while (methods != NULL) {
652          methods = (ptr = methods)->nextPtr;          methods = (ptr = methods)->nextPtr;
653          ckfree((char *) ptr);          ckfree((char *) ptr);
654      }      }
655  }  }
656  /*  /*
657   *--------------------------------------------------------------   *--------------------------------------------------------------
658   *   *
659   * TkSmoothParseProc --   * TkSmoothParseProc --
660   *   *
661   *      This procedure is invoked during option processing to handle   *      This procedure is invoked during option processing to handle
662   *      the "-smooth" option.   *      the "-smooth" option.
663   *   *
664   * Results:   * Results:
665   *      A standard Tcl return value.   *      A standard Tcl return value.
666   *   *
667   * Side effects:   * Side effects:
668   *      The smooth option for a given item gets replaced by the value   *      The smooth option for a given item gets replaced by the value
669   *      indicated in the value argument.   *      indicated in the value argument.
670   *   *
671   *--------------------------------------------------------------   *--------------------------------------------------------------
672   */   */
673    
674  int  int
675  TkSmoothParseProc(clientData, interp, tkwin, value, widgRec, offset)  TkSmoothParseProc(clientData, interp, tkwin, value, widgRec, offset)
676      ClientData clientData;              /* some flags.*/      ClientData clientData;              /* some flags.*/
677      Tcl_Interp *interp;                 /* Used for reporting errors. */      Tcl_Interp *interp;                 /* Used for reporting errors. */
678      Tk_Window tkwin;                    /* Window containing canvas widget. */      Tk_Window tkwin;                    /* Window containing canvas widget. */
679      CONST char *value;                  /* Value of option. */      CONST char *value;                  /* Value of option. */
680      char *widgRec;                      /* Pointer to record for item. */      char *widgRec;                      /* Pointer to record for item. */
681      int offset;                         /* Offset into item. */      int offset;                         /* Offset into item. */
682  {  {
683      register Tk_SmoothMethod **smoothPtr =      register Tk_SmoothMethod **smoothPtr =
684          (Tk_SmoothMethod **) (widgRec + offset);          (Tk_SmoothMethod **) (widgRec + offset);
685      Tk_SmoothMethod *smooth = NULL;      Tk_SmoothMethod *smooth = NULL;
686      int b;      int b;
687      size_t length;      size_t length;
688      SmoothAssocData *methods;      SmoothAssocData *methods;
689    
690      if (value == NULL || *value == 0) {      if (value == NULL || *value == 0) {
691          *smoothPtr = (Tk_SmoothMethod *) NULL;          *smoothPtr = (Tk_SmoothMethod *) NULL;
692          return TCL_OK;          return TCL_OK;
693      }      }
694      length = strlen(value);      length = strlen(value);
695      methods = (SmoothAssocData *) Tcl_GetAssocData(interp, "smoothMethod",      methods = (SmoothAssocData *) Tcl_GetAssocData(interp, "smoothMethod",
696              (Tcl_InterpDeleteProc **) NULL);              (Tcl_InterpDeleteProc **) NULL);
697      while (methods != (SmoothAssocData *) NULL) {      while (methods != (SmoothAssocData *) NULL) {
698          if (strncmp(value, methods->smooth.name, length) == 0) {          if (strncmp(value, methods->smooth.name, length) == 0) {
699              if (smooth != (Tk_SmoothMethod *) NULL) {              if (smooth != (Tk_SmoothMethod *) NULL) {
700                  Tcl_AppendResult(interp, "ambigeous smooth method \"", value,                  Tcl_AppendResult(interp, "ambigeous smooth method \"", value,
701                          "\"", (char *) NULL);                          "\"", (char *) NULL);
702                  return TCL_ERROR;                  return TCL_ERROR;
703              }              }
704              smooth = &methods->smooth;              smooth = &methods->smooth;
705          }          }
706          methods = methods->nextPtr;          methods = methods->nextPtr;
707      }      }
708      if (smooth) {      if (smooth) {
709          *smoothPtr = smooth;          *smoothPtr = smooth;
710          return TCL_OK;          return TCL_OK;
711      }      }
712    
713      if (Tcl_GetBoolean(interp, (char *) value, &b) != TCL_OK) {      if (Tcl_GetBoolean(interp, (char *) value, &b) != TCL_OK) {
714          return TCL_ERROR;          return TCL_ERROR;
715      }      }
716      *smoothPtr = b ? &tkBezierSmoothMethod : (Tk_SmoothMethod*) NULL;      *smoothPtr = b ? &tkBezierSmoothMethod : (Tk_SmoothMethod*) NULL;
717      return TCL_OK;      return TCL_OK;
718  }  }
719  /*  /*
720   *--------------------------------------------------------------   *--------------------------------------------------------------
721   *   *
722   * TkSmoothPrintProc --   * TkSmoothPrintProc --
723   *   *
724   *      This procedure is invoked by the Tk configuration code   *      This procedure is invoked by the Tk configuration code
725   *      to produce a printable string for the "-smooth"   *      to produce a printable string for the "-smooth"
726   *      configuration option.   *      configuration option.
727   *   *
728   * Results:   * Results:
729   *      The return value is a string describing the smooth option for   *      The return value is a string describing the smooth option for
730   *      the item referred to by "widgRec".  In addition, *freeProcPtr   *      the item referred to by "widgRec".  In addition, *freeProcPtr
731   *      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
732   *      the result string when it's no longer needed (or NULL to   *      the result string when it's no longer needed (or NULL to
733   *      indicate that the string doesn't need to be freed).   *      indicate that the string doesn't need to be freed).
734   *   *
735   * Side effects:   * Side effects:
736   *      None.   *      None.
737   *   *
738   *--------------------------------------------------------------   *--------------------------------------------------------------
739   */   */
740    
741  char *  char *
742  TkSmoothPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)  TkSmoothPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr)
743      ClientData clientData;              /* Ignored. */      ClientData clientData;              /* Ignored. */
744      Tk_Window tkwin;                    /* Window containing canvas widget. */      Tk_Window tkwin;                    /* Window containing canvas widget. */
745      char *widgRec;                      /* Pointer to record for item. */      char *widgRec;                      /* Pointer to record for item. */
746      int offset;                         /* Offset into item. */      int offset;                         /* Offset into item. */
747      Tcl_FreeProc **freeProcPtr;         /* Pointer to variable to fill in with      Tcl_FreeProc **freeProcPtr;         /* Pointer to variable to fill in with
748                                           * information about how to reclaim                                           * information about how to reclaim
749                                           * storage for return string. */                                           * storage for return string. */
750  {  {
751      register Tk_SmoothMethod **smoothPtr = (Tk_SmoothMethod **) (widgRec + offset);      register Tk_SmoothMethod **smoothPtr = (Tk_SmoothMethod **) (widgRec + offset);
752    
753      return (*smoothPtr) ? (*smoothPtr)->name : "0";      return (*smoothPtr) ? (*smoothPtr)->name : "0";
754  }  }
755  /*  /*
756   *--------------------------------------------------------------   *--------------------------------------------------------------
757   *   *
758   * Tk_GetDash   * Tk_GetDash
759   *   *
760   *      This procedure is used to parse a string, assuming   *      This procedure is used to parse a string, assuming
761   *      it is dash information.   *      it is dash information.
762   *   *
763   * Results:   * Results:
764   *      The return value is a standard Tcl result:  TCL_OK means   *      The return value is a standard Tcl result:  TCL_OK means
765   *      that the dash information was parsed ok, and   *      that the dash information was parsed ok, and
766   *      TCL_ERROR means it couldn't be parsed.   *      TCL_ERROR means it couldn't be parsed.
767   *   *
768   * Side effects:   * Side effects:
769   *      Dash information in the dash structure is updated.   *      Dash information in the dash structure is updated.
770   *   *
771   *--------------------------------------------------------------   *--------------------------------------------------------------
772   */   */
773    
774  int  int
775  Tk_GetDash(interp, value, dash)  Tk_GetDash(interp, value, dash)
776      Tcl_Interp *interp;         /* Used for error reporting. */      Tcl_Interp *interp;         /* Used for error reporting. */
777      CONST char *value;          /* Textual specification of dash list. */      CONST char *value;          /* Textual specification of dash list. */
778      Tk_Dash *dash;              /* Pointer to record in which to      Tk_Dash *dash;              /* Pointer to record in which to
779                                   * store dash information. */                                   * store dash information. */
780  {  {
781      int argc, i;      int argc, i;
782      char **largv, **argv = NULL;      char **largv, **argv = NULL;
783      char *pt;      char *pt;
784    
785      if ((value==(char *) NULL) || (*value==0) ) {      if ((value==(char *) NULL) || (*value==0) ) {
786          dash->number = 0;          dash->number = 0;
787          return TCL_OK;          return TCL_OK;
788      }      }
789      if ((*value == '.') || (*value == ',') ||      if ((*value == '.') || (*value == ',') ||
790              (*value == '-') || (*value == '_')) {              (*value == '-') || (*value == '_')) {
791          i = DashConvert((char *) NULL, value, -1, 0.0);          i = DashConvert((char *) NULL, value, -1, 0.0);
792          if (i>0) {          if (i>0) {
793              i = strlen(value);              i = strlen(value);
794          } else {          } else {
795              goto badDashList;              goto badDashList;
796          }          }
797          if (i > sizeof(char *)) {          if (i > sizeof(char *)) {
798              dash->pattern.pt = pt = (char *) ckalloc(strlen(value));              dash->pattern.pt = pt = (char *) ckalloc(strlen(value));
799          } else {          } else {
800              pt = dash->pattern.array;              pt = dash->pattern.array;
801          }          }
802          memcpy(pt,value, (unsigned int) i);          memcpy(pt,value, (unsigned int) i);
803          dash->number = -i;          dash->number = -i;
804          return TCL_OK;          return TCL_OK;
805      }      }
806      if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) {      if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) {
807          Tcl_ResetResult(interp);          Tcl_ResetResult(interp);
808      badDashList:      badDashList:
809          Tcl_AppendResult(interp, "bad dash list \"", value,          Tcl_AppendResult(interp, "bad dash list \"", value,
810                  "\": must be a list of integers or a format like \"-..\"",                  "\": must be a list of integers or a format like \"-..\"",
811                  (char *) NULL);                  (char *) NULL);
812      syntaxError:      syntaxError:
813          if (argv != NULL) {          if (argv != NULL) {
814              ckfree((char *) argv);              ckfree((char *) argv);
815          }          }
816          if (ABS(dash->number) > sizeof(char *))          if (ABS(dash->number) > sizeof(char *))
817              ckfree((char *) dash->pattern.pt);              ckfree((char *) dash->pattern.pt);
818          dash->number = 0;          dash->number = 0;
819          return TCL_ERROR;          return TCL_ERROR;
820      }      }
821    
822      if (ABS(dash->number) > sizeof(char *)) {      if (ABS(dash->number) > sizeof(char *)) {
823          ckfree((char *) dash->pattern.pt);          ckfree((char *) dash->pattern.pt);
824      }      }
825      if (argc > sizeof(char *)) {      if (argc > sizeof(char *)) {
826          dash->pattern.pt = pt = (char *) ckalloc((unsigned int) argc);          dash->pattern.pt = pt = (char *) ckalloc((unsigned int) argc);
827      } else {      } else {
828          pt = dash->pattern.array;          pt = dash->pattern.array;
829      }      }
830      dash->number = argc;      dash->number = argc;
831    
832      largv = argv;      largv = argv;
833      while(argc>0) {      while(argc>0) {
834          if (Tcl_GetInt(interp, *largv, &i) != TCL_OK ||          if (Tcl_GetInt(interp, *largv, &i) != TCL_OK ||
835              i < 1 || i>255) {              i < 1 || i>255) {
836              Tcl_ResetResult(interp);              Tcl_ResetResult(interp);
837              Tcl_AppendResult(interp, "expected integer in the range 1..255 but got \"",              Tcl_AppendResult(interp, "expected integer in the range 1..255 but got \"",
838                           *largv, "\"", (char *) NULL);                           *largv, "\"", (char *) NULL);
839              goto syntaxError;              goto syntaxError;
840          }          }
841          *pt++ = i;          *pt++ = i;
842          argc--; largv++;          argc--; largv++;
843      }      }
844        
845      if (argv != NULL) {      if (argv != NULL) {
846          ckfree((char *) argv);          ckfree((char *) argv);
847      }      }
848    
849      return TCL_OK;      return TCL_OK;
850  }  }
851    
852  /*  /*
853   *--------------------------------------------------------------   *--------------------------------------------------------------
854   *   *
855   * Tk_CreateOutline   * Tk_CreateOutline
856   *   *
857   *      This procedure initializes the Tk_Outline structure   *      This procedure initializes the Tk_Outline structure
858   *      with default values.   *      with default values.
859   *   *
860   * Results:   * Results:
861   *      None   *      None
862   *   *
863   * Side effects:   * Side effects:
864   *      None   *      None
865   *   *
866   *--------------------------------------------------------------   *--------------------------------------------------------------
867   */   */
868    
869  void Tk_CreateOutline(outline)  void Tk_CreateOutline(outline)
870      Tk_Outline *outline;      Tk_Outline *outline;
871  {  {
872      outline->gc = None;      outline->gc = None;
873      outline->width = 1.0;      outline->width = 1.0;
874      outline->activeWidth = 0.0;      outline->activeWidth = 0.0;
875      outline->disabledWidth = 0.0;      outline->disabledWidth = 0.0;
876      outline->offset = 0;      outline->offset = 0;
877      outline->dash.number = 0;      outline->dash.number = 0;
878      outline->activeDash.number = 0;      outline->activeDash.number = 0;
879      outline->disabledDash.number = 0;      outline->disabledDash.number = 0;
880      outline->tsoffset.flags = 0;      outline->tsoffset.flags = 0;
881      outline->tsoffset.xoffset = 0;      outline->tsoffset.xoffset = 0;
882      outline->tsoffset.yoffset = 0;      outline->tsoffset.yoffset = 0;
883      outline->color = NULL;      outline->color = NULL;
884      outline->activeColor = NULL;      outline->activeColor = NULL;
885      outline->disabledColor = NULL;      outline->disabledColor = NULL;
886      outline->stipple = None;      outline->stipple = None;
887      outline->activeStipple = None;      outline->activeStipple = None;
888      outline->disabledStipple = None;      outline->disabledStipple = None;
889  }  }
890    
891  /*  /*
892   *--------------------------------------------------------------   *--------------------------------------------------------------
893   *   *
894   * Tk_DeleteOutline   * Tk_DeleteOutline
895   *   *
896   *      This procedure frees all memory that might be   *      This procedure frees all memory that might be
897   *      allocated and referenced in the Tk_Outline structure.   *      allocated and referenced in the Tk_Outline structure.
898   *   *
899   * Results:   * Results:
900   *      None   *      None
901   *   *
902   * Side effects:   * Side effects:
903   *      None   *      None
904   *   *
905   *--------------------------------------------------------------   *--------------------------------------------------------------
906   */   */
907    
908  void Tk_DeleteOutline(display, outline)  void Tk_DeleteOutline(display, outline)
909      Display *display;                   /* Display containing window */      Display *display;                   /* Display containing window */
910      Tk_Outline *outline;      Tk_Outline *outline;
911  {  {
912      if (outline->gc != None) {      if (outline->gc != None) {
913          Tk_FreeGC(display, outline->gc);          Tk_FreeGC(display, outline->gc);
914      }      }
915      if (ABS(outline->dash.number) > sizeof(char *)) {      if (ABS(outline->dash.number) > sizeof(char *)) {
916          ckfree((char *) outline->dash.pattern.pt);          ckfree((char *) outline->dash.pattern.pt);
917      }      }
918      if (ABS(outline->activeDash.number) > sizeof(char *)) {      if (ABS(outline->activeDash.number) > sizeof(char *)) {
919          ckfree((char *) outline->activeDash.pattern.pt);          ckfree((char *) outline->activeDash.pattern.pt);
920      }      }
921      if (ABS(outline->disabledDash.number) > sizeof(char *)) {      if (ABS(outline->disabledDash.number) > sizeof(char *)) {
922          ckfree((char *) outline->disabledDash.pattern.pt);          ckfree((char *) outline->disabledDash.pattern.pt);
923      }      }
924      if (outline->color != NULL) {      if (outline->color != NULL) {
925          Tk_FreeColor(outline->color);          Tk_FreeColor(outline->color);
926      }      }
927      if (outline->activeColor != NULL) {      if (outline->activeColor != NULL) {
928          Tk_FreeColor(outline->activeColor);          Tk_FreeColor(outline->activeColor);
929      }      }
930      if (outline->disabledColor != NULL) {      if (outline->disabledColor != NULL) {
931          Tk_FreeColor(outline->disabledColor);          Tk_FreeColor(outline->disabledColor);
932      }      }
933      if (outline->stipple != None) {      if (outline->stipple != None) {
934          Tk_FreeBitmap(display, outline->stipple);          Tk_FreeBitmap(display, outline->stipple);
935      }      }
936      if (outline->activeStipple != None) {      if (outline->activeStipple != None) {
937          Tk_FreeBitmap(display, outline->activeStipple);          Tk_FreeBitmap(display, outline->activeStipple);
938      }      }
939      if (outline->disabledStipple != None) {      if (outline->disabledStipple != None) {
940          Tk_FreeBitmap(display, outline->disabledStipple);          Tk_FreeBitmap(display, outline->disabledStipple);
941      }      }
942  }  }
943    
944  /*  /*
945   *--------------------------------------------------------------   *--------------------------------------------------------------
946   *   *
947   * Tk_ConfigOutlineGC   * Tk_ConfigOutlineGC
948   *   *
949   *      This procedure should be called in the canvas object   *      This procedure should be called in the canvas object
950   *      during the configure command. The graphics context   *      during the configure command. The graphics context
951   *      description in gcValues is updated according to the   *      description in gcValues is updated according to the
952   *      information in the dash structure, as far as possible.   *      information in the dash structure, as far as possible.
953   *   *
954   * Results:   * Results:
955   *      The return-value is a mask, indicating which   *      The return-value is a mask, indicating which
956   *      elements of gcValues have been updated.   *      elements of gcValues have been updated.
957   *      0 means there is no outline.   *      0 means there is no outline.
958   *   *
959   * Side effects:   * Side effects:
960   *      GC information in gcValues is updated.   *      GC information in gcValues is updated.
961   *   *
962   *--------------------------------------------------------------   *--------------------------------------------------------------
963   */   */
964    
965  int Tk_ConfigOutlineGC(gcValues, canvas, item, outline)  int Tk_ConfigOutlineGC(gcValues, canvas, item, outline)
966      XGCValues *gcValues;      XGCValues *gcValues;
967      Tk_Canvas canvas;      Tk_Canvas canvas;
968      Tk_Item *item;      Tk_Item *item;
969      Tk_Outline *outline;      Tk_Outline *outline;
970  {  {
971      int mask = 0;      int mask = 0;
972      double width;      double width;
973      Tk_Dash *dash;      Tk_Dash *dash;
974      XColor *color;      XColor *color;
975      Pixmap stipple;      Pixmap stipple;
976      Tk_State state = item->state;      Tk_State state = item->state;
977    
978      if (outline->width < 0.0) {      if (outline->width < 0.0) {
979          outline->width = 0.0;          outline->width = 0.0;
980      }      }
981      if (outline->activeWidth < 0.0) {      if (outline->activeWidth < 0.0) {
982          outline->activeWidth = 0.0;          outline->activeWidth = 0.0;
983      }      }
984      if (outline->disabledWidth < 0) {      if (outline->disabledWidth < 0) {
985          outline->disabledWidth = 0.0;          outline->disabledWidth = 0.0;
986      }      }
987      if (state==TK_STATE_HIDDEN) {      if (state==TK_STATE_HIDDEN) {
988          return 0;          return 0;
989      }      }
990    
991      width = outline->width;      width = outline->width;
992      if (width < 1.0) {      if (width < 1.0) {
993          width = 1.0;          width = 1.0;
994      }      }
995      dash = &(outline->dash);      dash = &(outline->dash);
996      color = outline->color;      color = outline->color;
997      stipple = outline->stipple;      stipple = outline->stipple;
998      if (state == TK_STATE_NULL) {      if (state == TK_STATE_NULL) {
999          state = ((TkCanvas *)canvas)->canvas_state;          state = ((TkCanvas *)canvas)->canvas_state;
1000      }      }
1001      if (((TkCanvas *)canvas)->currentItemPtr == item) {      if (((TkCanvas *)canvas)->currentItemPtr == item) {
1002          if (outline->activeWidth>width) {          if (outline->activeWidth>width) {
1003              width = outline->activeWidth;              width = outline->activeWidth;
1004          }          }
1005          if (outline->activeDash.number != 0) {          if (outline->activeDash.number != 0) {
1006              dash = &(outline->activeDash);              dash = &(outline->activeDash);
1007          }          }
1008          if (outline->activeColor!=NULL) {          if (outline->activeColor!=NULL) {
1009              color = outline->activeColor;              color = outline->activeColor;
1010          }          }
1011          if (outline->activeStipple!=None) {          if (outline->activeStipple!=None) {
1012              stipple = outline->activeStipple;              stipple = outline->activeStipple;
1013          }          }
1014      } else if (state==TK_STATE_DISABLED) {      } else if (state==TK_STATE_DISABLED) {
1015          if (outline->disabledWidth>0) {          if (outline->disabledWidth>0) {
1016              width = outline->disabledWidth;              width = outline->disabledWidth;
1017          }          }
1018          if (outline->disabledDash.number != 0) {          if (outline->disabledDash.number != 0) {
1019              dash = &(outline->disabledDash);              dash = &(outline->disabledDash);
1020          }          }
1021          if (outline->disabledColor!=NULL) {          if (outline->disabledColor!=NULL) {
1022              color = outline->disabledColor;              color = outline->disabledColor;
1023          }          }
1024          if (outline->disabledStipple!=None) {          if (outline->disabledStipple!=None) {
1025              stipple = outline->disabledStipple;              stipple = outline->disabledStipple;
1026          }          }
1027      }      }
1028    
1029      if (color==NULL) {      if (color==NULL) {
1030          return 0;          return 0;
1031      }      }
1032    
1033      gcValues->line_width = (int) (width + 0.5);      gcValues->line_width = (int) (width + 0.5);
1034      if (color != NULL) {      if (color != NULL) {
1035          gcValues->foreground = color->pixel;          gcValues->foreground = color->pixel;
1036          mask = GCForeground|GCLineWidth;          mask = GCForeground|GCLineWidth;
1037          if (stipple != None) {          if (stipple != None) {
1038              gcValues->stipple = stipple;              gcValues->stipple = stipple;
1039              gcValues->fill_style = FillStippled;              gcValues->fill_style = FillStippled;
1040              mask |= GCStipple|GCFillStyle;              mask |= GCStipple|GCFillStyle;
1041          }          }
1042      }      }
1043      if (mask && (dash->number != 0)) {      if (mask && (dash->number != 0)) {
1044          gcValues->line_style = LineOnOffDash;          gcValues->line_style = LineOnOffDash;
1045          gcValues->dash_offset = outline->offset;          gcValues->dash_offset = outline->offset;
1046          if (dash->number >= 2) {          if (dash->number >= 2) {
1047              gcValues->dashes = 4;              gcValues->dashes = 4;
1048          } else if (dash->number > 0) {          } else if (dash->number > 0) {
1049              gcValues->dashes = dash->pattern.array[0];              gcValues->dashes = dash->pattern.array[0];
1050          } else {          } else {
1051              gcValues->dashes = (char) (4 * width);              gcValues->dashes = (char) (4 * width);
1052          }          }
1053          mask |= GCLineStyle|GCDashList|GCDashOffset;          mask |= GCLineStyle|GCDashList|GCDashOffset;
1054      }      }
1055      return mask;      return mask;
1056  }  }
1057    
1058  /*  /*
1059   *--------------------------------------------------------------   *--------------------------------------------------------------
1060   *   *
1061   * Tk_ChangeOutlineGC   * Tk_ChangeOutlineGC
1062   *   *
1063   *      Updates the GC to represent the full information of   *      Updates the GC to represent the full information of
1064   *      the dash structure. Partly this is already done in   *      the dash structure. Partly this is already done in
1065   *      Tk_ConfigOutlineGC().   *      Tk_ConfigOutlineGC().
1066   *      This function should be called just before drawing   *      This function should be called just before drawing
1067   *      the dashed item.   *      the dashed item.
1068   *   *
1069   * Results:   * Results:
1070   *      1 if there is a stipple pattern.   *      1 if there is a stipple pattern.
1071   *      0 otherwise.   *      0 otherwise.
1072   *   *
1073   * Side effects:   * Side effects:
1074   *      GC is updated.   *      GC is updated.
1075   *   *
1076   *--------------------------------------------------------------   *--------------------------------------------------------------
1077   */   */
1078    
1079  int  int
1080  Tk_ChangeOutlineGC(canvas, item, outline)  Tk_ChangeOutlineGC(canvas, item, outline)
1081      Tk_Canvas canvas;      Tk_Canvas canvas;
1082      Tk_Item *item;      Tk_Item *item;
1083      Tk_Outline *outline;      Tk_Outline *outline;
1084  {  {
1085      CONST char *p;      CONST char *p;
1086      double width;      double width;
1087      Tk_Dash *dash;      Tk_Dash *dash;
1088      XColor *color;      XColor *color;
1089      Pixmap stipple;      Pixmap stipple;
1090      Tk_State state = item->state;      Tk_State state = item->state;
1091    
1092      width = outline->width;      width = outline->width;
1093      if (width < 1.0) {      if (width < 1.0) {
1094          width = 1.0;          width = 1.0;
1095      }      }
1096      dash = &(outline->dash);      dash = &(outline->dash);
1097      color = outline->color;      color = outline->color;
1098      stipple = outline->stipple;      stipple = outline->stipple;
1099      if (state == TK_STATE_NULL) {      if (state == TK_STATE_NULL) {
1100          state = ((TkCanvas *)canvas)->canvas_state;          state = ((TkCanvas *)canvas)->canvas_state;
1101      }      }
1102      if (((TkCanvas *)canvas)->currentItemPtr == item) {      if (((TkCanvas *)canvas)->currentItemPtr == item) {
1103          if (outline->activeWidth > width) {          if (outline->activeWidth > width) {
1104              width = outline->activeWidth;              width = outline->activeWidth;
1105          }          }
1106          if (outline->activeDash.number != 0) {          if (outline->activeDash.number != 0) {
1107              dash = &(outline->activeDash);              dash = &(outline->activeDash);
1108          }          }
1109          if (outline->activeColor != NULL) {          if (outline->activeColor != NULL) {
1110              color = outline->activeColor;              color = outline->activeColor;
1111          }          }
1112          if (outline->activeStipple != None) {          if (outline->activeStipple != None) {
1113              stipple = outline->activeStipple;              stipple = outline->activeStipple;
1114          }          }
1115      } else if (state == TK_STATE_DISABLED) {      } else if (state == TK_STATE_DISABLED) {
1116          if (outline->disabledWidth > width) {          if (outline->disabledWidth > width) {
1117              width = outline->disabledWidth;              width = outline->disabledWidth;
1118          }          }
1119          if (outline->disabledDash.number != 0) {          if (outline->disabledDash.number != 0) {
1120              dash = &(outline->disabledDash);              dash = &(outline->disabledDash);
1121          }          }
1122          if (outline->disabledColor != NULL) {          if (outline->disabledColor != NULL) {
1123              color = outline->disabledColor;              color = outline->disabledColor;
1124          }          }
1125          if (outline->disabledStipple != None) {          if (outline->disabledStipple != None) {
1126              stipple = outline->disabledStipple;              stipple = outline->disabledStipple;
1127          }          }
1128      }      }
1129      if (color==NULL) {      if (color==NULL) {
1130          return 0;          return 0;
1131      }      }
1132    
1133      if ((dash->number<-1) || ((dash->number == -1) && (dash->pattern.array[1]!=','))) {      if ((dash->number<-1) || ((dash->number == -1) && (dash->pattern.array[1]!=','))) {
1134          char *q;          char *q;
1135          int i = -dash->number;          int i = -dash->number;
1136    
1137          p = (i > sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;          p = (i > sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
1138          q = (char *) ckalloc(2*(unsigned int)i);          q = (char *) ckalloc(2*(unsigned int)i);
1139          i = DashConvert(q, p, i, width);          i = DashConvert(q, p, i, width);
1140          XSetDashes(((TkCanvas *)canvas)->display, outline->gc, outline->offset, q, i);          XSetDashes(((TkCanvas *)canvas)->display, outline->gc, outline->offset, q, i);
1141          ckfree(q);          ckfree(q);
1142      } else if ( dash->number>2 || (dash->number==2 &&      } else if ( dash->number>2 || (dash->number==2 &&
1143                  (dash->pattern.array[0]!=dash->pattern.array[1]))) {                  (dash->pattern.array[0]!=dash->pattern.array[1]))) {
1144          p = (char *) (dash->number > sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;          p = (char *) (dash->number > sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
1145          XSetDashes(((TkCanvas *)canvas)->display, outline->gc, outline->offset, p, dash->number);          XSetDashes(((TkCanvas *)canvas)->display, outline->gc, outline->offset, p, dash->number);
1146      }      }
1147      if (stipple!=None) {      if (stipple!=None) {
1148          int w=0; int h=0;          int w=0; int h=0;
1149          Tk_TSOffset *tsoffset = &outline->tsoffset;          Tk_TSOffset *tsoffset = &outline->tsoffset;
1150          int flags = tsoffset->flags;          int flags = tsoffset->flags;
1151          if (!(flags & TK_OFFSET_INDEX) && (flags & (TK_OFFSET_CENTER|TK_OFFSET_MIDDLE))) {          if (!(flags & TK_OFFSET_INDEX) && (flags & (TK_OFFSET_CENTER|TK_OFFSET_MIDDLE))) {
1152              Tk_SizeOfBitmap(((TkCanvas *)canvas)->display, stipple, &w, &h);              Tk_SizeOfBitmap(((TkCanvas *)canvas)->display, stipple, &w, &h);
1153              if (flags & TK_OFFSET_CENTER) {              if (flags & TK_OFFSET_CENTER) {
1154                  w /= 2;                  w /= 2;
1155              } else {              } else {
1156                  w = 0;                  w = 0;
1157              }              }
1158              if (flags & TK_OFFSET_MIDDLE) {              if (flags & TK_OFFSET_MIDDLE) {
1159                  h /= 2;                  h /= 2;
1160              } else {              } else {
1161                  h = 0;                  h = 0;
1162              }              }
1163          }          }
1164          tsoffset->xoffset -= w;          tsoffset->xoffset -= w;
1165          tsoffset->yoffset -= h;          tsoffset->yoffset -= h;
1166          Tk_CanvasSetOffset(canvas, outline->gc, tsoffset);          Tk_CanvasSetOffset(canvas, outline->gc, tsoffset);
1167          tsoffset->xoffset += w;          tsoffset->xoffset += w;
1168          tsoffset->yoffset += h;          tsoffset->yoffset += h;
1169          return 1;          return 1;
1170      }      }
1171      return 0;      return 0;
1172  }  }
1173    
1174    
1175  /*  /*
1176   *--------------------------------------------------------------   *--------------------------------------------------------------
1177   *   *
1178   * Tk_ResetOutlineGC   * Tk_ResetOutlineGC
1179   *   *
1180   *      Restores the GC to the situation before   *      Restores the GC to the situation before
1181   *      Tk_ChangeDashGC() was called.   *      Tk_ChangeDashGC() was called.
1182   *      This function should be called just after the dashed   *      This function should be called just after the dashed
1183   *      item is drawn, because the GC is supposed to be   *      item is drawn, because the GC is supposed to be
1184   *      read-only.   *      read-only.
1185   *   *
1186   * Results:   * Results:
1187   *      1 if there is a stipple pattern.   *      1 if there is a stipple pattern.
1188   *      0 otherwise.   *      0 otherwise.
1189   *   *
1190   * Side effects:   * Side effects:
1191   *      GC is updated.   *      GC is updated.
1192   *   *
1193   *--------------------------------------------------------------   *--------------------------------------------------------------
1194   */   */
1195  int  int
1196  Tk_ResetOutlineGC(canvas, item, outline)  Tk_ResetOutlineGC(canvas, item, outline)
1197      Tk_Canvas canvas;      Tk_Canvas canvas;
1198      Tk_Item *item;      Tk_Item *item;
1199      Tk_Outline *outline;      Tk_Outline *outline;
1200  {  {
1201      char dashList;      char dashList;
1202      double width;      double width;
1203      Tk_Dash *dash;      Tk_Dash *dash;
1204      XColor *color;      XColor *color;
1205      Pixmap stipple;      Pixmap stipple;
1206      Tk_State state = item->state;      Tk_State state = item->state;
1207    
1208      width = outline->width;      width = outline->width;
1209      if (width < 1.0) {      if (width < 1.0) {
1210          width = 1.0;          width = 1.0;
1211      }      }
1212      dash = &(outline->dash);      dash = &(outline->dash);
1213      color = outline->color;      color = outline->color;
1214      stipple = outline->stipple;      stipple = outline->stipple;
1215      if (state == TK_STATE_NULL) {      if (state == TK_STATE_NULL) {
1216          state = ((TkCanvas *)canvas)->canvas_state;          state = ((TkCanvas *)canvas)->canvas_state;
1217      }      }
1218      if (((TkCanvas *)canvas)->currentItemPtr == item) {      if (((TkCanvas *)canvas)->currentItemPtr == item) {
1219          if (outline->activeWidth>width) {          if (outline->activeWidth>width) {
1220              width = outline->activeWidth;              width = outline->activeWidth;
1221          }          }
1222          if (outline->activeDash.number != 0) {          if (outline->activeDash.number != 0) {
1223              dash = &(outline->activeDash);              dash = &(outline->activeDash);
1224          }          }
1225          if (outline->activeColor!=NULL) {          if (outline->activeColor!=NULL) {
1226              color = outline->activeColor;              color = outline->activeColor;
1227          }          }
1228          if (outline->activeStipple!=None) {          if (outline->activeStipple!=None) {
1229              stipple = outline->activeStipple;              stipple = outline->activeStipple;
1230          }          }
1231      } else if (state==TK_STATE_DISABLED) {      } else if (state==TK_STATE_DISABLED) {
1232          if (outline->disabledWidth>width) {          if (outline->disabledWidth>width) {
1233              width = outline->disabledWidth;              width = outline->disabledWidth;
1234          }          }
1235          if (outline->disabledDash.number != 0) {          if (outline->disabledDash.number != 0) {
1236              dash = &(outline->disabledDash);              dash = &(outline->disabledDash);
1237          }          }
1238          if (outline->disabledColor!=NULL) {          if (outline->disabledColor!=NULL) {
1239              color = outline->disabledColor;              color = outline->disabledColor;
1240          }          }
1241          if (outline->disabledStipple!=None) {          if (outline->disabledStipple!=None) {
1242              stipple = outline->disabledStipple;              stipple = outline->disabledStipple;
1243          }          }
1244      }      }
1245      if (color==NULL) {      if (color==NULL) {
1246          return 0;          return 0;
1247      }      }
1248    
1249      if ((dash->number > 2) || (dash->number < -1) || (dash->number==2 &&      if ((dash->number > 2) || (dash->number < -1) || (dash->number==2 &&
1250                  (dash->pattern.array[0] != dash->pattern.array[1])) ||                  (dash->pattern.array[0] != dash->pattern.array[1])) ||
1251                  ((dash->number == -1) && (dash->pattern.array[1] != ','))) {                  ((dash->number == -1) && (dash->pattern.array[1] != ','))) {
1252          if (dash->number < 0) {          if (dash->number < 0) {
1253              dashList = (int) (4 * width + 0.5);              dashList = (int) (4 * width + 0.5);
1254          } else if (dash->number<3) {          } else if (dash->number<3) {
1255              dashList = dash->pattern.array[0];              dashList = dash->pattern.array[0];
1256          } else {          } else {
1257              dashList = 4;              dashList = 4;
1258          }          }
1259          XSetDashes(((TkCanvas *)canvas)->display, outline->gc,          XSetDashes(((TkCanvas *)canvas)->display, outline->gc,
1260                  outline->offset, &dashList , 1);                  outline->offset, &dashList , 1);
1261      }      }
1262      if (stipple != None) {      if (stipple != None) {
1263          XSetTSOrigin(((TkCanvas *)canvas)->display, outline->gc, 0, 0);          XSetTSOrigin(((TkCanvas *)canvas)->display, outline->gc, 0, 0);
1264          return 1;          return 1;
1265      }      }
1266      return 0;      return 0;
1267  }  }
1268    
1269    
1270  /*  /*
1271   *--------------------------------------------------------------   *--------------------------------------------------------------
1272   *   *
1273   * Tk_CanvasPsOutline   * Tk_CanvasPsOutline
1274   *   *
1275   *      Creates the postscript command for the correct   *      Creates the postscript command for the correct
1276   *      Outline-information (width, dash, color and stipple).   *      Outline-information (width, dash, color and stipple).
1277   *   *
1278   * Results:   * Results:
1279   *      TCL_OK if succeeded, otherwise TCL_ERROR.   *      TCL_OK if succeeded, otherwise TCL_ERROR.
1280   *   *
1281   * Side effects:   * Side effects:
1282   *      canvas->interp->result contains the postscript string,   *      canvas->interp->result contains the postscript string,
1283   *      or an error message if the result was TCL_ERROR.   *      or an error message if the result was TCL_ERROR.
1284   *   *
1285   *--------------------------------------------------------------   *--------------------------------------------------------------
1286   */   */
1287  int  int
1288  Tk_CanvasPsOutline(canvas, item, outline)  Tk_CanvasPsOutline(canvas, item, outline)
1289      Tk_Canvas canvas;      Tk_Canvas canvas;
1290      Tk_Item *item;      Tk_Item *item;
1291      Tk_Outline *outline;      Tk_Outline *outline;
1292  {  {
1293      char string[41];      char string[41];
1294      char pattern[11];      char pattern[11];
1295      int i;      int i;
1296      char *ptr;      char *ptr;
1297      char *str = string;      char *str = string;
1298      char *lptr = pattern;      char *lptr = pattern;
1299      Tcl_Interp *interp = ((TkCanvas *)canvas)->interp;      Tcl_Interp *interp = ((TkCanvas *)canvas)->interp;
1300      double width;      double width;
1301      Tk_Dash *dash;      Tk_Dash *dash;
1302      XColor *color;      XColor *color;
1303      Pixmap stipple;      Pixmap stipple;
1304      Tk_State state = item->state;      Tk_State state = item->state;
1305    
1306      width = outline->width;      width = outline->width;
1307      dash = &(outline->dash);      dash = &(outline->dash);
1308      color = outline->color;      color = outline->color;
1309      stipple = outline->stipple;      stipple = outline->stipple;
1310      if (state == TK_STATE_NULL) {      if (state == TK_STATE_NULL) {
1311          state = ((TkCanvas *)canvas)->canvas_state;          state = ((TkCanvas *)canvas)->canvas_state;
1312      }      }
1313      if (((TkCanvas *)canvas)->currentItemPtr == item) {      if (((TkCanvas *)canvas)->currentItemPtr == item) {
1314          if (outline->activeWidth > width) {          if (outline->activeWidth > width) {
1315              width = outline->activeWidth;              width = outline->activeWidth;
1316          }          }
1317          if (outline->activeDash.number > 0) {          if (outline->activeDash.number > 0) {
1318              dash = &(outline->activeDash);              dash = &(outline->activeDash);
1319          }          }
1320          if (outline->activeColor != NULL) {          if (outline->activeColor != NULL) {
1321              color = outline->activeColor;              color = outline->activeColor;
1322          }          }
1323          if (outline->activeStipple != None) {          if (outline->activeStipple != None) {
1324              stipple = outline->activeStipple;              stipple = outline->activeStipple;
1325          }          }
1326      } else if (state == TK_STATE_DISABLED) {      } else if (state == TK_STATE_DISABLED) {
1327          if (outline->disabledWidth > 0) {          if (outline->disabledWidth > 0) {
1328              width = outline->disabledWidth;              width = outline->disabledWidth;
1329          }          }
1330          if (outline->disabledDash.number > 0) {          if (outline->disabledDash.number > 0) {
1331              dash = &(outline->disabledDash);              dash = &(outline->disabledDash);
1332          }          }
1333          if (outline->disabledColor != NULL) {          if (outline->disabledColor != NULL) {
1334              color = outline->disabledColor;              color = outline->disabledColor;
1335          }          }
1336          if (outline->disabledStipple != None) {          if (outline->disabledStipple != None) {
1337              stipple = outline->disabledStipple;              stipple = outline->disabledStipple;
1338          }          }
1339      }      }
1340      sprintf(string, "%.15g setlinewidth\n", width);      sprintf(string, "%.15g setlinewidth\n", width);
1341      Tcl_AppendResult(interp, string, (char *) NULL);      Tcl_AppendResult(interp, string, (char *) NULL);
1342    
1343      if (dash->number > 10) {      if (dash->number > 10) {
1344          str = (char *)ckalloc((unsigned int) (1 + 4*dash->number));          str = (char *)ckalloc((unsigned int) (1 + 4*dash->number));
1345      } else if (dash->number < -5) {      } else if (dash->number < -5) {
1346          str = (char *)ckalloc((unsigned int) (1 - 8*dash->number));          str = (char *)ckalloc((unsigned int) (1 - 8*dash->number));
1347          lptr = (char *)ckalloc((unsigned int) (1 - 2*dash->number));          lptr = (char *)ckalloc((unsigned int) (1 - 2*dash->number));
1348      }      }
1349      ptr = (char *) ((ABS(dash->number) > sizeof(char *)) ) ?      ptr = (char *) ((ABS(dash->number) > sizeof(char *)) ) ?
1350          dash->pattern.pt : dash->pattern.array;          dash->pattern.pt : dash->pattern.array;
1351      if (dash->number > 0) {      if (dash->number > 0) {
1352          char *ptr0 = ptr;          char *ptr0 = ptr;
1353          sprintf(str, "[%d", *ptr++ & 0xff);          sprintf(str, "[%d", *ptr++ & 0xff);
1354          i = dash->number-1;          i = dash->number-1;
1355          while (i--) {          while (i--) {
1356              sprintf(str+strlen(str), " %d", *ptr++ & 0xff);              sprintf(str+strlen(str), " %d", *ptr++ & 0xff);
1357          }          }
1358          Tcl_AppendResult(interp, str, (char *)NULL);          Tcl_AppendResult(interp, str, (char *)NULL);
1359          if (dash->number&1) {          if (dash->number&1) {
1360              Tcl_AppendResult(interp, " ", str+1, (char *)NULL);              Tcl_AppendResult(interp, " ", str+1, (char *)NULL);
1361          }          }
1362          sprintf(str, "] %d setdash\n", outline->offset);          sprintf(str, "] %d setdash\n", outline->offset);
1363          Tcl_AppendResult(interp, str, (char *)NULL);          Tcl_AppendResult(interp, str, (char *)NULL);
1364          ptr = ptr0;          ptr = ptr0;
1365      } else if (dash->number < 0) {      } else if (dash->number < 0) {
1366          if ((i = DashConvert(lptr, ptr, -dash->number, width)) != 0) {          if ((i = DashConvert(lptr, ptr, -dash->number, width)) != 0) {
1367              char *lptr0 = lptr;              char *lptr0 = lptr;
1368              sprintf(str, "[%d", *lptr++ & 0xff);              sprintf(str, "[%d", *lptr++ & 0xff);
1369              while (--i) {              while (--i) {
1370                  sprintf(str+strlen(str), " %d", *lptr++ & 0xff);                  sprintf(str+strlen(str), " %d", *lptr++ & 0xff);
1371              }              }
1372              Tcl_AppendResult(interp, str, (char *)NULL);              Tcl_AppendResult(interp, str, (char *)NULL);
1373              sprintf(str, "] %d setdash\n", outline->offset);              sprintf(str, "] %d setdash\n", outline->offset);
1374              Tcl_AppendResult(interp, str, (char *)NULL);              Tcl_AppendResult(interp, str, (char *)NULL);
1375              lptr = lptr0;              lptr = lptr0;
1376          } else {          } else {
1377              Tcl_AppendResult(interp, "[] 0 setdash\n", (char *)NULL);              Tcl_AppendResult(interp, "[] 0 setdash\n", (char *)NULL);
1378          }          }
1379      } else {      } else {
1380          Tcl_AppendResult(interp, "[] 0 setdash\n", (char *)NULL);          Tcl_AppendResult(interp, "[] 0 setdash\n", (char *)NULL);
1381      }      }
1382      if (str != string) {      if (str != string) {
1383          ckfree(str);          ckfree(str);
1384      }      }
1385      if (lptr != pattern) {      if (lptr != pattern) {
1386          ckfree(lptr);          ckfree(lptr);
1387      }      }
1388      if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {      if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
1389          return TCL_ERROR;          return TCL_ERROR;
1390      }      }
1391      if (stipple != None) {      if (stipple != None) {
1392          Tcl_AppendResult(interp, "StrokeClip ", (char *) NULL);          Tcl_AppendResult(interp, "StrokeClip ", (char *) NULL);
1393          if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {          if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
1394              return TCL_ERROR;              return TCL_ERROR;
1395          }          }
1396      } else {      } else {
1397          Tcl_AppendResult(interp, "stroke\n", (char *) NULL);          Tcl_AppendResult(interp, "stroke\n", (char *) NULL);
1398      }      }
1399    
1400      return TCL_OK;      return TCL_OK;
1401  }  }
1402    
1403    
1404  /*  /*
1405   *--------------------------------------------------------------   *--------------------------------------------------------------
1406   *   *
1407   * DashConvert   * DashConvert
1408   *   *
1409   *      Converts a character-like dash-list (e.g. "-..")   *      Converts a character-like dash-list (e.g. "-..")
1410   *      into an X11-style. l must point to a string that   *      into an X11-style. l must point to a string that
1411   *      holds room to at least 2*n characters. if   *      holds room to at least 2*n characters. if
1412   *      l == NULL, this function can be used for   *      l == NULL, this function can be used for
1413   *      syntax checking only.   *      syntax checking only.
1414   *   *
1415   * Results:   * Results:
1416   *      The length of the resulting X11 compatible   *      The length of the resulting X11 compatible
1417   *      dash-list. -1 if failed.   *      dash-list. -1 if failed.
1418   *   *
1419   * Side effects:   * Side effects:
1420   *      None   *      None
1421   *   *
1422   *--------------------------------------------------------------   *--------------------------------------------------------------
1423   */   */
1424    
1425  static int  static int
1426  DashConvert (l, p, n, width)  DashConvert (l, p, n, width)
1427      char *l;      char *l;
1428      CONST char *p;      CONST char *p;
1429      int n;      int n;
1430      double width;      double width;
1431  {  {
1432      int result = 0;      int result = 0;
1433      int size, intWidth;      int size, intWidth;
1434    
1435      if (n<0) {      if (n<0) {
1436          n = strlen(p);          n = strlen(p);
1437      }      }
1438      intWidth = (int) (width + 0.5);      intWidth = (int) (width + 0.5);
1439      if (intWidth < 1) {      if (intWidth < 1) {
1440          intWidth = 1;          intWidth = 1;
1441      }      }
1442      while (n-- && *p) {      while (n-- && *p) {
1443          switch (*p++) {          switch (*p++) {
1444              case ' ':              case ' ':
1445                  if (result) {                  if (result) {
1446                      if (l) {                      if (l) {
1447                          l[-1] += intWidth + 1;                          l[-1] += intWidth + 1;
1448                      }                      }
1449                      continue;                      continue;
1450                  } else {                  } else {
1451                      return 0;                      return 0;
1452                  }                  }
1453                  break;                  break;
1454              case '_':              case '_':
1455                  size = 8;                  size = 8;
1456                  break;                  break;
1457              case '-':              case '-':
1458                  size = 6;                  size = 6;
1459                  break;                  break;
1460              case ',':              case ',':
1461                  size = 4;                  size = 4;
1462                  break;                  break;
1463              case '.':              case '.':
1464                  size = 2;                  size = 2;
1465                  break;                  break;
1466              default:              default:
1467                  return -1;                  return -1;
1468          }          }
1469          if (l) {          if (l) {
1470              *l++ = size * intWidth;              *l++ = size * intWidth;
1471              *l++ = 4 * intWidth;              *l++ = 4 * intWidth;
1472          }          }
1473          result += 2;          result += 2;
1474      }      }
1475      return result;      return result;
1476  }  }
1477  /* $Header$ */  /* $Header$ */
1478    
1479  /* End of tkcanvutil.c */  /* End of tkcanvutil.c */

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

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25