Subversion Repositories wimsdev

Rev

Rev 3840 | Rev 7676 | 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
 
18
        /* Check the zone of click in an image */
19
 
20
        /* Return value: -1 if no condition is met.
21
         * n>0 for the line of condition meeting the click.
22
         * empty if condition has error. */
23
 
24
/***************** Nothing should need change hereafter *****************/
25
 
26
#include "../Lib/libwims.h"
7614 schaersvoo 27
#include <gd.h>
10 reyssat 28
 
29
#define VLEN 1024
30
 
31
int clickx, clicky;
32
int prec;
33
double v[VLEN+2];
34
char namebuf[2048];
35
char oldfile[1024]="";
36
char filebase[10240];
37
gdImagePtr image=NULL;
38
int testcolor;
39
 
40
void fbase(void)
41
{
42
    char *p, *m, *p1, *p2;
43
    p=getenv("w_insdraw_filebase");
44
    m=getenv("module_dir"); if(m==NULL) m="";
45
    if(strncmp(m,"modules/",strlen("modules/"))!=0) {
46
        snprintf(filebase,sizeof(filebase),"gifs"); return;
47
    }
48
    if(p==NULL || *p==0) {
49
        if(strncmp(m,"modules/adm/",strlen("modules/adm"))==0)
50
          snprintf(filebase,sizeof(filebase),"%s/insdraw gifs",m);
51
        else
52
          snprintf(filebase,sizeof(filebase),"%s gifs",m);
53
        return;
54
    }
55
    for(p1=find_word_start(p); *p1; p1=find_word_start(p2)) {
56
        p2=find_word_end(p1); if(*p2) *p2++=0;
57
        if(strstr(p1,"..")!=NULL) continue;
58
        snprintf(filebase+strlen(filebase),
59
                 sizeof(filebase)-strlen(filebase),
60
                 " %s/%s",m,p1);
61
    }
62
    snprintf(filebase+strlen(filebase),
63
             sizeof(filebase)-strlen(filebase),
64
             " gifs");
65
}
66
 
67
        /* File opening: with security */
68
FILE *open4read(char *n)
69
{
70
    char *p, *p1, *p2;
71
    int t;
72
    FILE *f;
73
    n=find_word_start(n);
74
    if(*n==0) return NULL;
75
    p=filebase;
76
    p1=n+strlen(n)-4;if(p1<n || strcasecmp(p1,".gif")!=0) t=1; else t=0;
77
    if(p!=NULL && *p!=0) {
78
        char pbuf[MAX_LINELEN+1];
79
        snprintf(pbuf,sizeof(pbuf),"%s",p);
80
        p=find_word_start(pbuf); if(strstr(p,"..")!=NULL) return NULL;
81
        if(*n=='/' || strstr(n,"..")!=NULL) return NULL;
82
                /* prohibit unusual file/dir names */
83
        for(p1=p;*p1;p1++)
84
          if(!isalnum(*p1) && !isspace(*p1) && strchr("~_-/.",*p1)==NULL)
85
            return NULL;
86
        for(p1=n;*p1;p1++)
87
          if(!isalnum(*p1) && !isspace(*p1) && strchr("~_-/.",*p1)==NULL)
88
            return NULL;
89
        f=NULL;
90
        for(p1=p; *p1; p1=find_word_start(p2)) {
91
            if(*p1=='/') return NULL;
92
            p2=find_word_end(p1);
93
            if(*p2) *p2++=0;
94
            snprintf(namebuf,sizeof(namebuf),"%s/%s",p1,n);
95
            f=fopen(namebuf,"r"); if(f!=NULL) goto imgtype;
96
        }
97
        p1=getenv("w_wims_session");
98
        if(p1!=NULL && strstr(p1,"..")==NULL && strncmp(n,"insert",6)==0) {
99
            snprintf(namebuf,sizeof(namebuf),"../s2/%s/%s",p1,n);
100
            f=fopen(namebuf,"r");
101
        }
102
    }
103
    else {
104
        snprintf(namebuf,sizeof(namebuf),"%s",n);
105
        f=fopen(namebuf,"r");
106
    }
107
    imgtype:
108
    if(t && f!=NULL) {
109
        char tbuf[1024],sbuf[4096];
110
        fclose(f); f=NULL;
111
        p1=getenv("TMPDIR"); if(p1==NULL || *p1==0) p1=".";
112
        snprintf(tbuf,sizeof(tbuf),"%s/drawfile_.gif",p1);
113
        snprintf(sbuf,sizeof(sbuf),"convert %s %s",namebuf,tbuf);
3840 kbelabas 114
        if (system(sbuf)) fprintf(stderr,"system failed");
115
        f=fopen(tbuf,"r");     
10 reyssat 116
    }
117
    if(f!=NULL) snprintf(oldfile,sizeof(oldfile),"%s",n);
118
    return f;
119
}
120
 
