Back to index

wims  3.65+svn20090927
objects.c
Go to the documentation of this file.
00001 /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
00002  *
00003  *  This program is free software; you can redistribute it and/or modify
00004  *  it under the terms of the GNU General Public License as published by
00005  *  the Free Software Foundation; either version 2 of the License, or
00006  *  (at your option) any later version.
00007  *
00008  *  This program is distributed in the hope that it will be useful,
00009  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  *  GNU General Public License for more details.
00012  *
00013  *  You should have received a copy of the GNU General Public License
00014  *  along with this program; if not, write to the Free Software
00015  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00016  */
00017 
00018 #include <errno.h>
00019 
00020        /* File opening: with security */
00021 FILE *open4read(char *n)
00022 {
00023     char *p, *p1, *p2, namebuf[2048];
00024     int t;
00025     FILE *f;
00026     n=find_word_start(n);
00027     if(*n==0) return NULL;
00028     p=getenv("flydraw_filebase");
00029     p1=n+strlen(n)-4;if(p1<n || strcasecmp(p1,".gif")!=0) t=1; else t=0;
00030     if(p!=NULL && *p!=0) {
00031        char pbuf[MAX_LINELEN+1];
00032        snprintf(pbuf,sizeof(pbuf),"%s",p);
00033        p=find_word_start(pbuf); if(strstr(p,"..")!=NULL) return NULL;
00034        if(*n=='/' || strstr(n,"..")!=NULL) return NULL;
00035               /* prohibit unusual file/dir names */
00036        for(p1=p;*p1;p1++)
00037          if(!isalnum(*p1) && !isspace(*p1) && strchr("~_-/.",*p1)==NULL)
00038            return NULL;
00039        for(p1=n;*p1;p1++)
00040          if(!isalnum(*p1) && !isspace(*p1) && strchr("~_-/.",*p1)==NULL)
00041            return NULL;
00042        f=NULL;
00043        for(p1=p; *p1; p1=find_word_start(p2)) {
00044            p2=find_word_end(p1);
00045            if(*p2) *p2++=0;
00046            snprintf(namebuf,sizeof(namebuf),"%s/%s",p1,n);
00047            f=fopen(namebuf,"r"); if(f!=NULL) goto imgtype;
00048        }
00049        p1=getenv("w_wims_session");
00050        if(p1!=NULL && strncmp(n,"insert",6)==0) {
00051            snprintf(namebuf,sizeof(namebuf),"../s2/%s/%s",p1,n);
00052            f=fopen(namebuf,"r");
00053        }
00054     }
00055     else {
00056        snprintf(namebuf,sizeof(namebuf),"%s",n);
00057        f=fopen(namebuf,"r");
00058     }
00059     imgtype:
00060     if(t && f!=NULL) {
00061        char tbuf[1024],sbuf[4096];
00062        fclose(f); f=NULL;
00063        p1=getenv("TMPDIR"); if(p1==NULL || *p1==0) p1=".";
00064        snprintf(tbuf,sizeof(tbuf),"%s/drawfile_.gif",p1);
00065        snprintf(sbuf,sizeof(sbuf),"convert %s %s",namebuf,tbuf);
00066        system(sbuf); f=fopen(tbuf,"r");   
00067     }
00068     return f;
00069 }
00070 
00071        /* Does nothing; just a comment. */
00072 void obj_comment(objparm *pm)
00073 {
00074     return;
00075 }
00076 
00077        /* define image size */
00078 void obj_size(objparm *pm)
00079 {
00080     sizex=rint(pm->pd[0]); sizey=rint(pm->pd[1]);
00081     if(sizex<0 || sizey<0 || sizex>MAX_SIZE || sizey>MAX_SIZE) {
00082        error("bad_size"); return;
00083     }
00084     if(image!=NULL) {
00085        error("size_already_defined"); return;
00086     }
00087     image=gdImageCreate(sizex,sizey);
00088     if(image==NULL) error("image_creation_failure");
00089     else {
00090        color_white=gdImageColorAllocate(image,255,255,255);
00091        color_black=gdImageColorAllocate(image,0,0,0);
00092        color_bounder=gdImageColorAllocate(image,1,2,3);
00093     }
00094 }
00095 
00096        /* new image */
00097 void obj_new(objparm *pm)
00098 {
00099     if(image) {
00100        gdImageDestroy(image);image=NULL;
00101     }
00102     if(pm->pcnt>=2) obj_size(pm);
00103     else sizex=sizey=0;
00104     saved=0;
00105 }
00106 
00107        /* new image */
00108 void obj_existing(objparm *pm)
00109 {
00110     FILE *inf;
00111     char *pp;
00112     
00113     if(image) {
00114        gdImageDestroy(image);image=NULL;
00115     }
00116     pp=find_word_start(pm->str);*find_word_end(pp)=0;
00117     inf=open4read(pp);
00118     if(inf==NULL) {
00119        error("file_not_exist"); return;
00120     }
00121     image=gdImageCreateFromGif(inf); fclose(inf);
00122     if(image==NULL) {
00123        error("bad_gif"); return;
00124     }
00125     sizex=image->sx; sizey=image->sy;
00126     saved=0;
00127 }
00128 
00129        /* solid line */
00130 void obj_line(objparm *pm)
00131 {
00132     scale(pm->pd,pm->p,2);
00133     gdImageLine(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3],pm->color[0]);
00134     if(vimg_enable) vimg_line(scale_buf[0],scale_buf[1],scale_buf[2],scale_buf[3]);
00135 }
00136 
00137 void _obj_arrow(objparm *pm, int twoside)
00138 {
00139     int l,ii[6],xx,yy;
00140     double dx,dy,length,dd[6];
00141     scale(pm->pd,pm->p,2); 
00142     xx=ii[0]=pm->p[2];yy=ii[1]=pm->p[3];
00143     l=pm->pd[4];if(l<0) l=0; if(l>200) l=200;
00144     scale2(pm->pd[0]-pm->pd[2],pm->pd[1]-pm->pd[3],&dx,&dy);
00145     length=sqrt(dx*dx+dy*dy);
00146     if(length<3 || l<5) goto stem;
00147     dd[0]=l*dx/length; dd[1]=l*dy/length;
00148     #define fat 0.27
00149     dd[2]=dd[0]+dd[1]*fat; dd[3]=dd[1]-dd[0]*fat;
00150     dd[4]=dd[0]-dd[1]*fat; dd[5]=dd[1]+dd[0]*fat;
00151     ii[2]=rint(dd[2])+ii[0]; ii[3]=rint(dd[3])+ii[1];
00152     ii[4]=rint(dd[4])+ii[0]; ii[5]=rint(dd[5])+ii[1];
00153     gdImageFilledPolygon(image,(gdPointPtr) ii,3,pm->color[0]);
00154     xx=rint(dd[0])+ii[0];yy=rint(dd[1])+ii[1];
00155     if(twoside) {
00156        ii[0]=pm->p[0]; ii[1]=pm->p[1];
00157        ii[2]=-rint(dd[2])+ii[0]; ii[3]=-rint(dd[3])+ii[1];
00158        ii[4]=-rint(dd[4])+ii[0]; ii[5]=-rint(dd[5])+ii[1];
00159        gdImageFilledPolygon(image,(gdPointPtr) ii,3,pm->color[0]);
00160     }
00161     stem: if(pm->fill)
00162       gdImageDashedLine(image,pm->p[0],pm->p[1],xx,yy,pm->color[0]);
00163     else
00164       gdImageLine(image,pm->p[0],pm->p[1],xx,yy,pm->color[0]);
00165     if(vimg_enable) vimg_line(scale_buf[0],scale_buf[1],scale_buf[2],scale_buf[3]);
00166 }
00167 
00168        /* Arrow */
00169 void obj_arrow(objparm *pm)
00170 {
00171     _obj_arrow(pm,0);
00172 }
00173 
00174        /* 2-sided arrow */
00175 void obj_arrow2(objparm *pm)
00176 {
00177     _obj_arrow(pm,1);
00178 }
00179 
00180        /* horizontal line */
00181 void obj_hline(objparm *pm)
00182 {
00183     scale(pm->pd,pm->p,1);
00184     if(pm->fill)
00185       gdImageDashedLine(image,0,pm->p[1],sizex,pm->p[1],pm->color[0]);
00186     else
00187       gdImageLine(image,0,pm->p[1],sizex,pm->p[1],pm->color[0]);
00188 }
00189 
00190        /* vertical line */
00191 void obj_vline(objparm *pm)
00192 {
00193     scale(pm->pd,pm->p,1);
00194     if(pm->fill)
00195       gdImageDashedLine(image,pm->p[0],0,pm->p[0],sizey,pm->color[0]);
00196     else
00197       gdImageLine(image,pm->p[0],0,pm->p[0],sizey,pm->color[0]);
00198 }
00199 
00200        /* dashed line */
00201 void obj_dline(objparm *pm)
00202 {
00203     scale(pm->pd,pm->p,2);
00204     gdImageDashedLine(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3],
00205                     pm->color[0]);
00206 }
00207 
00208        /* parallel lines.
00209         * x1,y1,x2,y2,xv,yv,n,color */
00210 void obj_parallel(objparm *pm)
00211 {
00212     int i, n, xi,yi;
00213     double xv,yv;
00214     n=pm->pd[6]; if(n<0) return; if(n>256) n=256;
00215     scale(pm->pd,pm->p,3);
00216     scale2(pm->pd[4],pm->pd[5],&xv,&yv);
00217     for(i=0;i<n;i++) {
00218        xi=rint(i*xv); yi=rint(i*yv);
00219        gdImageLine(image,pm->p[0]+xi,pm->p[1]+yi,pm->p[2]+xi,pm->p[3]+yi,
00220                   pm->color[0]);
00221        if(vimg_enable) vimg_line(scale_buf[0]+i*(scale_buf[4]-transx),
00222                               scale_buf[1]+i*(scale_buf[5]-transy),
00223                               scale_buf[2]+i*(scale_buf[4]-transx),
00224                               scale_buf[3]+i*(scale_buf[5]-transy));
00225     }
00226 }
00227 
00228        /* rectangle */
00229 void obj_rect(objparm *pm)
00230 {
00231     int x1,y1,x2,y2;
00232     scale(pm->pd,pm->p,2);
00233     x1=min(pm->p[0],pm->p[2]); x2=max(pm->p[0],pm->p[2]);
00234     y1=min(pm->p[1],pm->p[3]); y2=max(pm->p[1],pm->p[3]);
00235     if(pm->fill)
00236       gdImageFilledRectangle(image,x1,y1,x2,y2,pm->color[0]);
00237     else
00238       gdImageRectangle(image,x1,y1,x2,y2,pm->color[0]);
00239     if(vimg_enable) vimg_rect(scale_buf[0],scale_buf[1],scale_buf[2],scale_buf[3]);
00240 }
00241 
00242        /* square */
00243 void obj_square(objparm *pm)
00244 {
00245     int w,h;
00246     scale(pm->pd,pm->p,1);
00247     w=rint(pm->pd[2]); h=rint(pm->pd[2]);
00248     if(pm->fill)
00249       gdImageFilledRectangle(image,pm->p[0],pm->p[1],
00250                    pm->p[0]+w,pm->p[1]+h,pm->color[0]);
00251     else
00252       gdImageRectangle(image,pm->p[0],pm->p[1],
00253                    pm->p[0]+w,pm->p[1]+h,pm->color[0]);
00254     if(vimg_enable) vimg_rect(scale_buf[0],scale_buf[1],
00255                            scale_buf[0]+pm->pd[2],scale_buf[1]+pm->pd[2]);
00256 }
00257 
00258        /* triangle */
00259 void obj_triangle(objparm *pm)
00260 {
00261     scale(pm->pd,pm->p,3);
00262     if(pm->fill)
00263       gdImageFilledPolygon(image,(gdPointPtr) pm->p,3,pm->color[0]);
00264     else
00265       gdImagePolygon(image,(gdPointPtr) pm->p,3,pm->color[0]);
00266     if(vimg_enable) vimg_polyline(scale_buf,3,1);
00267 }
00268 
00269        /* polygon */
00270 void obj_poly(objparm *pm)
00271 {
00272     int cnt;
00273     cnt=(pm->pcnt)/2;
00274     scale(pm->pd,pm->p,cnt);
00275     if(pm->fill)
00276       gdImageFilledPolygon(image,(gdPointPtr) pm->p,cnt,pm->color[0]);
00277     else
00278       gdImagePolygon(image,(gdPointPtr) pm->p,cnt,pm->color[0]);
00279     if(vimg_enable) vimg_polyline(scale_buf,cnt,1);
00280 }
00281 
00282        /* rays */
00283 void obj_rays(objparm *pm)
00284 {
00285     int i, n;
00286     n=(pm->pcnt)/2;
00287     scale(pm->pd,pm->p,n);
00288     for(i=2;i<2*n;i+=2) {
00289        gdImageLine(image,pm->p[0],pm->p[1],pm->p[i],pm->p[i+1],pm->color[0]);
00290        if(vimg_enable) vimg_line(scale_buf[0],scale_buf[1],
00291                               scale_buf[i],scale_buf[i+1]);
00292     }
00293 }
00294 
00295        /* segments */
00296 void obj_lines(objparm *pm)
00297 {
00298     int i, n;
00299     n=(pm->pcnt)/2;
00300     scale(pm->pd,pm->p,n);
00301     for(i=2;i<2*n;i+=2) 
00302       gdImageLine(image,pm->p[i-2],pm->p[i-1],pm->p[i],pm->p[i+1],pm->color[0]);
00303     if(vimg_enable) vimg_polyline(scale_buf,n,0);
00304 }
00305 
00306        /* segments */
00307 void obj_dlines(objparm *pm)
00308 {
00309     int i, n;
00310     n=(pm->pcnt)/2;
00311     scale(pm->pd,pm->p,n);
00312     for(i=2;i<2*n;i+=2)
00313       gdImageDashedLine(image,pm->p[i-2],pm->p[i-1],pm->p[i],pm->p[i+1],pm->color[0]);
00314     if(vimg_enable) vimg_polyline(scale_buf,n,0);
00315 }
00316 
00317        /* points */
00318 void obj_points(objparm *pm)
00319 {
00320     int i, n;
00321     n=(pm->pcnt)/2;
00322     scale(pm->pd,pm->p,n);
00323     for(i=0;i<2*n;i+=2)
00324       gdImageSetPixel(image,pm->p[i],pm->p[i+1],pm->color[0]);
00325 }
00326 
00327        /* lattice. 
00328         * x0,y0,xv1,yv1,xv2,yv2,n1,n2,color */
00329 void obj_lattice(objparm *pm)
00330 {
00331     int n1,n2,i1,i2,xi1,yi1,xi2,yi2;
00332     double xv1,xv2,yv1,yv2;
00333     n1=pm->pd[6];n2=pm->pd[7]; if(n1<0 || n2<0) return;
00334     if(n1>256) n1=256; if(n2>256) n2=256;
00335     scale(pm->pd,pm->p,1);
00336     scale2(pm->pd[2],pm->pd[3],&xv1,&yv1);
00337     scale2(pm->pd[4],pm->pd[5],&xv2,&yv2);
00338     for(i1=0;i1<n1;i1++) {
00339        xi1=rint(i1*xv1)+pm->p[0]; yi1=rint(i1*yv1)+pm->p[1];
00340        for(i2=0;i2<n2;i2++) {
00341            xi2=i2*xv2+xi1;yi2=i2*yv2+yi1;
00342            gdImageSetPixel(image,xi2,yi2,pm->color[0]);
00343        }
00344     }
00345 }
00346 
00347        /* arc */
00348 void obj_arc(objparm *pm)
00349 {
00350     scale(pm->pd,pm->p,1);
00351     pm->p[2]=rint(pm->pd[2]*xscale); pm->p[3]=rint(pm->pd[3]*yscale);
00352     gdImageArc(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3],
00353               pm->pd[4],pm->pd[5],pm->color[0]);
00354     if(vimg_enable) vimg_arc(scale_buf[0],scale_buf[1],
00355                           0.5*pm->pd[2],0.5*pm->pd[3],pm->pd[4],pm->pd[5]);
00356 }
00357 
00358        /* Ellipse: centre 0,1, width 2, hight 3, color 4,5,6 */
00359 void obj_ellipse(objparm *pm)
00360 {
00361     scale(pm->pd,pm->p,1);
00362     pm->p[2]=rint(pm->pd[2]*xscale); pm->p[3]=rint(pm->pd[3]*yscale);
00363     if(pm->fill) {
00364        gdImageArc(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3],0,360,
00365                  color_bounder);
00366        gdImageFillToBorder(image,pm->p[0],pm->p[1],
00367                          color_bounder,pm->color[0]);
00368     }
00369     gdImageArc(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3],0,360,pm->color[0]);
00370     if(vimg_enable) vimg_ellipse(scale_buf[0],scale_buf[1],0.5*pm->pd[2],0.5*pm->pd[3]);
00371 }
00372 
00373        /* Circle */
00374 void obj_circle(objparm *pm)
00375 {
00376     scale(pm->pd,pm->p,1);
00377     pm->p[2]=rint(pm->pd[2]); pm->p[3]=rint(pm->pd[2]);
00378     if(pm->fill) {
00379        gdImageArc(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3],0,360,
00380                  color_bounder);
00381        gdImageFillToBorder(image,pm->p[0],pm->p[1],
00382                          color_bounder,pm->color[0]);
00383     }
00384     gdImageArc(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3],0,360,pm->color[0]);
00385 }
00386 
00387        /* flood fill */
00388 void obj_fill(objparm *pm)
00389 {
00390     scale(pm->pd,pm->p,1);
00391     gdImageFill(image,pm->p[0],pm->p[1],pm->color[0]);
00392 }
00393 
00394        /* flood fill to border*/
00395 void obj_fillb(objparm *pm)
00396 {
00397     scale(pm->pd,pm->p,1);
00398     gdImageFillToBorder(image,pm->p[0],pm->p[1],pm->color[0],pm->color[1]);
00399 }
00400 
00401 gdImagePtr himg;
00402 
00403 int makehatchimage(int x, int y, int px, int py, int col)
00404 {
00405     int c1,c2,r,g,b;
00406     gdImagePtr saveimg;
00407     himg=gdImageCreate(x,y);
00408     c1=gdImageGetPixel(image,px,py);
00409     r=gdImageRed(image,c1); g=gdImageGreen(image,c1); b=gdImageBlue(image,c1);
00410     if(r>=255) r--; else r++; if(g>=255) g--; else g++; if(b>=255) b--; else b++;
00411     c1=gdImageColorAllocate(himg,r,g,b);
00412     r=gdImageRed(image,col); g=gdImageGreen(image,col); b=gdImageBlue(image,col);
00413     c2=gdImageColorAllocate(himg,r,g,b);
00414     if(width>1) {
00415        savew=-1; saveimg=image;
00416        image=himg; c2=widthcolor(width,c2); image=saveimg;
00417        c2=gdBrushed; savew=-1;
00418     }
00419     return c2;
00420 }
00421 
00422        /* flood fill with hatching */
00423 void obj_hatchfill(objparm *pm)
00424 {
00425     int nx,ny,ax,ay, dir, c;
00426     scale(pm->pd,pm->p,1);
00427     nx=pm->pd[2]; ny=pm->pd[3]; ax=abs(nx); ay=abs(ny);
00428     if(nx==0 && ny==0) {error("bad displacement vector"); return;}
00429     if((nx>0 && ny>0) || (nx<0 && ny<0)) dir=1; else dir=-1;
00430     if(ax==0) {ax=100; dir=2;}
00431     if(ay==0) {ay=100; dir=3;}
00432     c=makehatchimage(ax,ay,pm->p[0],pm->p[1],pm->color[0]);
00433     switch(dir) {
00434        case -1: {
00435            gdImageLine(himg,0,ay-1,ax-1,0,c);
00436            if(width>1) {
00437               gdImageLine(himg,-ax,ay-1,-1,0,c);
00438               gdImageLine(himg,ax,ay-1,2*ax-1,0,c);
00439               gdImageLine(himg,0,-1,ax-1,-ay,c);
00440               gdImageLine(himg,0,2*ay-1,ax-1,ay,c);
00441            }
00442            break;
00443        }
00444        case 1: {
00445            gdImageLine(himg,0,0,ax-1,ay-1,c);
00446            if(width>1) {
00447               gdImageLine(himg,-ax,0,-1,ay-1,c);
00448               gdImageLine(himg,ax,0,2*ax-1,ay-1,c);
00449               gdImageLine(himg,0,-ay,ax-1,-1,c);
00450               gdImageLine(himg,0,ay,ax-1,2*ay-1,c);
00451            }
00452            break;
00453        }
00454        case 2: gdImageLine(himg,0,ay/2,ax-1,ay/2,c); break;
00455        case 3: gdImageLine(himg,ax/2,0,ax/2,ay-1,c); break;
00456     }
00457     gdImageSetTile(image,himg);
00458     gdImageFill(image,pm->p[0],pm->p[1],gdTiled);
00459     gdImageDestroy(himg);
00460     if(tiled) gdImageSetTile(image,tileimg);
00461 }
00462 
00463        /* flood fill with grid */
00464 void obj_gridfill(objparm *pm)
00465 {
00466     int nx,ny, c;
00467     scale(pm->pd,pm->p,1);
00468     nx=pm->pd[2]; ny=pm->pd[3]; nx=abs(nx); ny=abs(ny);
00469     if(nx==0 && ny==0) {error("bad grid size"); return;}
00470     c=makehatchimage(nx,ny,pm->p[0],pm->p[1],pm->color[0]);
00471     gdImageLine(himg,0,ny/2,nx-1,ny/2,c); gdImageLine(himg,nx/2,0,nx/2,ny-1,c);
00472     gdImageSetTile(image,himg);
00473     gdImageFill(image,pm->p[0],pm->p[1],gdTiled);
00474     gdImageDestroy(himg);
00475     if(tiled) gdImageSetTile(image,tileimg);
00476 }
00477 
00478        /* flood fill with double hatching */
00479 void obj_diafill(objparm *pm)
00480 {
00481     int nx,ny, c;
00482     scale(pm->pd,pm->p,1);
00483     nx=pm->pd[2]; ny=pm->pd[3]; nx=abs(nx); ny=abs(ny);
00484     if(nx==0 && ny==0) {error("bad grid size"); return;}
00485     c=makehatchimage(nx,ny,pm->p[0],pm->p[1],pm->color[0]);
00486     gdImageLine(himg,0,0,nx-1,ny-1,c); gdImageLine(himg,0,ny-1,nx-1,0,c);
00487     gdImageSetTile(image,himg);
00488     gdImageFill(image,pm->p[0],pm->p[1],gdTiled);
00489     gdImageDestroy(himg);
00490     if(tiled) gdImageSetTile(image,tileimg);
00491 }
00492 
00493        /* flood fill with double hatching */
00494 void obj_dotfill(objparm *pm)
00495 {
00496     int nx,ny, c;
00497     scale(pm->pd,pm->p,1);
00498     nx=pm->pd[2]; ny=pm->pd[3]; nx=abs(nx); ny=abs(ny);
00499     if(nx==0 && ny==0) {error("bad grid size"); return;}
00500     c=makehatchimage(nx,ny,pm->p[0],pm->p[1],pm->color[0]);
00501     gdImageSetPixel(himg,nx/2,ny/2,c);
00502     gdImageSetTile(image,himg);
00503     gdImageFill(image,pm->p[0],pm->p[1],gdTiled);
00504     gdImageDestroy(himg);
00505     if(tiled) gdImageSetTile(image,tileimg);
00506 }
00507 
00508 struct {
00509     char *name;
00510     gdFontPtr *fpt;
00511 } fonttab[]={
00512       {"tiny",       &gdFontTiny},
00513       {"small",      &gdFontSmall},
00514       {"medium",&gdFontMediumBold},
00515       {"large",      &gdFontLarge},
00516       {"giant",      &gdFontGiant},
00517       {"huge",       &gdFontGiant}
00518 };
00519 
00520 #define fonttab_no (sizeof(fonttab)/sizeof(fonttab[0]))
00521 
00522        /* string */
00523 void obj_string(objparm *pm)
00524 {
00525     char *pp, *pe, *p2;
00526     int i;
00527     pp=pm->str; pe=strchr(pp,','); if(pe==NULL) {
00528        error("too_few_parms"); return;
00529     }
00530     *pe++=0; pp=find_word_start(pp); *find_word_end(pp)=0;
00531     pe=find_word_start(pe); strip_trailing_spaces(pe);
00532     if(*pp) {
00533        for(i=0;i<fonttab_no && strcmp(pp,fonttab[i].name)!=0; i++);
00534        if(i>=fonttab_no) i=1;
00535     }
00536     else i=1;
00537     scale(pm->pd,pm->p,1);
00538     if(*pe=='"') {
00539        p2=strchr(pe+1,'"');
00540        if(p2 && *(p2+1)==0) {*p2=0; pe++;}
00541     }
00542     if(pm->fill)
00543       gdImageStringUp(image,*(fonttab[i].fpt),pm->p[0],pm->p[1],pe,
00544                   pm->color[0]);
00545     else
00546       gdImageString(image,*(fonttab[i].fpt),pm->p[0],pm->p[1],pe,
00547                   pm->color[0]);
00548 }
00549 
00550        /* point */
00551 void obj_point(objparm *pm)
00552 {
00553     scale(pm->pd,pm->p,1);
00554     gdImageSetPixel(image,pm->p[0],pm->p[1],pm->color[0]);
00555 }
00556 
00557        /* copy an image file */
00558 void obj_copy(objparm *pm)
00559 {
00560     char *pp;
00561     FILE *inf;
00562     gdImagePtr       insimg;
00563     
00564     pp=find_word_start(pm->str);*find_word_end(pp)=0;
00565     inf=open4read(pp);
00566     if(inf==NULL) {
00567        error("file_not_exist"); return;
00568     }
00569     insimg=gdImageCreateFromGif(inf); fclose(inf);
00570     if(insimg==NULL) {
00571        error("bad_gif"); return;
00572     }
00573     scale(pm->pd,pm->p,1);
00574     if(pm->pd[2]<0 && pm->pd[3]<0 && pm->pd[4]<0 && pm->pd[5]<0) 
00575       gdImageCopy(image,insimg,pm->p[0],pm->p[1],0,0,
00576                 insimg->sx,insimg->sy);
00577     else
00578       gdImageCopy(image,insimg,pm->p[0],pm->p[1],pm->pd[2],pm->pd[3],
00579                 pm->pd[4]-pm->pd[2],pm->pd[5]-pm->pd[3]);
00580     gdImageDestroy(insimg);
00581 }
00582 
00583        /* copy an image file, with resizing */
00584 void obj_copyresize(objparm *pm)
00585 {
00586     char *pp;
00587     FILE *inf;
00588     gdImagePtr       insimg;
00589     
00590     pp=find_word_start(pm->str);*find_word_end(pp)=0;
00591     inf=open4read(pp);
00592     if(inf==NULL) {
00593        error("file_not_found"); return;
00594     }
00595     insimg=gdImageCreateFromGif(inf); fclose(inf);
00596     if(insimg==NULL) {
00597        error("bad_gif"); return;
00598     }
00599     scale(pm->pd+4,pm->p+4,2);
00600     if(pm->pd[0]<0 && pm->pd[1]<0 && pm->pd[2]<0 && pm->pd[3]<0) 
00601       gdImageCopyResized(image,insimg,pm->p[4],pm->p[5],0,0,
00602                       pm->p[6]-pm->p[4]+1,pm->p[7]-pm->p[5]+1,
00603                       insimg->sx,insimg->sy);
00604     else
00605       gdImageCopyResized(image,insimg,pm->p[4],pm->p[5],pm->pd[0],pm->pd[1],
00606                       pm->p[6]-pm->p[4]+1,pm->p[7]-pm->p[5]+1,
00607                       pm->pd[2]-pm->pd[0]+1,pm->pd[3]-pm->pd[1]+1);
00608     gdImageDestroy(insimg);
00609 }
00610 
00611        /* set brush or tile */
00612 void obj_setbrush(objparm *pm)
00613 {
00614     char *pp;
00615     FILE *inf;
00616     gdImagePtr insimg;
00617 
00618     pp=find_word_start(pm->str); *find_word_end(pp)=0;
00619     inf=open4read(pp); if(inf==NULL) {
00620        error("file_not_found"); return;
00621     }
00622     insimg=gdImageCreateFromGif(inf); fclose(inf);
00623     if(insimg==NULL) {
00624        error("bad_gif"); return;
00625     }
00626     if(pm->fill) {
00627        gdImageSetTile(image,insimg); tiled=1; tileimg=insimg;
00628     }
00629     else {
00630        gdImageSetBrush(image,insimg);brushed=1; brushimg=insimg;
00631     }
00632 }
00633 
00634        /* kill brush */
00635 void obj_killbrush(objparm *pm)
00636 {
00637     if(brushimg) gdImageDestroy(brushimg);
00638     brushed=0; brushimg=NULL;
00639 }
00640 
00641        /* kill tile */
00642 void obj_killtile(objparm *pm)
00643 {
00644     if(tileimg) gdImageDestroy(tileimg);
00645     tiled=0; tileimg=NULL;
00646 }
00647 
00648        /* set style */
00649 void obj_setstyle(objparm *pm)
00650 {
00651     int i,t;
00652     t=pm->pcnt/3; if(t<=0) {
00653        error("too_few_parms"); return;
00654     }
00655     for(i=0;i<t;i++) {
00656        if(pm->pd[3*i]<0 || pm->pd[3*i+1]<0 || pm->pd[3*i+2]<0)
00657          pm->p[i]=gdTransparent;
00658        else
00659          pm->p[i]=getcolor(pm->pd[3*i],pm->pd[3*i+1],pm->pd[3*i+2]);
00660     }
00661     gdImageSetStyle(image,pm->p,t); styled=1;
00662 }
00663 
00664        /* kill style */
00665 void obj_killstyle(objparm *pm)
00666 {
00667     styled=0;
00668 }
00669 
00670        /* set transparent */
00671 void obj_transp(objparm *pm)
00672 {
00673     gdImageColorTransparent(image,pm->color[0]);
00674 }
00675 
00676        /* set interlace */
00677 void obj_interlace(objparm *pm)
00678 {
00679     gdImageInterlace(image,1);
00680 }
00681 
00682        /* set linewidth */
00683 void obj_linewidth(objparm *pm)
00684 {
00685     if(pm->pd[0]<1 || pm->pd[0]>255) error("bad_parms");
00686     else width=pm->pd[0];
00687 }
00688 
00689        /* set x range */
00690 void obj_xrange(objparm *pm)
00691 {
00692     double dd;
00693     dd=pm->pd[1]-pm->pd[0];
00694     xstart=pm->pd[0]; xscale=sizex/dd;
00695 }
00696 
00697        /* set y range */
00698 void obj_yrange(objparm *pm)
00699 {
00700     double dd;
00701     dd=pm->pd[1]-pm->pd[0];
00702     ystart=pm->pd[1]; yscale=-sizey/dd;
00703 }
00704 
00705        /* set x et y range */
00706 void obj_range(objparm *pm)
00707 {
00708     double d1,d2;
00709     d1=pm->pd[1]-pm->pd[0]; d2=pm->pd[3]-pm->pd[2];
00710     xstart=pm->pd[0]; xscale=(sizex-1)/d1;
00711     ystart=pm->pd[3]; yscale=-(sizey-1)/d2;
00712 }
00713 
00714        /* set t range */
00715 void obj_trange(objparm *pm)
00716 {
00717     double dd;
00718     dd=pm->pd[1]-pm->pd[0];
00719     tstart=pm->pd[0]; tend=pm->pd[1];
00720     tranged=1;
00721 }
00722 
00723        /* set tstep (plotting step) */
00724 void obj_tstep(objparm *pm)
00725 {
00726     int dd;
00727     dd=pm->pd[0];
00728     if(dd<3) {
00729        error("bad_step"); return;
00730     }
00731     if(dd>2000) dd=2000;
00732     tstep=dd;
00733 }
00734 
00735        /* set plotjump (plot jump break threashold) */
00736 void obj_plotjump(objparm *pm)
00737 {
00738     int dd;
00739     dd=pm->pd[0];
00740     if(dd<3) dd=3; if(dd>MAX_SIZE) dd=MAX_SIZE;
00741     plotjump=dd;
00742 }
00743 
00744        /* plot a curve, either parametric or explicit */
00745 void obj_plot(objparm *pm)
00746 {
00747     int i,j,n,dist,xx,yy,varpos;
00748     char p1[MAX_LINELEN+1], p2[MAX_LINELEN+1];
00749     char *varn, *pp;
00750     double dc[2],t,v;
00751     int ic[2],oc[2];
00752 
00753     n=itemnum(pm->str);
00754     if(n<1) {
00755        error("bad_parms"); return;
00756     }
00757     fnd_item(pm->str,1,p1); fnd_item(pm->str,2,p2);
00758     if(n==1 && !tranged) v=sizex/xscale/tstep;
00759     else v=(tend-tstart)/tstep;
00760     if(n==1) varn="x"; else varn="t";
00761     for(pp=varchr(p1,varn); pp; pp=varchr(pp,varn)) {
00762        string_modify(p1,pp,pp+strlen(varn),EV_T);
00763        pp+=strlen(EV_T);
00764     }
00765     for(pp=varchr(p2,varn); pp; pp=varchr(pp,varn)) {
00766        string_modify(p2,pp,pp+strlen(varn),EV_T);
00767        pp+=strlen(EV_T);
00768     }
00769     varpos=eval_getpos(EV_T);
00770     if(varpos<0) return; /* unknown error */
00771     evalue_compile(p1); evalue_compile(p2);
00772     if(vimg_enable) vimg_plotstart();
00773     for(i=j=0;i<=tstep;i++) {
00774        if(n==1) {
00775            if(tranged) t=tstart+i*v; else t=xstart+i*v; 
00776            eval_setval(varpos,t); dc[0]=t; dc[1]=evalue(p1);
00777        }
00778        else {
00779            t=tstart+i*v; eval_setval(varpos,t);
00780            dc[0]=evalue(p1); dc[1]=evalue(p2);
00781        }
00782        if(!finite(dc[0]) || !finite(dc[1])) ic[0]=ic[1]=-BOUND;
00783        else scale(dc,ic,1);
00784        if(vimg_enable) vimg_plot1 (scale_buf[0],scale_buf[1]);
00785        if(j==0) {
00786            gdImageSetPixel(image,ic[0],ic[1],pm->color[0]); j++;
00787        }
00788        else {
00789            xx=ic[0]-oc[0]; yy=ic[1]-oc[1];
00790            dist=sqrt(xx*xx+yy*yy);
00791            if(dist>0) {
00792               if(dist>plotjump || dist==1)
00793                 gdImageSetPixel(image,ic[0],ic[1],pm->color[0]);
00794               else
00795                 gdImageLine(image,oc[0],oc[1],ic[0],ic[1],pm->color[0]);
00796               
00797            }
00798        }
00799        memmove(oc,ic,sizeof(oc));
00800     }
00801     if(vimg_enable) vimg_plotend();
00802 }
00803 
00804        /* set levelcurve granularity */
00805 void obj_levelstep(objparm *pm)
00806 {
00807     int dd;
00808     dd=pm->pd[0];
00809     if(dd<1) return; if(dd>16) dd=16;
00810     lstep=dd;
00811 }
00812 
00813        /* level curve */
00814 void obj_levelcurve(objparm *pm)
00815 {
00816     char fn[MAX_LINELEN+1],tc[MAX_LINELEN+1];
00817     int n,i;
00818     double d;
00819     leveldata *ld;
00820     
00821     ld=xmalloc(sizeof(leveldata)+16);
00822     ld->xname="x"; ld->yname="y";
00823     ld->xsize=sizex; ld->ysize=sizey; ld->datacnt=0;
00824     ld->xrange[0]=xstart; ld->xrange[1]=sizex/xscale+xstart;
00825     ld->yrange[0]=sizey/yscale+ystart; ld->yrange[1]=ystart;
00826     ld->grain=lstep;
00827     fnd_item(pm->str,1,fn); ld->fn=fn;
00828     n=itemnum(pm->str);
00829     if(n<=1) {ld->levelcnt=1; ld->levels[0]=0;}
00830     else {
00831        if(n>LEVEL_LIM+1) n=LEVEL_LIM+1;
00832        for(i=0;i<n-1;i++) {
00833            fnd_item(pm->str,i+2,tc);
00834            d=evalue(tc);
00835            if(finite(d)) ld->levels[i]=d; else ld->levels[i]=0;
00836        }
00837        ld->levelcnt=n-1;
00838     }
00839     levelcurve(ld);
00840     for(i=0;i<ld->datacnt;i++) {
00841        gdImageSetPixel(image,ld->xdata[i],ld->ydata[i],pm->color[0]);
00842     }
00843     free(ld);
00844 }
00845 
00846        /* set animation step */
00847 void obj_animstep(objparm *pm)
00848 {
00849     animstep=pm->pd[0];
00850     setvar("animstep",pm->pd[0]);
00851 }
00852 
00853        /* Starts a line counting */
00854 void obj_linecount(objparm *pm)
00855 {
00856     linecnt=pm->pd[0];
00857 }
00858 
00859        /* marks end of execution */
00860 void obj_end(objparm *pm)
00861 {
00862     error("successful_end_of_execution");
00863 }
00864 
00865        /* output */
00866 void obj_output(objparm *pm)
00867 {
00868     char *p, namebuf[1024];
00869     p=find_word_start(pm->str); *find_word_end(p)=0;
00870     snprintf(namebuf,sizeof(namebuf),"%s",imagefilename);
00871     snprintf(imagefilename,sizeof(imagefilename),"%s",p);
00872     output();
00873     snprintf(imagefilename,sizeof(imagefilename),"%s",namebuf);
00874 }
00875 
00876        /* vimgfile */
00877 void obj_vimgfile(objparm *pm)
00878 {
00879     char *p;
00880     p=find_word_start(pm->str); *find_word_end(p)=0;
00881     snprintf(vimgfilename,sizeof(vimgfilename),"%s",p);
00882     if(vimg_ready) vimg_close();
00883 }
00884 
00885        /* vimg enable/disable */
00886 void obj_vimg(objparm *pm)
00887 {
00888     vimg_enable=pm->pd[0];
00889     if(vimg_enable>0 && vimg_ready==0) {
00890        vimg_init();
00891     }
00892 }
00893 
00894        /* Set affine transformation */
00895 void obj_affine(objparm *pm)
00896 {
00897     int i;
00898     for(i=0;i<4;i++) matrix[i]=pm->pd[i];
00899     transx=pm->pd[4]; transy=pm->pd[5];
00900     transform=1;
00901 }
00902 
00903        /* Set affine transformation */
00904 void obj_rotation(objparm *pm)
00905 {
00906     double r;
00907     r=M_PI*pm->pd[0]/180;
00908     matrix[0]=matrix[3]=cos(r);
00909     matrix[1]=-sin(r); matrix[2]=sin(r);
00910     transform=1;
00911 }
00912 
00913        /* Set affine transformation */
00914 void obj_linear(objparm *pm)
00915 {
00916     int i;
00917     for(i=0;i<4;i++) matrix[i]=pm->pd[i];
00918     transform=1;
00919 }
00920 
00921        /* Set affine transformation */
00922 void obj_translation(objparm *pm)
00923 {
00924     transx=pm->pd[0]; transy=pm->pd[1];
00925 }
00926 
00927        /* Set affine transformation */
00928 void obj_killaffine(objparm *pm)
00929 {
00930     matrix[0]=matrix[3]=1;
00931     matrix[1]=matrix[2]=transx=transy=0;
00932     transform=0;
00933 }
00934 
00935        /* Set affine transformation */
00936 void obj_killlinear(objparm *pm)
00937 {
00938     matrix[0]=matrix[3]=1;
00939     matrix[1]=matrix[2]=0;
00940     transform=0;
00941 }
00942 
00943        /* Set affine transformation */
00944 void obj_killtranslation(objparm *pm)
00945 {
00946     transx=transy=0;
00947 }
00948 
00949 /***** Les modifs de Jean-Christophe Leger Fev 2006 *****/
00950 
00951 /* arguments: un numero de matrice entre 1 et JC_NB_MATRICES, une liste de 4 nombres reels pour la matrice */ 
00952 void obj_setmatrix(objparm *pm)
00953 {
00954   int nummatrix = (int) (pm->pd[0]);
00955   if((nummatrix < 1) ||(nummatrix>JC_NB_MATRICES)) {
00956     error("bad_matrix_number");
00957     return;
00958   }
00959   matrices_pavage[nummatrix][0] = pm->pd[1];
00960   matrices_pavage[nummatrix][1] = pm->pd[2];
00961   matrices_pavage[nummatrix][2] = pm->pd[3];
00962   matrices_pavage[nummatrix][3] = pm->pd[4];
00963 }
00964 
00965 /* arguments: un numero de matrice entre 1 et JC_NB_MATRICES */ 
00966 void obj_resetmatrix(objparm *pm)
00967 {
00968   int nummatrix = (int) (pm->pd[0]);
00969   if((nummatrix < 1) ||(nummatrix>JC_NB_MATRICES)) {
00970     error("bad_matrix_number");
00971     return;
00972   }
00973   matrices_pavage[nummatrix][0] = 1;
00974   matrices_pavage[nummatrix][1] = 0;
00975   matrices_pavage[nummatrix][2] = 0;
00976   matrices_pavage[nummatrix][3] = 1;
00977 
00978 }
00979 /* arguments: un numero de vecteur entre 1 et JC_NB_MATRICES, une liste de 2 nombres reels pour le vecteur */ 
00980 void obj_setvector(objparm *pm)
00981 {
00982   int nummatrix = (int) (pm->pd[0]);
00983   if((nummatrix < 1) ||(nummatrix>JC_NB_MATRICES)) {
00984     error("bad_vector_number");
00985     return;
00986   }
00987   vecteurs_pavage[nummatrix][0] = pm->pd[1];
00988   vecteurs_pavage[nummatrix][1] = pm->pd[2];
00989 }
00990 
00991 /* arguments: un numero de matrice entre 1 et JC_NB_MATRICES */ 
00992 void obj_resetvector(objparm *pm)
00993 {
00994   int nummatrix = (int) (pm->pd[0]);
00995   if((nummatrix < 1) ||(nummatrix>JC_NB_MATRICES)) {
00996     error("bad_vector_number");
00997     return;
00998   }
00999   vecteurs_pavage[nummatrix][0] = 0;
01000   vecteurs_pavage[nummatrix][1] = 0;
01001 }
01002 
01003 /* arguments: un numero de vecteur entre 1 et JC_NB_MATRICES, une liste de 6 nombres reels pour la matrice et le vecteur */ 
01004 void obj_settransform(objparm *pm)
01005 {
01006   int nummatrix = (int) (pm->pd[0]);
01007   if((nummatrix < 1) ||(nummatrix>JC_NB_MATRICES)) {
01008     error("bad_vector_number");
01009     return;
01010   }
01011   matrices_pavage[nummatrix][0] = pm->pd[1];
01012   matrices_pavage[nummatrix][1] = pm->pd[2];
01013   matrices_pavage[nummatrix][2] = pm->pd[3];
01014   matrices_pavage[nummatrix][3] = pm->pd[4];
01015   vecteurs_pavage[nummatrix][0] = pm->pd[5];
01016   vecteurs_pavage[nummatrix][1] = pm->pd[6];
01017 }
01018 
01019 
01020 /* arguments: un numero de matrice entre 1 et JC_NB_MATRICES */ 
01021 void obj_resettransform(objparm *pm)
01022 {
01023   int nummatrix = (int) (pm->pd[0]);
01024   if((nummatrix < 1) ||(nummatrix>JC_NB_MATRICES)) {
01025     error("bad_vector_number");
01026     return;
01027   }
01028   vecteurs_pavage[nummatrix][0] = 0;
01029   vecteurs_pavage[nummatrix][1] = 0;
01030   matrices_pavage[nummatrix][0] = 1;
01031   matrices_pavage[nummatrix][1] = 0;
01032   matrices_pavage[nummatrix][2] = 0;
01033   matrices_pavage[nummatrix][3] = 1;
01034 }
01035 
01036 /* arguments: une liste de 6 nombres reels pour les coordonnees de l'origine et des vecteurs de base */ 
01037 void obj_setparallelogram(objparm *pm)
01038 {
01039   int i;
01040   for(i=0;i<6;i++)  parallogram_fonda[i]=pm->pd[i];
01041 }
01042 
01043 /* arguments :aucun */
01044 void obj_resetparallelogram(objparm *pm)
01045 {
01046   parallogram_fonda[0]=0;
01047   parallogram_fonda[1]=0;
01048   parallogram_fonda[2]=100;
01049   parallogram_fonda[3]=0;
01050   parallogram_fonda[4]=0;
01051   parallogram_fonda[5]=100;
01052 }
01053 
01054 /* argument : la liste des numeros des matrices a faire agir, le nom du fichier de l'image a inclure */
01055 void obj_multicopy(objparm *pm)
01056 {
01057     char *pp,*pe,*cptr;
01058     FILE *inf;
01059     gdImagePtr       insimg;
01060     int i,j;
01061     int imax,jmax;
01062     int c; /* la couleur reperee */
01063     int mat;
01064     int nummatrices[JC_NB_MATRICES];
01065     double pt[2]; /* les coordonnees math. du point repere dans le parallelogramme */
01066     double ptr[2]; /* les coordonnees math. du point transforme */
01067     int pti[2]; /* les coordonnees img du point a placer sur le canevas */
01068     int t;
01069     /* gestion palette de couleur de l'image a inserer */
01070     int colorMap[gdMaxColors];
01071     int comptmat=0; /* combien de matrices en tout ? */
01072     
01073     for (i=0; (i<gdMaxColors); i++) {
01074       colorMap[i] = (-1);
01075     }
01076 
01077     /* Gestion des parametres la liste est censee finir avec le nom du fichier */
01078     t=pm->pcnt-1; /* il faut enlever le nom de fichier ! c'est le nombre de parametres en plus */ 
01079     pp=find_word_start(pm->str);
01080     /* visiblement find_word_start n'arrive pas a trouver le dernier mot dans un contexte ou le nombre de parameters est variable
01081      * on cherche donc l'emplacement de la derniere virgule:
01082      * il y en a une car t>0, on retrouve ensuite le debut de mot
01083      */
01084     for(pe=pp;*pe!=0;pe++);/* trouve la fin de la chaine */
01085     if(t>0){
01086       for(cptr = pe; cptr > pp && *cptr != ','; cptr--);
01087       pp=find_word_start(cptr+1);
01088     }
01089     pe=find_word_end(pp);*pe=0; /* strip junk final */
01090     //      printf("pp contient %s\n",pp);
01091 
01092 
01093     inf=open4read(pp);
01094     if(inf==NULL) {
01095        error("file_not_exist"); return;
01096     }
01097     insimg=gdImageCreateFromGif(inf); fclose(inf);
01098     if(insimg==NULL) {
01099        error("bad_gif"); return;
01100     }
01101 
01102     /* On recupere les numeros des matrices/vecteurs a faire agir, 
01103      * s'il n'y en a pas, on les fait toutes agir 
01104      */
01105     for(i=0;i<t && i< JC_NB_MATRICES;i++) {
01106       if(pm->pd[i]>=1 && pm->pd[i]<=JC_NB_MATRICES){
01107          nummatrices[comptmat] = pm->pd[i];
01108          comptmat++;
01109       }
01110     }
01111     if(t<=0){
01112       for(i=0;i<JC_NB_MATRICES;i++) {
01113        nummatrices[i] = i+1;
01114       }
01115       comptmat=JC_NB_MATRICES;
01116     }
01117   
01118 
01119     imax = gdImageSX(insimg);
01120     jmax = gdImageSY(insimg);
01121 
01122     for(i=0;i<imax;i++){
01123       for(j=0;j<jmax;j++){
01124        int nc;
01125        c=gdImageGetPixel(insimg,i,j);
01126        /* Le code suivant est une copie du code dans gdImageCopy  Added 7/24/95: support transparent copies */
01127        if (gdImageGetTransparent(insimg) != c) {
01128          /* Have we established a mapping for this color? */
01129          if (colorMap[c] == (-1)) {
01130            /* If it's the same image, mapping is trivial, dans notre cas ca n'arrive jamais... */
01131            if (image == insimg) {
01132              nc = c;
01133            } else { 
01134              /* First look for an exact match */
01135              nc = gdImageColorExact(image,
01136                                  insimg->red[c], insimg->green[c],
01137                                  insimg->blue[c]);
01138            }  
01139            if (nc == (-1)) {
01140              /* No, so try to allocate it */
01141              nc = gdImageColorAllocate(image,
01142                                    insimg->red[c], insimg->green[c],
01143                                    insimg->blue[c]);
01144              /* If we're out of colors, go for the
01145                closest color */
01146              if (nc == (-1)) {
01147               nc = gdImageColorClosest(image,
01148                                     insimg->red[c], insimg->green[c],
01149                                     insimg->blue[c]);
01150              }
01151            }
01152            colorMap[c] = nc;
01153          }
01154 
01155          pt[0]= i*(parallogram_fonda[2])/(imax-1)+(jmax-j)*(parallogram_fonda[4])/(jmax-1)+parallogram_fonda[0];
01156          pt[1]= i*(parallogram_fonda[3])/(imax-1)+(jmax-j)*(parallogram_fonda[5])/(jmax-1)+parallogram_fonda[1];
01157          for(mat=0;mat<comptmat;mat++){
01158            double *matricecourante = matrices_pavage[nummatrices[mat]];
01159            double *vecteurcourant = vecteurs_pavage[nummatrices[mat]];
01160            ptr[0] = matricecourante[0]*pt[0]+matricecourante[1]*pt[1]+vecteurcourant[0];
01161            ptr[1] = matricecourante[2]*pt[0]+matricecourante[3]*pt[1]+vecteurcourant[1];
01162            scale(ptr,pti,1);
01163            gdImageSetPixel(image,pti[0],pti[1],colorMap[c]);
01164          }
01165        }
01166       }
01167     }
01168     gdImageDestroy(insimg);
01169 }
01170 
01171 /**** Fin modifs JC Fev 06 ******/
01172 
01173        /* get color from value */
01174 int calc_color(char *p, struct objtab *o)
01175 {
01176     int k, cc[3];
01177     char buf[MAX_LINELEN+1];
01178     for(k=0;k<3;k++) {
01179        fnd_item(p,k+1,buf);
01180        cc[k]=evalue(buf);
01181     }
01182     collapse_item(p,3);
01183     if(cc[0]==-1 && cc[1]==-1 && cc[2]==-255) {
01184 
01185        if(brushed && o->subst&1) return gdBrushed;
01186        else return color_black;
01187     }
01188     if(cc[0]==-1 && cc[1]==-255 && cc[2]==-1) {
01189        if(styled && o->subst&2)  return gdStyled;
01190        else return color_black;
01191     }
01192     if(cc[0]==-255 && cc[1]==-1 && cc[2]==-1) {
01193        if(tiled && o->fill_tag==1)  return gdTiled;
01194        else return color_black;
01195     }
01196     return getcolor(cc[0],cc[1],cc[2]);
01197 }
01198 
01199        /* Routine to parse parameters */
01200 int parse_parms(char *p,objparm *pm,struct objtab *o)
01201 {
01202     char buf[MAX_LINELEN+1];
01203     char *p1, *p2;
01204     int j,t,c,c1,c2;
01205     
01206     c=o->color_pos;c1=c2=0;
01207     pm->color[0]=pm->color[1]=0;
01208     if(c>0) c1=c; if(c<0) c2=-c; c=c1+c2;
01209     t=itemnum(p);if(t<o->required_parms+3*c) return -1;
01210     if(c1>0 && t>o->required_parms+3*c) t=o->required_parms+3*c;
01211     pm->pcnt=t-3*c;
01212     if(pm->pcnt>MAX_PARMS) pm->pcnt=MAX_PARMS;
01213     if(c2>0) {
01214        for(j=0;j<2 && j<c2; j++) pm->color[j]=calc_color(p,o);
01215     }
01216     snprintf(buf,sizeof(buf),"%s",p);
01217     for(j=0, p1=buf; j<pm->pcnt; j++, p1=p2) {
01218        p2=find_item_end(p1); if(*p2) *p2++=0;
01219        p1=find_word_start(p1);
01220        if(*p1) pm->pd[j]=evalue(p1); else pm->pd[j]=0;
01221        if(!finite(pm->pd[j])) {
01222            if(j<o->required_parms) return -1;
01223            else {pm->pd[j]=0;break;}
01224        }
01225     }
01226     collapse_item(p,o->required_parms);
01227     if(c1>0) {
01228        for(j=0;j<c1 && j<2; j++) pm->color[j]=calc_color(p,o);
01229     }
01230     if(width>1 && o->subst&1 && pm->color[0]!=gdBrushed
01231        && pm->color[0]!=gdStyled && pm->color[0]!=gdTiled) {
01232        pm->color[1]=pm->color[0];
01233        pm->color[0]=widthcolor(width,pm->color[0]);
01234     }
01235     pm->fill=o->fill_tag;
01236     strcpy(pm->str,p); return 0;
01237 }
01238 
01239        /* Execute a command. Returns 0 if OK. */
01240 int obj_main(char *p)
01241 {
01242     int i;
01243     char *pp,*name,*pt;
01244     char tbuf2[MAX_LINELEN+1];
01245     struct objparm pm;
01246 
01247     p=find_word_start(p);
01248     if(*p==exec_prefix_char || *p==0) return 0; /* comment */
01249     name=p;
01250     pp=find_name_end(p);
01251     pt=find_word_start(pp); if(*pt=='=') *pt=' ';
01252     if(*pt==':' && *(pt+1)=='=') *pt=*(pt+1)=' ';
01253     pp=find_word_end(p);
01254     if(*pp!=0) {
01255        *(pp++)=0; pp=find_word_start(pp);
01256     }
01257     if(strlen(p)==1 || (strlen(p)==2 && isdigit(*(p+1)))) {
01258        setvar(p,evalue(pp)); return 0;
01259     }
01260     i=search_list(objtab,obj_no,sizeof(objtab[0]),name);
01261     if(i<0) {
01262        error("bad_cmd"); return 1;
01263     }
01264     if(image==NULL && (objtab[i].color_pos || objtab[i].required_parms>2)) {
01265        error("image_not_defined"); return 1;
01266     }
01267     strcpy(tbuf2,pp);
01268     if(objtab[i].color_pos || objtab[i].routine==obj_setstyle) {
01269        substit(tbuf2);
01270     }
01271     if(parse_parms(tbuf2,&pm,objtab+i)!=0) error("bad_parms");
01272     else objtab[i].routine(&pm);
01273     return 0;
01274 }
01275