1 /*
2  * $Id: oaxis.c,v 1.10 2002/07/06 08:51:42 isizaka Exp isizaka $
3  *
4  * This file is part of "Ngraph for X11".
5  *
6  * Copyright (C) 2002, Satoshi ISHIZAKA. isizaka@msa.biglobe.ne.jp
7  *
8  * "Ngraph for X11" is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * "Ngraph for X11" is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  */
23 
24 /**
25  *
26  * $Log: oaxis.c,v $
27  * Revision 1.10  2002/07/06 08:51:42  isizaka
28  * change to GPL.
29  *
30  * Revision 1.9  2001/03/23 12:15:31  isizaka
31  * for 6.3.13
32  *
33  * Revision 1.8  2000/10/28 14:46:43  isizaka
34  * axisautoscale(): inc is preserved if it is set.
35  *
36  * Revision 1.7  1999/10/15 16:32:12  isizaka
37  * add 'numformat' for "+/-0".
38  *
39  * Revision 1.6  1999/04/15 12:15:27  isizaka
40  * for release 6.03.01
41  *
42  * Revision 1.5  1999/04/11 06:08:10  isizaka
43  * *** empty log message ***
44  *
45  * Revision 1.4  1999/03/21 13:47:52  isizaka
46  * add 'axidloadconfig'
47  *
48  * Revision 1.3  1999/03/21 12:22:38  isizaka
49  * add 'default_grouping' and 'group_position'
50  *
51  * Revision 1.1  1999/03/17 13:46:09  isizaka
52  * Initial revision
53  *
54  *
55  **/
56 
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include <stdarg.h>
60 #include <math.h>
61 #include <string.h>
62 #include <ctype.h>
63 #include "ngraph.h"
64 #include "object.h"
65 #include "mathfn.h"
66 #include "spline.h"
67 #include "gra.h"
68 #include "oroot.h"
69 #include "odraw.h"
70 #include "olegend.h"
71 #include "axis.h"
72 #include "nstring.h"
73 #include "config.h"
74 
75 #define NAME "axis"
76 #define PARENT "draw"
77 #define VERSION  "1.00.00"
78 #define TRUE  1
79 #define FALSE 0
80 
81 #define ERRNUM 6
82 
83 #define ERRAXISTYPE 100
84 #define ERRAXISHEAD 101
85 #define ERRAXISGAUGE 102
86 #define ERRAXISSPL 103
87 #define ERRMINMAX 104
88 #define ERRFORMAT 105
89 
90 char *axiserrorlist[ERRNUM]={
91   "illegal axis type.",
92   "illegal arrow/wave type.",
93   "illegal gauge type.",
94   "error: spline interpolation.",
95   "illegal value of min/max/inc.",
96   "illegal format.",
97 };
98 
99 char *axistypechar[4]={
100   "linear",
101   "log",
102   "inverse",
103   NULL
104 };
105 
106 char *axisgaugechar[5]={
107   "none",
108   "both",
109   "left",
110   "right",
111   NULL
112 };
113 
114 char *axisnumchar[4]={
115   "none",
116   "left",
117   "right",
118   NULL
119 };
120 
121 char *anumalignchar[5]={
122   "center",
123   "left",
124   "right",
125   "point",
126   NULL
127 };
128 
129 char *anumdirchar[4]={
130   "normal",
131   "parallel",
132   "parallel2",
133   NULL
134 };
135 
axisuniqgroup(struct objlist * obj,char type)136 int axisuniqgroup(struct objlist *obj,char type)
137 {
138   int num;
139   char *inst,*group,*endptr;
140   int nextp;
141 
142   nextp=obj->nextp;
143   num=0;
144   do {
145     num++;
146     inst=obj->root;
147     while (inst!=NULL) {
148       _getobj(obj,"group",inst,&group);
149       if ((group!=NULL) && (group[0]==type)) {
150         if (num==strtol(group+2,&endptr,10)) break;
151       }
152       inst=*(char **)(inst+nextp);
153     }
154     if (inst==NULL) {
155       inst=obj->root2;
156       while (inst!=NULL) {
157         _getobj(obj,"group",inst,&group);
158         if ((group!=NULL) && (group[0]==type)) {
159           if (num==strtol(group+2,&endptr,10)) break;
160         }
161         inst=*(char **)(inst+nextp);
162       }
163     }
164   } while (inst!=NULL);
165   return num;
166 }
167 
axisloadconfig(struct objlist * obj,char * inst,char * conf)168 int axisloadconfig(struct objlist *obj,char *inst,char *conf)
169 {
170   FILE *fp;
171   char *tok,*str,*s2;
172   char *f1,*f2;
173   int val;
174   char *endptr;
175   int len;
176   struct narray *iarray;
177 
178   if ((fp=openconfig(conf))==NULL) return 0;
179   while ((tok=getconfig(fp,&str))!=NULL) {
180     s2=str;
181     if (strcmp(tok,"R")==0) {
182       f1=getitok2(&s2,&len," \t,");
183       val=strtol(f1,&endptr,10);
184       if (endptr[0]=='\0') _putobj(obj,"R",inst,&val);
185       memfree(f1);
186     } else if (strcmp(tok,"G")==0) {
187       f1=getitok2(&s2,&len," \t,");
188       val=strtol(f1,&endptr,10);
189       if (endptr[0]=='\0') _putobj(obj,"G",inst,&val);
190       memfree(f1);
191     } else if (strcmp(tok,"B")==0) {
192       f1=getitok2(&s2,&len," \t,");
193       val=strtol(f1,&endptr,10);
194       if (endptr[0]=='\0') _putobj(obj,"B",inst,&val);
195       memfree(f1);
196     } else if (strcmp(tok,"type")==0) {
197       f1=getitok2(&s2,&len," \t,");
198       val=strtol(f1,&endptr,10);
199       if (endptr[0]=='\0') _putobj(obj,"type",inst,&val);
200       memfree(f1);
201     } else if (strcmp(tok,"direction")==0) {
202       f1=getitok2(&s2,&len," \t,");
203       val=strtol(f1,&endptr,10);
204       if (endptr[0]=='\0') _putobj(obj,"direction",inst,&val);
205       memfree(f1);
206     } else if (strcmp(tok,"baseline")==0) {
207       f1=getitok2(&s2,&len," \t,");
208       val=strtol(f1,&endptr,10);
209       if (endptr[0]=='\0') _putobj(obj,"baseline",inst,&val);
210       memfree(f1);
211     } else if (strcmp(tok,"width")==0) {
212       f1=getitok2(&s2,&len," \t,");
213       val=strtol(f1,&endptr,10);
214       if (endptr[0]=='\0') _putobj(obj,"width",inst,&val);
215       memfree(f1);
216     } else if (strcmp(tok,"arrow")==0) {
217       f1=getitok2(&s2,&len," \t,");
218       val=strtol(f1,&endptr,10);
219       if (endptr[0]=='\0') _putobj(obj,"arrow",inst,&val);
220       memfree(f1);
221     } else if (strcmp(tok,"arrow_length")==0) {
222       f1=getitok2(&s2,&len," \t,");
223       val=strtol(f1,&endptr,10);
224       if (endptr[0]=='\0') _putobj(obj,"arrow_length",inst,&val);
225       memfree(f1);
226     } else if (strcmp(tok,"wave")==0) {
227       f1=getitok2(&s2,&len," \t,");
228       val=strtol(f1,&endptr,10);
229       if (endptr[0]=='\0') _putobj(obj,"wave",inst,&val);
230       memfree(f1);
231     } else if (strcmp(tok,"wave_length")==0) {
232       f1=getitok2(&s2,&len," \t,");
233       val=strtol(f1,&endptr,10);
234       if (endptr[0]=='\0') _putobj(obj,"wave_length",inst,&val);
235       memfree(f1);
236     } else if (strcmp(tok,"wave_width")==0) {
237       f1=getitok2(&s2,&len," \t,");
238       val=strtol(f1,&endptr,10);
239       if (endptr[0]=='\0') _putobj(obj,"wave_width",inst,&val);
240       memfree(f1);
241     } else if (strcmp(tok,"gauge")==0) {
242       f1=getitok2(&s2,&len," \t,");
243       val=strtol(f1,&endptr,10);
244       if (endptr[0]=='\0') _putobj(obj,"gauge",inst,&val);
245       memfree(f1);
246     } else if (strcmp(tok,"gauge_length1")==0) {
247       f1=getitok2(&s2,&len," \t,");
248       val=strtol(f1,&endptr,10);
249       if (endptr[0]=='\0') _putobj(obj,"gauge_length1",inst,&val);
250       memfree(f1);
251     } else if (strcmp(tok,"gauge_width1")==0) {
252       f1=getitok2(&s2,&len," \t,");
253       val=strtol(f1,&endptr,10);
254       if (endptr[0]=='\0') _putobj(obj,"gauge_width1",inst,&val);
255       memfree(f1);
256     } else if (strcmp(tok,"gauge_length2")==0) {
257       f1=getitok2(&s2,&len," \t,");
258       val=strtol(f1,&endptr,10);
259       if (endptr[0]=='\0') _putobj(obj,"gauge_length2",inst,&val);
260       memfree(f1);
261     } else if (strcmp(tok,"gauge_width2")==0) {
262       f1=getitok2(&s2,&len," \t,");
263       val=strtol(f1,&endptr,10);
264       if (endptr[0]=='\0') _putobj(obj,"gauge_width2",inst,&val);
265       memfree(f1);
266     } else if (strcmp(tok,"gauge_length3")==0) {
267       f1=getitok2(&s2,&len," \t,");
268       val=strtol(f1,&endptr,10);
269       if (endptr[0]=='\0') _putobj(obj,"gauge_length3",inst,&val);
270       memfree(f1);
271     } else if (strcmp(tok,"gauge_width3")==0) {
272       f1=getitok2(&s2,&len," \t,");
273       val=strtol(f1,&endptr,10);
274       if (endptr[0]=='\0') _putobj(obj,"gauge_width3",inst,&val);
275       memfree(f1);
276     } else if (strcmp(tok,"gauge_R")==0) {
277       f1=getitok2(&s2,&len," \t,");
278       val=strtol(f1,&endptr,10);
279       if (endptr[0]=='\0') _putobj(obj,"gauge_R",inst,&val);
280       memfree(f1);
281     } else if (strcmp(tok,"gauge_G")==0) {
282       f1=getitok2(&s2,&len," \t,");
283       val=strtol(f1,&endptr,10);
284       if (endptr[0]=='\0') _putobj(obj,"gauge_G",inst,&val);
285       memfree(f1);
286     } else if (strcmp(tok,"gauge_B")==0) {
287       f1=getitok2(&s2,&len," \t,");
288       val=strtol(f1,&endptr,10);
289       if (endptr[0]=='\0') _putobj(obj,"gauge_B",inst,&val);
290       memfree(f1);
291     } else if (strcmp(tok,"num")==0) {
292       f1=getitok2(&s2,&len," \t,");
293       val=strtol(f1,&endptr,10);
294       if (endptr[0]=='\0') _putobj(obj,"num",inst,&val);
295       memfree(f1);
296     } else if (strcmp(tok,"num_auto_norm")==0) {
297       f1=getitok2(&s2,&len," \t,");
298       val=strtol(f1,&endptr,10);
299       if (endptr[0]=='\0') _putobj(obj,"num_auto_norm",inst,&val);
300       memfree(f1);
301     } else if (strcmp(tok,"num_log_pow")==0) {
302       f1=getitok2(&s2,&len," \t,");
303       val=strtol(f1,&endptr,10);
304       if (endptr[0]=='\0') _putobj(obj,"num_log_pow",inst,&val);
305       memfree(f1);
306     } else if (strcmp(tok,"num_pt")==0) {
307       f1=getitok2(&s2,&len," \t,");
308       val=strtol(f1,&endptr,10);
309       if (endptr[0]=='\0') _putobj(obj,"num_pt",inst,&val);
310       memfree(f1);
311     } else if (strcmp(tok,"num_space")==0) {
312       f1=getitok2(&s2,&len," \t,");
313       val=strtol(f1,&endptr,10);
314       if (endptr[0]=='\0') _putobj(obj,"num_space",inst,&val);
315       memfree(f1);
316     } else if (strcmp(tok,"num_script_size")==0) {
317       f1=getitok2(&s2,&len," \t,");
318       val=strtol(f1,&endptr,10);
319       if (endptr[0]=='\0') _putobj(obj,"num_script_size",inst,&val);
320       memfree(f1);
321     } else if (strcmp(tok,"num_align")==0) {
322       f1=getitok2(&s2,&len," \t,");
323       val=strtol(f1,&endptr,10);
324       if (endptr[0]=='\0') _putobj(obj,"num_align",inst,&val);
325       memfree(f1);
326     } else if (strcmp(tok,"num_no_zero")==0) {
327       f1=getitok2(&s2,&len," \t,");
328       val=strtol(f1,&endptr,10);
329       if (endptr[0]=='\0') _putobj(obj,"num_no_zero",inst,&val);
330       memfree(f1);
331     } else if (strcmp(tok,"num_direction")==0) {
332       f1=getitok2(&s2,&len," \t,");
333       val=strtol(f1,&endptr,10);
334       if (endptr[0]=='\0') _putobj(obj,"num_direction",inst,&val);
335       memfree(f1);
336     } else if (strcmp(tok,"num_shift_p")==0) {
337       f1=getitok2(&s2,&len," \t,");
338       val=strtol(f1,&endptr,10);
339       if (endptr[0]=='\0') _putobj(obj,"num_shift_p",inst,&val);
340       memfree(f1);
341     } else if (strcmp(tok,"num_shift_n")==0) {
342       f1=getitok2(&s2,&len," \t,");
343       val=strtol(f1,&endptr,10);
344       if (endptr[0]=='\0') _putobj(obj,"num_shift_n",inst,&val);
345       memfree(f1);
346     } else if (strcmp(tok,"num_R")==0) {
347       f1=getitok2(&s2,&len," \t,");
348       val=strtol(f1,&endptr,10);
349       if (endptr[0]=='\0') _putobj(obj,"num_R",inst,&val);
350       memfree(f1);
351     } else if (strcmp(tok,"num_G")==0) {
352       f1=getitok2(&s2,&len," \t,");
353       val=strtol(f1,&endptr,10);
354       if (endptr[0]=='\0') _putobj(obj,"num_G",inst,&val);
355       memfree(f1);
356     } else if (strcmp(tok,"num_B")==0) {
357       f1=getitok2(&s2,&len," \t,");
358       val=strtol(f1,&endptr,10);
359       if (endptr[0]=='\0') _putobj(obj,"num_B",inst,&val);
360       memfree(f1);
361     } else if (strcmp(tok,"num_head")==0) {
362       f1=getitok2(&s2,&len,"");
363       _getobj(obj,"num_head",inst,&f2);
364       memfree(f2);
365       _putobj(obj,"num_head",inst,f1);
366     } else if (strcmp(tok,"num_format")==0) {
367       f1=getitok2(&s2,&len,"");
368       _getobj(obj,"num_format",inst,&f2);
369       memfree(f2);
370       _putobj(obj,"num_format",inst,f1);
371     } else if (strcmp(tok,"num_tail")==0) {
372       f1=getitok2(&s2,&len,"");
373       _getobj(obj,"num_tail",inst,&f2);
374       memfree(f2);
375       _putobj(obj,"num_tail",inst,f1);
376     } else if (strcmp(tok,"num_font")==0) {
377       f1=getitok2(&s2,&len,"");
378       _getobj(obj,"num_font",inst,&f2);
379       memfree(f2);
380       _putobj(obj,"num_font",inst,f1);
381     } else if (strcmp(tok,"num_jfont")==0) {
382       f1=getitok2(&s2,&len,"");
383       _getobj(obj,"num_jfont",inst,&f2);
384       memfree(f2);
385       _putobj(obj,"num_jfont",inst,f1);
386     } else if (strcmp(tok,"style")==0) {
387       if ((iarray=arraynew(sizeof(int)))!=NULL) {
388         while ((f1=getitok2(&s2,&len," \t,"))!=NULL) {
389           val=strtol(f1,&endptr,10);
390           if (endptr[0]=='\0') arrayadd(iarray,&val);
391           memfree(f1);
392         }
393         _putobj(obj,"style",inst,iarray);
394       }
395     } else if (strcmp(tok,"gauge_style")==0) {
396       if ((iarray=arraynew(sizeof(int)))!=NULL) {
397         while ((f1=getitok2(&s2,&len," \t,"))!=NULL) {
398           val=strtol(f1,&endptr,10);
399           if (endptr[0]=='\0') arrayadd(iarray,&val);
400           memfree(f1);
401         }
402         _putobj(obj,"gauge_style",inst,iarray);
403       }
404     }
405     memfree(tok);
406     memfree(str);
407   }
408   closeconfig(fp);
409   return 0;
410 }
411 
axisinit(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)412 int axisinit(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
413 {
414   int width;
415   int alen,awid,wlen,wwid;
416   int bline;
417   int len1,wid1,len2,wid2,len3,wid3;
418   int pt,sx,sy,logpow,scriptsize;
419   int autonorm,num,gnum;
420   char *font,*jfont,*format,*group,*name;
421 
422   if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
423   width=40;
424   alen=72426;
425   awid=60000;
426   wlen=300;
427   wwid=40;
428   len1=100;
429   wid1=40;
430   len2=200;
431   wid2=40;
432   len3=300;
433   wid3=40;
434   bline=TRUE;
435   pt=2000;
436   sx=0;
437   sy=100;
438   autonorm=5;
439   logpow=TRUE;
440   scriptsize=7000;
441   num=-1;
442   if (_putobj(obj,"baseline",inst,&bline)) return 1;
443   if (_putobj(obj,"width",inst,&width)) return 1;
444   if (_putobj(obj,"arrow_length",inst,&alen)) return 1;
445   if (_putobj(obj,"arrow_width",inst,&awid)) return 1;
446   if (_putobj(obj,"wave_length",inst,&wlen)) return 1;
447   if (_putobj(obj,"wave_width",inst,&wwid)) return 1;
448   if (_putobj(obj,"gauge_length1",inst,&len1)) return 1;
449   if (_putobj(obj,"gauge_width1",inst,&wid1)) return 1;
450   if (_putobj(obj,"gauge_length2",inst,&len2)) return 1;
451   if (_putobj(obj,"gauge_width2",inst,&wid2)) return 1;
452   if (_putobj(obj,"gauge_length3",inst,&len3)) return 1;
453   if (_putobj(obj,"gauge_width3",inst,&wid3)) return 1;
454   if (_putobj(obj,"num_pt",inst,&pt)) return 1;
455   if (_putobj(obj,"num_script_size",inst,&scriptsize)) return 1;
456   if (_putobj(obj,"num_auto_norm",inst,&autonorm)) return 1;
457   if (_putobj(obj,"num_shift_p",inst,&sx)) return 1;
458   if (_putobj(obj,"num_shift_n",inst,&sy)) return 1;
459   if (_putobj(obj,"num_log_pow",inst,&logpow)) return 1;
460   if (_putobj(obj,"num_num",inst,&num)) return 1;
461   format=font=jfont=group=name=NULL;
462   if ((format=memalloc(3))==NULL) goto errexit;
463   strcpy(format,"%g");
464   if (_putobj(obj,"num_format",inst,format)) goto errexit;
465   if ((font=memalloc(strlen(fontchar[4])+1))==NULL) goto errexit;
466   strcpy(font,fontchar[4]);
467   if (_putobj(obj,"num_font",inst,font)) goto errexit;
468   if ((jfont=memalloc(strlen(jfontchar[1])+1))==NULL) goto errexit;
469   strcpy(jfont,jfontchar[1]);
470   if (_putobj(obj,"num_jfont",inst,jfont)) goto errexit;
471   if ((group=memalloc(13))==NULL) goto errexit;
472   gnum=axisuniqgroup(obj,'a');
473   sprintf(group,"a_%d",gnum);
474   if (_putobj(obj,"group",inst,group)) goto errexit;
475   if ((name=memalloc(13))==NULL) goto errexit;
476   sprintf(name,"a_%d",gnum);
477   if (_putobj(obj,"name",inst,name)) goto errexit;
478   axisloadconfig(obj,inst,"[axis]");
479   return 0;
480 errexit:
481   memfree(format);
482   memfree(font);
483   memfree(jfont);
484   memfree(group);
485   memfree(name);
486   return 1;
487 }
488 
axisdone(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)489 int axisdone(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
490 {
491   if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
492   return 0;
493 }
494 
axisput(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)495 int axisput(struct objlist *obj,char *inst,char *rval,
496             int argc,char **argv)
497 {
498   char *field;
499   char *format;
500   int sharp,minus,plus;
501   int i,j;
502 
503   field=argv[1];
504   if (strcmp(field,"arrow_length")==0) {
505     if (*(int *)(argv[2])<10000) *(int *)(argv[2])=10000;
506     else if (*(int *)(argv[2])>200000) *(int *)(argv[2])=200000;
507   } else if (strcmp(field,"arrow_width")==0) {
508     if (*(int *)(argv[2])<10000) *(int *)(argv[2])=10000;
509     else if (*(int *)(argv[2])>200000) *(int *)(argv[2])=200000;
510   } else if ((strcmp(field,"wave_length")==0)
511           || (strcmp(field,"wave_width"))==0) {
512     if (*(int *)(argv[2])<1) *(int *)(argv[2])=1;
513   } else if (strcmp(field,"num_pt")==0) {
514     if (*(int *)(argv[2])<500) *(int *)(argv[2])=500;
515   } else if (strcmp(field,"num_script_size")==0) {
516     if (*(int *)(argv[2])<1000) *(int *)(argv[2])=1000;
517 	else if (*(int *)(argv[2])>100000) *(int *)(argv[2])=100000;
518   } else if (strcmp(field,"num_format")==0) {
519     format=(char *)(argv[2]);
520     if (format==NULL) {
521       error(obj,ERRFORMAT);
522       return 1;
523     }
524     if (format[0]!='%') {
525       error(obj,ERRFORMAT);
526       return 1;
527     }
528     sharp=minus=plus=FALSE;
529     for (i=1;(format[i]!='\0') && (strchr("#-+",format[i])!=NULL);i++) {
530       if (format[i]=='#') {
531         if (sharp) {
532           error(obj,ERRFORMAT);
533           return 1;
534         } else sharp=TRUE;
535       }
536       if (format[i]=='-') {
537         if (minus) {
538           error(obj,ERRFORMAT);
539           return 1;
540         } else minus=TRUE;
541       }
542       if (format[i]=='+') {
543         if (plus) {
544           error(obj,ERRFORMAT);
545           return 1;
546         } else plus=TRUE;
547       }
548     }
549     if (format[i]=='0') i++;
550     for (j=i;isdigit(format[i]);i++) ;
551     if (j-i>2) {
552       error(obj,ERRFORMAT);
553       return 1;
554     }
555     if (format[i]=='.') {
556       i++;
557       for (j=i;isdigit(format[i]);i++) ;
558       if ((j-i>2) || (j==i)) {
559         error(obj,ERRFORMAT);
560         return 1;
561       }
562     }
563     if (format[i]=='\0') {
564       error(obj,ERRFORMAT);
565       return 1;
566     }
567     if (strchr("efgEG",format[i])==NULL) {
568       error(obj,ERRFORMAT);
569       return 1;
570     }
571     if (format[i+1]!='\0') {
572       error(obj,ERRFORMAT);
573       return 1;
574     }
575   } else if (strcmp(field,"num_num")==0) {
576     if (*(int *)(argv[2])<-1) *(int *)(argv[2])=-1;
577   }
578   return 0;
579 }
580 
axisgeometry(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)581 int axisgeometry(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
582 {
583   struct narray *array;
584 
585   _getobj(obj,"bbox",inst,&array);
586   arrayfree(array);
587   if (_putobj(obj,"bbox",inst,NULL)) return 1;
588   return 0;
589 }
590 
591 
axisbbox2(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)592 int axisbbox2(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
593 {
594   int minx,miny,maxx,maxy;
595   int x0,y0,x1,y1,length,direction;
596   double dir;
597   struct narray *array;
598 
599   array=*(struct narray **)rval;
600   if (arraynum(array)!=0) return 0;
601   _getobj(obj,"x",inst,&x0);
602   _getobj(obj,"y",inst,&y0);
603   _getobj(obj,"length",inst,&length);
604   _getobj(obj,"direction",inst,&direction);
605   if ((array==NULL) && ((array=arraynew(sizeof(int)))==NULL)) return 1;
606   dir=direction/18000.0*MPI;
607   x1=x0+nround(length*cos(dir));
608   y1=y0-nround(length*sin(dir));
609   maxx=minx=x0;
610   maxy=miny=y0;
611   arrayadd(array,&x0);
612   arrayadd(array,&y0);
613   arrayadd(array,&x1);
614   arrayadd(array,&y1);
615   if (x1<minx) minx=x1;
616   if (x1>maxx) maxx=x1;
617   if (y1<miny) miny=y1;
618   if (y1>maxy) maxy=y1;
619   arrayins(array,&(maxy),0);
620   arrayins(array,&(maxx),0);
621   arrayins(array,&(miny),0);
622   arrayins(array,&(minx),0);
623   if (arraynum(array)==0) {
624     arrayfree(array);
625     return 1;
626   }
627   *(struct narray **)rval=array;
628   return 0;
629 }
630 
axisbbox(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)631 int axisbbox(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
632 {
633   int i,id;
634   char *group,*group2;
635   char type;
636   int findX,findY,findU,findR;
637   char *inst2;
638   char *instX,*instY,*instU,*instR;
639   struct narray *rval2,*array;
640   int minx,miny,maxx,maxy;
641   int x0,y0,x1,y1;
642 
643   array=*(struct narray **)rval;
644   if (arraynum(array)!=0) return 0;
645   _getobj(obj,"group",inst,&group);
646   if ((group==NULL) || (group[0]=='a'))
647     return axisbbox2(obj,inst,rval,argc,argv);
648   _getobj(obj,"id",inst,&id);
649   findX=findY=findU=findR=FALSE;
650   type=group[0];
651   for (i=0;i<=id;i++) {
652     inst2=chkobjinst(obj,i);
653     _getobj(obj,"group",inst2,&group2);
654     if ((group2!=NULL) && (group2[0]==type)) {
655       if (strcmp(group+2,group2+2)==0) {
656         if (group2[1]=='X') {
657           findX=TRUE;
658           instX=inst2;
659         } else if (group2[1]=='Y') {
660           findY=TRUE;
661           instY=inst2;
662         } else if (group2[1]=='U') {
663           findU=TRUE;
664           instU=inst2;
665         } else if (group2[1]=='R') {
666           findR=TRUE;
667           instR=inst2;
668         }
669       }
670     }
671   }
672   if (((type=='f') || (type=='s')) && findX && findY && findU && findR) {
673     rval2=NULL;
674     axisbbox2(obj,instX,(void *)&rval2,argc,argv);
675     minx=*(int *)arraynget(rval2,0);
676     miny=*(int *)arraynget(rval2,1);
677     maxx=*(int *)arraynget(rval2,2);
678     maxy=*(int *)arraynget(rval2,3);
679     arrayfree(rval2);
680     rval2=NULL;
681     axisbbox2(obj,instY,(void *)&rval2,argc,argv);
682     x0=*(int *)arraynget(rval2,0);
683     y0=*(int *)arraynget(rval2,1);
684     x1=*(int *)arraynget(rval2,2);
685     y1=*(int *)arraynget(rval2,3);
686     if (x0<minx) minx=x0;
687     if (y0<miny) miny=y0;
688     if (x1>maxx) maxx=x1;
689     if (y1>maxy) maxy=y1;
690     arrayfree(rval2);
691     rval2=NULL;
692     axisbbox2(obj,instU,(void *)&rval2,argc,argv);
693     x0=*(int *)arraynget(rval2,0);
694     y0=*(int *)arraynget(rval2,1);
695     x1=*(int *)arraynget(rval2,2);
696     y1=*(int *)arraynget(rval2,3);
697     if (x0<minx) minx=x0;
698     if (y0<miny) miny=y0;
699     if (x1>maxx) maxx=x1;
700     if (y1>maxy) maxy=y1;
701     arrayfree(rval2);
702     rval2=NULL;
703     axisbbox2(obj,instR,(void *)&rval2,argc,argv);
704     x0=*(int *)arraynget(rval2,0);
705     y0=*(int *)arraynget(rval2,1);
706     x1=*(int *)arraynget(rval2,2);
707     y1=*(int *)arraynget(rval2,3);
708     if (x0<minx) minx=x0;
709     if (y0<miny) miny=y0;
710     if (x1>maxx) maxx=x1;
711     if (y1>maxy) maxy=y1;
712     arrayfree(rval2);
713     if ((array==NULL) && ((array=arraynew(sizeof(int)))==NULL)) return 1;
714     arrayadd(array,&minx);
715     arrayadd(array,&miny);
716     arrayadd(array,&maxx);
717     arrayadd(array,&maxy);
718     arrayadd(array,&minx);
719     arrayadd(array,&miny);
720     arrayadd(array,&maxx);
721     arrayadd(array,&miny);
722     arrayadd(array,&maxx);
723     arrayadd(array,&maxy);
724     arrayadd(array,&minx);
725     arrayadd(array,&maxy);
726     if (arraynum(array)==0) {
727       arrayfree(array);
728       return 1;
729     }
730     *(struct narray **)rval=array;
731   } else if ((type=='c') && findX && findY) {
732     rval2=NULL;
733     axisbbox2(obj,instX,(void *)&rval2,argc,argv);
734     minx=*(int *)arraynget(rval2,0);
735     miny=*(int *)arraynget(rval2,1);
736     maxx=*(int *)arraynget(rval2,2);
737     maxy=*(int *)arraynget(rval2,3);
738     arrayfree(rval2);
739     rval2=NULL;
740     axisbbox2(obj,instY,(void *)&rval2,argc,argv);
741     x0=*(int *)arraynget(rval2,0);
742     y0=*(int *)arraynget(rval2,1);
743     x1=*(int *)arraynget(rval2,2);
744     y1=*(int *)arraynget(rval2,3);
745     if (x0<minx) minx=x0;
746     if (y0<miny) miny=y0;
747     if (x1>maxx) maxx=x1;
748     if (y1>maxy) maxy=y1;
749     arrayfree(rval2);
750     if ((array==NULL) && ((array=arraynew(sizeof(int)))==NULL)) return 1;
751     arrayadd(array,&minx);
752     arrayadd(array,&miny);
753     arrayadd(array,&maxx);
754     arrayadd(array,&maxy);
755     arrayadd(array,&minx);
756     arrayadd(array,&miny);
757     arrayadd(array,&maxx);
758     arrayadd(array,&miny);
759     arrayadd(array,&maxx);
760     arrayadd(array,&maxy);
761     arrayadd(array,&minx);
762     arrayadd(array,&maxy);
763     if (arraynum(array)==0) {
764       arrayfree(array);
765       return 1;
766     }
767     *(struct narray **)rval=array;
768   }
769   return 0;
770 }
771 
axismatch2(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)772 int axismatch2(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
773 {
774   int minx,miny,maxx,maxy,err;
775   int bminx,bminy,bmaxx,bmaxy;
776   int i,num,*data;
777   double x1,y1,x2,y2;
778   double r,r2,r3,ip;
779   struct narray *array;
780 
781   *(int *)rval=FALSE;
782   array=NULL;
783   axisbbox2(obj,inst,(void *)&array,argc,argv);
784   if (array==NULL) return 0;
785   minx=*(int *)argv[2];
786   miny=*(int *)argv[3];
787   maxx=*(int *)argv[4];
788   maxy=*(int *)argv[5];
789   err=*(int *)argv[6];
790   if ((minx==maxx) && (miny==maxy)) {
791     num=arraynum(array)-4;
792     data=arraydata(array);
793     for (i=0;i<num-2;i+=2) {
794       x1=data[4+i];
795       y1=data[5+i];
796       x2=data[6+i];
797       y2=data[7+i];
798       r2=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
799       r=sqrt((minx-x1)*(minx-x1)+(miny-y1)*(miny-y1));
800       r3=sqrt((minx-x2)*(minx-x2)+(miny-y2)*(miny-y2));
801       if ((r<=err) || (r3<err)) {
802         *(int *)rval=TRUE;
803         break;
804       }
805       if (r2!=0) {
806         ip=((x2-x1)*(minx-x1)+(y2-y1)*(miny-y1))/r2;
807         if ((0<=ip) && (ip<=r2)) {
808           x2=x1+(x2-x1)*ip/r2;
809           y2=y1+(y2-y1)*ip/r2;
810           r=sqrt((minx-x2)*(minx-x2)+(miny-y2)*(miny-y2));
811           if (r<err) {
812             *(int *)rval=TRUE;
813             break;
814           }
815         }
816       }
817     }
818   } else {
819     if (arraynum(array)<4) {
820       arrayfree(array);
821       return 1;
822     }
823     bminx=*(int *)arraynget(array,0);
824     bminy=*(int *)arraynget(array,1);
825     bmaxx=*(int *)arraynget(array,2);
826     bmaxy=*(int *)arraynget(array,3);
827     if ((minx<=bminx) && (bminx<=maxx)
828      && (minx<=bmaxx) && (bmaxx<=maxx)
829      && (miny<=bminy) && (bminy<=maxy)
830      && (miny<=bmaxy) && (bmaxy<=maxy)) *(int *)rval=TRUE;
831   }
832   arrayfree(array);
833   return 0;
834 }
835 
axismatch(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)836 int axismatch(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
837 {
838   int i,id;
839   char *group,*group2;
840   char type;
841   int findX,findY,findU,findR;
842   char *inst2;
843   char *instX,*instY,*instU,*instR;
844   int rval2,match;
845 
846   *(int *)rval=FALSE;
847   _getobj(obj,"group",inst,&group);
848   if ((group==NULL) || (group[0]=='a'))
849     return axismatch2(obj,inst,rval,argc,argv);
850   _getobj(obj,"id",inst,&id);
851   findX=findY=findU=findR=FALSE;
852   type=group[0];
853   for (i=0;i<=id;i++) {
854     inst2=chkobjinst(obj,i);
855     _getobj(obj,"group",inst2,&group2);
856     if ((group2!=NULL) && (group2[0]==type)) {
857       if (strcmp(group+2,group2+2)==0) {
858         if (group2[1]=='X') {
859           findX=TRUE;
860           instX=inst2;
861         } else if (group2[1]=='Y') {
862           findY=TRUE;
863           instY=inst2;
864         } else if (group2[1]=='U') {
865           findU=TRUE;
866           instU=inst2;
867         } else if (group2[1]=='R') {
868           findR=TRUE;
869           instR=inst2;
870         }
871       }
872     }
873   }
874   if (((type=='f') || (type=='s')) && findX && findY && findU && findR) {
875     match=FALSE;
876     axismatch2(obj,instX,(void *)&rval2,argc,argv);
877     match=match || rval2;
878     axismatch2(obj,instY,(void *)&rval2,argc,argv);
879     match=match || rval2;
880     axismatch2(obj,instU,(void *)&rval2,argc,argv);
881     match=match || rval2;
882     axismatch2(obj,instR,(void *)&rval2,argc,argv);
883     match=match || rval2;
884     *(int *)rval=match;
885   } else if ((type=='c') && findX && findY) {
886     match=FALSE;
887     axismatch2(obj,instX,(void *)&rval2,argc,argv);
888     match=match || rval2;
889     axismatch2(obj,instY,(void *)&rval2,argc,argv);
890     match=match || rval2;
891     *(int *)rval=match;
892   }
893   return 0;
894 }
895 
axismove2(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)896 int axismove2(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
897 {
898   int x,y;
899   struct narray *array;
900 
901   if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
902   _getobj(obj,"x",inst,&x);
903   _getobj(obj,"y",inst,&y);
904   x+=*(int *)argv[2];
905   y+=*(int *)argv[3];
906   if (_putobj(obj,"x",inst,&x)) return 1;
907   if (_putobj(obj,"y",inst,&y)) return 1;
908   _getobj(obj,"bbox",inst,&array);
909   arrayfree(array);
910   if (_putobj(obj,"bbox",inst,NULL)) return 1;
911   return 0;
912 }
913 
axismove(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)914 int axismove(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
915 {
916   int i,id;
917   char *group,*group2;
918   char type;
919   int findX,findY,findU,findR;
920   char *inst2;
921   char *instX,*instY,*instU,*instR;
922 
923   _getobj(obj,"group",inst,&group);
924   if ((group==NULL) || (group[0]=='a'))
925     return axismove2(obj,inst,rval,argc,argv);
926   _getobj(obj,"id",inst,&id);
927   findX=findY=findU=findR=FALSE;
928   type=group[0];
929   for (i=0;i<=id;i++) {
930     inst2=chkobjinst(obj,i);
931     _getobj(obj,"group",inst2,&group2);
932     if ((group2!=NULL) && (group2[0]==type)) {
933       if (strcmp(group+2,group2+2)==0) {
934         if (group2[1]=='X') {
935           findX=TRUE;
936           instX=inst2;
937         } else if (group2[1]=='Y') {
938           findY=TRUE;
939           instY=inst2;
940         } else if (group2[1]=='U') {
941           findU=TRUE;
942           instU=inst2;
943         } else if (group2[1]=='R') {
944           findR=TRUE;
945           instR=inst2;
946         }
947       }
948     }
949   }
950   if (((type=='f') || (type=='s')) && findX && findY && findU && findR) {
951     axismove2(obj,instX,rval,argc,argv);
952     axismove2(obj,instY,rval,argc,argv);
953     axismove2(obj,instU,rval,argc,argv);
954     axismove2(obj,instR,rval,argc,argv);
955   } else if ((type=='c') && findX && findY) {
956     axismove2(obj,instX,rval,argc,argv);
957     axismove2(obj,instY,rval,argc,argv);
958   }
959   return 0;
960 }
961 
axischange2(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)962 int axischange2(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
963 {
964   int len,dir,x,y;
965   double x2,y2;
966   int point,x0,y0;
967   struct narray *array;
968 
969   if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
970   _getobj(obj,"x",inst,&x);
971   _getobj(obj,"y",inst,&y);
972   _getobj(obj,"length",inst,&len);
973   _getobj(obj,"direction",inst,&dir);
974   x2=x+len*cos(dir*MPI/18000.0);
975   y2=y-len*sin(dir*MPI/18000.0);
976   point=*(int *)argv[2];
977   x0=*(int *)argv[3];
978   y0=*(int *)argv[4];
979   if (point==0) {
980     x+=x0;
981     y+=y0;
982   } else if (point==1) {
983     x2+=x0;
984     y2+=y0;
985   }
986   len=sqrt((x2-x)*(x2-x)+(y2-y)*(y2-y));
987   if ((x2-x)==0) {
988     if ((y2-y)==0) dir=0;
989     else if ((y2-y)>0) dir=27000;
990     else dir=9000;
991   } else {
992     dir=atan(-(y2-y)/(x2-x))/MPI*18000.0;
993     if ((x2-x)<0) dir+=18000;
994     if (dir<0) dir+=36000;
995   }
996   if (_putobj(obj,"x",inst,&x)) return 1;
997   if (_putobj(obj,"y",inst,&y)) return 1;
998   if (_putobj(obj,"length",inst,&len)) return 1;
999   if (_putobj(obj,"direction",inst,&dir)) return 1;
1000   _getobj(obj,"bbox",inst,&array);
1001   arrayfree(array);
1002   if (_putobj(obj,"bbox",inst,NULL)) return 1;
1003   return 0;
1004 }
1005 
axischange(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)1006 int axischange(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
1007 {
1008   int i,id;
1009   char *group,*group2;
1010   char type;
1011   int findX,findY,findU,findR;
1012   char *inst2;
1013   char *instX,*instY,*instU,*instR;
1014   int point,x0,y0;
1015   int x,y,len,x1,x2,y1,y2;
1016   struct narray *array;
1017 
1018   _getobj(obj,"group",inst,&group);
1019   if ((group==NULL) || (group[0]=='a'))
1020     return axischange2(obj,inst,rval,argc,argv);
1021   _getobj(obj,"id",inst,&id);
1022   findX=findY=findU=findR=FALSE;
1023   type=group[0];
1024   for (i=0;i<=id;i++) {
1025     inst2=chkobjinst(obj,i);
1026     _getobj(obj,"group",inst2,&group2);
1027     if ((group2!=NULL) && (group2[0]==type)) {
1028       if (strcmp(group+2,group2+2)==0) {
1029         if (group2[1]=='X') {
1030           findX=TRUE;
1031           instX=inst2;
1032         } else if (group2[1]=='Y') {
1033           findY=TRUE;
1034           instY=inst2;
1035         } else if (group2[1]=='U') {
1036           findU=TRUE;
1037           instU=inst2;
1038         } else if (group2[1]=='R') {
1039           findR=TRUE;
1040           instR=inst2;
1041         }
1042       }
1043     }
1044   }
1045   point=*(int *)argv[2];
1046   x0=*(int *)argv[3];
1047   y0=*(int *)argv[4];
1048   if (((type=='f') || (type=='s')) && findX && findY && findU && findR) {
1049     _getobj(obj,"y",instX,&y1);
1050     _getobj(obj,"y",instU,&y2);
1051     if  (y1<y2) {
1052       if (point==0) point=3;
1053       else if (point==1) point=2;
1054       else if (point==2) point=1;
1055       else if (point==3) point=0;
1056     }
1057     _getobj(obj,"x",instY,&x1);
1058     _getobj(obj,"x",instR,&x2);
1059     if  (x1>x2) {
1060       if (point==0) point=1;
1061       else if (point==1) point=0;
1062       else if (point==2) point=3;
1063       else if (point==3) point=2;
1064     }
1065     if (point==0) {
1066       _getobj(obj,"x",instX,&x);
1067       _getobj(obj,"length",instX,&len);
1068       x+=x0;
1069       len-=x0;
1070       _putobj(obj,"x",instX,&x);
1071       _putobj(obj,"length",instX,&len);
1072       _getobj(obj,"x",instY,&x);
1073       _getobj(obj,"length",instY,&len);
1074       x+=x0;
1075       len-=y0;
1076       _putobj(obj,"x",instY,&x);
1077       _putobj(obj,"length",instY,&len);
1078       _getobj(obj,"x",instU,&x);
1079       _getobj(obj,"y",instU,&y);
1080       _getobj(obj,"length",instU,&len);
1081       x+=x0;
1082       y+=y0;
1083       len-=x0;
1084       _putobj(obj,"x",instU,&x);
1085       _putobj(obj,"y",instU,&y);
1086       _putobj(obj,"length",instU,&len);
1087       _getobj(obj,"length",instR,&len);
1088       len-=y0;
1089       _putobj(obj,"length",instR,&len);
1090     } else if (point==1) {
1091       _getobj(obj,"length",instX,&len);
1092       len+=x0;
1093       _putobj(obj,"length",instX,&len);
1094       _getobj(obj,"length",instY,&len);
1095       len-=y0;
1096       _putobj(obj,"length",instY,&len);
1097       _getobj(obj,"y",instU,&y);
1098       _getobj(obj,"length",instU,&len);
1099       y+=y0;
1100       len+=x0;
1101       _putobj(obj,"y",instU,&y);
1102       _putobj(obj,"length",instU,&len);
1103       _getobj(obj,"x",instR,&x);
1104       _getobj(obj,"length",instR,&len);
1105       x+=x0;
1106       len-=y0;
1107       _putobj(obj,"x",instR,&x);
1108       _putobj(obj,"length",instR,&len);
1109     } else if (point==2) {
1110       _getobj(obj,"y",instX,&y);
1111       _getobj(obj,"length",instX,&len);
1112       y+=y0;
1113       len+=x0;
1114       _putobj(obj,"y",instX,&y);
1115       _putobj(obj,"length",instX,&len);
1116       _getobj(obj,"y",instY,&y);
1117       _getobj(obj,"length",instY,&len);
1118       y+=y0;
1119       len+=y0;
1120       _putobj(obj,"y",instY,&y);
1121       _putobj(obj,"length",instY,&len);
1122       _getobj(obj,"length",instU,&len);
1123       len+=x0;
1124       _putobj(obj,"length",instU,&len);
1125       _getobj(obj,"x",instR,&x);
1126       _getobj(obj,"y",instR,&y);
1127       _getobj(obj,"length",instR,&len);
1128       x+=x0;
1129       y+=y0;
1130       len+=y0;
1131       _putobj(obj,"x",instR,&x);
1132       _putobj(obj,"y",instR,&y);
1133       _putobj(obj,"length",instR,&len);
1134     } else if (point==3) {
1135       _getobj(obj,"x",instX,&x);
1136       _getobj(obj,"y",instX,&y);
1137       _getobj(obj,"length",instX,&len);
1138       x+=x0;
1139       y+=y0;
1140       len-=x0;
1141       _putobj(obj,"x",instX,&x);
1142       _putobj(obj,"y",instX,&y);
1143       _putobj(obj,"length",instX,&len);
1144       _getobj(obj,"x",instY,&x);
1145       _getobj(obj,"y",instY,&y);
1146       _getobj(obj,"length",instY,&len);
1147       x+=x0;
1148       y+=y0;
1149       len+=y0;
1150       _putobj(obj,"x",instY,&x);
1151       _putobj(obj,"y",instY,&y);
1152       _putobj(obj,"length",instY,&len);
1153       _getobj(obj,"x",instU,&x);
1154       _getobj(obj,"length",instU,&len);
1155       x+=x0;
1156       len-=x0;
1157       _putobj(obj,"x",instU,&x);
1158       _putobj(obj,"length",instU,&len);
1159       _getobj(obj,"y",instR,&y);
1160       _getobj(obj,"length",instR,&len);
1161       y+=y0;
1162       len+=y0;
1163       _putobj(obj,"y",instR,&y);
1164       _putobj(obj,"length",instR,&len);
1165     }
1166     _getobj(obj,"bbox",inst,&array);
1167     arrayfree(array);
1168     if (_putobj(obj,"bbox",inst,NULL)) return 1;
1169   } else if ((type=='c') && findX && findY) {
1170     if (point==0) {
1171       _getobj(obj,"x",instX,&x);
1172       _getobj(obj,"length",instX,&len);
1173       x+=x0;
1174       len-=x0;
1175       _putobj(obj,"x",instX,&x);
1176       _putobj(obj,"length",instX,&len);
1177       _getobj(obj,"x",instY,&x);
1178       _getobj(obj,"length",instY,&len);
1179       x+=x0;
1180       len-=y0;
1181       _putobj(obj,"x",instY,&x);
1182       _putobj(obj,"length",instY,&len);
1183     } else if (point==1) {
1184       _getobj(obj,"length",instX,&len);
1185       len+=x0;
1186       _putobj(obj,"length",instX,&len);
1187       _getobj(obj,"length",instY,&len);
1188       len-=y0;
1189       _putobj(obj,"length",instY,&len);
1190     } else if (point==2) {
1191       _getobj(obj,"y",instX,&y);
1192       _getobj(obj,"length",instX,&len);
1193       y+=y0;
1194       len+=x0;
1195       _putobj(obj,"y",instX,&y);
1196       _putobj(obj,"length",instX,&len);
1197       _getobj(obj,"y",instY,&y);
1198       _getobj(obj,"length",instY,&len);
1199       y+=y0;
1200       len+=y0;
1201       _putobj(obj,"y",instY,&y);
1202       _putobj(obj,"length",instY,&len);
1203     } else if (point==3) {
1204       _getobj(obj,"x",instX,&x);
1205       _getobj(obj,"y",instX,&y);
1206       _getobj(obj,"length",instX,&len);
1207       x+=x0;
1208       y+=y0;
1209       len-=x0;
1210       _putobj(obj,"x",instX,&x);
1211       _putobj(obj,"y",instX,&y);
1212       _putobj(obj,"length",instX,&len);
1213       _getobj(obj,"x",instY,&x);
1214       _getobj(obj,"y",instY,&y);
1215       _getobj(obj,"length",instY,&len);
1216       x+=x0;
1217       y+=y0;
1218       len+=y0;
1219       _putobj(obj,"x",instY,&x);
1220       _putobj(obj,"y",instY,&y);
1221       _putobj(obj,"length",instY,&len);
1222     }
1223     _getobj(obj,"bbox",inst,&array);
1224     arrayfree(array);
1225     if (_putobj(obj,"bbox",inst,NULL)) return 1;
1226   }
1227   return 0;
1228 }
1229 
axiszoom2(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)1230 int axiszoom2(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
1231 {
1232   int x,y,len,refx,refy;
1233   double zoom;
1234   struct narray *array;
1235   int pt,space,wid1,wid2,wid3,len1,len2,len3,wid,wlen,wwid;
1236   struct narray *style,*gstyle;
1237   int i,snum,*sdata,gsnum,*gsdata;
1238 
1239   if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
1240   zoom=(*(int *)argv[2])/10000.0;
1241   refx=(*(int *)argv[3]);
1242   refy=(*(int *)argv[4]);
1243   _getobj(obj,"x",inst,&x);
1244   _getobj(obj,"y",inst,&y);
1245   _getobj(obj,"length",inst,&len);
1246   _getobj(obj,"width",inst,&wid);
1247   _getobj(obj,"num_pt",inst,&pt);
1248   _getobj(obj,"num_space",inst,&space);
1249   _getobj(obj,"wave_length",inst,&wlen);
1250   _getobj(obj,"wave_width",inst,&wwid);
1251   _getobj(obj,"gauge_length1",inst,&len1);
1252   _getobj(obj,"gauge_width1",inst,&wid1);
1253   _getobj(obj,"gauge_length2",inst,&len2);
1254   _getobj(obj,"gauge_width2",inst,&wid2);
1255   _getobj(obj,"gauge_length3",inst,&len3);
1256   _getobj(obj,"gauge_width3",inst,&wid3);
1257   _getobj(obj,"gauge_style",inst,&gstyle);
1258   _getobj(obj,"style",inst,&style);
1259   snum=arraynum(style);
1260   sdata=arraydata(style);
1261   gsnum=arraynum(gstyle);
1262   gsdata=arraydata(gstyle);
1263   wlen*=zoom;
1264   wwid*=zoom;
1265   len1*=zoom;
1266   wid1*=zoom;
1267   len2*=zoom;
1268   wid2*=zoom;
1269   len3*=zoom;
1270   wid3*=zoom;
1271   x=(x-refx)*zoom+refx;
1272   y=(y-refy)*zoom+refy;
1273   len*=zoom;
1274   wid*=zoom;
1275   pt*=zoom;
1276   space*=zoom;
1277   for (i=0;i<snum;i++) sdata[i]=sdata[i]*zoom;
1278   for (i=0;i<gsnum;i++) gsdata[i]=gsdata[i]*zoom;
1279   if (_putobj(obj,"x",inst,&x)) return 1;
1280   if (_putobj(obj,"y",inst,&y)) return 1;
1281   if (_putobj(obj,"length",inst,&len)) return 1;
1282   if (_putobj(obj,"width",inst,&wid)) return 1;
1283   if (_putobj(obj,"num_pt",inst,&pt)) return 1;
1284   if (_putobj(obj,"num_space",inst,&space)) return 1;
1285   if (_putobj(obj,"wave_length",inst,&wlen)) return 1;
1286   if (_putobj(obj,"wave_width",inst,&wwid)) return 1;
1287   if (_putobj(obj,"gauge_length1",inst,&len1)) return 1;
1288   if (_putobj(obj,"gauge_width1",inst,&wid1)) return 1;
1289   if (_putobj(obj,"gauge_length2",inst,&len2)) return 1;
1290   if (_putobj(obj,"gauge_width2",inst,&wid2)) return 1;
1291   if (_putobj(obj,"gauge_length3",inst,&len3)) return 1;
1292   if (_putobj(obj,"gauge_width3",inst,&wid3)) return 1;
1293   _getobj(obj,"bbox",inst,&array);
1294   arrayfree(array);
1295   if (_putobj(obj,"bbox",inst,NULL)) return 1;
1296   return 0;
1297 }
1298 
axiszoom(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)1299 int axiszoom(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
1300 {
1301   int i,id;
1302   char *group,*group2;
1303   char type;
1304   int findX,findY,findU,findR;
1305   char *inst2;
1306   char *instX,*instY,*instU,*instR;
1307 
1308   _getobj(obj,"group",inst,&group);
1309   if ((group==NULL) || (group[0]=='a'))
1310     return axiszoom2(obj,inst,rval,argc,argv);
1311   _getobj(obj,"id",inst,&id);
1312   findX=findY=findU=findR=FALSE;
1313   type=group[0];
1314   for (i=0;i<=id;i++) {
1315     inst2=chkobjinst(obj,i);
1316     _getobj(obj,"group",inst2,&group2);
1317     if ((group2!=NULL) && (group2[0]==type)) {
1318       if (strcmp(group+2,group2+2)==0) {
1319         if (group2[1]=='X') {
1320           findX=TRUE;
1321           instX=inst2;
1322         } else if (group2[1]=='Y') {
1323           findY=TRUE;
1324           instY=inst2;
1325         } else if (group2[1]=='U') {
1326           findU=TRUE;
1327           instU=inst2;
1328         } else if (group2[1]=='R') {
1329           findR=TRUE;
1330           instR=inst2;
1331         }
1332       }
1333     }
1334   }
1335   if (((type=='f') || (type=='s')) && findX && findY && findU && findR) {
1336     axiszoom2(obj,instX,rval,argc,argv);
1337     axiszoom2(obj,instY,rval,argc,argv);
1338     axiszoom2(obj,instU,rval,argc,argv);
1339     axiszoom2(obj,instR,rval,argc,argv);
1340   } else if ((type=='c') && findX && findY) {
1341     axiszoom2(obj,instX,rval,argc,argv);
1342     axiszoom2(obj,instY,rval,argc,argv);
1343   }
1344   return 0;
1345 }
1346 
numformat(char * num,char * format,double a)1347 void numformat(char *num,char *format,double a)
1348 {
1349   int i,j,len,ret;
1350   char *s;
1351   char format2[256];
1352 
1353   s=strchr(format,'+');
1354   if ((a==0) && (s!=NULL)) {
1355     len=strlen(format);
1356     for (i=j=0;i<=len;i++) {
1357       format2[j]=format[i];
1358       if (format[i]!='+') j++;
1359     }
1360     ret=sprintf(num,"\\xb1");
1361     ret+=sprintf(num+ret,format2,a);
1362   } else {
1363     ret=sprintf(num,format,a);
1364   }
1365 }
1366 
axisdraw(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)1367 int axisdraw(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
1368 {
1369   int GC;
1370   int fr,fg,fb,lm,tm,w,h;
1371   int arrow,alength,awidth;
1372   int wave,wlength,wwidth;
1373   int x0,y0,x1,y1,direction,length,width;
1374   int bline;
1375   double min,max,inc;
1376   struct narray *style;
1377   int snum,*sdata;
1378   int div,type;
1379   double alen,awid,dx,dy,dir;
1380   int ap[6];
1381   double wx[5],wxc1[5],wxc2[5],wxc3[5];
1382   double wy[5],wyc1[5],wyc2[5],wyc3[5];
1383   double ww[5],c[6];
1384   int i;
1385   int clip,zoom;
1386   char *axis;
1387   struct axislocal alocal;
1388   double po,gmin,gmax,min1,max1,min2,max2;
1389   int gauge,len1,wid1,len2,wid2,len3,wid3,len,wid;
1390   struct narray iarray;
1391   struct objlist *aobj;
1392   int anum,id;
1393   char *inst1;
1394   int limit;
1395   int rcode;
1396   int gx0,gy0,gx1,gy1;
1397   int logpow,scriptsize;
1398   int side,pt,space,begin,step,nnum,numcount,cstep,ndir;
1399   int autonorm,align,sx,sy,nozero;
1400   char *format,*head,*tail,*font,*jfont,num[256],*text;
1401   int headlen,taillen,numlen;
1402   int dlx,dly,dlx2,dly2,maxlen,ndirection;
1403   int n,count;
1404   double norm;
1405   double t,nndir;
1406   int hx0,hy0,hx1,hy1,fx0,fy0,fx1,fy1,px0,px1,py0,py1;
1407   int ilenmax,flenmax,plen;
1408   char ch;
1409   int hidden,hidden2;
1410 
1411   _getobj(obj,"hidden",inst,&hidden);
1412   hidden2=FALSE;
1413   _putobj(obj,"hidden",inst,&hidden2);
1414   if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
1415   _putobj(obj,"hidden",inst,&hidden);
1416   _getobj(obj,"GC",inst,&GC);
1417   if (GC<0) return 0;
1418   if (hidden) goto exit;
1419   _getobj(obj,"R",inst,&fr);
1420   _getobj(obj,"G",inst,&fg);
1421   _getobj(obj,"B",inst,&fb);
1422   _getobj(obj,"x",inst,&x0);
1423   _getobj(obj,"y",inst,&y0);
1424   _getobj(obj,"direction",inst,&direction);
1425   _getobj(obj,"baseline",inst,&bline);
1426   _getobj(obj,"length",inst,&length);
1427   _getobj(obj,"width",inst,&width);
1428   _getobj(obj,"style",inst,&style);
1429   _getobj(obj,"arrow",inst,&arrow);
1430   _getobj(obj,"arrow_length",inst,&alength);
1431   _getobj(obj,"arrow_width",inst,&awidth);
1432   _getobj(obj,"wave",inst,&wave);
1433   _getobj(obj,"wave_length",inst,&wlength);
1434   _getobj(obj,"wave_width",inst,&wwidth);
1435   _getobj(obj,"clip",inst,&clip);
1436   snum=arraynum(style);
1437   sdata=arraydata(style);
1438 
1439   dir=direction/18000.0*MPI;
1440   x1=x0+nround(length*cos(dir));
1441   y1=y0-nround(length*sin(dir));
1442 
1443   GRAregion(GC,&lm,&tm,&w,&h,&zoom);
1444   GRAview(GC,0,0,w*10000.0/zoom,h*10000.0/zoom,clip);
1445   GRAcolor(GC,fr,fg,fb);
1446 
1447   if (bline) {
1448     GRAlinestyle(GC,snum,sdata,width,2,0,1000);
1449     GRAline(GC,x0,y0,x1,y1);
1450   }
1451 
1452   alen=width*(double )alength/10000;
1453   awid=width*(double )awidth/20000;
1454   if ((arrow==2) || (arrow==3)) {
1455     dx=-cos(dir);
1456     dy=sin(dir);
1457     ap[0]=nround(x0-dy*awid);
1458     ap[1]=nround(y0+dx*awid);
1459     ap[2]=nround(x0+dx*alen);
1460     ap[3]=nround(y0+dy*alen);
1461     ap[4]=nround(x0+dy*awid);
1462     ap[5]=nround(y0-dx*awid);
1463     GRAlinestyle(GC,0,NULL,1,0,0,1000);
1464     GRAdrawpoly(GC,3,ap,1);
1465   }
1466   if ((arrow==1) || (arrow==3)) {
1467     dx=cos(dir);
1468     dy=-sin(dir);
1469     ap[0]=nround(x1-dy*awid);
1470     ap[1]=nround(y1+dx*awid);
1471     ap[2]=nround(x1+dx*alen);
1472     ap[3]=nround(y1+dy*alen);
1473     ap[4]=nround(x1+dy*awid);
1474     ap[5]=nround(y1-dx*awid);
1475     GRAlinestyle(GC,0,NULL,1,0,0,1000);
1476     GRAdrawpoly(GC,3,ap,1);
1477   }
1478   for (i=0;i<5;i++) ww[i]=i;
1479   if ((wave==2) || (wave==3)) {
1480     dx=cos(dir);
1481     dy=sin(dir);
1482     wx[0]=nround(x0-dy*wlength);
1483     wx[1]=nround(x0-dy*0.5*wlength-dx*0.25*wlength);
1484     wx[2]=x0;
1485     wx[3]=nround(x0+dy*0.5*wlength+dx*0.25*wlength);
1486     wx[4]=nround(x0+dy*wlength);
1487     if (spline(ww,wx,wxc1,wxc2,wxc3,5,SPLCND2NDDIF,SPLCND2NDDIF,0,0)) {
1488       error(obj,ERRAXISSPL);
1489       goto exit;
1490     }
1491     wy[0]=nround(y0-dx*wlength);
1492     wy[1]=nround(y0-dx*0.5*wlength+dy*0.25*wlength);
1493     wy[2]=y0;
1494     wy[3]=nround(y0+dx*0.5*wlength-dy*0.25*wlength);
1495     wy[4]=nround(y0+dx*wlength);
1496     if (spline(ww,wy,wyc1,wyc2,wyc3,5,SPLCND2NDDIF,SPLCND2NDDIF,0,0)) {
1497       error(obj,ERRAXISSPL);
1498       goto exit;
1499     }
1500     GRAlinestyle(GC,0,NULL,wwidth,0,0,1000);
1501     GRAcurvefirst(GC,0,NULL,NULL,NULL,splinedif,splineint,NULL,wx[0],wy[0]);
1502     for (i=0;i<4;i++) {
1503       c[0]=wxc1[i];
1504       c[1]=wxc2[i];
1505       c[2]=wxc3[i];
1506       c[3]=wyc1[i];
1507       c[4]=wyc2[i];
1508       c[5]=wyc3[i];
1509       if (!GRAcurve(GC,c,wx[i],wy[i])) break;
1510     }
1511   }
1512   if ((wave==1) || (wave==3)) {
1513     dx=cos(dir);
1514     dy=sin(dir);
1515     wx[0]=nround(x1-dy*wlength);
1516     wx[1]=nround(x1-dy*0.5*wlength-dx*0.25*wlength);
1517     wx[2]=x1;
1518     wx[3]=nround(x1+dy*0.5*wlength+dx*0.25*wlength);
1519     wx[4]=nround(x1+dy*wlength);
1520     if (spline(ww,wx,wxc1,wxc2,wxc3,5,SPLCND2NDDIF,SPLCND2NDDIF,0,0)) {
1521       error(obj,ERRAXISSPL);
1522       goto exit;
1523     }
1524     wy[0]=nround(y1-dx*wlength);
1525     wy[1]=nround(y1-dx*0.5*wlength+dy*0.25*wlength);
1526     wy[2]=y1;
1527     wy[3]=nround(y1+dx*0.5*wlength-dy*0.25*wlength);
1528     wy[4]=nround(y1+dx*wlength);
1529     if (spline(ww,wy,wyc1,wyc2,wyc3,5,SPLCND2NDDIF,SPLCND2NDDIF,0,0)) {
1530       error(obj,ERRAXISSPL);
1531       goto exit;
1532     }
1533     GRAlinestyle(GC,0,NULL,wwidth,0,0,1000);
1534     GRAcurvefirst(GC,0,NULL,NULL,NULL,splinedif,splineint,NULL,wx[0],wy[0]);
1535     for (i=0;i<4;i++) {
1536       c[0]=wxc1[i];
1537       c[1]=wxc2[i];
1538       c[2]=wxc3[i];
1539       c[3]=wyc1[i];
1540       c[4]=wyc2[i];
1541       c[5]=wyc3[i];
1542       if (!GRAcurve(GC,c,wx[i],wy[i])) break;
1543     }
1544   }
1545 
1546   _getobj(obj,"min",inst,&min);
1547   _getobj(obj,"max",inst,&max);
1548   _getobj(obj,"inc",inst,&inc);
1549   _getobj(obj,"div",inst,&div);
1550   _getobj(obj,"type",inst,&type);
1551 
1552   if ((min==0) && (max==0) && (inc==0)) {
1553     _getobj(obj,"reference",inst,&axis);
1554     if (axis!=NULL) {
1555       arrayinit(&iarray,sizeof(int));
1556       if (getobjilist(axis,&aobj,&iarray,FALSE,NULL)) goto numbering;
1557       anum=arraynum(&iarray);
1558       if (anum>0) {
1559         id=*(int *)arraylast(&iarray);
1560         arraydel(&iarray);
1561         if ((anum>0) && ((inst1=getobjinst(aobj,id))!=NULL)) {
1562            _getobj(aobj,"min",inst1,&min);
1563            _getobj(aobj,"max",inst1,&max);
1564            _getobj(aobj,"inc",inst1,&inc);
1565            _getobj(aobj,"div",inst1,&div);
1566            _getobj(aobj,"type",inst1,&type);
1567         }
1568       }
1569     }
1570   }
1571 
1572   if ((min==max) || (inc==0)) goto numbering;
1573 
1574   dir=direction/18000.0*MPI;
1575 
1576   _getobj(obj,"gauge",inst,&gauge);
1577 
1578   if (gauge!=0) {
1579     _getobj(obj,"gauge_R",inst,&fr);
1580     _getobj(obj,"gauge_G",inst,&fg);
1581     _getobj(obj,"gauge_B",inst,&fb);
1582     _getobj(obj,"gauge_min",inst,&gmin);
1583     _getobj(obj,"gauge_max",inst,&gmax);
1584     _getobj(obj,"gauge_style",inst,&style);
1585     _getobj(obj,"gauge_length1",inst,&len1);
1586     _getobj(obj,"gauge_width1",inst,&wid1);
1587     _getobj(obj,"gauge_length2",inst,&len2);
1588     _getobj(obj,"gauge_width2",inst,&wid2);
1589     _getobj(obj,"gauge_length3",inst,&len3);
1590     _getobj(obj,"gauge_width3",inst,&wid3);
1591 
1592     snum=arraynum(style);
1593     sdata=arraydata(style);
1594 
1595     GRAcolor(GC,fr,fg,fb);
1596 
1597     if (getaxispositionini(&alocal,type,min,max,inc,div,FALSE)!=0) {
1598       error(obj,ERRMINMAX);
1599       goto exit;
1600     }
1601 
1602     if ((gmin!=0) || (gmax!=0)) limit=TRUE;
1603     else limit=FALSE;
1604 
1605     if (type==1) {
1606       min1=log10(min);
1607       max1=log10(max);
1608       if (limit && (gmin>0) && (gmax>0)) {
1609         min2=log10(gmin);
1610         max2=log10(gmax);
1611       } else limit=FALSE;
1612     } else if (type==2) {
1613       min1=1/min;
1614       max1=1/max;
1615       if (limit && (gmin*gmax>0)) {
1616         min2=1/gmin;
1617         max2=1/gmax;
1618       } else limit=FALSE;
1619     } else {
1620       min1=min;
1621       max1=max;
1622       if (limit) {
1623         min2=gmin;
1624         max2=gmax;
1625       }
1626     }
1627 
1628     while ((rcode=getaxisposition(&alocal,&po))!=-2) {
1629       if ((rcode>=0) && (!limit || ((min2-po)*(max2-po)<=0))) {
1630         gx0=x0+(po-min1)*length/(max1-min1)*cos(dir);
1631         gy0=y0-(po-min1)*length/(max1-min1)*sin(dir);
1632         if (rcode==1) {
1633           len=len1;
1634           wid=wid1;
1635         } else if (rcode==2) {
1636           len=len2;
1637           wid=wid2;
1638         } else {
1639           len=len3;
1640           wid=wid3;
1641         }
1642         GRAlinestyle(GC,snum,sdata,wid,0,0,1000);
1643         if ((gauge==1) || (gauge==2)) {
1644           gx1=gx0-len*sin(dir);
1645           gy1=gy0-len*cos(dir);
1646           GRAline(GC,gx0,gy0,gx1,gy1);
1647         }
1648         if ((gauge==1) || (gauge==3)) {
1649           gx1=gx0+len*sin(dir);
1650           gy1=gy0+len*cos(dir);
1651           GRAline(GC,gx0,gy0,gx1,gy1);
1652         }
1653       }
1654     }
1655   }
1656 
1657 numbering:
1658 
1659   _getobj(obj,"min",inst,&min);
1660   _getobj(obj,"max",inst,&max);
1661   _getobj(obj,"inc",inst,&inc);
1662   _getobj(obj,"div",inst,&div);
1663   _getobj(obj,"type",inst,&type);
1664 
1665   if ((min==max) || (inc==0)) goto exit;
1666 
1667   _getobj(obj,"num",inst,&side);
1668 
1669   if (side!=0) {
1670     _getobj(obj,"num_R",inst,&fr);
1671     _getobj(obj,"num_G",inst,&fg);
1672     _getobj(obj,"num_B",inst,&fb);
1673     _getobj(obj,"num_pt",inst,&pt);
1674     _getobj(obj,"num_space",inst,&space);
1675     _getobj(obj,"num_script_size",inst,&scriptsize);
1676     _getobj(obj,"num_begin",inst,&begin);
1677     _getobj(obj,"num_step",inst,&step);
1678     _getobj(obj,"num_num",inst,&nnum);
1679     _getobj(obj,"num_auto_norm",inst,&autonorm);
1680     _getobj(obj,"num_head",inst,&head);
1681     _getobj(obj,"num_format",inst,&format);
1682     _getobj(obj,"num_tail",inst,&tail);
1683     _getobj(obj,"num_log_pow",inst,&logpow);
1684     _getobj(obj,"num_align",inst,&align);
1685     _getobj(obj,"num_shift_p",inst,&sx);
1686     _getobj(obj,"num_shift_n",inst,&sy);
1687     _getobj(obj,"num_direction",inst,&ndir);
1688     _getobj(obj,"num_no_zero",inst,&nozero);
1689     _getobj(obj,"num_font",inst,&font);
1690     _getobj(obj,"num_jfont",inst,&jfont);
1691 
1692     GRAcolor(GC,fr,fg,fb);
1693 
1694     if (side==2) sy*=-1;
1695 
1696     if (head!=NULL) headlen=strlen(head);
1697     else headlen=0;
1698     if (tail!=NULL) taillen=strlen(tail);
1699     else taillen=0;
1700 
1701     if (ndir==0) ndirection=0;
1702     else if (ndir==1) ndirection=direction;
1703     else if (ndir==2) {
1704       ndirection=direction+18000;
1705       if (ndirection>36000) ndirection-=36000;
1706     }
1707     nndir=ndirection/18000.0*MPI;
1708 
1709     if (type==1) {
1710       min1=log10(min);
1711       max1=log10(max);
1712     } else if (type==2) {
1713       min1=1/min;
1714       max1=1/max;
1715     } else {
1716       min1=min;
1717       max1=max;
1718     }
1719 
1720     if (getaxispositionini(&alocal,type,min,max,inc,div,FALSE)!=0) {
1721       error(obj,ERRMINMAX);
1722       goto exit;
1723     }
1724 
1725     count=0;
1726     while ((rcode=getaxisposition(&alocal,&po))!=-2) {
1727       if (rcode>=2) count++;
1728     }
1729 
1730     if (alocal.atype==AXISINVERSE) {
1731       if (step==0) {
1732         if (count==0) n=1;
1733         else n=nround(pow(10.0,(double )(int )(log10((double )count))));
1734         if (n!=1) n--;
1735         if (count>=18*n) step=9*n;
1736         else if (count>=6*n) step=3*n;
1737         else step=n;
1738       }
1739       if (begin==0) begin=1;
1740     } else if (alocal.atype==AXISLOGSMALL) {
1741       if (step==0) step=1;
1742       if (begin==0) begin=1;
1743     } else {
1744       if (step==0) {
1745         if (count==0) n=1;
1746         else n=nround(pow(10.0,(double )(int )(log10(count*0.5))));
1747         if (count>=10*n) step=5*n;
1748         else if (count>=5*n) step=2*n;
1749         else step=n;
1750       }
1751       if (begin==0)
1752         begin=nround(fabs((roundmin(alocal.posst,alocal.dposl)
1753                         -roundmin(alocal.posst,alocal.dposm))/alocal.dposm))
1754              % step+1;
1755     }
1756 
1757     norm=1;
1758     if (alocal.atype==AXISNORMAL) {
1759       if ((fabs(alocal.dposm)>=pow(10.0,(double )autonorm))
1760        || (fabs(alocal.dposm)<=pow(10.0,(double )-autonorm)))
1761         norm=fabs(alocal.dposm);
1762     }
1763 
1764     if (getaxispositionini(&alocal,type,min,max,inc,div,FALSE)!=0)
1765       goto exit;
1766     GRAtextextent(".",font,jfont,pt,space,scriptsize,&fx0,&fy0,&fx1,&fy1,FALSE);
1767     plen=abs(fx1-fx0);
1768     hx0=hy0=hx1=hy1=0;
1769     flenmax=ilenmax=0;
1770     if (begin<=0) begin=1;
1771     cstep=step-begin+1;
1772     numcount=0;
1773     while ((rcode=getaxisposition(&alocal,&po))!=-2) {
1774       if (rcode>=2) {
1775         if ((cstep==step) || ((alocal.atype==AXISLOGSMALL) && (rcode==3))) {
1776           numcount++;
1777           if (((numcount<=nnum) || (nnum==-1)) && ((po!=0) || !nozero)) {
1778             if ((!logpow
1779             && ((alocal.atype==AXISLOGBIG) || (alocal.atype==AXISLOGNORM)))
1780             || (alocal.atype==AXISLOGSMALL))
1781               numformat(num,format,pow(10.0,po));
1782             else if (alocal.atype==AXISINVERSE)
1783               numformat(num,format,1.0/po);
1784             else
1785               numformat(num,format,po/norm);
1786             numlen=strlen(num);
1787             if ((text=memalloc(numlen+headlen+taillen+5))==NULL) goto exit;
1788             text[0]='\0';
1789             if (headlen!=0) strcpy(text,head);
1790             if (logpow
1791             && ((alocal.atype==AXISLOGBIG) || (alocal.atype==AXISLOGNORM)))
1792               strcat(text,"10^");
1793             if (numlen!=0) strcat(text,num);
1794             if (logpow
1795             && ((alocal.atype==AXISLOGBIG) || (alocal.atype==AXISLOGNORM)))
1796               strcat(text,"@");
1797             if (taillen!=0) strcat(text,tail);
1798             if (align==3) {
1799               for (i=headlen;i<headlen+numlen;i++) if (text[i]=='.') break;
1800               if (text[i]=='.') {
1801                 GRAtextextent(text+i+1,font,jfont,pt,space,scriptsize,
1802                               &fx0,&fy0,&fx1,&fy1,FALSE);
1803                 if (fy0<hy0) hy0=fy0;
1804                 if (fy1>hy1) hy1=fy1;
1805                 if (abs(fx1-fx0)>flenmax) flenmax=abs(fx1-fx0);
1806               }
1807               text[i]='\0';
1808               GRAtextextent(text,font,jfont,pt,space,scriptsize,
1809                                 &fx0,&fy0,&fx1,&fy1,FALSE);
1810               if (abs(fx1-fx0)>ilenmax) ilenmax=abs(fx1-fx0);
1811               if (fy0<hy0) hy0=fy0;
1812               if (fy1>hy1) hy1=fy1;
1813             } else {
1814               GRAtextextent(text,font,jfont,pt,space,scriptsize,
1815                             &fx0,&fy0,&fx1,&fy1,FALSE);
1816               if (fx0<hx0) hx0=fx0;
1817               if (fx1>hx1) hx1=fx1;
1818               if (fy0<hy0) hy0=fy0;
1819               if (fy1>hy1) hy1=fy1;
1820             }
1821             memfree(text);
1822           }
1823           if ((alocal.atype==AXISLOGSMALL) && (rcode==3)) cstep=step-begin;
1824           else cstep=0;
1825 	}
1826         cstep++;
1827       }
1828     }
1829     if (align==3) {
1830       hx0=0;
1831       hx1=flenmax+ilenmax+plen/2;
1832     }
1833 
1834     if ((abs(hx0-hx1)!=0) && (abs(hy0-hy1)!=0)) {
1835 
1836       if (ndir==0) {
1837         if (side==1) {
1838           if (direction<9000) {
1839             px0=hx1;
1840             py0=hy1;
1841           } else if (direction<18000) {
1842             px0=hx1;
1843             py0=hy0;
1844           } else if (direction<27000) {
1845             px0=hx0;
1846             py0=hy0;
1847           } else {
1848             px0=hx0;
1849             py0=hy1;
1850           }
1851         } else {
1852           if (direction<9000) {
1853             px0=hx0;
1854             py0=hy0;
1855           } else if (direction<18000) {
1856             px0=hx0;
1857             py0=hy1;
1858           } else if (direction<27000) {
1859             px0=hx1;
1860             py0=hy1;
1861           } else {
1862             px0=hx1;
1863             py0=hy0;
1864           }
1865         }
1866         if (align==0) px1=(hx0+hx1)/2;
1867         else if (align==1) px1=hx0;
1868         else if (align==2) px1=hx1;
1869         else if (align==3) px1=ilenmax+plen/2;
1870         py1=(hy0+hy1)/2;
1871         fx0=px1-px0;
1872         fy0=py1-py0;
1873         t=cos(dir)*fx0-sin(dir)*fy0;
1874         dlx=fx0-t*cos(dir);
1875         dly=fy0+t*sin(dir);
1876         if (side==1) {
1877           if (direction<9000) px1=hx1;
1878           else if (direction<18000) px1=hx1;
1879           else if (direction<27000) px1=hx0;
1880           else px1=hx0;
1881         } else {
1882           if (direction<9000) px1=hx0;
1883           else if (direction<18000) px1=hx0;
1884           else if (direction<27000) px1=hx1;
1885           else px1=hx1;
1886         }
1887         py1=(hy0+hy1)/2;
1888         fx0=px1-px0;
1889         fy0=py1-py0;
1890         t=cos(dir)*fx0-sin(dir)*fy0;
1891         dlx2=fx0-t*cos(dir);
1892         dly2=fy0+t*sin(dir);
1893         maxlen=abs(hx1-hx0);
1894       } else if ((ndir==1) || (ndir==2)) {
1895         py1=(hy0+hy1)/2;
1896         if (side==1) py1*=-1;
1897         dlx=-py1*sin(dir);
1898         dly=-py1*cos(dir);
1899         dlx2=-py1*sin(dir);
1900         dly2=-py1*cos(dir);
1901         maxlen=abs(hx1-hx0);
1902       }
1903       if (getaxispositionini(&alocal,type,min,max,inc,div,FALSE)!=0)
1904         goto exit;
1905       if (begin<=0) begin=1;
1906       cstep=step-begin+1;
1907       numcount=0;
1908       while ((rcode=getaxisposition(&alocal,&po))!=-2) {
1909         if (rcode>=2) {
1910           gx0=x0+(po-min1)*length/(max1-min1)*cos(dir);
1911           gy0=y0-(po-min1)*length/(max1-min1)*sin(dir);
1912           gx0=gx0-sy*sin(dir)+sx*cos(dir)+dlx;
1913           gy0=gy0-sy*cos(dir)-sx*sin(dir)+dly;
1914           if ((cstep==step) || ((alocal.atype==AXISLOGSMALL) && (rcode==3))) {
1915             numcount++;
1916             if (((numcount<=nnum) || (nnum==-1)) && ((po!=0) || !nozero)) {
1917               if ((!logpow
1918               && ((alocal.atype==AXISLOGBIG) || (alocal.atype==AXISLOGNORM)))
1919               || (alocal.atype==AXISLOGSMALL))
1920                 numformat(num,format,pow(10.0,po));
1921               else if (alocal.atype==AXISINVERSE)
1922                 numformat(num,format,1.0/po);
1923               else
1924                 numformat(num,format,po/norm);
1925               numlen=strlen(num);
1926               if ((text=memalloc(numlen+headlen+taillen+5))==NULL)
1927                 goto exit;
1928               text[0]='\0';
1929               if (headlen!=0) strcpy(text,head);
1930               if (logpow
1931               && ((alocal.atype==AXISLOGBIG) || (alocal.atype==AXISLOGNORM)))
1932                 strcat(text,"10^");
1933               if (numlen!=0) strcat(text,num);
1934               if (logpow
1935               && ((alocal.atype==AXISLOGBIG) || (alocal.atype==AXISLOGNORM)))
1936                 strcat(text,"@");
1937               if (taillen!=0) strcat(text,tail);
1938               if (align==3) {
1939                 for (i=headlen;i<headlen+numlen;i++) if (text[i]=='.') break;
1940                 ch=text[i];
1941                 text[i]='\0';
1942                 GRAtextextent(text,font,jfont,pt,space,scriptsize,
1943                               &fx0,&fy0,&fx1,&fy1,FALSE);
1944                 if (abs(fx1-fx0)>ilenmax) ilenmax=abs(fx1-fx0);
1945                 text[i]=ch;
1946                 GRAtextextent(text,font,jfont,pt,space,scriptsize,
1947                               &px0,&py0,&px1,&py1,FALSE);
1948                 if (py0<fy0) fy0=py0;
1949                 if (py1>fy1) fy1=py1;
1950               } else {
1951                 GRAtextextent(text,font,jfont,pt,space,scriptsize,
1952                               &fx0,&fy0,&fx1,&fy1,FALSE);
1953               }
1954               if (ndir==0) {
1955                 if (align==0) px1=(fx0+fx1)/2;
1956 				else if (align==1) px1=fx0;
1957                 else if (align==2) px1=fx1;
1958                 else if (align==3) px1=fx1+plen/2;
1959                 py1=(fy0+fy1)/2;
1960               } else if ((ndir==1) || (ndir==2)) {
1961                 if (align==0) px0=(fx0+fx1)/2;
1962                 else if (align==1) px0=fx0;
1963 				else if (align==2) px0=fx1;
1964                 else if (align==3) px0=fx1+plen/2;
1965                 py0=(fy0+fy1)/2;
1966                 px1=cos(nndir)*px0+sin(nndir)*py0;
1967 				py1=-sin(nndir)*px0+cos(nndir)*py0;
1968               }
1969               GRAmoveto(GC,gx0-px1,gy0-py1);
1970               GRAdrawtext(GC,text,font,jfont,pt,space,ndirection,scriptsize);
1971 			  memfree(text);
1972             }
1973             if ((alocal.atype==AXISLOGSMALL) && (rcode==3)) cstep=step-begin;
1974             else cstep=0;
1975           }
1976           cstep++;
1977         }
1978       }
1979 
1980       if (norm!=1) {
1981         if (norm/pow(10.0,cutdown(log10(norm)))==1) {
1982           sprintf(num,"[%%F{Symbol}%c%%F{%s}10^%+d@]",
1983                       (char )0xb4,font,(int )cutdown(log10(norm)));
1984         } else {
1985           sprintf(num,"[%g%%F{Symbol}%c%%F{%s}10^%+d@]",
1986                       norm/pow(10.0,cutdown(log10(norm))),
1987                       (char )0xb4,font,(int )cutdown(log10(norm)));
1988         }
1989         GRAtextextent(num,font,jfont,pt,space,scriptsize,
1990                       &fx0,&fy0,&fx1,&fy1,FALSE);
1991         if (abs(fy1-fy0)>maxlen) maxlen=abs(fy1-fy0);
1992         gx0=x0+(length+maxlen*1.2)*cos(dir);
1993         gy0=y0-(length+maxlen*1.2)*sin(dir);
1994         gx0=gx0-sy*sin(dir)+sx*cos(dir)+dlx2;
1995         gy0=gy0-sy*cos(dir)-sx*sin(dir)+dly2;
1996         if (ndir==0) {
1997           if (side==1) {
1998             if ((direction>4500) && (direction<=22500)) px1=fx1;
1999             else px1=fx0;
2000           } else {
2001             if ((direction>13500) && (direction<=31500)) px1=fx1;
2002             else px1=fx0;
2003           }
2004           py1=(fy0+fy1)/2;
2005         } else {
2006           if (ndir==1) px0=fx0;
2007           else px0=fx1;
2008           py0=(fy0+fy1)/2;
2009           px1=cos(nndir)*px0+sin(nndir)*py0;
2010           py1=-sin(nndir)*px0+cos(nndir)*py0;
2011         }
2012         GRAmoveto(GC,gx0-px1,gy0-py1);
2013         GRAdrawtext(GC,num,font,jfont,pt,space,ndirection,scriptsize);
2014       }
2015 
2016     }
2017 
2018   }
2019 
2020 exit:
2021   GRAaddlist(GC,obj,inst,(char *)argv[0],(char *)argv[1]);
2022   return 0;
2023 }
2024 
axisclear(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)2025 int axisclear(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
2026 {
2027   double min,max,inc;
2028 
2029   min=max=inc=0;
2030   if (_putobj(obj,"min",inst,&min)) return 1;
2031   if (_putobj(obj,"max",inst,&max)) return 1;
2032   if (_putobj(obj,"inc",inst,&inc)) return 1;
2033   return 0;
2034 }
2035 
axisadjust(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)2036 int axisadjust(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
2037 {
2038   char *axis;
2039   int ad;
2040   struct objlist *aobj;
2041   int anum,id;
2042   struct narray iarray,*array;
2043   char *inst1;
2044   double min,max,inc,dir,po,dir1,x;
2045   int type,posx,posy,len,idir,posx1,posy1,div;
2046   struct axislocal alocal;
2047   int rcode;
2048   int first;
2049   int gx,gy,gx0,gy0,count;
2050 
2051   _getobj(obj,"x",inst,&posx1);
2052   _getobj(obj,"y",inst,&posy1);
2053   _getobj(obj,"direction",inst,&idir);
2054   _getobj(obj,"adjust_axis",inst,&axis);
2055   _getobj(obj,"adjust_position",inst,&ad);
2056   dir1=idir*MPI/18000;
2057   if (axis==NULL) return 0;
2058   arrayinit(&iarray,sizeof(int));
2059   if (getobjilist(axis,&aobj,&iarray,FALSE,NULL)) return 1;
2060   anum=arraynum(&iarray);
2061   if (anum<1) {
2062      arraydel(&iarray);
2063      return 1;
2064   }
2065   id=*(int *)arraylast(&iarray);
2066   arraydel(&iarray);
2067   if ((inst1=getobjinst(aobj,id))==NULL) return 1;
2068   if (_getobj(aobj,"min",inst1,&min)) return 1;
2069   if (_getobj(aobj,"max",inst1,&max)) return 1;
2070   if (_getobj(aobj,"inc",inst1,&inc)) return 1;
2071   if (_getobj(aobj,"div",inst1,&div)) return 1;
2072   if (_getobj(aobj,"type",inst1,&type)) return 1;
2073   if (_getobj(aobj,"x",inst1,&posx)) return 1;
2074   if (_getobj(aobj,"y",inst1,&posy)) return 1;
2075   if (_getobj(aobj,"length",inst1,&len)) return 1;
2076   if (_getobj(aobj,"direction",inst1,&idir)) return 1;
2077   dir=idir*MPI/18000;
2078   if (min==max) return 0;
2079   if (dir==dir1) return 0;
2080   if (getaxispositionini(&alocal,type,min,max,inc,div,FALSE)!=0) return 0;
2081   if (type==1) {
2082     min=log10(min);
2083     max=log10(max);
2084   } else if (type==2) {
2085     min=1/min;
2086     max=1/max;
2087   }
2088   first=TRUE;
2089   count=0;
2090   while ((rcode=getaxisposition(&alocal,&po))!=-2) {
2091     if (rcode>=2) {
2092       count++;
2093       gx=posx+(po-min)*len/(max-min)*cos(dir);
2094       gy=posy-(po-min)*len/(max-min)*sin(dir);
2095       if (first) {
2096         gx0=gx;
2097         gy0=gy;
2098         first=FALSE;
2099       }
2100       if (((ad==0) && (po==0)) || (count==ad)) {
2101         gx0=gx;
2102         gy0=gy;
2103       }
2104     }
2105   }
2106   if (first) return 0;
2107   x=-sin(dir1)*(gx0-posx1)-cos(dir1)*(gy0-posy1);
2108   x=x/(-cos(dir)*sin(dir1)+sin(dir)*cos(dir1));
2109   posx1=nround(posx1+x*cos(dir));
2110   posy1=nround(posy1-x*sin(dir));
2111   if (_putobj(obj,"x",inst,&posx1)) return 1;
2112   if (_putobj(obj,"y",inst,&posy1)) return 1;
2113   _getobj(obj,"bbox",inst,&array);
2114   arrayfree(array);
2115   if (_putobj(obj,"bbox",inst,NULL)) return 1;
2116   return 0;
2117 }
2118 
axischangescale(struct objlist * obj,char * inst,double * rmin,double * rmax,double * rinc,int room)2119 int axischangescale(struct objlist *obj,char *inst,
2120                     double *rmin,double *rmax,double *rinc,int room)
2121 {
2122   int type;
2123   double min,max,inc,ming,maxg,order,mmin;
2124   double a;
2125 
2126   _getobj(obj,"type",inst,&type);
2127   ming=*rmin;
2128   maxg=*rmax;
2129   if (ming>maxg) {
2130     a=ming;
2131     ming=maxg;
2132     maxg=a;
2133   }
2134   if (type==1) {
2135     if (ming<=0) return 1;
2136     if (maxg<=0) return 1;
2137     ming=log10(ming);
2138     maxg=log10(maxg);
2139   } else if (type==2) {
2140     if (ming*maxg<=0) return 1;
2141   }
2142   order=(fabs(ming)+fabs(maxg))*0.5;
2143   if (order==0) {
2144     maxg=1;
2145     ming=-1;
2146   } else if (fabs(maxg-ming)/order<1e-6) {
2147     maxg=maxg+order*0.5;
2148     ming=ming-order*0.5;
2149   }
2150   inc=scale(maxg-ming);
2151   if (room==0) {
2152     max=maxg+(maxg-ming)*0.05;
2153     max=nraise(max/inc*10)*inc/10;
2154     min=ming-(maxg-ming)*0.05;
2155     min=cutdown(min/inc*10)*inc/10;
2156     if (type==1) {
2157       max=pow(10.0,max);
2158       min=pow(10.0,min);
2159       max=log10(nraise(max/scale(max))*scale(max));
2160       min=log10(cutdown(min/scale(min)+1e-15)*scale(min));
2161     } else if (type==2) {
2162       if (ming*min<=0) min=ming;
2163       if (maxg*max<=0) max=maxg;
2164     }
2165   } else {
2166     max=maxg;
2167     min=ming;
2168   }
2169   if (min==max) max=min+1;
2170   if (type!=2) {
2171     inc=scale(max-min);
2172     if (max<min) inc*=-1;
2173     mmin=roundmin(min,inc)+inc;
2174     if ((mmin-min)*(mmin-max)>0) inc/=10;
2175   } else {
2176     inc=scale(max-min);
2177   }
2178   if ((type!=1) && (inc==0)) inc=1;
2179   if (type==1) inc=nround(inc);
2180   inc=fabs(inc);
2181   if (type==1) {
2182     min=pow(10.0,min);
2183     max=pow(10.0,max);
2184     inc=pow(10.0,inc);
2185   }
2186   *rmin=min;
2187   *rmax=max;
2188   *rinc=inc;
2189   return 0;
2190 }
2191 
axisscale(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)2192 int axisscale(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
2193 {
2194   int type,room;
2195   double min,max,inc;
2196 
2197   _getobj(obj,"type",inst,&type);
2198   min=*(double *)argv[2];
2199   max=*(double *)argv[3];
2200   room=*(int *)argv[4];
2201   axischangescale(obj,inst,&min,&max,&inc,room);
2202   if (_putobj(obj,"min",inst,&min)) return 1;
2203   if (_putobj(obj,"max",inst,&max)) return 1;
2204   if (_putobj(obj,"inc",inst,&inc)) return 1;
2205   return 0;
2206 }
2207 
axiscoordinate(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)2208 int axiscoordinate(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
2209 {
2210   int x,y,dx,dy,type,dir,len;
2211   double min,max,c,t,val;
2212 
2213   _getobj(obj,"type",inst,&type);
2214   _getobj(obj,"min",inst,&min);
2215   _getobj(obj,"max",inst,&max);
2216   _getobj(obj,"x",inst,&x);
2217   _getobj(obj,"y",inst,&y);
2218   _getobj(obj,"length",inst,&len);
2219   _getobj(obj,"direction",inst,&dir);
2220   if (min==max) return 1;
2221   if (len==0) return 1;
2222   dx=*(int *)argv[2];
2223   dy=*(int *)argv[3];
2224   c=dir/18000.0*MPI;
2225   t=-(x-dx)*cos(c)+(y-dy)*sin(c);
2226   if (type==1) {
2227     if (min<=0) return 1;
2228     if (max<=0) return 1;
2229     min=log10(min);
2230     max=log10(max);
2231   } else if (type==2) {
2232     if (min*max<=0) return 1;
2233     min=1.0/min;
2234     max=1.0/max;
2235   }
2236   val=min+(max-min)*t/len;
2237   if (type==1) {
2238     val=pow(10.0,val);
2239   } else if (type==2) {
2240     if (val==0) return 1;
2241     val=1.0/val;
2242   }
2243   *(double *)rval=val;
2244   return 0;
2245 }
2246 
axisautoscalefile(struct objlist * obj,char * inst,char * fileobj,double * rmin,double * rmax)2247 int axisautoscalefile(struct objlist *obj,char *inst,char *fileobj,double *rmin,double *rmax)
2248 {
2249   struct objlist *fobj;
2250   int fnum;
2251   int *fdata;
2252   struct narray iarray;
2253   double min,max,min1,max1;
2254   int i,id,set;
2255   char buf[20];
2256   char *argv2[4];
2257   struct narray *minmax;
2258 
2259   arrayinit(&iarray,sizeof(int));
2260   if (getobjilist(fileobj,&fobj,&iarray,FALSE,NULL)) return 1;
2261   fnum=arraynum(&iarray);
2262   fdata=arraydata(&iarray);
2263   _getobj(obj,"id",inst,&id);
2264   sprintf(buf,"axis:%d",id);
2265   argv2[0]=(void *)buf;
2266   argv2[1]=NULL;
2267   set=FALSE;
2268   for (i=0;i<fnum;i++) {
2269     minmax=NULL;
2270     getobj(fobj,"bounding",fdata[i],1,argv2,&minmax);
2271     if (arraynum(minmax)>=2) {
2272       min1=*(double *)arraynget(minmax,0);
2273       max1=*(double *)arraynget(minmax,1);
2274       if (!set) {
2275         min=min1;
2276         max=max1;
2277       } else {
2278         if (min1<min) min=min1;
2279         if (max1>max) max=max1;
2280       }
2281       set=TRUE;
2282     }
2283   }
2284   arraydel(&iarray);
2285   if (!set) return 1;
2286   *rmin=min;
2287   *rmax=max;
2288   return 0;
2289 }
2290 
axisautoscale(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)2291 int axisautoscale(struct objlist *obj,char *inst,char *rval,
2292                   int argc,char **argv)
2293 {
2294   char *fileobj;
2295   int room;
2296   double omin,omax,oinc;
2297   double min,max,inc;
2298 
2299   fileobj=(char *)argv[2];
2300   room=*(int *)argv[3];
2301   if (axisautoscalefile(obj,inst,fileobj,&min,&max)==0) {
2302     axischangescale(obj,inst,&min,&max,&inc,room);
2303     _getobj(obj,"min",inst,&omin);
2304     _getobj(obj,"max",inst,&omax);
2305     _getobj(obj,"inc",inst,&oinc);
2306     if (omin==omax) {
2307       if (_putobj(obj,"min",inst,&min)) return 1;
2308       if (_putobj(obj,"max",inst,&max)) return 1;
2309     }
2310     if (oinc==0) {
2311       if (_putobj(obj,"inc",inst,&inc)) return 1;
2312     }
2313   }
2314   return 0;
2315 }
2316 
axisgetautoscale(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)2317 int axisgetautoscale(struct objlist *obj,char *inst,char *rval,
2318                   int argc,char **argv)
2319 {
2320   char *fileobj;
2321   int room;
2322   double min,max,inc;
2323   struct narray *result;
2324 
2325   result=*(struct narray **)rval;
2326   arrayfree(result);
2327   *(struct narray **)rval=NULL;
2328   fileobj=(char *)argv[2];
2329   room=*(int *)argv[3];
2330   if (axisautoscalefile(obj,inst,fileobj,&min,&max)==0) {
2331     axischangescale(obj,inst,&min,&max,&inc,room);
2332     result=arraynew(sizeof(double));
2333     arrayadd(result,&min);
2334     arrayadd(result,&max);
2335     arrayadd(result,&inc);
2336     *(struct narray **)rval=result;
2337   }
2338   return 0;
2339 }
2340 
axistight(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)2341 int axistight(struct objlist *obj,char *inst,char *rval,
2342               int argc,char **argv)
2343 {
2344   char *axis,*axis2;
2345   struct narray iarray;
2346   int anum,id,oid;
2347   struct objlist *aobj;
2348 
2349   if ((!_getobj(obj,"reference",inst,&axis)) && (axis!=NULL)) {
2350     arrayinit(&iarray,sizeof(int));
2351     if (!getobjilist(axis,&aobj,&iarray,FALSE,NULL)) {
2352       anum=arraynum(&iarray);
2353       if (anum>0) {
2354         id=*(int *)arraylast(&iarray);
2355         if (getobj(aobj,"oid",id,0,NULL,&oid)!=-1) {
2356           if ((axis2=(char *)memalloc(strlen(chkobjectname(aobj))+10))!=NULL) {
2357             sprintf(axis2,"%s:^%d",chkobjectname(aobj),oid);
2358             _putobj(obj,"reference",inst,axis2);
2359             memfree(axis);
2360           }
2361         }
2362       }
2363     }
2364     arraydel(&iarray);
2365   }
2366   if ((!_getobj(obj,"adjust_axis",inst,&axis)) && (axis!=NULL)) {
2367     arrayinit(&iarray,sizeof(int));
2368     if (!getobjilist(axis,&aobj,&iarray,FALSE,NULL)) {
2369       anum=arraynum(&iarray);
2370       if (anum>0) {
2371         id=*(int *)arraylast(&iarray);
2372         if (getobj(aobj,"oid",id,0,NULL,&oid)!=-1) {
2373           if ((axis2=(char *)memalloc(strlen(chkobjectname(aobj))+10))!=NULL) {
2374             sprintf(axis2,"%s:^%d",chkobjectname(aobj),oid);
2375             _putobj(obj,"adjust_axis",inst,axis2);
2376             memfree(axis);
2377           }
2378         }
2379       }
2380     }
2381     arraydel(&iarray);
2382   }
2383   return 0;
2384 }
2385 
axisgrouping(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)2386 int axisgrouping(struct objlist *obj,char *inst,char *rval,
2387                  int argc,char **argv)
2388 {
2389   struct narray *iarray;
2390   int *data;
2391   int num,gnum;
2392   char *group,*group2;
2393   char *inst2,type;
2394 
2395   iarray=(struct narray *)argv[2];
2396   num=arraynum(iarray);
2397   if (num<1) return 1;
2398   data=(int *)arraydata(iarray);
2399   if (data[0]==1) type='f';
2400   else if (data[0]==2) type='s';
2401   else if (data[0]==3) type='c';
2402   gnum=axisuniqgroup(obj,type);
2403   if ((data[0]==1) || (data[0]==2)) {
2404     if (num<5) return 1;
2405     if ((inst2=chkobjinst(obj,data[1]))!=NULL) {
2406       if ((group=memalloc(13))!=NULL) {
2407         _getobj(obj,"group",inst2,&group2);
2408         memfree(group2);
2409         sprintf(group,"%cX%d",type,gnum);
2410         _putobj(obj,"group",inst2,group);
2411       }
2412       if ((group=memalloc(13))!=NULL) {
2413         _getobj(obj,"name",inst2,&group2);
2414         memfree(group2);
2415         sprintf(group,"%cX%d",type,gnum);
2416         _putobj(obj,"name",inst2,group);
2417       }
2418     }
2419     if ((inst2=chkobjinst(obj,data[2]))!=NULL) {
2420       if ((group=memalloc(13))!=NULL) {
2421         _getobj(obj,"group",inst2,&group2);
2422         memfree(group2);
2423         sprintf(group,"%cY%d",type,gnum);
2424         _putobj(obj,"group",inst2,group);
2425       }
2426       if ((group=memalloc(13))!=NULL) {
2427         _getobj(obj,"name",inst2,&group2);
2428         memfree(group2);
2429         sprintf(group,"%cY%d",type,gnum);
2430         _putobj(obj,"name",inst2,group);
2431       }
2432     }
2433     if ((inst2=chkobjinst(obj,data[3]))!=NULL) {
2434       if ((group=memalloc(13))!=NULL) {
2435         _getobj(obj,"group",inst2,&group2);
2436         memfree(group2);
2437         sprintf(group,"%cU%d",type,gnum);
2438         _putobj(obj,"group",inst2,group);
2439       }
2440       if ((group=memalloc(13))!=NULL) {
2441         _getobj(obj,"name",inst2,&group2);
2442         memfree(group2);
2443         sprintf(group,"%cU%d",type,gnum);
2444         _putobj(obj,"name",inst2,group);
2445       }
2446     }
2447     if ((inst2=chkobjinst(obj,data[4]))!=NULL) {
2448       if ((group=memalloc(13))!=NULL) {
2449         _getobj(obj,"group",inst2,&group2);
2450         memfree(group2);
2451         sprintf(group,"%cR%d",type,gnum);
2452         _putobj(obj,"group",inst2,group);
2453       }
2454       if ((group=memalloc(13))!=NULL) {
2455         _getobj(obj,"name",inst2,&group2);
2456         memfree(group2);
2457         sprintf(group,"%cR%d",type,gnum);
2458         _putobj(obj,"name",inst2,group);
2459       }
2460     }
2461   } else if (data[0]==3) {
2462     if (num<3) return 1;
2463     if ((inst2=chkobjinst(obj,data[1]))!=NULL) {
2464       if ((group=memalloc(13))!=NULL) {
2465         _getobj(obj,"group",inst2,&group2);
2466         memfree(group2);
2467         sprintf(group,"%cX%d",type,gnum);
2468         _putobj(obj,"group",inst2,group);
2469       }
2470       if ((group=memalloc(13))!=NULL) {
2471         _getobj(obj,"name",inst2,&group2);
2472         memfree(group2);
2473         sprintf(group,"%cX%d",type,gnum);
2474         _putobj(obj,"name",inst2,group);
2475       }
2476     }
2477     if ((inst2=chkobjinst(obj,data[2]))!=NULL) {
2478       if ((group=memalloc(13))!=NULL) {
2479         _getobj(obj,"group",inst2,&group2);
2480         memfree(group2);
2481         sprintf(group,"%cY%d",type,gnum);
2482         _putobj(obj,"group",inst2,group);
2483       }
2484       if ((group=memalloc(13))!=NULL) {
2485         _getobj(obj,"name",inst2,&group2);
2486         memfree(group2);
2487         sprintf(group,"%cY%d",type,gnum);
2488         _putobj(obj,"name",inst2,group);
2489       }
2490     }
2491   }
2492   return 0;
2493 }
2494 
axisgrouppos(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)2495 int axisgrouppos(struct objlist *obj,char *inst,char *rval,
2496                  int argc,char **argv)
2497 {
2498   int x0,y0,x,y,lenx,leny,len,dir;
2499   struct narray *iarray;
2500   struct narray *array;
2501   int *data;
2502   int anum;
2503   char *inst2;
2504 
2505   iarray=(struct narray *)argv[2];
2506   anum=arraynum(iarray);
2507   if (anum<1) return 1;
2508   data=(int *)arraydata(iarray);
2509   if ((data[0]==1) || (data[0]==2)) {
2510     if (anum<9) return 1;
2511     x0=data[5];
2512     y0=data[6];
2513     lenx=data[7];
2514     leny=data[8];
2515     if ((inst2=chkobjinst(obj,data[1]))!=NULL) {
2516       x=x0;
2517       y=y0;
2518       len=lenx;
2519       dir=0;
2520       _putobj(obj,"direction",inst2,&dir);
2521       _putobj(obj,"x",inst2,&x);
2522       _putobj(obj,"y",inst2,&y);
2523       _putobj(obj,"length",inst2,&len);
2524       _getobj(obj,"bbox",inst2,&array);
2525       arrayfree(array);
2526       _putobj(obj,"bbox",inst2,NULL);
2527     }
2528     if ((inst2=chkobjinst(obj,data[2]))!=NULL) {
2529       x=x0;
2530       y=y0;
2531       len=leny;
2532       dir=9000;
2533       _putobj(obj,"direction",inst2,&dir);
2534       _putobj(obj,"x",inst2,&x);
2535       _putobj(obj,"y",inst2,&y);
2536       _putobj(obj,"length",inst2,&len);
2537       _getobj(obj,"bbox",inst2,&array);
2538       arrayfree(array);
2539       _putobj(obj,"bbox",inst2,NULL);
2540     }
2541     if ((inst2=chkobjinst(obj,data[3]))!=NULL) {
2542       x=x0;
2543       y=y0-leny;
2544       len=lenx;
2545       dir=0;
2546       _putobj(obj,"direction",inst2,&dir);
2547       _putobj(obj,"x",inst2,&x);
2548       _putobj(obj,"y",inst2,&y);
2549       _putobj(obj,"length",inst2,&len);
2550       _getobj(obj,"bbox",inst2,&array);
2551       arrayfree(array);
2552       _putobj(obj,"bbox",inst2,NULL);
2553     }
2554     if ((inst2=chkobjinst(obj,data[4]))!=NULL) {
2555       x=x0+lenx;
2556       y=y0;
2557       len=leny;
2558       dir=9000;
2559       _putobj(obj,"direction",inst2,&dir);
2560       _putobj(obj,"x",inst2,&x);
2561       _putobj(obj,"y",inst2,&y);
2562       _putobj(obj,"length",inst2,&len);
2563       _getobj(obj,"bbox",inst2,&array);
2564       arrayfree(array);
2565       _putobj(obj,"bbox",inst2,NULL);
2566     }
2567   } else if (data[0]==3) {
2568     if (anum<7) return 1;
2569     x0=data[3];
2570     y0=data[4];
2571     lenx=data[5];
2572     leny=data[6];
2573     if ((inst2=chkobjinst(obj,data[1]))!=NULL) {
2574       x=x0;
2575       y=y0;
2576       len=lenx;
2577       dir=0;
2578       _putobj(obj,"direction",inst2,&dir);
2579       _putobj(obj,"x",inst2,&x);
2580       _putobj(obj,"y",inst2,&y);
2581       _putobj(obj,"length",inst2,&len);
2582       _getobj(obj,"bbox",inst2,&array);
2583       arrayfree(array);
2584       _putobj(obj,"bbox",inst2,NULL);
2585     }
2586     if ((inst2=chkobjinst(obj,data[2]))!=NULL) {
2587       x=x0;
2588       y=y0;
2589       len=leny;
2590       dir=9000;
2591       _putobj(obj,"direction",inst2,&dir);
2592       _putobj(obj,"x",inst2,&x);
2593       _putobj(obj,"y",inst2,&y);
2594       _putobj(obj,"length",inst2,&len);
2595       _getobj(obj,"bbox",inst2,&array);
2596       arrayfree(array);
2597       _putobj(obj,"bbox",inst2,NULL);
2598     }
2599   }
2600   return 0;
2601 }
2602 
axisdefgrouping(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)2603 int axisdefgrouping(struct objlist *obj,char *inst,char *rval,
2604                  int argc,char **argv)
2605 {
2606   int dir,gauge,num,align,oidx,oidy;
2607   struct narray *iarray;
2608   int *data;
2609   int anum;
2610   char *ref,*ref2;
2611   char *inst2;
2612 
2613   if (axisgrouping(obj,inst,rval,argc,argv)) return 1;
2614   iarray=(struct narray *)argv[2];
2615   anum=arraynum(iarray);
2616   if (anum<1) return 1;
2617   data=(int *)arraydata(iarray);
2618   oidx=oidy=0;
2619   if ((data[0]==1) || (data[0]==2)) {
2620     if (anum<5) return 1;
2621     if ((inst2=chkobjinst(obj,data[1]))!=NULL) {
2622       dir=0;
2623       if (data[0]==2) gauge=0;
2624       else gauge=2;
2625       num=2;
2626       align=0;
2627       _putobj(obj,"gauge",inst2,&gauge);
2628       _putobj(obj,"num",inst2,&num);
2629       _putobj(obj,"num_align",inst2,&align);
2630       _putobj(obj,"direction",inst2,&dir);
2631       _getobj(obj,"oid",inst2,&oidx);
2632       if (data[0]==1) axisloadconfig(obj,inst2,"[axis_fX]");
2633       else axisloadconfig(obj,inst2,"[axis_sX]");
2634     }
2635     if ((inst2=chkobjinst(obj,data[2]))!=NULL) {
2636       dir=9000;
2637       if (data[0]==2) gauge=0;
2638       else gauge=3;
2639       num=1;
2640       align=2;
2641       _putobj(obj,"gauge",inst2,&gauge);
2642       _putobj(obj,"num",inst2,&num);
2643       _putobj(obj,"num_align",inst2,&align);
2644       _putobj(obj,"direction",inst2,&dir);
2645       _getobj(obj,"oid",inst2,&oidy);
2646       if (data[0]==1) axisloadconfig(obj,inst2,"[axis_fY]");
2647       else axisloadconfig(obj,inst2,"[axis_sY]");
2648     }
2649     if ((inst2=chkobjinst(obj,data[3]))!=NULL) {
2650       dir=0;
2651       if (data[0]==2) gauge=0;
2652       else gauge=3;
2653       num=1;
2654       align=0;
2655       _putobj(obj,"gauge",inst2,&gauge);
2656       _putobj(obj,"num",inst2,&num);
2657       _putobj(obj,"num_align",inst2,&align);
2658       _putobj(obj,"direction",inst2,&dir);
2659       if ((ref=memalloc(15))!=NULL) {
2660         _getobj(obj,"reference",inst2,&ref2);
2661         memfree(ref2);
2662         sprintf(ref,"axis:^%d",oidx);
2663         _putobj(obj,"reference",inst2,ref);
2664       }
2665       if (data[0]==1) axisloadconfig(obj,inst2,"[axis_fU]");
2666       else axisloadconfig(obj,inst2,"[axis_sU]");
2667     }
2668     if ((inst2=chkobjinst(obj,data[4]))!=NULL) {
2669       dir=9000;
2670       if (data[0]==2) gauge=0;
2671       else gauge=2;
2672       num=2;
2673       align=1;
2674       _putobj(obj,"gauge",inst2,&gauge);
2675       _putobj(obj,"num",inst2,&num);
2676       _putobj(obj,"num_align",inst2,&align);
2677       _putobj(obj,"direction",inst2,&dir);
2678       if ((ref=memalloc(15))!=NULL) {
2679         _getobj(obj,"reference",inst2,&ref2);
2680         memfree(ref2);
2681         sprintf(ref,"axis:^%d",oidy);
2682         _putobj(obj,"reference",inst2,ref);
2683       }
2684       if (data[0]==1) axisloadconfig(obj,inst2,"[axis_fR]");
2685       else axisloadconfig(obj,inst2,"[axis_sR]");
2686     }
2687     if (anum<9) return 0;
2688     if (axisgrouppos(obj,inst,rval,argc,argv)) return 1;
2689   } else if (data[0]==3) {
2690     if (anum<3) return 1;
2691     if ((inst2=chkobjinst(obj,data[1]))!=NULL) {
2692       dir=0;
2693       gauge=1;
2694       num=2;
2695       align=0;
2696       _putobj(obj,"gauge",inst2,&gauge);
2697       _putobj(obj,"num",inst2,&num);
2698       _putobj(obj,"num_align",inst2,&align);
2699       _putobj(obj,"direction",inst2,&dir);
2700       _getobj(obj,"oid",inst2,&oidx);
2701     }
2702     if ((inst2=chkobjinst(obj,data[2]))!=NULL) {
2703       dir=9000;
2704       gauge=1;
2705       num=1;
2706       align=2;
2707       _putobj(obj,"gauge",inst2,&gauge);
2708       _putobj(obj,"num",inst2,&num);
2709       _putobj(obj,"num_align",inst2,&align);
2710       _putobj(obj,"direction",inst2,&dir);
2711       _getobj(obj,"oid",inst2,&oidy);
2712     }
2713     if ((inst2=chkobjinst(obj,data[1]))!=NULL) {
2714       if ((ref=memalloc(15))!=NULL) {
2715         _getobj(obj,"adjust_axis",inst2,&ref2);
2716         memfree(ref2);
2717         sprintf(ref,"axis:^%d",oidy);
2718         _putobj(obj,"adjust_axis",inst2,ref);
2719       }
2720       axisloadconfig(obj,inst2,"[axis_cX]");
2721     }
2722     if ((inst2=chkobjinst(obj,data[2]))!=NULL) {
2723       if ((ref=memalloc(15))!=NULL) {
2724         _getobj(obj,"adjust_axis",inst2,&ref2);
2725         memfree(ref2);
2726         sprintf(ref,"axis:^%d",oidx);
2727         _putobj(obj,"adjust_axis",inst2,ref);
2728       }
2729       axisloadconfig(obj,inst2,"[axis_cY]");
2730     }
2731     if (anum<7) return 0;
2732     if (axisgrouppos(obj,inst,rval,argc,argv)) return 1;
2733   }
2734   return 0;
2735 }
2736 
axissave(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)2737 int axissave(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
2738 {
2739   int i,j,id;
2740   char *group,*group2;
2741   struct narray *array;
2742   int anum;
2743   char **adata;
2744   char type;
2745   int idx,idy,idu,idr;
2746   int findX,findY,findU,findR;
2747   char *inst2;
2748   char buf[12];
2749   char *s;
2750 
2751   if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
2752   _getobj(obj,"group",inst,&group);
2753   if ((group==NULL) || (group[0]=='a')) return 0;
2754   array=(struct narray *)argv[2];
2755   anum=arraynum(array);
2756   adata=arraydata(array);
2757   for (j=0;j<anum;j++)
2758     if (strcmp("grouping",adata[j])==0) return 0;
2759   _getobj(obj,"id",inst,&id);
2760   findX=findY=findU=findR=FALSE;
2761   type=group[0];
2762   for (i=0;i<=id;i++) {
2763     inst2=chkobjinst(obj,i);
2764     _getobj(obj,"group",inst2,&group2);
2765     if ((group2!=NULL) && (group2[0]==type)) {
2766       if (strcmp(group+2,group2+2)==0) {
2767         if (group2[1]=='X') {
2768           findX=TRUE;
2769           idx=i;
2770         } else if (group2[1]=='Y') {
2771           findY=TRUE;
2772           idy=i;
2773         } else if (group2[1]=='U') {
2774           findU=TRUE;
2775           idu=i;
2776         } else if (group2[1]=='R') {
2777           findR=TRUE;
2778           idr=i;
2779         }
2780       }
2781     }
2782   }
2783   if ((type=='f') && findX && findY && findU && findR) {
2784     if ((s=nstrnew())==NULL) return 1;
2785     if ((s=nstrcat(s,*(char **)rval))==NULL) return 1;
2786     if ((s=nstrcat(s,"\naxis::grouping 1"))==NULL) return 1;
2787     sprintf(buf," %d",idx);
2788     if ((s=nstrcat(s,buf))==NULL) return 1;
2789     sprintf(buf," %d",idy);
2790     if ((s=nstrcat(s,buf))==NULL) return 1;
2791     sprintf(buf," %d",idu);
2792     if ((s=nstrcat(s,buf))==NULL) return 1;
2793     sprintf(buf," %d\n",idr);
2794     if ((s=nstrcat(s,buf))==NULL) return 1;
2795     memfree(*(char **)rval);
2796     *(char **)rval=s;
2797   } else if ((type=='s') && findX && findY && findU && findR) {
2798     if ((s=nstrnew())==NULL) return 1;
2799     if ((s=nstrcat(s,*(char **)rval))==NULL) return 1;
2800     if ((s=nstrcat(s,"\naxis::grouping 2"))==NULL) return 1;
2801     sprintf(buf," %d",idx);
2802     if ((s=nstrcat(s,buf))==NULL) return 1;
2803     sprintf(buf," %d",idy);
2804     if ((s=nstrcat(s,buf))==NULL) return 1;
2805     sprintf(buf," %d",idu);
2806     if ((s=nstrcat(s,buf))==NULL) return 1;
2807     sprintf(buf," %d\n",idr);
2808     if ((s=nstrcat(s,buf))==NULL) return 1;
2809     memfree(*(char **)rval);
2810     *(char **)rval=s;
2811   } else if ((type=='c') && findX && findY) {
2812     if ((s=nstrnew())==NULL) return 1;
2813     if ((s=nstrcat(s,*(char **)rval))==NULL) return 1;
2814     if ((s=nstrcat(s,"\naxis::grouping 3"))==NULL) return 1;
2815     sprintf(buf," %d",idx);
2816     if ((s=nstrcat(s,buf))==NULL) return 1;
2817     sprintf(buf," %d\n",idy);
2818     if ((s=nstrcat(s,buf))==NULL) return 1;
2819     memfree(*(char **)rval);
2820     *(char **)rval=s;
2821   }
2822   return 0;
2823 }
2824 
axismanager(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)2825 int axismanager(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
2826 {
2827   int i,id,lastinst;
2828   char *group,*group2;
2829   char type;
2830   char *inst2;
2831 
2832   _getobj(obj,"id",inst,&id);
2833   _getobj(obj,"group",inst,&group);
2834   if ((group==NULL) || (group[0]=='a')) {
2835     *(int *)rval=id;
2836     return 0;
2837   }
2838   lastinst=chkobjlastinst(obj);
2839   id=-1;
2840   type=group[0];
2841   for (i=0;i<=lastinst;i++) {
2842     inst2=chkobjinst(obj,i);
2843     _getobj(obj,"group",inst2,&group2);
2844     if ((group2!=NULL) && (group2[0]==type) && (strcmp(group+2,group2+2)==0))
2845       id=i;
2846   }
2847   *(int *)rval=id;
2848   return 0;
2849 }
2850 
axisscalepush(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)2851 int axisscalepush(struct objlist *obj,char *inst,char *rval,int argc,
2852                   char **argv)
2853 {
2854   struct narray *array;
2855   int num;
2856   double min,max,inc,*data;
2857 
2858   _getobj(obj,"min",inst,&min);
2859   _getobj(obj,"max",inst,&max);
2860   _getobj(obj,"inc",inst,&inc);
2861   if ((min==0) && (max==0) && (inc==0)) return 0;
2862   _getobj(obj,"scale_history",inst,&array);
2863   if (array==NULL) {
2864     if ((array=arraynew(sizeof(double)))==NULL) return 1;
2865     if (_putobj(obj,"scale_history",inst,array)) {
2866       arrayfree(array);
2867       return 1;
2868     }
2869   }
2870   num=arraynum(array);
2871   data=arraydata(array);
2872   if ((num>=3) && (data[0]==min) && (data[1]==max) && (data[2]==inc)) return 0;
2873   if (num>30) {
2874     arrayndel(array,29);
2875     arrayndel(array,28);
2876     arrayndel(array,27);
2877   }
2878   arrayins(array,&inc,0);
2879   arrayins(array,&max,0);
2880   arrayins(array,&min,0);
2881   return 0;
2882 }
2883 
axisscalepop(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)2884 int axisscalepop(struct objlist *obj,char *inst,char *rval,int argc,
2885                   char **argv)
2886 {
2887   struct narray *array;
2888   int num;
2889   double *data;
2890 
2891   _getobj(obj,"scale_history",inst,&array);
2892   if (array==NULL) return 0;
2893   num=arraynum(array);
2894   data=arraydata(array);
2895   if (num>=3) {
2896     _putobj(obj,"min",inst,&(data[0]));
2897     _putobj(obj,"max",inst,&(data[1]));
2898     _putobj(obj,"inc",inst,&(data[2]));
2899     arrayndel(array,2);
2900     arrayndel(array,1);
2901     arrayndel(array,0);
2902   }
2903   if (arraynum(array)==0) {
2904     arrayfree(array);
2905     _putobj(obj,"scale_history",inst,NULL);
2906   }
2907   return 0;
2908 }
2909 
2910 #define TBLNUM 81
2911 
2912 struct objtable axis[TBLNUM] = {
2913   {"init",NVFUNC,NEXEC,axisinit,NULL,0},
2914   {"done",NVFUNC,NEXEC,axisdone,NULL,0},
2915   {"next",NPOINTER,0,NULL,NULL,0},
2916   {"group",NSTR,NREAD,NULL,NULL,0},
2917   {"min",NDOUBLE,NREAD|NWRITE,NULL,NULL,0},
2918   {"max",NDOUBLE,NREAD|NWRITE,NULL,NULL,0},
2919   {"inc",NDOUBLE,NREAD|NWRITE,NULL,NULL,0},
2920   {"div",NINT,NREAD|NWRITE,oputabs,NULL,0},
2921   {"type",NENUM,NREAD|NWRITE,NULL,axistypechar,0},
2922   {"x",NINT,NREAD|NWRITE,axisgeometry,NULL,0},
2923   {"y",NINT,NREAD|NWRITE,axisgeometry,NULL,0},
2924   {"direction",NINT,NREAD|NWRITE,axisgeometry,NULL,0},
2925   {"baseline",NBOOL,NREAD|NWRITE,NULL,NULL,0},
2926   {"length",NINT,NREAD|NWRITE,axisgeometry,NULL,0},
2927   {"width",NINT,NREAD|NWRITE,NULL,NULL,0},
2928   {"style",NIARRAY,NREAD|NWRITE,NULL,NULL,0},
2929   {"adjust_axis",NOBJ,NREAD|NWRITE,NULL,NULL,0},
2930   {"adjust_position",NINT,NREAD|NWRITE,NULL,NULL,0},
2931   {"arrow",NENUM,NREAD|NWRITE,NULL,arrowchar,0},
2932   {"arrow_length",NINT,NREAD|NWRITE,axisput,NULL,0},
2933   {"arrow_width",NINT,NREAD|NWRITE,axisput,NULL,0},
2934   {"wave",NENUM,NREAD|NWRITE,NULL,arrowchar,0},
2935   {"wave_length",NINT,NREAD|NWRITE,axisput,NULL,0},
2936   {"wave_width",NINT,NREAD|NWRITE,axisput,NULL,0},
2937   {"reference",NOBJ,NREAD|NWRITE,NULL,NULL,0},
2938   {"gauge",NENUM,NREAD|NWRITE,NULL,axisgaugechar,0},
2939   {"gauge_min",NDOUBLE,NREAD|NWRITE,NULL,NULL,0},
2940   {"gauge_max",NDOUBLE,NREAD|NWRITE,NULL,NULL,0},
2941   {"gauge_style",NIARRAY,NREAD|NWRITE,NULL,NULL,0},
2942   {"gauge_length1",NINT,NREAD|NWRITE,oputabs,NULL,0},
2943   {"gauge_width1",NINT,NREAD|NWRITE,oputabs,NULL,0},
2944   {"gauge_length2",NINT,NREAD|NWRITE,oputabs,NULL,0},
2945   {"gauge_width2",NINT,NREAD|NWRITE,oputabs,NULL,0},
2946   {"gauge_length3",NINT,NREAD|NWRITE,oputabs,NULL,0},
2947   {"gauge_width3",NINT,NREAD|NWRITE,oputabs,NULL,0},
2948   {"gauge_R",NINT,NREAD|NWRITE,NULL,NULL,0},
2949   {"gauge_G",NINT,NREAD|NWRITE,NULL,NULL,0},
2950   {"gauge_B",NINT,NREAD|NWRITE,NULL,NULL,0},
2951   {"num",NENUM,NREAD|NWRITE,NULL,axisnumchar,0},
2952   {"num_begin",NINT,NREAD|NWRITE,oputabs,NULL,0},
2953   {"num_step",NINT,NREAD|NWRITE,oputabs,NULL,0},
2954   {"num_num",NINT,NREAD|NWRITE,axisput,NULL,0},
2955   {"num_auto_norm",NINT,NREAD|NWRITE,oputabs,NULL,0},
2956   {"num_head",NSTR,NREAD|NWRITE,NULL,NULL,0},
2957   {"num_format",NSTR,NREAD|NWRITE,axisput,NULL,0},
2958   {"num_tail",NSTR,NREAD|NWRITE,NULL,NULL,0},
2959   {"num_log_pow",NBOOL,NREAD|NWRITE,NULL,NULL,0},
2960   {"num_pt",NINT,NREAD|NWRITE,axisput,NULL,0},
2961   {"num_space",NINT,NREAD|NWRITE,NULL,NULL,0},
2962   {"num_font",NSTR,NREAD|NWRITE,NULL,NULL,0},
2963   {"num_jfont",NSTR,NREAD|NWRITE,NULL,NULL,0},
2964   {"num_script_size",NINT,NREAD|NWRITE,axisput,NULL,0},
2965   {"num_align",NENUM,NREAD|NWRITE,NULL,anumalignchar,0},
2966   {"num_no_zero",NBOOL,NREAD|NWRITE,NULL,NULL,0},
2967   {"num_direction",NENUM,NREAD|NWRITE,NULL,anumdirchar,0},
2968   {"num_shift_p",NINT,NREAD|NWRITE,NULL,NULL,0},
2969   {"num_shift_n",NINT,NREAD|NWRITE,NULL,NULL,0},
2970   {"num_R",NINT,NREAD|NWRITE,NULL,NULL,0},
2971   {"num_G",NINT,NREAD|NWRITE,NULL,NULL,0},
2972   {"num_B",NINT,NREAD|NWRITE,NULL,NULL,0},
2973   {"scale_push",NVFUNC,NREAD|NEXEC,axisscalepush,NULL,0},
2974   {"scale_pop",NVFUNC,NREAD|NEXEC,axisscalepop,NULL,0},
2975   {"scale_history",NDARRAY,NREAD,NULL,NULL,0},
2976   {"scale",NVFUNC,NREAD|NEXEC,axisscale,"ddi",0},
2977   {"auto_scale",NVFUNC,NREAD|NEXEC,axisautoscale,"oi",0},
2978   {"get_auto_scale",NDAFUNC,NREAD|NEXEC,axisgetautoscale,"oi",0},
2979   {"clear",NVFUNC,NREAD|NEXEC,axisclear,NULL,0},
2980   {"adjust",NVFUNC,NREAD|NEXEC,axisadjust,NULL,0},
2981   {"draw",NVFUNC,NREAD|NEXEC,axisdraw,"i",0},
2982   {"bbox",NIAFUNC,NREAD|NEXEC,axisbbox,"",0},
2983   {"move",NVFUNC,NREAD|NEXEC,axismove,"ii",0},
2984   {"change",NVFUNC,NREAD|NEXEC,axischange,"iii",0},
2985   {"zooming",NVFUNC,NREAD|NEXEC,axiszoom,"iii",0},
2986   {"match",NBFUNC,NREAD|NEXEC,axismatch,"iiiii",0},
2987   {"coordinate",NDFUNC,NREAD|NEXEC,axiscoordinate,"ii",0},
2988   {"tight",NVFUNC,NREAD|NEXEC,axistight,NULL,0},
2989   {"grouping",NVFUNC,NREAD|NEXEC,axisgrouping,"ia",0},
2990   {"default_grouping",NVFUNC,NREAD|NEXEC,axisdefgrouping,"ia",0},
2991   {"group_position",NVFUNC,NREAD|NEXEC,axisgrouppos,"ia",0},
2992   {"group_manager",NIFUNC,NREAD|NEXEC,axismanager,NULL,0},
2993   {"save",NSFUNC,NREAD|NEXEC,axissave,"sa",0},
2994 };
2995 
addaxis()2996 void *addaxis()
2997 /* addaxis() returns NULL on error */
2998 {
2999   return addobject(NAME,NULL,PARENT,VERSION,TBLNUM,axis,ERRNUM,axiserrorlist,NULL,NULL);
3000 }
3001