121
int getvalue(char *p, int n)
122
{
123
    int t;
124
    char *p1;
125
    if(n<0) n=VLEN;
126
    for(t=0; t<n; t++,p=p1) {
127
        p1=find_item_end(p); if(*p1) *p1++=0;
128
        p=find_word_start(p);
129
        if(*p==0) break;
130
        v[t]=strevalue(p);
131
        if(!finite(v[t])) exit(-1);
132
    }
133
    return t;
134
}
135
 
136
        /* test one condition. Returns 1 if met. */
137
int test(char *p)
138
{
139
    char *p1;
140
    int i,t;
141
    double d;
142
    p=find_word_start(p); p1=find_item_end(p);
143
    if(*p1) *p1++=0; else exit(-1);
144
    prec=0;
145
    *p=tolower(*p);
146
    if(strncasecmp(p,"polygon",3)==0 || *p=='g') {
147
        int cross;
148
        double x0,y0,a1,b1,c1,a2,b2,c2,s1,s2,s3,s4;
149
        t=getvalue(p1,-1); if(t<6) exit(-1);
150
        cross=0; x0=-19; y0=-19;
151
        a1=clicky-y0;b1=x0-clickx;c1=clickx*y0-x0*clicky;
152
        v[t]=v[0];v[t+1]=v[1];
153
        for(i=2;i<t+2;i+=2) {
154
            a2=v[i+1]-v[i-1];b2=v[i-2]-v[i];
155
            c2=v[i]*v[i-1]-v[i-2]*v[i+1];
156
            s1=a1*v[i-2]+b1*v[i-1]+c1;
157
            s2=a1*v[i]+b1*v[i+1]+c1;
158
            s3=a2*x0+b2*y0+c2;
159
            s4=a2*clickx+b2*clicky+c2;
160
            if(s1==0) continue;
161
            if(s1*s2<=0 && s3*s4<=0) cross++;
162
        }
163
        return cross&1;
164
    }
165
    if(*p=='p' || strncasecmp(p,"point",3)==0) {
166
        t=getvalue(p1,-1); if(t<2) exit(-1);
167
        for(i=0;i<t;i+=2) {
168
            d=sqrt(pow(v[i]-clickx,2)+pow(v[i+1]-clicky,2));
169
            if(d<=4) return 1;
170
            if(d<=7) {prec=1; return 1;}
171
        }
172
        return 0;
173
    }
174
    if(strncasecmp(p,"rectangle",1)==0) {
175
        double x1,x2,y1,y2;
176
        if(getvalue(p1,4)!=4) exit(-1);
177
        x1=min(v[0],v[2]); x2=max(v[0],v[2]);
178
        y1=min(v[1],v[3]); y2=max(v[1],v[3]);
179
        if(clickx<x1 || clickx>x2 || clicky<y1 || clicky>y2) return 0;
180
        else return 1;
181
    }
182
    if(strncasecmp(p,"circle",1)==0) {
183
        double dist;
184
        if(getvalue(p1,3)!=3 || v[2]<0) exit(-1);
185
        dist=sqrt(pow(v[0]-clickx,2)+pow(v[1]-clicky,2));
186
        if(dist>v[2]/2) return 0; else return 1;
187
    }
188
    if(strncasecmp(p,"ellipse",1)==0) {
189
        double dist;
190
        if(getvalue(p1,4)!=4) exit(-1);
191
        if(v[2]<=0 || v[3]<=0) exit(-1);
192
        dist=sqrt(pow(2*(v[0]-clickx)/v[2],2)+pow(2*(v[1]-clicky)/v[3],2));
193
        if(dist>1) return 0; else return 1;
194
        return 0;
195
    }
196
    if(strncasecmp(p,"bound",1)==0) {
197
        char *p2;
198
        FILE *f;
199
        int c, T;
200
        p2=find_item_end(p1); if(*p2) *p2++=0;
201
        T=getvalue(p2,2); if(T!=2 && T!=0) exit(-1);
202
        p1=find_word_start(p1); *find_word_end(p1)=0;
203
        if(*p1==0) exit(-1);
204
        if(strcmp(p1,oldfile)!=0) {
205
            if(image) gdImageDestroy(image);
206
            f=open4read(p1); if(f==NULL) exit(-1);
207
            image=gdImageCreateFromGif(f); fclose(f);
208
            if(T==0) {
209
                testcolor=gdImageGetPixel(image,1,1);
210
            }
211
            else {
212
                testcolor=gdImageColorAllocate(image,2,3,5);
213
                gdImageFill(image,clickx,clicky,testcolor);
214
            }
215
        }
216
        if(T==0) {
217
            c=gdImageGetPixel(image,clickx,clicky);
218
            if(c!=testcolor) return 1;
219
        }
220
        else {
221
            c=gdImageGetPixel(image,v[0],v[1]);
222
            if(c==testcolor) return 1;
223
        }
224
        return 0;
225
    }
226
    exit(-1);
227
}
228
 
