Subversion Repositories wimsdev

Rev

Rev 8899 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  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.  
  25. /***************** Nothing should need change hereafter *****************/
  26.  
  27. #include <gd.h>
  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) {
  47.     snprintf(filebase,sizeof(filebase),"gifs"); return;
  48.   }
  49.   if(p==NULL || *p==0) {
  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;
  55.   }
  56.   for(p1=find_word_start(p); *p1; p1=find_word_start(p2)) {
  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);
  62.   }
  63.   snprintf(filebase+strlen(filebase),
  64.          sizeof(filebase)-strlen(filebase),
  65.          " gifs");
  66. }
  67.  
  68. /* File opening: with security */
  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) {
  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.     }
  103.   }
  104.   else {
  105.     snprintf(namebuf,sizeof(namebuf),"%s",n);
  106.     f=fopen(namebuf,"r");
  107.   }
  108.   imgtype:
  109.   if(t && f!=NULL) {
  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");
  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) {
  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);
  132.     if(!isfinite(v[t])) exit(-1);
  133.   }
  134.   return t;
  135. }
  136.  
  137. /* test one condition. Returns 1 if met. */
  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') {
  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;
  165.   }
  166.   if(*p=='p' || strncasecmp(p,"point",3)==0) {
  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;
  174.   }
  175.   if(strncasecmp(p,"rectangle",1)==0) {
  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;
  182.   }
  183.   if(strncasecmp(p,"circle",1)==0) {
  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;
  188.   }
  189.   if(strncasecmp(p,"ellipse",1)==0) {
  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;
  196.   }
  197.   if(strncasecmp(p,"bound",1)==0) {
  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;
  226.   }
  227.   exit(-1);
  228. }
  229.  
  230. static
  231. int oneline(char *p)
  232. {
  233.   char *p1, *p2;
  234.   int t, rev;
  235.  
  236.   if(strparchr(p,'|')!=NULL) {
  237.     t=0; for(p1=p;p1;p1=p2) {
  238.       p2=strparchr(p1,'|'); if(p2!=NULL) *p2++=0;
  239.       t|=oneline(p1);
  240.     }
  241.     return t;
  242.   }
  243.   if(strparchr(p,'&')!=NULL) {
  244.     t=1; for(p1=p;p1;p1=p2) {
  245.       p2=strparchr(p1,'&'); if(p2!=NULL) *p2++=0;
  246.       t&=oneline(p1);
  247.     }
  248.     return t;
  249.   }
  250.   p1=find_word_start(p); rev=0;
  251.   if(*p1=='^') {
  252.     rev=1; p1=find_word_start(++p1);
  253.   }
  254.   if(*p1==0) return rev^1;
  255.   if(*p1=='(') {
  256.     p1++; p2=find_matching(p1,')');
  257.     if(p2==NULL) exit(-1);
  258.     *p2=0; return oneline(p1)^rev;
  259.   }
  260.     return test(p1)^rev;
  261. }
  262.  
  263. /* Returns the number of lines matching the click coordinates */
  264. int main()
  265. {
  266.   char *p, *p2, *p3;
  267.   int i,j;
  268.  
  269.   fbase();
  270.   p=getenv("wims_exec_parm"); if(p==NULL || *p==0) return -1;
  271.   p=find_word_start(p); p2=strchr(p,'\n');
  272.   if(p2==NULL) p2=p+strlen(p); else *p2++=0;
  273.   p3=strchr(p,','); if(p3==NULL) return -1; else *p3++=0;
  274.   clickx=atoi(p); clicky=atoi(p3);
  275.   for(i=1,p=find_word_start(p2);*p;i++, p=find_word_start(p2)) {
  276.     fprintf(stderr,"Line %d.\n",i);
  277.     p2=strchr(p,'\n'); if(p2==NULL) p2=p+strlen(p); else *p2++=0;
  278.     if(*p==0) continue;
  279.     j=oneline(p);
  280.     if(j) {printf("%d %d",i,prec); return 0;}
  281.   }
  282.   printf("-1"); return 0;
  283. }
  284.