1 /*
2  * $Id: olegend.c,v 1.3 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: olegend.c,v $
27  * Revision 1.3  2002/07/06 08:51:42  isizaka
28  * change to GPL.
29  *
30  * Revision 1.2  1999/04/15 12:15:27  isizaka
31  * for release 6.03.01
32  *
33  * Revision 1.1  1999/03/17 13:46:09  isizaka
34  * Initial revision
35  *
36  *
37  **/
38 
39 #include <stdlib.h>
40 #include <string.h>
41 #include <math.h>
42 #include "ngraph.h"
43 #include "object.h"
44 #include "olegend.h"
45 
46 #define NAME "legend"
47 #define PARENT "draw"
48 #define VERSION  "1.00.00"
49 #define TRUE  1
50 #define FALSE 0
51 
52 #define ERRNUM 1
53 
54 char *legenderrorlist[ERRNUM]={
55   "",
56 };
57 
legendinit(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)58 int legendinit(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
59 {
60   if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
61   return 0;
62 }
63 
legenddone(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)64 int legenddone(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
65 {
66   if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
67   return 0;
68 }
69 
legendgeometry(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)70 int legendgeometry(struct objlist *obj,char *inst,char *rval,
71                    int argc,char **argv)
72 {
73   struct narray *array;
74 
75   _getobj(obj,"bbox",inst,&array);
76   arrayfree(array);
77   if (_putobj(obj,"bbox",inst,NULL)) return 1;
78   return 0;
79 }
80 
legendmatch(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)81 int legendmatch(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
82 {
83   int minx,miny,maxx,maxy,err;
84   int bminx,bminy,bmaxx,bmaxy;
85   int i,num,*data;
86   double x1,y1,x2,y2;
87   double r,r2,r3,ip;
88   struct narray *array;
89 
90   *(int *)rval=FALSE;
91   if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
92   if (_exeobj(obj,"bbox",inst,0,NULL)) return 1;
93   _getobj(obj,"bbox",inst,&array);
94   if (array==NULL) return 0;
95   minx=*(int *)argv[2];
96   miny=*(int *)argv[3];
97   maxx=*(int *)argv[4];
98   maxy=*(int *)argv[5];
99   err=*(int *)argv[6];
100   if ((minx==maxx) && (miny==maxy)) {
101     num=arraynum(array)-4;
102     data=arraydata(array);
103     for (i=0;i<num-2;i+=2) {
104       x1=data[4+i];
105       y1=data[5+i];
106       x2=data[6+i];
107       y2=data[7+i];
108       r2=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
109       r=sqrt((minx-x1)*(minx-x1)+(miny-y1)*(miny-y1));
110       r3=sqrt((minx-x2)*(minx-x2)+(miny-y2)*(miny-y2));
111       if ((r<=err) || (r3<err)) {
112         *(int *)rval=TRUE;
113         break;
114       }
115       if (r2!=0) {
116         ip=((x2-x1)*(minx-x1)+(y2-y1)*(miny-y1))/r2;
117         if ((0<=ip) && (ip<=r2)) {
118           x2=x1+(x2-x1)*ip/r2;
119           y2=y1+(y2-y1)*ip/r2;
120           r=sqrt((minx-x2)*(minx-x2)+(miny-y2)*(miny-y2));
121           if (r<err) {
122             *(int *)rval=TRUE;
123             break;
124           }
125         }
126       }
127     }
128   } else {
129     if (arraynum(array)<4) return 1;
130     bminx=*(int *)arraynget(array,0);
131     bminy=*(int *)arraynget(array,1);
132     bmaxx=*(int *)arraynget(array,2);
133     bmaxy=*(int *)arraynget(array,3);
134     if ((minx<=bminx) && (bminx<=maxx)
135      && (minx<=bmaxx) && (bmaxx<=maxx)
136      && (miny<=bminy) && (bminy<=maxy)
137      && (miny<=bmaxy) && (bmaxy<=maxy)) *(int *)rval=TRUE;
138   }
139   return 0;
140 }
141 
legendbbox(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)142 int legendbbox(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
143 {
144   int minx,miny,maxx,maxy;
145   int x,y,num;
146   struct narray *points;
147   int pnum;
148   int *pdata;
149   struct narray *array;
150   int i,width;
151 
152   array=*(struct narray **)rval;
153   if (arraynum(array)!=0) return 0;
154   _getobj(obj,"points",inst,&points);
155   _getobj(obj,"width",inst,&width);
156   pnum=arraynum(points);
157   pdata=arraydata(points);
158   num=pnum/2;
159   if (num<2) return 0;
160   if ((array==NULL) && ((array=arraynew(sizeof(int)))==NULL)) return 1;
161   maxx=minx=pdata[0];
162   maxy=miny=pdata[1];
163   arrayadd(array,&(pdata[0]));
164   arrayadd(array,&(pdata[1]));
165   for (i=1;i<num;i++) {
166     x=pdata[i*2];
167     y=pdata[i*2+1];
168     arrayadd(array,&x);
169     arrayadd(array,&y);
170     if (x<minx) minx=x;
171     if (x>maxx) maxx=x;
172     if (y<miny) miny=y;
173     if (y>maxy) maxy=y;
174   }
175   minx-=width/2;
176   miny-=width/2;
177   maxx+=width/2;
178   maxy+=width/2;
179   arrayins(array,&(maxy),0);
180   arrayins(array,&(maxx),0);
181   arrayins(array,&(miny),0);
182   arrayins(array,&(minx),0);
183   if (arraynum(array)==0) {
184     arrayfree(array);
185     return 1;
186   }
187   *(struct narray **)rval=array;
188   return 0;
189 }
190 
legendmove(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)191 int legendmove(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
192 {
193   struct narray *points,*array;
194   int i,num,*pdata;
195 
196   if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
197   _getobj(obj,"points",inst,&points);
198   num=arraynum(points);
199   pdata=arraydata(points);
200   for (i=0;i<num;i++) {
201     if (i%2==0) pdata[i]+=*(int *)argv[2];
202     else pdata[i]+=*(int *)argv[3];
203   }
204   _getobj(obj,"bbox",inst,&array);
205   arrayfree(array);
206   if (_putobj(obj,"bbox",inst,NULL)) return 1;
207   return 0;
208 }
209 
210 
legendchange(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)211 int legendchange(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
212 {
213   struct narray *points,*array;
214   int num,*pdata;
215   int point,x,y;
216 
217   if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
218   _getobj(obj,"points",inst,&points);
219   point=*(int *)argv[2];
220   x=*(int *)argv[3];
221   y=*(int *)argv[4];
222   num=arraynum(points);
223   pdata=arraydata(points);
224   if (point<num/2) {
225     pdata[point*2]+=x;
226     pdata[point*2+1]+=y;
227   }
228   _getobj(obj,"bbox",inst,&array);
229   arrayfree(array);
230   if (_putobj(obj,"bbox",inst,NULL)) return 1;
231   return 0;
232 }
233 
legendzoom(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)234 int legendzoom(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
235 {
236   struct narray *points,*array,*style;
237   int i,num,width,snum,*pdata,*sdata;
238   int refx,refy;
239   double zoom;
240 
241   if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
242   zoom=(*(int *)argv[2])/10000.0;
243   refx=(*(int *)argv[3]);
244   refy=(*(int *)argv[4]);
245   _getobj(obj,"points",inst,&points);
246   _getobj(obj,"width",inst,&width);
247   _getobj(obj,"style",inst,&style);
248   num=arraynum(points);
249   pdata=arraydata(points);
250   snum=arraynum(style);
251   sdata=arraydata(style);
252   if (num<4) return 0;
253   for (i=0;i<num;i++) {
254     if (i%2==0) pdata[i]=(pdata[i]-refx)*zoom+refx;
255     else pdata[i]=(pdata[i]-refy)*zoom+refy;
256   }
257   width=width*zoom;
258   for (i=0;i<snum;i++) sdata[i]=sdata[i]*zoom;
259   if (_putobj(obj,"width",inst,&width)) return 1;
260   _getobj(obj,"bbox",inst,&array);
261   arrayfree(array);
262   if (_putobj(obj,"bbox",inst,NULL)) return 1;
263   return 0;
264 }
265 
266 #define TBLNUM 6
267 
268 struct objtable legend[TBLNUM] = {
269   {"init",NVFUNC,0,legendinit,NULL,0},
270   {"done",NVFUNC,0,legenddone,NULL,0},
271   {"bbox",NIAFUNC,NREAD|NEXEC,NULL,"",0},
272   {"move",NVFUNC,NREAD|NEXEC,NULL,"ii",0},
273   {"zooming",NVFUNC,NREAD|NEXEC,NULL,"iii",0},
274   {"match",NBFUNC,NREAD|NEXEC,NULL,"iiiii",0},
275 };
276 
addlegend()277 void *addlegend()
278 /* addlegend() returns NULL on error */
279 {
280   return addobject(NAME,NULL,PARENT,VERSION,TBLNUM,legend,ERRNUM,legenderrorlist,NULL,NULL);
281 }
282