Rev 8171 | Rev 8899 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
10 | reyssat | 1 | /* Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis |
2 | * |
||
3 | * This program is free software; you can redistribute it and/or modify |
||
4 | * it under the terms of the GNU General Public License as published by |
||
5 | * the Free Software Foundation; either version 2 of the License, or |
||
6 | * (at your option) any later version. |
||
7 | * |
||
8 | * This program is distributed in the hope that it will be useful, |
||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
11 | * GNU General Public License for more details. |
||
12 | * |
||
13 | * You should have received a copy of the GNU General Public License |
||
14 | * along with this program; if not, write to the Free Software |
||
15 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
||
16 | */ |
||
17 | |||
7676 | bpr | 18 | /* Check the zone of click in an image */ |
10 | reyssat | 19 | |
7676 | bpr | 20 | /* Return value: -1 if no condition is met. |
21 | * n>0 for the line of condition meeting the click. |
||
8149 | bpr | 22 | * empty if condition has error. |
23 | */ |
||
10 | reyssat | 24 | |
25 | /***************** Nothing should need change hereafter *****************/ |
||
26 | |||
8177 | bpr | 27 | #include <gd.h> |
10 | reyssat | 28 | #include "../Lib/libwims.h" |
29 | |||
30 | #define VLEN 1024 |
||
31 | |||
32 | int clickx, clicky; |
||
33 | int prec; |
||
34 | double v[VLEN+2]; |
||
35 | char namebuf[2048]; |
||
36 | char oldfile[1024]=""; |
||
37 | char filebase[10240]; |
||
38 | gdImagePtr image=NULL; |
||
39 | int testcolor; |
||
40 | |||
41 | void fbase(void) |
||
42 | { |
||
43 | char *p, *m, *p1, *p2; |
||
44 | p=getenv("w_insdraw_filebase"); |
||
45 | m=getenv("module_dir"); if(m==NULL) m=""; |
||
46 | if(strncmp(m,"modules/",strlen("modules/"))!=0) { |
||
7676 | bpr | 47 | snprintf(filebase,sizeof(filebase),"gifs"); return; |
10 | reyssat | 48 | } |
49 | if(p==NULL || *p==0) { |
||
7676 | bpr | 50 | if(strncmp(m,"modules/adm/",strlen("modules/adm"))==0) |
51 | snprintf(filebase,sizeof(filebase),"%s/insdraw gifs",m); |
||
52 | else |
||
53 | snprintf(filebase,sizeof(filebase),"%s gifs",m); |
||
54 | return; |
||
10 | reyssat | 55 | } |
56 | for(p1=find_word_start(p); *p1; p1=find_word_start(p2)) { |
||
7676 | bpr | 57 | p2=find_word_end(p1); if(*p2) *p2++=0; |
58 | if(strstr(p1,"..")!=NULL) continue; |
||
59 | snprintf(filebase+strlen(filebase), |
||
60 | sizeof(filebase)-strlen(filebase), |
||
61 | " %s/%s",m,p1); |
||
10 | reyssat | 62 | } |
63 | snprintf(filebase+strlen(filebase), |
||
7676 | bpr | 64 | sizeof(filebase)-strlen(filebase), |
65 | " gifs"); |
||
10 | reyssat | 66 | } |
67 | |||
7676 | bpr | 68 | /* File opening: with security */ |
10 | reyssat | 69 | FILE *open4read(char *n) |
70 | { |
||
71 | char *p, *p1, *p2; |
||
72 | int t; |
||
73 | FILE *f; |
||
74 | n=find_word_start(n); |
||
75 | if(*n==0) return NULL; |
||
76 | p=filebase; |
||
77 | p1=n+strlen(n)-4;if(p1<n || strcasecmp(p1,".gif")!=0) t=1; else t=0; |
||
78 | if(p!=NULL && *p!=0) { |
||
7676 | bpr | 79 | char pbuf[MAX_LINELEN+1]; |
80 | snprintf(pbuf,sizeof(pbuf),"%s",p); |
||
81 | p=find_word_start(pbuf); if(strstr(p,"..")!=NULL) return NULL; |
||
82 | if(*n=='/' || strstr(n,"..")!=NULL) return NULL; |
||
83 | /* prohibit unusual file/dir names */ |
||
84 | for(p1=p;*p1;p1++) |
||
85 | if(!isalnum(*p1) && !isspace(*p1) && strchr("~_-/.",*p1)==NULL) |
||
86 | return NULL; |
||
87 | for(p1=n;*p1;p1++) |
||
88 | if(!isalnum(*p1) && !isspace(*p1) && strchr("~_-/.",*p1)==NULL) |
||
89 | return NULL; |
||
90 | f=NULL; |
||
91 | for(p1=p; *p1; p1=find_word_start(p2)) { |
||
92 | if(*p1=='/') return NULL; |
||
93 | p2=find_word_end(p1); |
||
94 | if(*p2) *p2++=0; |
||
95 | snprintf(namebuf,sizeof(namebuf),"%s/%s",p1,n); |
||
96 | f=fopen(namebuf,"r"); if(f!=NULL) goto imgtype; |
||
97 | } |
||
98 | p1=getenv("w_wims_session"); |
||
99 | if(p1!=NULL && strstr(p1,"..")==NULL && strncmp(n,"insert",6)==0) { |
||
100 | snprintf(namebuf,sizeof(namebuf),"../s2/%s/%s",p1,n); |
||
101 | f=fopen(namebuf,"r"); |
||
102 | } |
||
10 | reyssat | 103 | } |
104 | else { |
||
7676 | bpr | 105 | snprintf(namebuf,sizeof(namebuf),"%s",n); |
106 | f=fopen(namebuf,"r"); |
||
10 | reyssat | 107 | } |
108 | imgtype: |
||
109 | if(t && f!=NULL) { |
||
7676 | bpr | 110 | char tbuf[1024],sbuf[4096]; |
111 | fclose(f); f=NULL; |
||
112 | p1=getenv("TMPDIR"); if(p1==NULL || *p1==0) p1="."; |
||
113 | snprintf(tbuf,sizeof(tbuf),"%s/drawfile_.gif",p1); |
||
114 | snprintf(sbuf,sizeof(sbuf),"convert %s %s",namebuf,tbuf); |
||
115 | if (system(sbuf)) fprintf(stderr,"system failed"); |
||
116 | f=fopen(tbuf,"r"); |
||
10 | reyssat | 117 | } |
118 | if(f!=NULL) snprintf(oldfile,sizeof(oldfile),"%s",n); |
||
119 | return f; |
||
120 | } |
||
121 | |||
122 | int getvalue(char *p, int n) |
||
123 | { |
||
124 | int t; |
||
125 | char *p1; |
||
126 | if(n<0) n=VLEN; |
||
127 | for(t=0; t<n; t++,p=p1) { |
||
7676 | bpr | 128 | p1=find_item_end(p); if(*p1) *p1++=0; |
129 | p=find_word_start(p); |
||
130 | if(*p==0) break; |
||
131 | v[t]=strevalue(p); |
||
8171 | bpr | 132 | if(!isfinite(v[t])) exit(-1); |
10 | reyssat | 133 | } |
7676 | bpr | 134 | return t; |
10 | reyssat | 135 | } |
136 | |||
7676 | bpr | 137 | /* test one condition. Returns 1 if met. */ |
10 | reyssat | 138 | int test(char *p) |
139 | { |
||
140 | char *p1; |
||
141 | int i,t; |
||
142 | double d; |
||
143 | p=find_word_start(p); p1=find_item_end(p); |
||
144 | if(*p1) *p1++=0; else exit(-1); |
||
145 | prec=0; |
||
146 | *p=tolower(*p); |
||
147 | if(strncasecmp(p,"polygon",3)==0 || *p=='g') { |
||
7676 | bpr | 148 | int cross; |
149 | double x0,y0,a1,b1,c1,a2,b2,c2,s1,s2,s3,s4; |
||
150 | t=getvalue(p1,-1); if(t<6) exit(-1); |
||
151 | cross=0; x0=-19; y0=-19; |
||
152 | a1=clicky-y0;b1=x0-clickx;c1=clickx*y0-x0*clicky; |
||
153 | v[t]=v[0];v[t+1]=v[1]; |
||
154 | for(i=2;i<t+2;i+=2) { |
||
155 | a2=v[i+1]-v[i-1];b2=v[i-2]-v[i]; |
||
156 | c2=v[i]*v[i-1]-v[i-2]*v[i+1]; |
||
157 | s1=a1*v[i-2]+b1*v[i-1]+c1; |
||
158 | s2=a1*v[i]+b1*v[i+1]+c1; |
||
159 | s3=a2*x0+b2*y0+c2; |
||
160 | s4=a2*clickx+b2*clicky+c2; |
||
161 | if(s1==0) continue; |
||
162 | if(s1*s2<=0 && s3*s4<=0) cross++; |
||
163 | } |
||
164 | return cross&1; |
||
10 | reyssat | 165 | } |
166 | if(*p=='p' || strncasecmp(p,"point",3)==0) { |
||
7676 | bpr | 167 | t=getvalue(p1,-1); if(t<2) exit(-1); |
168 | for(i=0;i<t;i+=2) { |
||
169 | d=sqrt(pow(v[i]-clickx,2)+pow(v[i+1]-clicky,2)); |
||
170 | if(d<=4) return 1; |
||
171 | if(d<=7) {prec=1; return 1;} |
||
172 | } |
||
173 | return 0; |
||
10 | reyssat | 174 | } |
175 | if(strncasecmp(p,"rectangle",1)==0) { |
||
7676 | bpr | 176 | double x1,x2,y1,y2; |
177 | if(getvalue(p1,4)!=4) exit(-1); |
||
178 | x1=min(v[0],v[2]); x2=max(v[0],v[2]); |
||
179 | y1=min(v[1],v[3]); y2=max(v[1],v[3]); |
||
180 | if(clickx<x1 || clickx>x2 || clicky<y1 || clicky>y2) return 0; |
||
181 | else return 1; |
||
10 | reyssat | 182 | } |
183 | if(strncasecmp(p,"circle",1)==0) { |
||
7676 | bpr | 184 | double dist; |
185 | if(getvalue(p1,3)!=3 || v[2]<0) exit(-1); |
||
186 | dist=sqrt(pow(v[0]-clickx,2)+pow(v[1]-clicky,2)); |
||
187 | if(dist>v[2]/2) return 0; else return 1; |
||
10 | reyssat | 188 | } |
189 | if(strncasecmp(p,"ellipse",1)==0) { |
||
7676 | bpr | 190 | double dist; |
191 | if(getvalue(p1,4)!=4) exit(-1); |
||
192 | if(v[2]<=0 || v[3]<=0) exit(-1); |
||
193 | dist=sqrt(pow(2*(v[0]-clickx)/v[2],2)+pow(2*(v[1]-clicky)/v[3],2)); |
||
194 | if(dist>1) return 0; else return 1; |
||
195 | return 0; |
||
10 | reyssat | 196 | } |
197 | if(strncasecmp(p,"bound",1)==0) { |
||
7676 | bpr | 198 | char *p2; |
199 | FILE *f; |
||
200 | int c, T; |
||
201 | p2=find_item_end(p1); if(*p2) *p2++=0; |
||
202 | T=getvalue(p2,2); if(T!=2 && T!=0) exit(-1); |
||
203 | p1=find_word_start(p1); *find_word_end(p1)=0; |
||
204 | if(*p1==0) exit(-1); |
||
205 | if(strcmp(p1,oldfile)!=0) { |
||
206 | if(image) gdImageDestroy(image); |
||
207 | f=open4read(p1); if(f==NULL) exit(-1); |
||
208 | image=gdImageCreateFromGif(f); fclose(f); |
||
209 | if(T==0) { |
||
210 | testcolor=gdImageGetPixel(image,1,1); |
||
211 | } |
||
212 | else { |
||
213 | testcolor=gdImageColorAllocate(image,2,3,5); |
||
214 | gdImageFill(image,clickx,clicky,testcolor); |
||
215 | } |
||
216 | } |
||
217 | if(T==0) { |
||
218 | c=gdImageGetPixel(image,clickx,clicky); |
||
219 | if(c!=testcolor) return 1; |
||
220 | } |
||
221 | else { |
||
222 | c=gdImageGetPixel(image,v[0],v[1]); |
||
223 | if(c==testcolor) return 1; |
||
224 | } |
||
225 | return 0; |
||
10 | reyssat | 226 | } |
227 | exit(-1); |
||
228 | } |
||
229 | |||
230 | int oneline(char *p) |
||
231 | { |
||
232 | char *p1, *p2; |
||
233 | int t, rev; |
||
234 | |||
235 | if(strparchr(p,'|')!=NULL) { |
||
7676 | bpr | 236 | t=0; for(p1=p;p1;p1=p2) { |
237 | p2=strparchr(p1,'|'); if(p2!=NULL) *p2++=0; |
||
238 | t|=oneline(p1); |
||
239 | } |
||
240 | return t; |
||
10 | reyssat | 241 | } |
242 | if(strparchr(p,'&')!=NULL) { |
||
7676 | bpr | 243 | t=1; for(p1=p;p1;p1=p2) { |
244 | p2=strparchr(p1,'&'); if(p2!=NULL) *p2++=0; |
||
245 | t&=oneline(p1); |
||
246 | } |
||
247 | return t; |
||
10 | reyssat | 248 | } |
249 | p1=find_word_start(p); rev=0; |
||
250 | if(*p1=='^') { |
||
7676 | bpr | 251 | rev=1; p1=find_word_start(++p1); |
10 | reyssat | 252 | } |
253 | if(*p1==0) return rev^1; |
||
254 | if(*p1=='(') { |
||
7676 | bpr | 255 | p1++; p2=find_matching(p1,')'); |
256 | if(p2==NULL) exit(-1); |
||
257 | *p2=0; return oneline(p1)^rev; |
||
10 | reyssat | 258 | } |
259 | return test(p1)^rev; |
||
260 | } |
||
261 | |||
8149 | bpr | 262 | /* Returns the number of lines matching the click coordinates */ |
10 | reyssat | 263 | int main() |
264 | { |
||
265 | char *p, *p2, *p3; |
||
266 | int i,j; |
||
267 | |||
268 | fbase(); |
||
269 | p=getenv("wims_exec_parm"); if(p==NULL || *p==0) return -1; |
||
7676 | bpr | 270 | p=find_word_start(p); p2=strchr(p,'\n'); |
10 | reyssat | 271 | if(p2==NULL) p2=p+strlen(p); else *p2++=0; |
272 | p3=strchr(p,','); if(p3==NULL) return -1; else *p3++=0; |
||
273 | clickx=atoi(p); clicky=atoi(p3); |
||
274 | for(i=1,p=find_word_start(p2);*p;i++, p=find_word_start(p2)) { |
||
7676 | bpr | 275 | fprintf(stderr,"Line %d.\n",i); |
276 | p2=strchr(p,'\n'); if(p2==NULL) p2=p+strlen(p); else *p2++=0; |
||
277 | if(*p==0) continue; |
||
278 | j=oneline(p); |
||
279 | if(j) {printf("%d %d",i,prec); return 0;} |
||
10 | reyssat | 280 | } |
281 | printf("-1"); return 0; |
||
282 | } |