1 /*
2  * Author:      William Chia-Wei Cheng (bill.cheng@acm.org)
3  *
4  * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5  *
6  * This file may be distributed under the terms of the Q Public License
7  * as defined by Trolltech AS of Norway and appearing in the file
8  * LICENSE.QPL included in the packaging of this file.
9  *
10  * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11  * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  *
18  * @(#)$Header: /mm2/home/cvs/bc-src/tgif/mark.c,v 1.25 2011/05/16 16:21:58 william Exp $
19  */
20 
21 #define _INCLUDE_FROM_MARK_C_
22 
23 #include "tgifdefs.h"
24 #include "cmdids.h"
25 
26 #include "choice.e"
27 #include "cmd.e"
28 #include "dialog.e"
29 #include "drawing.e"
30 #include "dup.e"
31 #include "exec.e"
32 #include "file.e"
33 #include "mark.e"
34 #include "msg.e"
35 #include "obj.e"
36 #include "oval.e"
37 #include "pattern.e"
38 #include "page.e"
39 #include "poly.e"
40 #include "polygon.e"
41 #include "raster.e"
42 #include "rect.e"
43 #include "setup.e"
44 #include "select.e"
45 #include "spline.e"
46 #include "stretch.e"
47 #include "strtbl.e"
48 #include "util.e"
49 
50 int somethingHighLighted=FALSE;
51 
52 static int tickMarkSize=8;
53 
54 /* --------------------- Init & Clean Up --------------------- */
55 
CleanUpMark()56 void CleanUpMark()
57 {
58 }
59 
InitMark()60 int InitMark()
61 {
62    if (!(PRTGIF && !cmdLineOpenDisplay)) {
63       char *c_ptr=NULL;
64 
65       tickMarkSize = 8;
66       if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"TickMarkSize")) != NULL) {
67          SetTickMarkSizeValue(c_ptr);
68       }
69       autoRotatePivot = FALSE;
70       if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"AutoRotatePivot")) !=
71             NULL && UtilStrICmp(c_ptr, "true") == 0) {
72          autoRotatePivot = TRUE;
73          choicePixmap[ROTATEMODE] = rotateModePixmap[!autoRotatePivot];
74       }
75    }
76    return TRUE;
77 }
78 
79 /* --------------------- HighLight Functions --------------------- */
80 
81 static
MarkStructuredSpline(obj_ptr,ssn,ssvs,ssmooth,curved,locked)82 void MarkStructuredSpline(obj_ptr, ssn, ssvs, ssmooth, curved, locked)
83    struct ObjRec *obj_ptr;
84    int ssn, curved, locked;
85    char *ssmooth;
86    IntPoint *ssvs;
87 {
88    int i=0;
89 
90 #ifdef _TGIF_DBG /* debug, do not translate */
91    TgAssert(curved==LT_STRUCT_SPLINE,
92          "curved != LT_STRUCT_SPLINE in MarkStructuredSpline()", NULL);
93 #endif /* _TGIF_DBG */
94 
95    if (obj_ptr->ctm == NULL) {
96       if (ssmooth != NULL) {
97          for (i = 0; i < ssn; i++) {
98             if (ssmooth[i]) {
99                MARKHO(drawWindow, locked ? revGrayGC : revDefaultGC,
100                      OFFSET_X(ssvs[i].x), OFFSET_Y(ssvs[i].y));
101             } else {
102                MARKHR(drawWindow, locked ? revGrayGC : revDefaultGC,
103                      OFFSET_X(ssvs[i].x), OFFSET_Y(ssvs[i].y));
104             }
105          }
106       } else {
107          for (i = 0; i < ssn; i++) {
108             MARKHR(drawWindow, locked ? revGrayGC : revDefaultGC,
109                   OFFSET_X(ssvs[i].x), OFFSET_Y(ssvs[i].y));
110          }
111       }
112    } else {
113       for (i=0; i < ssn; i++) {
114          int x, y;
115 
116          TransformPointThroughCTM(ssvs[i].x-obj_ptr->x, ssvs[i].y-obj_ptr->y,
117                obj_ptr->ctm, &x, &y);
118          if (ssmooth != NULL && ssmooth[i]) {
119             MARKHO(drawWindow, locked ? revGrayGC : revDefaultGC,
120                   OFFSET_X(x+obj_ptr->x), OFFSET_Y(y+obj_ptr->y));
121          } else {
122             MARKHR(drawWindow, locked ? revGrayGC : revDefaultGC,
123                   OFFSET_X(x+obj_ptr->x), OFFSET_Y(y+obj_ptr->y));
124          }
125       }
126    }
127 }
128 
129 static
MarkPoly(ObjPtr,NumPts,V,Smooth,Curved,Locked)130 void MarkPoly(ObjPtr, NumPts, V, Smooth, Curved, Locked)
131    struct ObjRec *ObjPtr;
132    int NumPts, Curved, Locked;
133    char *Smooth;
134    IntPoint *V;
135 {
136    register int i;
137 
138    if (ObjPtr->ctm == NULL) {
139       if (Curved != LT_INTSPLINE && Smooth != NULL) {
140          for (i = 0; i < NumPts; i++) {
141             if (Smooth[i]) {
142                if (Curved == LT_STRUCT_SPLINE) {
143                   MARKHO(drawWindow, Locked ? revGrayGC : revDefaultGC,
144                         OFFSET_X(V[i].x), OFFSET_Y(V[i].y));
145                } else {
146                   MARKO(drawWindow, Locked ? revGrayGC : revDefaultGC,
147                         OFFSET_X(V[i].x), OFFSET_Y(V[i].y));
148                }
149             } else {
150                if (Curved == LT_STRUCT_SPLINE) {
151                   MARKHR(drawWindow, Locked ? revGrayGC : revDefaultGC,
152                         OFFSET_X(V[i].x), OFFSET_Y(V[i].y));
153                } else {
154                   MARK(drawWindow, Locked ? revGrayGC : revDefaultGC,
155                         OFFSET_X(V[i].x), OFFSET_Y(V[i].y));
156                }
157             }
158          }
159       } else {
160          for (i = 0; i < NumPts; i++) {
161             MARK(drawWindow, Locked ? revGrayGC : revDefaultGC,
162                   OFFSET_X(V[i].x), OFFSET_Y(V[i].y));
163          }
164       }
165    } else {
166       for (i=0; i < NumPts; i++) {
167          int x, y;
168 
169          TransformPointThroughCTM(V[i].x-ObjPtr->x, V[i].y-ObjPtr->y,
170                ObjPtr->ctm, &x, &y);
171          if (Curved != LT_INTSPLINE && Smooth != NULL && Smooth[i]) {
172             if (Curved == LT_STRUCT_SPLINE) {
173                MARKHO(drawWindow, Locked ? revGrayGC : revDefaultGC,
174                      OFFSET_X(x+ObjPtr->x), OFFSET_Y(y+ObjPtr->y));
175             } else {
176                MARKO(drawWindow, Locked ? revGrayGC : revDefaultGC,
177                      OFFSET_X(x+ObjPtr->x), OFFSET_Y(y+ObjPtr->y));
178             }
179          } else {
180             if (Curved == LT_STRUCT_SPLINE) {
181                MARKHR(drawWindow, Locked ? revGrayGC : revDefaultGC,
182                      OFFSET_X(x+ObjPtr->x), OFFSET_Y(y+ObjPtr->y));
183             } else {
184                MARK(drawWindow, Locked ? revGrayGC : revDefaultGC,
185                      OFFSET_X(x+ObjPtr->x), OFFSET_Y(y+ObjPtr->y));
186             }
187          }
188       }
189    }
190 }
191 
192 static
Mark4Corners(BBox,Locked,Thin)193 void Mark4Corners(BBox, Locked, Thin)
194    struct BBRec BBox;
195    int Locked, Thin;
196 {
197    if (Locked) {
198       MARK(drawWindow, revGrayGC, OFFSET_X(BBox.ltx), OFFSET_Y(BBox.lty));
199       if (!Thin) {
200          MARK(drawWindow, revGrayGC, OFFSET_X(BBox.ltx), OFFSET_Y(BBox.rby));
201          MARK(drawWindow, revGrayGC, OFFSET_X(BBox.rbx), OFFSET_Y(BBox.lty));
202       }
203       MARK(drawWindow, revGrayGC, OFFSET_X(BBox.rbx), OFFSET_Y(BBox.rby));
204    } else {
205       MARK(drawWindow, revDefaultGC, OFFSET_X(BBox.ltx), OFFSET_Y(BBox.lty));
206       if (!Thin) {
207          MARK(drawWindow, revDefaultGC, OFFSET_X(BBox.ltx), OFFSET_Y(BBox.rby));
208          MARK(drawWindow, revDefaultGC, OFFSET_X(BBox.rbx), OFFSET_Y(BBox.lty));
209       }
210       MARK(drawWindow, revDefaultGC, OFFSET_X(BBox.rbx), OFFSET_Y(BBox.rby));
211    }
212 }
213 
214 static
Mark8Places(BBox,Locked)215 void Mark8Places(BBox, Locked)
216    struct BBRec BBox;
217    int Locked;
218 {
219    register int xmid=0, ymid=0;
220 
221    if (ZOOMED_SIZE(BBox.rbx - BBox.ltx) == 0) {
222       if (ZOOMED_SIZE(BBox.rby - BBox.lty) == 0) {
223          MARK(drawWindow, Locked ? revGrayGC : revDefaultGC,
224                OFFSET_X(BBox.ltx), OFFSET_Y(BBox.lty));
225       } else {
226          if (ZOOMED_SIZE(BBox.rby - BBox.lty) >= 10) {
227             ymid = ((BBox.lty+BBox.rby) >> 1);
228             MARK(drawWindow, Locked ? revGrayGC : revDefaultGC,
229                   OFFSET_X(BBox.ltx), OFFSET_Y(ymid));
230          }
231          Mark4Corners(BBox, Locked, TRUE);
232       }
233    } else if (ZOOMED_SIZE(BBox.rby - BBox.lty) == 0) {
234       if (ZOOMED_SIZE(BBox.rbx - BBox.ltx) >= 10) {
235          xmid = (BBox.ltx+BBox.rbx) / 2;
236          MARK(drawWindow, Locked ? revGrayGC : revDefaultGC,
237                OFFSET_X(xmid), OFFSET_Y(BBox.lty));
238       }
239       Mark4Corners(BBox, Locked, TRUE);
240    } else {
241       if (ZOOMED_SIZE(BBox.rbx - BBox.ltx) >= 10) {
242          xmid = (BBox.ltx+BBox.rbx) / 2;
243          if (Locked) {
244             MARK(drawWindow, revGrayGC, OFFSET_X(xmid), OFFSET_Y(BBox.lty));
245             MARK(drawWindow, revGrayGC, OFFSET_X(xmid), OFFSET_Y(BBox.rby));
246          } else {
247             MARK(drawWindow, revDefaultGC, OFFSET_X(xmid), OFFSET_Y(BBox.lty));
248             MARK(drawWindow, revDefaultGC, OFFSET_X(xmid), OFFSET_Y(BBox.rby));
249          }
250       }
251       if (ZOOMED_SIZE(BBox.rby - BBox.lty) >= 10) {
252          ymid = ((BBox.lty+BBox.rby) >> 1);
253          if (Locked) {
254             MARK(drawWindow, revGrayGC, OFFSET_X(BBox.ltx), OFFSET_Y(ymid));
255             MARK(drawWindow, revGrayGC, OFFSET_X(BBox.rbx), OFFSET_Y(ymid));
256          } else {
257             MARK(drawWindow, revDefaultGC, OFFSET_X(BBox.ltx), OFFSET_Y(ymid));
258             MARK(drawWindow, revDefaultGC, OFFSET_X(BBox.rbx), OFFSET_Y(ymid));
259          }
260       }
261       Mark4Corners(BBox, Locked, FALSE);
262    }
263 }
264 
HighLightAnObj(ObjPtr)265 void HighLightAnObj(ObjPtr)
266    register struct ObjRec *ObjPtr;
267 {
268    if (execCurDepth > 0) return;
269    switch (ObjPtr->type) {
270    case OBJ_POLY:
271       if (ObjPtr->detail.p->curved == LT_STRUCT_SPLINE) {
272          MarkStructuredSpline(ObjPtr, ObjPtr->detail.p->ssn,
273                ObjPtr->detail.p->ssvlist, ObjPtr->detail.p->ssmooth,
274                ObjPtr->detail.p->curved, ObjPtr->locked);
275       } else {
276          MarkPoly(ObjPtr, ObjPtr->detail.p->n, ObjPtr->detail.p->vlist,
277                ObjPtr->detail.p->smooth, ObjPtr->detail.p->curved,
278                ObjPtr->locked);
279       }
280       break;
281    case OBJ_POLYGON:
282       if (ObjPtr->detail.g->curved == LT_STRUCT_SPLINE) {
283          MarkStructuredSpline(ObjPtr, ObjPtr->detail.g->ssn-1,
284                ObjPtr->detail.g->ssvlist, ObjPtr->detail.g->ssmooth,
285                ObjPtr->detail.g->curved, ObjPtr->locked);
286       } else {
287          MarkPoly(ObjPtr, ObjPtr->detail.g->n-1, ObjPtr->detail.g->vlist,
288                ObjPtr->detail.g->smooth, ObjPtr->detail.g->curved,
289                ObjPtr->locked);
290       }
291       break;
292 
293    case OBJ_BOX:
294    case OBJ_OVAL:
295    case OBJ_TEXT:
296    case OBJ_ARC:
297    case OBJ_RCBOX:
298    case OBJ_GROUP:
299    case OBJ_XBM:
300    case OBJ_XPM:
301    case OBJ_SYM:
302    case OBJ_ICON:
303    case OBJ_PIN:
304       Mark8Places(ObjPtr->obbox, ObjPtr->locked);
305       break;
306    }
307 }
308 
309 static
HighLightVertices(Dir)310 void HighLightVertices(Dir)
311    int Dir;
312 {
313    register struct VSelRec *vsel_ptr=NULL;
314    register struct ObjRec *obj_ptr;
315    register int i;
316    struct SelRec *sel_ptr=NULL;
317 
318    if (mainDisplay == NULL || execCurDepth > 0) return;
319 
320    switch (Dir) {
321    case FORWARD: vsel_ptr=botVSel; sel_ptr=botSel; break;
322    case REVERSE: vsel_ptr=topVSel; sel_ptr=topSel; break;
323    }
324    while (sel_ptr != NULL) {
325       obj_ptr = sel_ptr->obj;
326 
327       switch (obj_ptr->type) {
328       case OBJ_POLY:
329          if (obj_ptr->detail.p->curved == LT_STRUCT_SPLINE) {
330             MarkStructuredSpline(obj_ptr, obj_ptr->detail.p->ssn,
331                   obj_ptr->detail.p->ssvlist, obj_ptr->detail.p->ssmooth,
332                   obj_ptr->detail.p->curved, obj_ptr->locked);
333          } else {
334             MarkPoly(obj_ptr, obj_ptr->detail.p->n, obj_ptr->detail.p->vlist,
335                   obj_ptr->detail.p->smooth, obj_ptr->detail.p->curved,
336                   obj_ptr->locked);
337          }
338          break;
339       case OBJ_POLYGON:
340          if (obj_ptr->detail.g->curved == LT_STRUCT_SPLINE) {
341             MarkStructuredSpline(obj_ptr, obj_ptr->detail.g->ssn-1,
342                   obj_ptr->detail.g->ssvlist, obj_ptr->detail.g->ssmooth,
343                   obj_ptr->detail.g->curved, obj_ptr->locked);
344          } else {
345             MarkPoly(obj_ptr, obj_ptr->detail.g->n-1, obj_ptr->detail.g->vlist,
346                   obj_ptr->detail.g->smooth, obj_ptr->detail.g->curved,
347                   obj_ptr->locked);
348          }
349          break;
350       }
351       switch (Dir) {
352       case FORWARD: sel_ptr = sel_ptr->prev; break;
353       case REVERSE: sel_ptr = sel_ptr->next; break;
354       }
355    }
356    while (vsel_ptr != NULL) {
357       char *smooth=NULL;
358       int curved=(-1);
359 
360       switch (vsel_ptr->obj->type) {
361       case OBJ_POLY:
362          curved = vsel_ptr->obj->detail.p->curved;
363          if (curved == LT_STRUCT_SPLINE) {
364             smooth = vsel_ptr->obj->detail.p->ssmooth;
365          } else {
366             smooth = vsel_ptr->obj->detail.p->smooth;
367          }
368          break;
369       case OBJ_POLYGON:
370          curved = vsel_ptr->obj->detail.g->curved;
371          if (curved == LT_STRUCT_SPLINE) {
372             smooth = vsel_ptr->obj->detail.g->ssmooth;
373          } else {
374             smooth = vsel_ptr->obj->detail.g->smooth;
375          }
376          break;
377       }
378       for (i = 0; i < vsel_ptr->n; i++) {
379          if (!(vsel_ptr->obj->type==OBJ_POLYGON &&
380                vsel_ptr->obj->detail.g->n-1==vsel_ptr->v_index[i])) {
381             if (curved != LT_INTSPLINE && curved != (-1) && smooth != NULL) {
382                if (smooth[vsel_ptr->v_index[i]]) {
383                   if (curved == LT_STRUCT_SPLINE) {
384                      MARKHO(drawWindow, revDefaultGC, OFFSET_X(vsel_ptr->x[i]),
385                            OFFSET_Y(vsel_ptr->y[i]));
386                   } else {
387                      MARKO(drawWindow, revDefaultGC, OFFSET_X(vsel_ptr->x[i]),
388                            OFFSET_Y(vsel_ptr->y[i]));
389                   }
390                } else {
391                   if (curved == LT_STRUCT_SPLINE) {
392                      MARKHR(drawWindow, revDefaultGC, OFFSET_X(vsel_ptr->x[i]),
393                            OFFSET_Y(vsel_ptr->y[i]));
394                   } else {
395                      MARK(drawWindow, revDefaultGC, OFFSET_X(vsel_ptr->x[i]),
396                            OFFSET_Y(vsel_ptr->y[i]));
397                   }
398                }
399             } else {
400                MARK(drawWindow, revDefaultGC, OFFSET_X(vsel_ptr->x[i]),
401                      OFFSET_Y(vsel_ptr->y[i]));
402             }
403             MARKV(drawWindow, revDefaultGC, OFFSET_X(vsel_ptr->x[i]),
404                   OFFSET_Y(vsel_ptr->y[i]));
405          }
406       }
407       switch (Dir) {
408       case FORWARD: vsel_ptr = vsel_ptr->prev; break;
409       case REVERSE: vsel_ptr = vsel_ptr->next; break;
410       }
411    }
412 }
413 
414 static
HighLight(Dir)415 void HighLight(Dir)
416    int Dir;
417 {
418    register struct SelRec *sel_ptr=NULL;
419    register struct ObjRec *obj_ptr;
420 
421    if (mainDisplay == NULL || execCurDepth > 0) return;
422 
423    switch (Dir) {
424    case FORWARD: sel_ptr = botSel; break;
425    case REVERSE: sel_ptr = topSel; break;
426    }
427    while (sel_ptr != NULL) {
428       obj_ptr = sel_ptr->obj;
429       switch (obj_ptr->type) {
430       case OBJ_POLY:
431          if (obj_ptr->detail.p->curved == LT_STRUCT_SPLINE) {
432             MarkStructuredSpline(obj_ptr, obj_ptr->detail.p->ssn,
433                   obj_ptr->detail.p->ssvlist, obj_ptr->detail.p->ssmooth,
434                   obj_ptr->detail.p->curved, obj_ptr->locked);
435          } else {
436             MarkPoly(obj_ptr, obj_ptr->detail.p->n, obj_ptr->detail.p->vlist,
437                   obj_ptr->detail.p->smooth, obj_ptr->detail.p->curved,
438                   obj_ptr->locked);
439          }
440          break;
441       case OBJ_POLYGON:
442          if (obj_ptr->detail.g->curved == LT_STRUCT_SPLINE) {
443             MarkStructuredSpline(obj_ptr, obj_ptr->detail.g->ssn-1,
444                   obj_ptr->detail.g->ssvlist, obj_ptr->detail.g->ssmooth,
445                   obj_ptr->detail.g->curved, obj_ptr->locked);
446          } else {
447             MarkPoly(obj_ptr, obj_ptr->detail.g->n-1, obj_ptr->detail.g->vlist,
448                   obj_ptr->detail.g->smooth, obj_ptr->detail.g->curved,
449                   obj_ptr->locked);
450          }
451          break;
452 
453       case OBJ_BOX:
454       case OBJ_OVAL:
455       case OBJ_TEXT:
456       case OBJ_GROUP:
457       case OBJ_ARC:
458       case OBJ_RCBOX:
459       case OBJ_XBM:
460       case OBJ_XPM:
461       case OBJ_SYM:
462       case OBJ_ICON:
463       case OBJ_PIN:
464          Mark8Places(obj_ptr->obbox, obj_ptr->locked);
465          break;
466       }
467       switch (Dir) {
468       case FORWARD: sel_ptr = sel_ptr->prev; break;
469       case REVERSE: sel_ptr = sel_ptr->next; break;
470       }
471    }
472 }
473 
HighLightForward()474 void HighLightForward()
475 {
476    if (curChoice == VERTEXMODE) {
477       HighLightVertices(FORWARD);
478    } else {
479       HighLight(FORWARD);
480       if (!autoRotatePivot && curChoice == ROTATEMODE) {
481          HighLightRotatePivot(FORWARD);
482       }
483    }
484    somethingHighLighted = TRUE;
485 }
486 
HighLightReverse()487 void HighLightReverse()
488 {
489    if (curChoice == VERTEXMODE) {
490       HighLightVertices(REVERSE);
491    } else {
492       if (!autoRotatePivot && curChoice == ROTATEMODE) {
493          HighLightRotatePivot(REVERSE);
494       }
495       HighLight(REVERSE);
496    }
497    somethingHighLighted = FALSE;
498 }
499 
500 /* --------------------- AddTickMarks() --------------------- */
501 
502 struct tagAddTickMarksInfo {
503    int n;
504    IntPoint *vs;
505    char *smooth;
506 } gATMI;
507 
508 static
CreatePolygonTickMarks(num_pts)509 int CreatePolygonTickMarks(num_pts)
510    int num_pts;
511 {
512    gATMI.vs = (IntPoint*)malloc((num_pts+1)*sizeof(IntPoint));
513    if (gATMI.vs == NULL) return FailAllocMessage();
514    memset(gATMI.vs, 0, (num_pts+1)*sizeof(IntPoint));
515 
516    gATMI.smooth = (char*)malloc(num_pts*sizeof(char));
517    if (gATMI.smooth == NULL) {
518       free(gATMI.vs);
519       gATMI.vs = NULL;
520       return FailAllocMessage();
521    }
522    memset(gATMI.smooth, 0, num_pts*sizeof(char));
523 
524    gATMI.n = num_pts;
525    return TRUE;
526 }
527 
528 static
StartCreateTickMarks(nCmdId)529 int StartCreateTickMarks(nCmdId)
530    int nCmdId;
531 {
532    switch (nCmdId) {
533    case CMDID_ADDSQUARETICKMARKS: return CreatePolygonTickMarks(5);
534    case CMDID_ADDTRIANGLETICKMARKS: return CreatePolygonTickMarks(4);
535    case CMDID_ADDCIRCLETICKMARKS: return TRUE;
536    case CMDID_ADDXTICKMARKS: return CreatePolygonTickMarks(9);
537    case CMDID_ADDDIAMONDTICKMARKS: return CreatePolygonTickMarks(5);
538    case CMDID_ADDBOWTIETICKMARKS: return CreatePolygonTickMarks(5);
539    case CMDID_ADDINVTRIANGLETICKMARKS: return CreatePolygonTickMarks(4);
540    case CMDID_ADDPLUSTICKMARKS: return CreatePolygonTickMarks(9);
541    case CMDID_ADDHOURGLASSTICKMARKS: return CreatePolygonTickMarks(5);
542    default: break;
543    }
544    return FALSE;
545 }
546 
547 static
EndCreateTickMarks()548 void EndCreateTickMarks()
549 {
550    if (gATMI.vs != NULL) free(gATMI.vs);
551    if (gATMI.smooth != NULL) free(gATMI.smooth);
552    gATMI.vs = NULL;
553    gATMI.smooth = NULL;
554    gATMI.n = 0;
555 }
556 
557 static
CreatePolygonalTickMark()558 void CreatePolygonalTickMark()
559 {
560    int i=0, saved_cur_spline=curSpline;
561 
562    curSpline = LT_STRAIGHT;
563    ResetCreatePolygon();
564    for (i=0; i < gATMI.n; i++) {
565       AddPtToCreatePolygon(gATMI.vs[i].x, gATMI.vs[i].y);
566    }
567    CreatePolygonObj(gATMI.n, TRUE);
568    curSpline = saved_cur_spline;
569 }
570 
571 static
CalcSquareVs(v)572 void CalcSquareVs(v)
573    IntPoint v;
574 {
575    int half_w=(tickMarkSize>>1);
576 
577    gATMI.vs[0].x = v.x-half_w; gATMI.vs[0].y = v.y-half_w;
578    gATMI.vs[1].x = v.x+half_w; gATMI.vs[1].y = v.y-half_w;
579    gATMI.vs[2].x = v.x+half_w; gATMI.vs[2].y = v.y+half_w;
580    gATMI.vs[3].x = v.x-half_w; gATMI.vs[3].y = v.y+half_w;
581    gATMI.vs[4].x = v.x-half_w; gATMI.vs[4].y = v.y-half_w;
582 
583    CreatePolygonalTickMark();
584 }
585 
586 static
CalcTriangleVs(v)587 void CalcTriangleVs(v)
588    IntPoint v;
589 {
590    int i=0, half_w=(tickMarkSize>>1);
591    double d_offset=((double)tickMarkSize)*((double)3)/((double)16);
592    int offset=round(d_offset);
593 
594    gATMI.vs[0].x = v.x;        gATMI.vs[0].y = v.y-half_w;
595    gATMI.vs[1].x = v.x+half_w; gATMI.vs[1].y = v.y+half_w;
596    gATMI.vs[2].x = v.x-half_w; gATMI.vs[2].y = v.y+half_w;
597    gATMI.vs[3].x = v.x;        gATMI.vs[3].y = v.y-half_w;
598    for (i=0; i < 4; i++) gATMI.vs[i].y -= offset;
599 
600    CreatePolygonalTickMark();
601 }
602 
603 static
CalcCircleVs(v)604 void CalcCircleVs(v)
605    IntPoint v;
606 {
607    int half_w=(tickMarkSize>>1);
608    struct BBRec obbox;
609 
610    obbox.ltx = v.x-half_w; obbox.lty = v.y-half_w;
611    obbox.rbx = v.x+half_w; obbox.rby = v.y+half_w;
612 
613    CreateOvalObj(&obbox, TRUE);
614 }
615 
616 static
CalcXVs(v)617 void CalcXVs(v)
618    IntPoint v;
619 {
620    int half_w=(tickMarkSize>>1);
621 
622    gATMI.vs[0].x = v.x;        gATMI.vs[0].y = v.y;
623    gATMI.vs[1].x = v.x-half_w; gATMI.vs[1].y = v.y-half_w;
624    gATMI.vs[2].x = v.x;        gATMI.vs[2].y = v.y;
625    gATMI.vs[3].x = v.x+half_w; gATMI.vs[3].y = v.y-half_w;
626    gATMI.vs[4].x = v.x;        gATMI.vs[4].y = v.y;
627    gATMI.vs[5].x = v.x+half_w; gATMI.vs[5].y = v.y+half_w;
628    gATMI.vs[6].x = v.x;        gATMI.vs[6].y = v.y;
629    gATMI.vs[7].x = v.x-half_w; gATMI.vs[7].y = v.y+half_w;
630    gATMI.vs[8].x = v.x;        gATMI.vs[8].y = v.y;
631 
632    CreatePolygonalTickMark();
633 }
634 
635 static
CalcDiamondVs(v)636 void CalcDiamondVs(v)
637    IntPoint v;
638 {
639    int half_w=(tickMarkSize>>1);
640 
641    gATMI.vs[0].x = v.x-half_w; gATMI.vs[0].y = v.y;
642    gATMI.vs[1].x = v.x;        gATMI.vs[1].y = v.y-half_w;
643    gATMI.vs[2].x = v.x+half_w; gATMI.vs[2].y = v.y;
644    gATMI.vs[3].x = v.x;        gATMI.vs[3].y = v.y+half_w;
645    gATMI.vs[4].x = v.x-half_w; gATMI.vs[4].y = v.y;
646 
647    CreatePolygonalTickMark();
648 }
649 
650 static
CalcBowtieVs(v)651 void CalcBowtieVs(v)
652    IntPoint v;
653 {
654    int half_w=(tickMarkSize>>1);
655 
656    gATMI.vs[0].x = v.x-half_w; gATMI.vs[0].y = v.y-half_w;
657    gATMI.vs[1].x = v.x-half_w; gATMI.vs[1].y = v.y+half_w;
658    gATMI.vs[2].x = v.x+half_w; gATMI.vs[2].y = v.y-half_w;
659    gATMI.vs[3].x = v.x+half_w; gATMI.vs[3].y = v.y+half_w;
660    gATMI.vs[4].x = v.x-half_w; gATMI.vs[4].y = v.y-half_w;
661 
662    CreatePolygonalTickMark();
663 }
664 
665 static
CalcInvTriangleVs(v)666 void CalcInvTriangleVs(v)
667    IntPoint v;
668 {
669    int i=0, half_w=(tickMarkSize>>1);
670    double d_offset=((double)tickMarkSize)*((double)3)/((double)16);
671    int offset=round(d_offset);
672 
673    gATMI.vs[0].x = v.x;        gATMI.vs[0].y = v.y+half_w;
674    gATMI.vs[1].x = v.x+half_w; gATMI.vs[1].y = v.y-half_w;
675    gATMI.vs[2].x = v.x-half_w; gATMI.vs[2].y = v.y-half_w;
676    gATMI.vs[3].x = v.x;        gATMI.vs[3].y = v.y+half_w;
677    for (i=0; i < 4; i++) gATMI.vs[i].y += offset;
678 
679    CreatePolygonalTickMark();
680 }
681 
682 static
CalcPlusVs(v)683 void CalcPlusVs(v)
684    IntPoint v;
685 {
686    int half_w=(tickMarkSize>>1);
687 
688    gATMI.vs[0].x = v.x;        gATMI.vs[0].y = v.y;
689    gATMI.vs[1].x = v.x-half_w; gATMI.vs[1].y = v.y;
690    gATMI.vs[2].x = v.x;        gATMI.vs[2].y = v.y;
691    gATMI.vs[3].x = v.x;        gATMI.vs[3].y = v.y-half_w;
692    gATMI.vs[4].x = v.x;        gATMI.vs[4].y = v.y;
693    gATMI.vs[5].x = v.x+half_w; gATMI.vs[5].y = v.y;
694    gATMI.vs[6].x = v.x;        gATMI.vs[6].y = v.y;
695    gATMI.vs[7].x = v.x;        gATMI.vs[7].y = v.y+half_w;
696    gATMI.vs[8].x = v.x;        gATMI.vs[8].y = v.y;
697 
698    CreatePolygonalTickMark();
699 }
700 
701 static
CalcHourGlassVs(v)702 void CalcHourGlassVs(v)
703    IntPoint v;
704 {
705    int half_w=(tickMarkSize>>1);
706 
707    gATMI.vs[0].x = v.x-half_w; gATMI.vs[0].y = v.y-half_w;
708    gATMI.vs[1].x = v.x+half_w; gATMI.vs[1].y = v.y-half_w;
709    gATMI.vs[2].x = v.x-half_w; gATMI.vs[2].y = v.y+half_w;
710    gATMI.vs[3].x = v.x+half_w; gATMI.vs[3].y = v.y+half_w;
711    gATMI.vs[4].x = v.x-half_w; gATMI.vs[4].y = v.y-half_w;
712 
713    CreatePolygonalTickMark();
714 }
715 
716 static
CreateTickMarks(n,vs,nCmdId)717 void CreateTickMarks(n, vs, nCmdId)
718    int n, nCmdId;
719    IntPoint *vs;
720 {
721    int i=0;
722 
723    for (i=0; i < n; i++) {
724       switch (nCmdId) {
725       case CMDID_ADDSQUARETICKMARKS: CalcSquareVs(vs[i]); break;
726       case CMDID_ADDTRIANGLETICKMARKS: CalcTriangleVs(vs[i]); break;
727       case CMDID_ADDCIRCLETICKMARKS: CalcCircleVs(vs[i]); break;
728       case CMDID_ADDXTICKMARKS: CalcXVs(vs[i]); break;
729       case CMDID_ADDDIAMONDTICKMARKS: CalcDiamondVs(vs[i]); break;
730       case CMDID_ADDBOWTIETICKMARKS: CalcBowtieVs(vs[i]); break;
731       case CMDID_ADDINVTRIANGLETICKMARKS: CalcInvTriangleVs(vs[i]); break;
732       case CMDID_ADDPLUSTICKMARKS: CalcPlusVs(vs[i]); break;
733       case CMDID_ADDHOURGLASSTICKMARKS: CalcHourGlassVs(vs[i]); break;
734       default: break;
735       }
736    }
737 }
738 
739 static
SetRealVertex(vs_return,i,dvs)740 void SetRealVertex(vs_return, i, dvs)
741    IntPoint *vs_return;
742    int i;
743    DoublePoint dvs[3];
744 {
745    DoublePoint m1, m2, m;
746 
747    m1.x = (dvs[0].x+dvs[1].x) / ((double)2);
748    m1.y = (dvs[0].y+dvs[1].y) / ((double)2);
749    m2.x = (dvs[1].x+dvs[2].x) / ((double)2);
750    m2.y = (dvs[1].y+dvs[2].y) / ((double)2);
751    m.x = (m1.x+m2.x) / ((double)2);
752    m.y = (m1.y+m2.y) / ((double)2);
753 
754    vs_return[i].x = round(m.x);
755    vs_return[i].y = round(m.y);
756 }
757 
758 static
GetSplinePolyTickMarkVs(pn_return,n,vs,smooth)759 IntPoint *GetSplinePolyTickMarkVs(pn_return, n, vs, smooth)
760    int *pn_return, n;
761    IntPoint *vs;
762    char *smooth;
763 {
764    int i=0, first_hinge_index=0, write_index=0;
765    IntPoint *vs_return=(IntPoint*)malloc(((n<<1)-1)*sizeof(IntPoint));
766 
767    if (vs_return == NULL) FailAllocMessage();
768    memset(vs_return, 0, n*sizeof(IntPoint));
769 
770    i = write_index = 0;
771    while (i < n) {
772       if (smooth[i]) {
773          int j=0, last_hinge_index=i, num_vs=0;
774          DoublePoint dvs[3];
775 
776          for (last_hinge_index=i+1; smooth[last_hinge_index];
777                last_hinge_index++) {
778          }
779          num_vs = last_hinge_index-first_hinge_index+1;
780          if (num_vs > 3) {
781             DoublePoint *mid_pt_of_mid_segs=NULL;
782 
783             mid_pt_of_mid_segs =
784                   (DoublePoint*)malloc((num_vs-3)*sizeof(DoublePoint));
785             if (mid_pt_of_mid_segs == NULL) FailAllocMessage();
786             memset(mid_pt_of_mid_segs, 0, (num_vs-3)*sizeof(DoublePoint));
787 
788             for (j=first_hinge_index+1; j < last_hinge_index-1; j++) {
789                /*
790                 * These are the midpoints of imaginary line segments
791                 * the spline actually runs through.
792                 */
793                mid_pt_of_mid_segs[j-first_hinge_index-1].x =
794                      ((double)(vs[j].x + vs[j+1].x)) / ((double)2);
795                mid_pt_of_mid_segs[j-first_hinge_index-1].y =
796                      ((double)(vs[j].y + vs[j+1].y)) / ((double)2);
797             }
798             dvs[0].x = (double)(vs[first_hinge_index].x);
799             dvs[0].y = (double)(vs[first_hinge_index].y);
800             dvs[1].x = (double)(vs[first_hinge_index+1].x);
801             dvs[1].y = (double)(vs[first_hinge_index+1].y);
802             dvs[2].x = mid_pt_of_mid_segs[0].x;
803             dvs[2].y = mid_pt_of_mid_segs[0].y;
804             SetRealVertex(vs_return, write_index++, dvs);
805             vs_return[write_index].x = round(dvs[2].x);
806             vs_return[write_index].y = round(dvs[2].y);
807             write_index++;
808 
809             for (j=first_hinge_index+2; j < last_hinge_index-1; j++) {
810                dvs[0].x = mid_pt_of_mid_segs[j-first_hinge_index-2].x;
811                dvs[0].y = mid_pt_of_mid_segs[j-first_hinge_index-2].y;
812                dvs[1].x = (double)(vs[j].x);
813                dvs[1].y = (double)(vs[j].y);
814                dvs[2].x = mid_pt_of_mid_segs[j-first_hinge_index-1].x;
815                dvs[2].y = mid_pt_of_mid_segs[j-first_hinge_index-1].y;
816                SetRealVertex(vs_return, write_index++, dvs);
817                vs_return[write_index].x = round(dvs[2].x);
818                vs_return[write_index].y = round(dvs[2].y);
819                write_index++;
820             }
821             dvs[0].x = mid_pt_of_mid_segs[j-2].x;
822             dvs[0].y = mid_pt_of_mid_segs[j-2].y;
823             dvs[1].x = (double)(vs[last_hinge_index-1].x);
824             dvs[1].y = (double)(vs[last_hinge_index-1].y);
825             dvs[2].x = (double)(vs[last_hinge_index].x);
826             dvs[2].y = (double)(vs[last_hinge_index].y);
827             SetRealVertex(vs_return, write_index++, dvs);
828 
829             free(mid_pt_of_mid_segs);
830          } else {
831             dvs[0].x = (double)(vs[first_hinge_index].x);
832             dvs[0].y = (double)(vs[first_hinge_index].y);
833             dvs[1].x = (double)(vs[first_hinge_index+1].x);
834             dvs[1].y = (double)(vs[first_hinge_index+1].y);
835             dvs[2].x = (double)(vs[first_hinge_index+2].x);
836             dvs[2].y = (double)(vs[first_hinge_index+2].y);
837             SetRealVertex(vs_return, write_index++, dvs);
838          }
839          i = last_hinge_index;
840       } else {
841          vs_return[write_index].x = vs[i].x;
842          vs_return[write_index].y = vs[i].y;
843          first_hinge_index = i;
844          i++;
845          write_index++;
846       }
847    }
848    *pn_return = write_index;
849 
850    return vs_return;
851 }
852 
853 static
GetHingedPolygonTickMarkVs(pn_return,n,vs,smooth,first_hinge_index)854 IntPoint *GetHingedPolygonTickMarkVs(pn_return, n, vs, smooth,
855       first_hinge_index)
856    int *pn_return, n, first_hinge_index;
857    IntPoint *vs;
858    char *smooth;
859 {
860    int i=0, j=0;
861    IntPoint *tmp_vs=NULL;
862    char *tmp_smooth=NULL;
863    IntPoint *vs_return=NULL;
864 
865    if (first_hinge_index == 0) {
866       return GetSplinePolyTickMarkVs(pn_return, n-1, vs, smooth);
867    }
868    tmp_vs = (IntPoint*)malloc(n*sizeof(IntPoint));
869    if (tmp_vs == NULL) FailAllocMessage();
870    memset(tmp_vs, 0, n*sizeof(IntPoint));
871 
872    tmp_smooth = (char*)malloc(n*sizeof(char));
873    if (tmp_smooth == NULL) FailAllocMessage();
874    memset(tmp_smooth, 0, n*sizeof(char));
875 
876    i = first_hinge_index;
877    for (j=0; i < n-1; j++, i++) {
878       tmp_vs[j].x = vs[i].x;
879       tmp_vs[j].y = vs[i].y;
880       tmp_smooth[j] = smooth[i];
881    }
882    for (i=0; j < n; j++, i++) {
883       tmp_vs[j].x = vs[i].x;
884       tmp_vs[j].y = vs[i].y;
885       tmp_smooth[j] = smooth[i];
886    }
887    vs_return =  GetSplinePolyTickMarkVs(pn_return, n-1, tmp_vs,
888          tmp_smooth);
889    free(tmp_vs);
890 
891    return vs_return;
892 }
893 
894 static
GetSplinePolygonTickMarkVs(pn_return,n,vs,smooth)895 IntPoint *GetSplinePolygonTickMarkVs(pn_return, n, vs, smooth)
896    int *pn_return, n;
897    IntPoint *vs;
898    char *smooth;
899 {
900    int i=0, write_index=0;
901    IntPoint *vs_return=NULL;
902    DoublePoint *mid_pt_of_mid_segs=NULL, dvs[3];
903 
904    for (i=0; i < n; i++) {
905       if (!smooth[i]) {
906          return GetHingedPolygonTickMarkVs(pn_return, n, vs, smooth, i);
907       }
908    }
909    /* every control point is smooth */
910    vs_return = (IntPoint*)malloc(((n<<1)-1)*sizeof(IntPoint));
911    if (vs_return == NULL) FailAllocMessage();
912    memset(vs_return, 0, ((n<<1)-1)*sizeof(IntPoint));
913 
914    write_index = 0;
915 
916    mid_pt_of_mid_segs =
917          (DoublePoint*)malloc((n-1)*sizeof(DoublePoint));
918    if (mid_pt_of_mid_segs == NULL) FailAllocMessage();
919    memset(mid_pt_of_mid_segs, 0, (n-1)*sizeof(DoublePoint));
920 
921    for (i=0; i < n-1; i++) {
922       /*
923        * These are the midpoints of imaginary line segments
924        * the spline actually runs through.
925        */
926       mid_pt_of_mid_segs[i].x = ((double)(vs[i].x + vs[i+1].x)) / ((double)2);
927       mid_pt_of_mid_segs[i].y = ((double)(vs[i].y + vs[i+1].y)) / ((double)2);
928    }
929    for (i=0; i < n-1; i++) {
930       if (i == 0) {
931          dvs[0].x = mid_pt_of_mid_segs[n-2].x;
932          dvs[0].y = mid_pt_of_mid_segs[n-2].y;
933       } else {
934          dvs[0].x = mid_pt_of_mid_segs[i-1].x;
935          dvs[0].y = mid_pt_of_mid_segs[i-1].y;
936       }
937       dvs[1].x = (double)(vs[i].x);
938       dvs[1].y = (double)(vs[i].y);
939       dvs[2].x = mid_pt_of_mid_segs[i].x;
940       dvs[2].y = mid_pt_of_mid_segs[i].y;
941 
942       SetRealVertex(vs_return, write_index++, dvs);
943       vs_return[write_index].x = round(dvs[2].x);
944       vs_return[write_index].y = round(dvs[2].y);
945       write_index++;
946    }
947    free(mid_pt_of_mid_segs);
948 
949    *pn_return = write_index;
950 
951    return vs_return;
952 }
953 
954 static
AddObjTickMarks(ObjPtr,nCmdId)955 int AddObjTickMarks(ObjPtr, nCmdId)
956    struct ObjRec *ObjPtr;
957    int nCmdId;
958 {
959    int n=0, vs_allocated=FALSE, num_cntrl_points=0, cntrl_vs_allocated=FALSE;
960    IntPoint *vs=NULL, *cntrl_vs=NULL;
961    char *smooth=NULL;
962    struct PolyRec *poly_ptr=NULL;
963    struct PolygonRec *polygon_ptr=NULL;
964 
965    cntrl_vs = GetPolyOrPolygonAbsVs(&num_cntrl_points, &cntrl_vs_allocated,
966          ObjPtr);
967    switch (ObjPtr->type) {
968    case OBJ_POLY:
969       poly_ptr = ObjPtr->detail.p;
970       smooth = poly_ptr->smooth;
971       switch (poly_ptr->curved) {
972       case LT_STRAIGHT:
973          n = num_cntrl_points;
974          vs = cntrl_vs;
975          break;
976       case LT_SPLINE:
977          vs = GetSplinePolyTickMarkVs(&n, num_cntrl_points, cntrl_vs, smooth);
978          vs_allocated = TRUE;
979          break;
980       case LT_INTSPLINE:
981          n = num_cntrl_points;
982          vs = cntrl_vs;
983          break;
984       case LT_STRUCT_SPLINE:
985          vs = GetStructuredSplinePolyTickMarkVs(&n, ObjPtr, poly_ptr, NULL);
986          vs_allocated = TRUE;
987          break;
988       }
989       break;
990    case OBJ_POLYGON:
991       polygon_ptr = ObjPtr->detail.g;
992       smooth = polygon_ptr->smooth;
993       switch (polygon_ptr->curved) {
994       case LT_STRAIGHT:
995          n = num_cntrl_points-1;
996          vs = cntrl_vs;
997          break;
998       case LT_SPLINE:
999          vs = GetSplinePolygonTickMarkVs(&n, num_cntrl_points, cntrl_vs,
1000                smooth);
1001          vs_allocated = TRUE;
1002          break;
1003       case LT_INTSPLINE:
1004          n = num_cntrl_points-1;
1005          vs = cntrl_vs;
1006          break;
1007       case LT_STRUCT_SPLINE:
1008          vs = GetStructuredSplinePolyTickMarkVs(&n, ObjPtr, NULL, polygon_ptr);
1009          vs_allocated = TRUE;
1010          break;
1011       }
1012       break;
1013    }
1014    CreateTickMarks(n, vs, nCmdId);
1015 
1016    if (vs_allocated) free(vs);
1017    if (cntrl_vs_allocated) free(cntrl_vs);
1018 
1019    return TRUE;
1020 }
1021 
AddTickMarks(nCmdId)1022 void AddTickMarks(nCmdId)
1023    int nCmdId;
1024 {
1025    struct SelRec *sel_ptr=NULL;
1026    struct ObjRec *saved_top_obj=topObj, *saved_bot_obj=botObj;
1027    int changed=FALSE;
1028 
1029    if (topSel == NULL) {
1030       MsgBox(TgLoadString(STID_NO_POLY_ETC_SELECTED), TOOL_NAME, INFO_MB);
1031       return;
1032    }
1033    StartCreateTickMarks(nCmdId);
1034    HighLightReverse();
1035    curPage->top = curPage->bot = topObj = botObj = NULL;
1036    for (sel_ptr=botSel; sel_ptr != NULL; sel_ptr=sel_ptr->prev) {
1037       struct ObjRec *obj_ptr=sel_ptr->obj;
1038 
1039       if (obj_ptr->type == OBJ_POLY || obj_ptr->type == OBJ_POLYGON) {
1040          AddObjTickMarks(sel_ptr->obj, nCmdId);
1041       }
1042    }
1043    EndCreateTickMarks();
1044 
1045    if (topObj != NULL) {
1046       struct ObjRec *obj_ptr=NULL, *new_bot_obj=botObj, *prev_obj=NULL;
1047 
1048       changed = TRUE;
1049       RemoveAllSel();
1050       curPage->top = topObj = saved_top_obj;
1051       curPage->bot = botObj = saved_bot_obj;
1052       StartCompositeCmd();
1053       for (obj_ptr=new_bot_obj; obj_ptr != NULL; obj_ptr=prev_obj) {
1054          prev_obj = obj_ptr->prev;
1055          AddObj(NULL, topObj, obj_ptr);
1056          RecordNewObjCmd();
1057       }
1058       EndCompositeCmd();
1059 
1060       for (obj_ptr=saved_top_obj->prev; obj_ptr != NULL; obj_ptr=prev_obj) {
1061          prev_obj = obj_ptr->prev;
1062          AddObjIntoSel(obj_ptr, NULL, topSel, &topSel, &botSel);
1063       }
1064    } else {
1065       curPage->top = topObj = saved_top_obj;
1066       curPage->bot = botObj = saved_bot_obj;
1067    }
1068    if (changed) {
1069       SetFileModified(TRUE);
1070       UpdSelBBox();
1071       RedrawAnArea(botObj, selLtX-GRID_ABS_SIZE(1), selLtY-GRID_ABS_SIZE(1),
1072             selRbX+GRID_ABS_SIZE(1), selRbY+GRID_ABS_SIZE(1));
1073       justDupped = FALSE;
1074    } else {
1075       HighLightForward();
1076       MsgBox(TgLoadString(STID_NO_POLY_ETC_SELECTED), TOOL_NAME, INFO_MB);
1077       return;
1078    }
1079    HighLightForward();
1080 }
1081 
SetTickMarkSizeValue(spec)1082 int SetTickMarkSizeValue(spec)
1083    char *spec;
1084 {
1085    int ival=0;
1086 
1087    if (sscanf(spec, "%d", &ival) != 1) {
1088       sprintf(gszMsgBox, TgLoadCachedString(CSTID_MALFORMED_INPUT_STR), spec);
1089       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1090       return FALSE;
1091    } else if (ival < 2) {
1092       sprintf(gszMsgBox, TgLoadString(STID_ENT_VAL_RANGE_ENTER_GE_INT),
1093             spec, 3);
1094       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1095       return FALSE;
1096    }
1097    tickMarkSize = ival;
1098 
1099    return TRUE;
1100 }
1101 
SetTickMarkSize(psz_num_segs)1102 void SetTickMarkSize(psz_num_segs)
1103    char *psz_num_segs;
1104 {
1105    char spec[MAXSTRING+1];
1106 
1107    *spec = '\0';
1108    if (psz_num_segs != NULL && strcmp(psz_num_segs, "-1") != 0) {
1109       UtilStrCpyN(spec, sizeof(spec), psz_num_segs);
1110    } else {
1111       sprintf(gszMsgBox, TgLoadString(STID_ENTER_TICK_MARK_SIZE_CUR_IS),
1112             tickMarkSize);
1113       if (Dialog(gszMsgBox, NULL, spec) == INVALID) return;
1114    }
1115    UtilTrimBlanks(spec);
1116    if (*spec == '\0') return;
1117 
1118    if (SetTickMarkSizeValue(spec)) {
1119       sprintf(gszMsgBox, TgLoadString(STID_TICK_MARK_SIZE_SET_TO_INT),
1120             tickMarkSize);
1121       Msg(gszMsgBox);
1122    }
1123 }
1124