229
int oneline(char *p)
230
{
231
    char *p1, *p2;
232
    int t, rev;
233
 
234
    if(strparchr(p,'|')!=NULL) {
235
        t=0; for(p1=p;p1;p1=p2) {
236
            p2=strparchr(p1,'|'); if(p2!=NULL) *p2++=0;
237
            t|=oneline(p1);
238
        }
239
        return t;
240
    }
241
    if(strparchr(p,'&')!=NULL) {
242
        t=1; for(p1=p;p1;p1=p2) {
243
            p2=strparchr(p1,'&'); if(p2!=NULL) *p2++=0;
244
            t&=oneline(p1);
245
        }
246
        return t;
247
    }
248
    p1=find_word_start(p); rev=0;
249
    if(*p1=='^') {
250
        rev=1; p1=find_word_start(++p1);
251
    }
252
    if(*p1==0) return rev^1;
253
    if(*p1=='(') {
254
        p1++; p2=find_matching(p1,')');
255
        if(p2==NULL) exit(-1);
256
        *p2=0; return oneline(p1)^rev;
257
    }
258
    return test(p1)^rev;
259
}
260
 
261
        /* Returns the number of line matching the click coordinates */
262
int main()
263
{
264
    char *p, *p2, *p3;
265
    int i,j;
266
 
267
    fbase();
268
    p=getenv("wims_exec_parm"); if(p==NULL || *p==0) return -1;
269
    p=find_word_start(p); p2=strchr(p,'\n');
270
    if(p2==NULL) p2=p+strlen(p); else *p2++=0;
271
    p3=strchr(p,','); if(p3==NULL) return -1; else *p3++=0;
272
    clickx=atoi(p); clicky=atoi(p3);
273
    for(i=1,p=find_word_start(p2);*p;i++, p=find_word_start(p2)) {
274
        fprintf(stderr,"Line %d.\n",i);
275
        p2=strchr(p,'\n'); if(p2==NULL) p2=p+strlen(p); else *p2++=0;
276
        if(*p==0) continue;
277
        j=oneline(p);
278
        if(j) {printf("%d %d",i,prec); return 0;}
279
    }
280
    printf("-1"); return 0;
281
}
282