Subversion Repositories wimsdev

Rev

Rev 8163 | Rev 8177 | 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
 */
8102 bpr 17
#include "flydraw.h"
10 reyssat 18
#include <errno.h>
8010 bpr 19
/* bug in gdImageFillToBorder */
10 reyssat 20
 
8162 bpr 21
void patchgdImageFillToBorder (gdImagePtr im, int x, int y, int border, int color)
8076 bpr 22
{
8156 bpr 23
   if(x>=im->sx || x<0 || y>=im->sy || y<0) return;
8076 bpr 24
   gdImageFillToBorder(im,x,y,border,color);
25
}
26
 
8162 bpr 27
void patchgdImageFill (gdImagePtr im, int x, int y, int color)
8156 bpr 28
{
29
   if(x>=im->sx || x<0 || y>=im->sy || y<0) return;
30
   gdImageFill(im,x,y,color);
31
}
8076 bpr 32
 
8156 bpr 33
 
7675 bpr 34
/* File opening: with security */
10 reyssat 35
FILE *open4read(char *n)
36
{
37
    char *p, *p1, *p2, namebuf[2048];
38
    int t;
39
    FILE *f;
40
    n=find_word_start(n);
41
    if(*n==0) return NULL;
42
    p=getenv("flydraw_filebase");
43
    p1=n+strlen(n)-4;if(p1<n || strcasecmp(p1,".gif")!=0) t=1; else t=0;
44
    if(p!=NULL && *p!=0) {
7675 bpr 45
      char pbuf[MAX_LINELEN+1];
46
      snprintf(pbuf,sizeof(pbuf),"%s",p);
47
      p=find_word_start(pbuf); if(strstr(p,"..")!=NULL) return NULL;
48
      if(*n=='/' || strstr(n,"..")!=NULL) return NULL;
49
/* prohibit unusual file/dir names */
50
      for(p1=p;*p1;p1++)
51
        if(!isalnum(*p1) && !isspace(*p1) && strchr("~_-/.",*p1)==NULL)
52
          return NULL;
53
      for(p1=n;*p1;p1++)
54
        if(!isalnum(*p1) && !isspace(*p1) && strchr("~_-/.",*p1)==NULL)
55
          return NULL;
56
      f=NULL;
57
      for(p1=p; *p1; p1=find_word_start(p2)) {
58
          p2=find_word_end(p1);
59
          if(*p2) *p2++=0;
60
          snprintf(namebuf,sizeof(namebuf),"%s/%s",p1,n);
61
          f=fopen(namebuf,"r"); if(f!=NULL) goto imgtype;
62
      }
63
      p1=getenv("w_wims_session");
64
      if(p1!=NULL && strncmp(n,"insert",6)==0) {
65
          snprintf(namebuf,sizeof(namebuf),"../s2/%s/%s",p1,n);
66
          f=fopen(namebuf,"r");
67
      }
10 reyssat 68
    }
69
    else {
7675 bpr 70
      snprintf(namebuf,sizeof(namebuf),"%s",n);
71
      f=fopen(namebuf,"r");
10 reyssat 72
    }
73
    imgtype:
74
    if(t && f!=NULL) {
7675 bpr 75
      char tbuf[1024],sbuf[4096];
76
      fclose(f); f=NULL;
77
      p1=getenv("TMPDIR"); if(p1==NULL || *p1==0) p1=".";
78
      snprintf(tbuf,sizeof(tbuf),"%s/drawfile_.gif",p1);
79
      snprintf(sbuf,sizeof(sbuf),"convert %s %s",namebuf,tbuf);
80
      if (system(sbuf)) error("system_failed");
7615 bpr 81
        f=fopen(tbuf,"r");
10 reyssat 82
    }
83
    return f;
84
}
85
 
7675 bpr 86
/* Does nothing; just a comment. */
10 reyssat 87
void obj_comment(objparm *pm)
88
{
89
    return;
90
}
91
 
7675 bpr 92
/* define image size */
10 reyssat 93
void obj_size(objparm *pm)
94
{
95
    sizex=rint(pm->pd[0]); sizey=rint(pm->pd[1]);
96
    if(sizex<0 || sizey<0 || sizex>MAX_SIZE || sizey>MAX_SIZE) {
7675 bpr 97
      error("bad_size"); return;
10 reyssat 98
    }
99
    if(image!=NULL) {
7675 bpr 100
      error("size_already_defined"); return;
10 reyssat 101
    }
102
    image=gdImageCreate(sizex,sizey);
103
    if(image==NULL) error("image_creation_failure");
104
    else {
7675 bpr 105
      color_white=gdImageColorAllocate(image,255,255,255);
106
      color_black=gdImageColorAllocate(image,0,0,0);
107
      color_bounder=gdImageColorAllocate(image,1,2,3);
8158 bpr 108
      color_frame=gdImageColorAllocate(image,254,254,254);
10 reyssat 109
    }
110
}
111
 
7675 bpr 112
/* new image */
10 reyssat 113
void obj_new(objparm *pm)
114
{
115
    if(image) {
7675 bpr 116
      gdImageDestroy(image);image=NULL;
10 reyssat 117
    }
8158 bpr 118
    if(pm->pcnt>=2) { obj_size(pm); gdImageRectangle(image,0,0,sizex-1,sizey-1,color_frame);}
10 reyssat 119
    else sizex=sizey=0;
120
    saved=0;
121
}
122
 
7675 bpr 123
/* new image */
10 reyssat 124
void obj_existing(objparm *pm)
125
{
126
    FILE *inf;
127
    char *pp;
7615 bpr 128
 
10 reyssat 129
    if(image) {
7675 bpr 130
      gdImageDestroy(image);image=NULL;
10 reyssat 131
    }
132
    pp=find_word_start(pm->str);*find_word_end(pp)=0;
133
    inf=open4read(pp);
134
    if(inf==NULL) {
7675 bpr 135
      error("file_not_exist"); return;
10 reyssat 136
    }
137
    image=gdImageCreateFromGif(inf); fclose(inf);
138
    if(image==NULL) {
7675 bpr 139
      error("bad_gif"); return;
10 reyssat 140
    }
141
    sizex=image->sx; sizey=image->sy;
142
    saved=0;
143
}
144
 
7675 bpr 145
/* solid line */
10 reyssat 146
void obj_line(objparm *pm)
147
{
148
    scale(pm->pd,pm->p,2);
149
    gdImageLine(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3],pm->color[0]);
1024 bpr 150
    if(vimg_enable) vimg_line(scale_buf[0],scale_buf[1],scale_buf[2],scale_buf[3]);
10 reyssat 151
}
152
 
1024 bpr 153
void _obj_arrow(objparm *pm, int twoside)
10 reyssat 154
{
8163 bpr 155
    int l,xx,yy;
156
    gdPoint ii[3];
10 reyssat 157
    double dx,dy,length,dd[6];
7615 bpr 158
    scale(pm->pd,pm->p,2);
8163 bpr 159
    xx=ii[0].x=pm->p[2];yy=ii[0].y=pm->p[3];
10 reyssat 160
    l=pm->pd[4];if(l<0) l=0; if(l>200) l=200;
161
    scale2(pm->pd[0]-pm->pd[2],pm->pd[1]-pm->pd[3],&dx,&dy);
162
    length=sqrt(dx*dx+dy*dy);
163
    if(length<3 || l<5) goto stem;
164
    dd[0]=l*dx/length; dd[1]=l*dy/length;
165
    #define fat 0.27
166
    dd[2]=dd[0]+dd[1]*fat; dd[3]=dd[1]-dd[0]*fat;
167
    dd[4]=dd[0]-dd[1]*fat; dd[5]=dd[1]+dd[0]*fat;
8163 bpr 168
    ii[1].x=rint(dd[2])+ii[0].x; ii[1].y=rint(dd[3])+ii[0].y;
169
    ii[2].x=rint(dd[4])+ii[0].x; ii[2].y=rint(dd[5])+ii[0].y;
170
    gdImageFilledPolygon(image, ii,3,pm->color[0]);
171
    xx=rint(dd[0])+ii[0].x;yy=rint(dd[1])+ii[0].y;
1024 bpr 172
    if(twoside) {
8163 bpr 173
      ii[0].x=pm->p[0]; ii[0].y=pm->p[1];
174
      ii[1].x=-rint(dd[2])+ii[0].x; ii[1].y=-rint(dd[3])+ii[0].y;
175
      ii[2].x=-rint(dd[4])+ii[0].x; ii[2].y=-rint(dd[5])+ii[0].y;
176
      gdImageFilledPolygon(image, ii,3,pm->color[0]);
1024 bpr 177
    }
10 reyssat 178
    stem: if(pm->fill)
179
      gdImageDashedLine(image,pm->p[0],pm->p[1],xx,yy,pm->color[0]);
180
    else
181
      gdImageLine(image,pm->p[0],pm->p[1],xx,yy,pm->color[0]);
1024 bpr 182
    if(vimg_enable) vimg_line(scale_buf[0],scale_buf[1],scale_buf[2],scale_buf[3]);
10 reyssat 183
}
184
 
7675 bpr 185
/* Arrow */
1024 bpr 186
void obj_arrow(objparm *pm)
187
{
188
    _obj_arrow(pm,0);
189
}
190
 
7675 bpr 191
/* 2-sided arrow */
1024 bpr 192
void obj_arrow2(objparm *pm)
193
{
194
    _obj_arrow(pm,1);
195
}
196
 
7675 bpr 197
/* horizontal line */
10 reyssat 198
void obj_hline(objparm *pm)
199
{
200
    scale(pm->pd,pm->p,1);
201
    if(pm->fill)
202
      gdImageDashedLine(image,0,pm->p[1],sizex,pm->p[1],pm->color[0]);
203
    else
204
      gdImageLine(image,0,pm->p[1],sizex,pm->p[1],pm->color[0]);
205
}
206
 
7675 bpr 207
/* vertical line */
10 reyssat 208
void obj_vline(objparm *pm)
209
{
210
    scale(pm->pd,pm->p,1);
211
    if(pm->fill)
212
      gdImageDashedLine(image,pm->p[0],0,pm->p[0],sizey,pm->color[0]);
213
    else
214
      gdImageLine(image,pm->p[0],0,pm->p[0],sizey,pm->color[0]);
215
}
216
 
7675 bpr 217
/* dashed line */
10 reyssat 218
void obj_dline(objparm *pm)
219
{
220
    scale(pm->pd,pm->p,2);
221
    gdImageDashedLine(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3],
7675 bpr 222
                  pm->color[0]);
10 reyssat 223
}
224
 
7675 bpr 225
/* parallel lines.
226
 * x1,y1,x2,y2,xv,yv,n,color */
10 reyssat 227
void obj_parallel(objparm *pm)
228
{
229
    int i, n, xi,yi;
230
    double xv,yv;
231
    n=pm->pd[6]; if(n<0) return; if(n>256) n=256;
1122 bpr 232
    scale(pm->pd,pm->p,3);
10 reyssat 233
    scale2(pm->pd[4],pm->pd[5],&xv,&yv);
234
    for(i=0;i<n;i++) {
7675 bpr 235
      xi=rint(i*xv); yi=rint(i*yv);
236
      gdImageLine(image,pm->p[0]+xi,pm->p[1]+yi,pm->p[2]+xi,pm->p[3]+yi,
237
                pm->color[0]);
238
      if(vimg_enable) vimg_line(scale_buf[0]+i*(scale_buf[4]-transx),
239
                          scale_buf[1]+i*(scale_buf[5]-transy),
240
                          scale_buf[2]+i*(scale_buf[4]-transx),
241
                          scale_buf[3]+i*(scale_buf[5]-transy));
10 reyssat 242
    }
243
}
244
 
7675 bpr 245
/* rectangle */
10 reyssat 246
void obj_rect(objparm *pm)
247
{
248
    int x1,y1,x2,y2;
249
    scale(pm->pd,pm->p,2);
250
    x1=min(pm->p[0],pm->p[2]); x2=max(pm->p[0],pm->p[2]);
251
    y1=min(pm->p[1],pm->p[3]); y2=max(pm->p[1],pm->p[3]);
252
    if(pm->fill)
253
      gdImageFilledRectangle(image,x1,y1,x2,y2,pm->color[0]);
254
    else
255
      gdImageRectangle(image,x1,y1,x2,y2,pm->color[0]);
1024 bpr 256
    if(vimg_enable) vimg_rect(scale_buf[0],scale_buf[1],scale_buf[2],scale_buf[3]);
10 reyssat 257
}
258
 
7675 bpr 259
/* square */
10 reyssat 260
void obj_square(objparm *pm)
261
{
262
    int w,h;
263
    scale(pm->pd,pm->p,1);
264
    w=rint(pm->pd[2]); h=rint(pm->pd[2]);
265
    if(pm->fill)
266
      gdImageFilledRectangle(image,pm->p[0],pm->p[1],
7675 bpr 267
                 pm->p[0]+w,pm->p[1]+h,pm->color[0]);
10 reyssat 268
    else
269
      gdImageRectangle(image,pm->p[0],pm->p[1],
7675 bpr 270
                 pm->p[0]+w,pm->p[1]+h,pm->color[0]);
1024 bpr 271
    if(vimg_enable) vimg_rect(scale_buf[0],scale_buf[1],
7675 bpr 272
                        scale_buf[0]+pm->pd[2],scale_buf[1]+pm->pd[2]);
10 reyssat 273
}
274
 
7675 bpr 275
/* triangle */
10 reyssat 276
void obj_triangle(objparm *pm)
277
{
278
    scale(pm->pd,pm->p,3);
279
    if(pm->fill)
280
      gdImageFilledPolygon(image,(gdPointPtr) pm->p,3,pm->color[0]);
281
    else
282
      gdImagePolygon(image,(gdPointPtr) pm->p,3,pm->color[0]);
1024 bpr 283
    if(vimg_enable) vimg_polyline(scale_buf,3,1);
10 reyssat 284
}
285
 
7675 bpr 286
/* polygon */
10 reyssat 287
void obj_poly(objparm *pm)
288
{
289
    int cnt;
290
    cnt=(pm->pcnt)/2;
291
    scale(pm->pd,pm->p,cnt);
292
    if(pm->fill)
293
      gdImageFilledPolygon(image,(gdPointPtr) pm->p,cnt,pm->color[0]);
294
    else
295
      gdImagePolygon(image,(gdPointPtr) pm->p,cnt,pm->color[0]);
1024 bpr 296
    if(vimg_enable) vimg_polyline(scale_buf,cnt,1);
10 reyssat 297
}
298
 
7675 bpr 299
/* rays */
10 reyssat 300
void obj_rays(objparm *pm)
301
{
302
    int i, n;
303
    n=(pm->pcnt)/2;
304
    scale(pm->pd,pm->p,n);
1024 bpr 305
    for(i=2;i<2*n;i+=2) {
7675 bpr 306
      gdImageLine(image,pm->p[0],pm->p[1],pm->p[i],pm->p[i+1],pm->color[0]);
307
      if(vimg_enable) vimg_line(scale_buf[0],scale_buf[1],
308
                          scale_buf[i],scale_buf[i+1]);
1024 bpr 309
    }
10 reyssat 310
}
311
 
7675 bpr 312
/* segments */
10 reyssat 313
void obj_lines(objparm *pm)
314
{
315
    int i, n;
316
    n=(pm->pcnt)/2;
317
    scale(pm->pd,pm->p,n);
7615 bpr 318
    for(i=2;i<2*n;i+=2)
10 reyssat 319
      gdImageLine(image,pm->p[i-2],pm->p[i-1],pm->p[i],pm->p[i+1],pm->color[0]);
1024 bpr 320
    if(vimg_enable) vimg_polyline(scale_buf,n,0);
10 reyssat 321
}
322
 
7675 bpr 323
/* segments */
10 reyssat 324
void obj_dlines(objparm *pm)
325
{
326
    int i, n;
327
    n=(pm->pcnt)/2;
328
    scale(pm->pd,pm->p,n);
329
    for(i=2;i<2*n;i+=2)
330
      gdImageDashedLine(image,pm->p[i-2],pm->p[i-1],pm->p[i],pm->p[i+1],pm->color[0]);
1024 bpr 331
    if(vimg_enable) vimg_polyline(scale_buf,n,0);
10 reyssat 332
}
333
 
7675 bpr 334
/* points */
10 reyssat 335
void obj_points(objparm *pm)
336
{
337
    int i, n;
338
    n=(pm->pcnt)/2;
339
    scale(pm->pd,pm->p,n);
340
    for(i=0;i<2*n;i+=2)
341
      gdImageSetPixel(image,pm->p[i],pm->p[i+1],pm->color[0]);
342
}
343
 
7675 bpr 344
/* lattice.
345
 * x0,y0,xv1,yv1,xv2,yv2,n1,n2,color */
10 reyssat 346
void obj_lattice(objparm *pm)
347
{
348
    int n1,n2,i1,i2,xi1,yi1,xi2,yi2;
349
    double xv1,xv2,yv1,yv2;
350
    n1=pm->pd[6];n2=pm->pd[7]; if(n1<0 || n2<0) return;
351
    if(n1>256) n1=256; if(n2>256) n2=256;
352
    scale(pm->pd,pm->p,1);
353
    scale2(pm->pd[2],pm->pd[3],&xv1,&yv1);
354
    scale2(pm->pd[4],pm->pd[5],&xv2,&yv2);
355
    for(i1=0;i1<n1;i1++) {
7675 bpr 356
      xi1=rint(i1*xv1)+pm->p[0]; yi1=rint(i1*yv1)+pm->p[1];
357
      for(i2=0;i2<n2;i2++) {
358
          xi2=i2*xv2+xi1;yi2=i2*yv2+yi1;
359
          gdImageSetPixel(image,xi2,yi2,pm->color[0]);
360
      }
10 reyssat 361
    }
362
}
363
 
7675 bpr 364
/* arc */
10 reyssat 365
void obj_arc(objparm *pm)
366
{
367
    scale(pm->pd,pm->p,1);
368
    pm->p[2]=rint(pm->pd[2]*xscale); pm->p[3]=rint(pm->pd[3]*yscale);
369
    gdImageArc(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3],
7675 bpr 370
             pm->pd[4],pm->pd[5],pm->color[0]);
1024 bpr 371
    if(vimg_enable) vimg_arc(scale_buf[0],scale_buf[1],
7675 bpr 372
                       0.5*pm->pd[2],0.5*pm->pd[3],pm->pd[4],pm->pd[5]);
10 reyssat 373
}
374
 
7675 bpr 375
/* Ellipse: centre 0,1, width 2, hight 3, color 4,5,6 */
10 reyssat 376
void obj_ellipse(objparm *pm)
377
{
378
    scale(pm->pd,pm->p,1);
379
    pm->p[2]=rint(pm->pd[2]*xscale); pm->p[3]=rint(pm->pd[3]*yscale);
380
    if(pm->fill) {
7675 bpr 381
      gdImageArc(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3],0,360,
382
               color_bounder);
8162 bpr 383
      patchgdImageFillToBorder(image,pm->p[0],pm->p[1],
7675 bpr 384
                      color_bounder,pm->color[0]);
10 reyssat 385
    }
386
    gdImageArc(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3],0,360,pm->color[0]);
1024 bpr 387
    if(vimg_enable) vimg_ellipse(scale_buf[0],scale_buf[1],0.5*pm->pd[2],0.5*pm->pd[3]);
10 reyssat 388
}
389
 
7675 bpr 390
/* Circle */
10 reyssat 391
void obj_circle(objparm *pm)
392
{
393
    scale(pm->pd,pm->p,1);
394
    pm->p[2]=rint(pm->pd[2]); pm->p[3]=rint(pm->pd[2]);
395
    if(pm->fill) {
7675 bpr 396
      gdImageArc(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3],0,360,
397
               color_bounder);
8162 bpr 398
      patchgdImageFillToBorder(image,pm->p[0],pm->p[1],
7675 bpr 399
                      color_bounder,pm->color[0]);
10 reyssat 400
    }
401
    gdImageArc(image,pm->p[0],pm->p[1],pm->p[2],pm->p[3],0,360,pm->color[0]);
402
}
403
 
7675 bpr 404
/* flood fill */
10 reyssat 405
void obj_fill(objparm *pm)
406
{
407
    scale(pm->pd,pm->p,1);
8162 bpr 408
    patchgdImageFill(image,pm->p[0],pm->p[1],pm->color[0]);
10 reyssat 409
}
410
 
7675 bpr 411
/* flood fill to border*/
10 reyssat 412
void obj_fillb(objparm *pm)
413
{
414
    scale(pm->pd,pm->p,1);
8162 bpr 415
    patchgdImageFillToBorder(image,pm->p[0],pm->p[1],pm->color[0],pm->color[1]);
10 reyssat 416
}
417
 
418
gdImagePtr himg;
419
 
420
int makehatchimage(int x, int y, int px, int py, int col)
421
{
422
    int c1,c2,r,g,b;
423
    gdImagePtr saveimg;
424
    himg=gdImageCreate(x,y);
425
    c1=gdImageGetPixel(image,px,py);
426
    r=gdImageRed(image,c1); g=gdImageGreen(image,c1); b=gdImageBlue(image,c1);
427
    if(r>=255) r--; else r++; if(g>=255) g--; else g++; if(b>=255) b--; else b++;
428
    c1=gdImageColorAllocate(himg,r,g,b);
429
    r=gdImageRed(image,col); g=gdImageGreen(image,col); b=gdImageBlue(image,col);
430
    c2=gdImageColorAllocate(himg,r,g,b);
431
    if(width>1) {
7675 bpr 432
      savew=-1; saveimg=image;
433
      image=himg; c2=widthcolor(width,c2); image=saveimg;
434
      c2=gdBrushed; savew=-1;
10 reyssat 435
    }
436
    return c2;
437
}
438
 
7675 bpr 439
/* flood fill with hatching */
10 reyssat 440
void obj_hatchfill(objparm *pm)
441
{
442
    int nx,ny,ax,ay, dir, c;
443
    scale(pm->pd,pm->p,1);
444
    nx=pm->pd[2]; ny=pm->pd[3]; ax=abs(nx); ay=abs(ny);
445
    if(nx==0 && ny==0) {error("bad displacement vector"); return;}
446
    if((nx>0 && ny>0) || (nx<0 && ny<0)) dir=1; else dir=-1;
447
    if(ax==0) {ax=100; dir=2;}
448
    if(ay==0) {ay=100; dir=3;}
449
    c=makehatchimage(ax,ay,pm->p[0],pm->p[1],pm->color[0]);
450
    switch(dir) {
7675 bpr 451
      case -1: {
452
          gdImageLine(himg,0,ay-1,ax-1,0,c);
453
          if(width>1) {
454
            gdImageLine(himg,-ax,ay-1,-1,0,c);
455
            gdImageLine(himg,ax,ay-1,2*ax-1,0,c);
456
            gdImageLine(himg,0,-1,ax-1,-ay,c);
457
            gdImageLine(himg,0,2*ay-1,ax-1,ay,c);
458
          }
459
          break;
460
      }
461
      case 1: {
462
          gdImageLine(himg,0,0,ax-1,ay-1,c);
463
          if(width>1) {
464
            gdImageLine(himg,-ax,0,-1,ay-1,c);
465
            gdImageLine(himg,ax,0,2*ax-1,ay-1,c);
466
            gdImageLine(himg,0,-ay,ax-1,-1,c);
467
            gdImageLine(himg,0,ay,ax-1,2*ay-1,c);
468
          }
469
          break;
470
      }
471
      case 2: gdImageLine(himg,0,ay/2,ax-1,ay/2,c); break;
472
      case 3: gdImageLine(himg,ax/2,0,ax/2,ay-1,c); break;
10 reyssat 473
    }
474
    gdImageSetTile(image,himg);
8162 bpr 475
    patchgdImageFill(image,pm->p[0],pm->p[1],gdTiled);
10 reyssat 476
    gdImageDestroy(himg);
477
    if(tiled) gdImageSetTile(image,tileimg);
478
}
479
 
7675 bpr 480
/* flood fill with grid */
10 reyssat 481
void obj_gridfill(objparm *pm)
482
{
483
    int nx,ny, c;
484
    scale(pm->pd,pm->p,1);
485
    nx=pm->pd[2]; ny=pm->pd[3]; nx=abs(nx); ny=abs(ny);
486
    if(nx==0 && ny==0) {error("bad grid size"); return;}
487
    c=makehatchimage(nx,ny,pm->p[0],pm->p[1],pm->color[0]);
488
    gdImageLine(himg,0,ny/2,nx-1,ny/2,c); gdImageLine(himg,nx/2,0,nx/2,ny-1,c);
489
    gdImageSetTile(image,himg);
8162 bpr 490
    patchgdImageFill(image,pm->p[0],pm->p[1],gdTiled);
10 reyssat 491
    gdImageDestroy(himg);
492
    if(tiled) gdImageSetTile(image,tileimg);
493
}
494
 
7675 bpr 495
/* flood fill with double hatching */
10 reyssat 496
void obj_diafill(objparm *pm)
497
{
498
    int nx,ny, c;
499
    scale(pm->pd,pm->p,1);
500
    nx=pm->pd[2]; ny=pm->pd[3]; nx=abs(nx); ny=abs(ny);
501
    if(nx==0 && ny==0) {error("bad grid size"); return;}
502
    c=makehatchimage(nx,ny,pm->p[0],pm->p[1],pm->color[0]);
503
    gdImageLine(himg,0,0,nx-1,ny-1,c); gdImageLine(himg,0,ny-1,nx-1,0,c);
504
    gdImageSetTile(image,himg);
8162 bpr 505
    patchgdImageFill(image,pm->p[0],pm->p[1],gdTiled);
10 reyssat 506
    gdImageDestroy(himg);
507
    if(tiled) gdImageSetTile(image,tileimg);
508
}
509
 
7675 bpr 510
/* flood fill with double hatching */
10 reyssat 511
void obj_dotfill(objparm *pm)
512
{
513
    int nx,ny, c;
514
    scale(pm->pd,pm->p,1);
515
    nx=pm->pd[2]; ny=pm->pd[3]; nx=abs(nx); ny=abs(ny);
516
    if(nx==0 && ny==0) {error("bad grid size"); return;}
517
    c=makehatchimage(nx,ny,pm->p[0],pm->p[1],pm->color[0]);
518
    gdImageSetPixel(himg,nx/2,ny/2,c);
519
    gdImageSetTile(image,himg);
8162 bpr 520
    patchgdImageFill(image,pm->p[0],pm->p[1],gdTiled);
10 reyssat 521
    gdImageDestroy(himg);
522
    if(tiled) gdImageSetTile(image,tileimg);
523
}
524
 
525
struct {
526
    char *name;
527
    gdFontPtr *fpt;
528
} fonttab[]={
7675 bpr 529
      {"tiny",      &gdFontTiny},
530
      {"small",      &gdFontSmall},
10 reyssat 531
      {"medium",&gdFontMediumBold},
7675 bpr 532
      {"large",      &gdFontLarge},
533
      {"giant",      &gdFontGiant},
534
      {"huge",      &gdFontGiant}
10 reyssat 535
};
536
 
537
#define fonttab_no (sizeof(fonttab)/sizeof(fonttab[0]))
538
 
7675 bpr 539
/* string */
10 reyssat 540
void obj_string(objparm *pm)
541
{
542
    char *pp, *pe, *p2;
543
    int i;
544
    pp=pm->str; pe=strchr(pp,','); if(pe==NULL) {
7675 bpr 545
      error("too_few_parms"); return;
10 reyssat 546
    }
547
    *pe++=0; pp=find_word_start(pp); *find_word_end(pp)=0;
548
    pe=find_word_start(pe); strip_trailing_spaces(pe);
549
    if(*pp) {
7675 bpr 550
      for(i=0;i<fonttab_no && strcmp(pp,fonttab[i].name)!=0; i++);
551
      if(i>=fonttab_no) i=1;
10 reyssat 552
    }
553
    else i=1;
554
    scale(pm->pd,pm->p,1);
555
    if(*pe=='"') {
7675 bpr 556
      p2=strchr(pe+1,'"');
557
      if(p2 && *(p2+1)==0) {*p2=0; pe++;}
10 reyssat 558
    }
559
    if(pm->fill)
7615 bpr 560
      gdImageStringUp(image,*(fonttab[i].fpt),pm->p[0],pm->p[1], (unsigned char*) pe,
7675 bpr 561
                pm->color[0]);
10 reyssat 562
    else
7615 bpr 563
      gdImageString(image,*(fonttab[i].fpt),pm->p[0],pm->p[1], (unsigned char*) pe,
7675 bpr 564
                pm->color[0]);
10 reyssat 565
}
566
 
7675 bpr 567
/* point */
10 reyssat 568
void obj_point(objparm *pm)
569
{
570
    scale(pm->pd,pm->p,1);
571
    gdImageSetPixel(image,pm->p[0],pm->p[1],pm->color[0]);
572
}
573
 
7675 bpr 574
/* copy an image file */
10 reyssat 575
void obj_copy(objparm *pm)
576
{
577
    char *pp;
578
    FILE *inf;
7675 bpr 579
    gdImagePtr insimg;
7615 bpr 580
 
10 reyssat 581
    pp=find_word_start(pm->str);*find_word_end(pp)=0;
582
    inf=open4read(pp);
583
    if(inf==NULL) {
7675 bpr 584
      error("file_not_exist"); return;
10 reyssat 585
    }
586
    insimg=gdImageCreateFromGif(inf); fclose(inf);
587
    if(insimg==NULL) {
7675 bpr 588
      error("bad_gif"); return;
10 reyssat 589
    }
590
    scale(pm->pd,pm->p,1);
7615 bpr 591
    if(pm->pd[2]<0 && pm->pd[3]<0 && pm->pd[4]<0 && pm->pd[5]<0)
10 reyssat 592
      gdImageCopy(image,insimg,pm->p[0],pm->p[1],0,0,
7675 bpr 593
              insimg->sx,insimg->sy);
10 reyssat 594
    else
595
      gdImageCopy(image,insimg,pm->p[0],pm->p[1],pm->pd[2],pm->pd[3],
7675 bpr 596
              pm->pd[4]-pm->pd[2],pm->pd[5]-pm->pd[3]);
10 reyssat 597
    gdImageDestroy(insimg);
598
}
599
 
7675 bpr 600
/* copy an image file, with resizing */
10 reyssat 601
void obj_copyresize(objparm *pm)
602
{
603
    char *pp;
604
    FILE *inf;
7675 bpr 605
    gdImagePtr insimg;
7615 bpr 606
 
10 reyssat 607
    pp=find_word_start(pm->str);*find_word_end(pp)=0;
608
    inf=open4read(pp);
609
    if(inf==NULL) {
7675 bpr 610
      error("file_not_found"); return;
10 reyssat 611
    }
612
    insimg=gdImageCreateFromGif(inf); fclose(inf);
613
    if(insimg==NULL) {
7675 bpr 614
      error("bad_gif"); return;
10 reyssat 615
    }
616
    scale(pm->pd+4,pm->p+4,2);
7615 bpr 617
    if(pm->pd[0]<0 && pm->pd[1]<0 && pm->pd[2]<0 && pm->pd[3]<0)
10 reyssat 618
      gdImageCopyResized(image,insimg,pm->p[4],pm->p[5],0,0,
7675 bpr 619
                   pm->p[6]-pm->p[4]+1,pm->p[7]-pm->p[5]+1,
620
                   insimg->sx,insimg->sy);
10 reyssat 621
    else
622
      gdImageCopyResized(image,insimg,pm->p[4],pm->p[5],pm->pd[0],pm->pd[1],
7675 bpr 623
                   pm->p[6]-pm->p[4]+1,pm->p[7]-pm->p[5]+1,
624
                   pm->pd[2]-pm->pd[0]+1,pm->pd[3]-pm->pd[1]+1);
10 reyssat 625
    gdImageDestroy(insimg);
626
}
627
 
7675 bpr 628
/* set brush or tile */
10 reyssat 629
void obj_setbrush(objparm *pm)
630
{
631
    char *pp;
632
    FILE *inf;
633
    gdImagePtr insimg;
634
 
635
    pp=find_word_start(pm->str); *find_word_end(pp)=0;
636
    inf=open4read(pp); if(inf==NULL) {
7675 bpr 637
      error("file_not_found"); return;
10 reyssat 638
    }
639
    insimg=gdImageCreateFromGif(inf); fclose(inf);
640
    if(insimg==NULL) {
7675 bpr 641
      error("bad_gif"); return;
10 reyssat 642
    }
643
    if(pm->fill) {
7675 bpr 644
      gdImageSetTile(image,insimg); tiled=1; tileimg=insimg;
10 reyssat 645
    }
646
    else {
7675 bpr 647
      gdImageSetBrush(image,insimg);brushed=1; brushimg=insimg;
10 reyssat 648
    }
649
}
650
 
7675 bpr 651
/* kill brush */
10 reyssat 652
void obj_killbrush(objparm *pm)
653
{
654
    if(brushimg) gdImageDestroy(brushimg);
655
    brushed=0; brushimg=NULL;
656
}
657
 
7675 bpr 658
/* kill tile */
10 reyssat 659
void obj_killtile(objparm *pm)
660
{
661
    if(tileimg) gdImageDestroy(tileimg);
662
    tiled=0; tileimg=NULL;
663
}
664
 
7675 bpr 665
/* set style */
10 reyssat 666
void obj_setstyle(objparm *pm)
667
{
668
    int i,t;
669
    t=pm->pcnt/3; if(t<=0) {
7675 bpr 670
      error("too_few_parms"); return;
10 reyssat 671
    }
672
    for(i=0;i<t;i++) {
7675 bpr 673
      if(pm->pd[3*i]<0 || pm->pd[3*i+1]<0 || pm->pd[3*i+2]<0)
674
        pm->p[i]=gdTransparent;
675
      else
676
        pm->p[i]=getcolor(pm->pd[3*i],pm->pd[3*i+1],pm->pd[3*i+2]);
10 reyssat 677
    }
678
    gdImageSetStyle(image,pm->p,t); styled=1;
679
}
680
 
7675 bpr 681
/* kill style */
10 reyssat 682
void obj_killstyle(objparm *pm)
683
{
684
    styled=0;
685
}
686
 
7675 bpr 687
/* set transparent */
10 reyssat 688
void obj_transp(objparm *pm)
689
{
690
    gdImageColorTransparent(image,pm->color[0]);
691
}
692
 
7675 bpr 693
/* set interlace */
10 reyssat 694
void obj_interlace(objparm *pm)
695
{
696
    gdImageInterlace(image,1);
697
}
698
 
7675 bpr 699
/* set linewidth */
10 reyssat 700
void obj_linewidth(objparm *pm)
701
{
702
    if(pm->pd[0]<1 || pm->pd[0]>255) error("bad_parms");
703
    else width=pm->pd[0];
704
}
705
 
7675 bpr 706
/* set x range */
10 reyssat 707
void obj_xrange(objparm *pm)
708
{
709
    double dd;
710
    dd=pm->pd[1]-pm->pd[0];
711
    xstart=pm->pd[0]; xscale=sizex/dd;
712
}
713
 
7675 bpr 714
/* set y range */
10 reyssat 715
void obj_yrange(objparm *pm)
716
{
717
    double dd;
718
    dd=pm->pd[1]-pm->pd[0];
719
    ystart=pm->pd[1]; yscale=-sizey/dd;
720
}
721
 
7675 bpr 722
/* set x et y range */
10 reyssat 723
void obj_range(objparm *pm)
724
{
725
    double d1,d2;
726
    d1=pm->pd[1]-pm->pd[0]; d2=pm->pd[3]-pm->pd[2];
727
    xstart=pm->pd[0]; xscale=(sizex-1)/d1;
728
    ystart=pm->pd[3]; yscale=-(sizey-1)/d2;
729
}
730
 
7675 bpr 731
/* set t range */
10 reyssat 732
void obj_trange(objparm *pm)
733
{
6790 bpr 734
    /*double dd;
735
    dd=pm->pd[1]-pm->pd[0];*/
10 reyssat 736
    tstart=pm->pd[0]; tend=pm->pd[1];
737
    tranged=1;
738
}
739
 
7675 bpr 740
/* set tstep (plotting step) */
10 reyssat 741
void obj_tstep(objparm *pm)
742
{
743
    int dd;
744
    dd=pm->pd[0];
745
    if(dd<3) {
7675 bpr 746
      error("bad_step"); return;
10 reyssat 747
    }
748
    if(dd>2000) dd=2000;
749
    tstep=dd;
750
}
751
 
7675 bpr 752
/* set plotjump (plot jump break threashold) */
10 reyssat 753
void obj_plotjump(objparm *pm)
754
{
755
    int dd;
756
    dd=pm->pd[0];
757
    if(dd<3) dd=3; if(dd>MAX_SIZE) dd=MAX_SIZE;
758
    plotjump=dd;
759
}
760
 
7675 bpr 761
/* plot a curve, either parametric or explicit */
6578 bpr 762
void _obj_plot(objparm *pm,int dash)
10 reyssat 763
{
764
    int i,j,n,dist,xx,yy,varpos;
765
    char p1[MAX_LINELEN+1], p2[MAX_LINELEN+1];
766
    char *varn, *pp;
767
    double dc[2],t,v;
768
    int ic[2],oc[2];
769
 
770
    n=itemnum(pm->str);
771
    if(n<1) {
7675 bpr 772
      error("bad_parms"); return;
10 reyssat 773
    }
774
    fnd_item(pm->str,1,p1); fnd_item(pm->str,2,p2);
775
    if(n==1 && !tranged) v=sizex/xscale/tstep;
776
    else v=(tend-tstart)/tstep;
777
    if(n==1) varn="x"; else varn="t";
778
    for(pp=varchr(p1,varn); pp; pp=varchr(pp,varn)) {
7675 bpr 779
      string_modify(p1,pp,pp+strlen(varn),EV_T);
780
      pp+=strlen(EV_T);
10 reyssat 781
    }
782
    for(pp=varchr(p2,varn); pp; pp=varchr(pp,varn)) {
7675 bpr 783
      string_modify(p2,pp,pp+strlen(varn),EV_T);
784
      pp+=strlen(EV_T);
10 reyssat 785
    }
786
    varpos=eval_getpos(EV_T);
787
    if(varpos<0) return; /* unknown error */
788
    evalue_compile(p1); evalue_compile(p2);
1024 bpr 789
    if(vimg_enable) vimg_plotstart();
10 reyssat 790
    for(i=j=0;i<=tstep;i++) {
7675 bpr 791
      if(n==1) {
792
          if(tranged) t=tstart+i*v; else t=xstart+i*v;
8076 bpr 793
          eval_setval(varpos,t); dc[0]=t; dc[1]=strevalue(p1);
7675 bpr 794
      }
795
      else {
796
          t=tstart+i*v; eval_setval(varpos,t);
8076 bpr 797
          dc[0]=strevalue(p1); dc[1]=strevalue(p2);
7675 bpr 798
      }
8171 bpr 799
      if(!isfinite(dc[0]) || !isfinite(dc[1])) ic[0]=ic[1]=-BOUND;
7675 bpr 800
      else scale(dc,ic,1);
801
      if(vimg_enable) vimg_plot1 (scale_buf[0],scale_buf[1]);
802
      if(j==0) {
803
          gdImageSetPixel(image,ic[0],ic[1],pm->color[0]); j++;
804
      }
805
      else {
806
          xx=ic[0]-oc[0]; yy=ic[1]-oc[1];
807
          dist=sqrt(xx*xx+yy*yy);
808
          if(dist>0) {
809
            if(dist>plotjump || dist==1)
810
              gdImageSetPixel(image,ic[0],ic[1],pm->color[0]);
811
            else
812
             if ( dash==1) {
813
              gdImageDashedLine(image,oc[0],oc[1],ic[0],ic[1],pm->color[0]);
814
              } else
815
              {gdImageLine(image,oc[0],oc[1],ic[0],ic[1],pm->color[0]); }
7615 bpr 816
 
7675 bpr 817
          }
818
      }
819
      memmove(oc,ic,sizeof(oc));
10 reyssat 820
    }
1024 bpr 821
    if(vimg_enable) vimg_plotend();
10 reyssat 822
}
823
 
6578 bpr 824
void obj_plot(objparm *pm) { _obj_plot( pm,0) ;}
825
void obj_dplot(objparm *pm) { _obj_plot( pm,1) ; }
826
 
7675 bpr 827
/* set levelcurve granularity */
10 reyssat 828
void obj_levelstep(objparm *pm)
829
{
830
    int dd;
831
    dd=pm->pd[0];
832
    if(dd<1) return; if(dd>16) dd=16;
833
    lstep=dd;
834
}
835
 
7675 bpr 836
/* level curve */
10 reyssat 837
void obj_levelcurve(objparm *pm)
838
{
839
    char fn[MAX_LINELEN+1],tc[MAX_LINELEN+1];
840
    int n,i;
841
    double d;
842
    leveldata *ld;
7615 bpr 843
 
10 reyssat 844
    ld=xmalloc(sizeof(leveldata)+16);
845
    ld->xname="x"; ld->yname="y";
846
    ld->xsize=sizex; ld->ysize=sizey; ld->datacnt=0;
847
    ld->xrange[0]=xstart; ld->xrange[1]=sizex/xscale+xstart;
848
    ld->yrange[0]=sizey/yscale+ystart; ld->yrange[1]=ystart;
849
    ld->grain=lstep;
850
    fnd_item(pm->str,1,fn); ld->fn=fn;
851
    n=itemnum(pm->str);
852
    if(n<=1) {ld->levelcnt=1; ld->levels[0]=0;}
853
    else {
7675 bpr 854
      if(n>LEVEL_LIM+1) n=LEVEL_LIM+1;
855
      for(i=0;i<n-1;i++) {
856
          fnd_item(pm->str,i+2,tc);
8076 bpr 857
          d=strevalue(tc);
8171 bpr 858
          if(isfinite(d)) ld->levels[i]=d; else ld->levels[i]=0;
7675 bpr 859
      }
860
      ld->levelcnt=n-1;
10 reyssat 861
    }
862
    levelcurve(ld);
863
    for(i=0;i<ld->datacnt;i++) {
7675 bpr 864
      gdImageSetPixel(image,ld->xdata[i],ld->ydata[i],pm->color[0]);
10 reyssat 865
    }
866
    free(ld);
867
}
868
 
7675 bpr 869
/* set animation step */
10 reyssat 870
void obj_animstep(objparm *pm)
871
{
872
    animstep=pm->pd[0];
873
    setvar("animstep",pm->pd[0]);
874
}
875
 
7675 bpr 876
/* Starts a line counting */
10 reyssat 877
void obj_linecount(objparm *pm)
878
{
879
    linecnt=pm->pd[0];
880
}
881
 
7675 bpr 882
/* marks end of execution */
10 reyssat 883
void obj_end(objparm *pm)
884
{
885
    error("successful_end_of_execution");
886
}
887
 
7675 bpr 888
/* output */
10 reyssat 889
void obj_output(objparm *pm)
890
{
891
    char *p, namebuf[1024];
892
    p=find_word_start(pm->str); *find_word_end(p)=0;
893
    snprintf(namebuf,sizeof(namebuf),"%s",imagefilename);
894
    snprintf(imagefilename,sizeof(imagefilename),"%s",p);
895
    output();
896
    snprintf(imagefilename,sizeof(imagefilename),"%s",namebuf);
897
}
898
 
7675 bpr 899
/* vimgfile */
1024 bpr 900
void obj_vimgfile(objparm *pm)
901
{
902
    char *p;
903
    p=find_word_start(pm->str); *find_word_end(p)=0;
904
    snprintf(vimgfilename,sizeof(vimgfilename),"%s",p);
905
    if(vimg_ready) vimg_close();
906
}
907
 
7675 bpr 908
/* vimg enable/disable */
1024 bpr 909
void obj_vimg(objparm *pm)
910
{
911
    vimg_enable=pm->pd[0];
912
    if(vimg_enable>0 && vimg_ready==0) {
7675 bpr 913
      vimg_init();
1024 bpr 914
    }
915
}
916
 
7675 bpr 917
/* Set affine transformation */
10 reyssat 918
void obj_affine(objparm *pm)
919
{
920
    int i;
921
    for(i=0;i<4;i++) matrix[i]=pm->pd[i];
922
    transx=pm->pd[4]; transy=pm->pd[5];
923
    transform=1;
924
}
925
 
7675 bpr 926
/* Set affine transformation */
10 reyssat 927
void obj_rotation(objparm *pm)
928
{
929
    double r;
930
    r=M_PI*pm->pd[0]/180;
931
    matrix[0]=matrix[3]=cos(r);
932
    matrix[1]=-sin(r); matrix[2]=sin(r);
933
    transform=1;
934
}
935
 
7675 bpr 936
/* Set affine transformation */
10 reyssat 937
void obj_linear(objparm *pm)
938
{
939
    int i;
940
    for(i=0;i<4;i++) matrix[i]=pm->pd[i];
941
    transform=1;
942
}
943
 
7675 bpr 944
/* Set affine transformation */
10 reyssat 945
void obj_translation(objparm *pm)
946
{
947
    transx=pm->pd[0]; transy=pm->pd[1];
948
}
949
 
7675 bpr 950
/* Set affine transformation */
10 reyssat 951
void obj_killaffine(objparm *pm)
952
{
953
    matrix[0]=matrix[3]=1;
954
    matrix[1]=matrix[2]=transx=transy=0;
955
    transform=0;
956
}
957
 
7675 bpr 958
/* Set affine transformation */
10 reyssat 959
void obj_killlinear(objparm *pm)
960
{
961
    matrix[0]=matrix[3]=1;
962
    matrix[1]=matrix[2]=0;
963
    transform=0;
964
}
965
 
7675 bpr 966
/* Set affine transformation */
10 reyssat 967
void obj_killtranslation(objparm *pm)
968
{
969
    transx=transy=0;
970
}
971
 
972
/***** Les modifs de Jean-Christophe Leger Fev 2006 *****/
973
 
7615 bpr 974
/* arguments: un numero de matrice entre 1 et JC_NB_MATRICES, une liste de 4 nombres reels pour la matrice */
10 reyssat 975
void obj_setmatrix(objparm *pm)
976
{
977
  int nummatrix = (int) (pm->pd[0]);
978
  if((nummatrix < 1) ||(nummatrix>JC_NB_MATRICES)) {
979
    error("bad_matrix_number");
980
    return;
981
  }
982
  matrices_pavage[nummatrix][0] = pm->pd[1];
983
  matrices_pavage[nummatrix][1] = pm->pd[2];
984
  matrices_pavage[nummatrix][2] = pm->pd[3];
985
  matrices_pavage[nummatrix][3] = pm->pd[4];
986
}
987
 
7615 bpr 988
/* arguments: un numero de matrice entre 1 et JC_NB_MATRICES */
10 reyssat 989
void obj_resetmatrix(objparm *pm)
990
{
991
  int nummatrix = (int) (pm->pd[0]);
992
  if((nummatrix < 1) ||(nummatrix>JC_NB_MATRICES)) {
993
    error("bad_matrix_number");
994
    return;
995
  }
996
  matrices_pavage[nummatrix][0] = 1;
997
  matrices_pavage[nummatrix][1] = 0;
998
  matrices_pavage[nummatrix][2] = 0;
999
  matrices_pavage[nummatrix][3] = 1;
1000
 
1001
}
7615 bpr 1002
/* arguments: un numero de vecteur entre 1 et JC_NB_MATRICES, une liste de 2 nombres reels pour le vecteur */
10 reyssat 1003
void obj_setvector(objparm *pm)
1004
{
1005
  int nummatrix = (int) (pm->pd[0]);
1006
  if((nummatrix < 1) ||(nummatrix>JC_NB_MATRICES)) {
1007
    error("bad_vector_number");
1008
    return;
1009
  }
1010
  vecteurs_pavage[nummatrix][0] = pm->pd[1];
1011
  vecteurs_pavage[nummatrix][1] = pm->pd[2];
1012
}
1013
 
7615 bpr 1014
/* arguments: un numero de matrice entre 1 et JC_NB_MATRICES */
10 reyssat 1015
void obj_resetvector(objparm *pm)
1016
{
1017
  int nummatrix = (int) (pm->pd[0]);
1018
  if((nummatrix < 1) ||(nummatrix>JC_NB_MATRICES)) {
1019
    error("bad_vector_number");
1020
    return;
1021
  }
1022
  vecteurs_pavage[nummatrix][0] = 0;
1023
  vecteurs_pavage[nummatrix][1] = 0;
1024
}
1025
 
7615 bpr 1026
/* arguments: un numero de vecteur entre 1 et JC_NB_MATRICES, une liste de 6 nombres reels pour la matrice et le vecteur */
10 reyssat 1027
void obj_settransform(objparm *pm)
1028
{
1029
  int nummatrix = (int) (pm->pd[0]);
1030
  if((nummatrix < 1) ||(nummatrix>JC_NB_MATRICES)) {
1031
    error("bad_vector_number");
1032
    return;
1033
  }
1034
  matrices_pavage[nummatrix][0] = pm->pd[1];
1035
  matrices_pavage[nummatrix][1] = pm->pd[2];
1036
  matrices_pavage[nummatrix][2] = pm->pd[3];
1037
  matrices_pavage[nummatrix][3] = pm->pd[4];
1038
  vecteurs_pavage[nummatrix][0] = pm->pd[5];
1039
  vecteurs_pavage[nummatrix][1] = pm->pd[6];
1040
}
1041
 
1042
 
7615 bpr 1043
/* arguments: un numero de matrice entre 1 et JC_NB_MATRICES */
10 reyssat 1044
void obj_resettransform(objparm *pm)
1045
{
1046
  int nummatrix = (int) (pm->pd[0]);
1047
  if((nummatrix < 1) ||(nummatrix>JC_NB_MATRICES)) {
1048
    error("bad_vector_number");
1049
    return;
1050
  }
1051
  vecteurs_pavage[nummatrix][0] = 0;
1052
  vecteurs_pavage[nummatrix][1] = 0;
1053
  matrices_pavage[nummatrix][0] = 1;
1054
  matrices_pavage[nummatrix][1] = 0;
1055
  matrices_pavage[nummatrix][2] = 0;
1056
  matrices_pavage[nummatrix][3] = 1;
1057
}
1058
 
7615 bpr 1059
/* arguments: une liste de 6 nombres reels pour les coordonnees de l'origine et des vecteurs de base */
10 reyssat 1060
void obj_setparallelogram(objparm *pm)
1061
{
1062
  int i;
1063
  for(i=0;i<6;i++)  parallogram_fonda[i]=pm->pd[i];
1064
}
1065
 
1066
/* arguments :aucun */
1067
void obj_resetparallelogram(objparm *pm)
1068
{
1069
  parallogram_fonda[0]=0;
1070
  parallogram_fonda[1]=0;
1071
  parallogram_fonda[2]=100;
1072
  parallogram_fonda[3]=0;
1073
  parallogram_fonda[4]=0;
1074
  parallogram_fonda[5]=100;
1075
}
1076
 
1077
/* argument : la liste des numeros des matrices a faire agir, le nom du fichier de l'image a inclure */
1078
void obj_multicopy(objparm *pm)
1079
{
1080
    char *pp,*pe,*cptr;
1081
    FILE *inf;
7675 bpr 1082
    gdImagePtr insimg;
10 reyssat 1083
    int i,j;
1084
    int imax,jmax;
1085
    int c; /* la couleur reperee */
1086
    int mat;
1087
    int nummatrices[JC_NB_MATRICES];
1088
    double pt[2]; /* les coordonnees math. du point repere dans le parallelogramme */
1089
    double ptr[2]; /* les coordonnees math. du point transforme */
1090
    int pti[2]; /* les coordonnees img du point a placer sur le canevas */
1091
    int t;
1092
    /* gestion palette de couleur de l'image a inserer */
1093
    int colorMap[gdMaxColors];
1094
    int comptmat=0; /* combien de matrices en tout ? */
7615 bpr 1095
 
10 reyssat 1096
    for (i=0; (i<gdMaxColors); i++) {
1097
      colorMap[i] = (-1);
1098
    }
1099
 
1100
    /* Gestion des parametres la liste est censee finir avec le nom du fichier */
7615 bpr 1101
    t=pm->pcnt-1; /* il faut enlever le nom de fichier ! c'est le nombre de parametres en plus */
10 reyssat 1102
    pp=find_word_start(pm->str);
1103
    /* visiblement find_word_start n'arrive pas a trouver le dernier mot dans un contexte ou le nombre de parameters est variable
1104
     * on cherche donc l'emplacement de la derniere virgule:
1105
     * il y en a une car t>0, on retrouve ensuite le debut de mot
1106
     */
1107
    for(pe=pp;*pe!=0;pe++);/* trouve la fin de la chaine */
1108
    if(t>0){
1109
      for(cptr = pe; cptr > pp && *cptr != ','; cptr--);
1110
      pp=find_word_start(cptr+1);
1111
    }
1112
    pe=find_word_end(pp);*pe=0; /* strip junk final */
1113
    //      printf("pp contient %s\n",pp);
1114
 
1115
 
1116
    inf=open4read(pp);
1117
    if(inf==NULL) {
7675 bpr 1118
      error("file_not_exist"); return;
10 reyssat 1119
    }
1120
    insimg=gdImageCreateFromGif(inf); fclose(inf);
1121
    if(insimg==NULL) {
7675 bpr 1122
      error("bad_gif"); return;
10 reyssat 1123
    }
1124
 
7675 bpr 1125
/* On recupere les numeros des matrices/vecteurs a faire agir,
1126
 * s'il n'y en a pas, on les fait toutes agir
1127
 */
10 reyssat 1128
    for(i=0;i<t && i< JC_NB_MATRICES;i++) {
1129
      if(pm->pd[i]>=1 && pm->pd[i]<=JC_NB_MATRICES){
7675 bpr 1130
        nummatrices[comptmat] = pm->pd[i];
1131
        comptmat++;
10 reyssat 1132
      }
1133
    }
1134
    if(t<=0){
1135
      for(i=0;i<JC_NB_MATRICES;i++) {
7675 bpr 1136
        nummatrices[i] = i+1;
10 reyssat 1137
      }
1138
      comptmat=JC_NB_MATRICES;
1139
    }
1140
 
7615 bpr 1141
 
10 reyssat 1142
    imax = gdImageSX(insimg);
1143
    jmax = gdImageSY(insimg);
1144
 
1145
    for(i=0;i<imax;i++){
1146
      for(j=0;j<jmax;j++){
7675 bpr 1147
        int nc;
1148
        c=gdImageGetPixel(insimg,i,j);
1149
/* Le code suivant est une copie du code dans gdImageCopy  Added 7/24/95: support transparent copies */
1150
        if (gdImageGetTransparent(insimg) != c) {
1151
/* Have we established a mapping for this color? */
1152
          if (colorMap[c] == (-1)) {
1153
/* If it's the same image, mapping is trivial, dans notre cas ca n'arrive jamais... */
1154
            if (image == insimg) {
1155
              nc = c;
1156
            } else {
1157
/* First look for an exact match */
1158
              nc = gdImageColorExact(image,
1159
                     insimg->red[c], insimg->green[c],
1160
                             insimg->blue[c]);
1161
           }
1162
           if (nc == (-1)) {
1163
/* No, so try to allocate it */
1164
             nc = gdImageColorAllocate(image,
1165
                              insimg->red[c], insimg->green[c],
1166
                              insimg->blue[c]);
1167
/* If we're out of colors, go for the closest color */
1168
             if (nc == (-1)) {
1169
               nc = gdImageColorClosest(image,
1170
                               insimg->red[c], insimg->green[c],
1171
                               insimg->blue[c]);
1172
             }
1173
           }
1174
           colorMap[c] = nc;
1175
         }
10 reyssat 1176
 
7675 bpr 1177
         pt[0]= i*(parallogram_fonda[2])/(imax-1)+(jmax-j)*(parallogram_fonda[4])/(jmax-1)+parallogram_fonda[0];
1178
         pt[1]= i*(parallogram_fonda[3])/(imax-1)+(jmax-j)*(parallogram_fonda[5])/(jmax-1)+parallogram_fonda[1];
1179
         for(mat=0;mat<comptmat;mat++){
1180
          double *matricecourante = matrices_pavage[nummatrices[mat]];
1181
          double *vecteurcourant = vecteurs_pavage[nummatrices[mat]];
1182
          ptr[0] = matricecourante[0]*pt[0]+matricecourante[1]*pt[1]+vecteurcourant[0];
1183
          ptr[1] = matricecourante[2]*pt[0]+matricecourante[3]*pt[1]+vecteurcourant[1];
1184
          scale(ptr,pti,1);
1185
          gdImageSetPixel(image,pti[0],pti[1],colorMap[c]);
1186
         }
1187
       }
10 reyssat 1188
      }
1189
    }
1190
    gdImageDestroy(insimg);
1191
}
1192
 
1193
/**** Fin modifs JC Fev 06 ******/
1194
 
7675 bpr 1195
/* get color from value */
10 reyssat 1196
int calc_color(char *p, struct objtab *o)
1197
{
1198
    int k, cc[3];
1199
    char buf[MAX_LINELEN+1];
1200
    for(k=0;k<3;k++) {
7675 bpr 1201
      fnd_item(p,k+1,buf);
8076 bpr 1202
      cc[k]=strevalue(buf);
10 reyssat 1203
    }
1204
    collapse_item(p,3);
1205
    if(cc[0]==-1 && cc[1]==-1 && cc[2]==-255) {
1206
 
7675 bpr 1207
      if(brushed && o->subst&1) return gdBrushed;
1208
      else return color_black;
10 reyssat 1209
    }
1210
    if(cc[0]==-1 && cc[1]==-255 && cc[2]==-1) {
7675 bpr 1211
      if(styled && o->subst&2)  return gdStyled;
1212
      else return color_black;
10 reyssat 1213
    }
1214
    if(cc[0]==-255 && cc[1]==-1 && cc[2]==-1) {
7675 bpr 1215
      if(tiled && o->fill_tag==1)  return gdTiled;
1216
      else return color_black;
10 reyssat 1217
    }
1218
    return getcolor(cc[0],cc[1],cc[2]);
1219
}
1220
 
7675 bpr 1221
/* Routine to parse parameters */
10 reyssat 1222
int parse_parms(char *p,objparm *pm,struct objtab *o)
1223
{
1224
    char buf[MAX_LINELEN+1];
1225
    char *p1, *p2;
1226
    int j,t,c,c1,c2;
7615 bpr 1227
 
10 reyssat 1228
    c=o->color_pos;c1=c2=0;
1229
    pm->color[0]=pm->color[1]=0;
1230
    if(c>0) c1=c; if(c<0) c2=-c; c=c1+c2;
1231
    t=itemnum(p);if(t<o->required_parms+3*c) return -1;
1232
    if(c1>0 && t>o->required_parms+3*c) t=o->required_parms+3*c;
1233
    pm->pcnt=t-3*c;
1234
    if(pm->pcnt>MAX_PARMS) pm->pcnt=MAX_PARMS;
1235
    if(c2>0) {
7675 bpr 1236
      for(j=0;j<2 && j<c2; j++) pm->color[j]=calc_color(p,o);
10 reyssat 1237
    }
1238
    snprintf(buf,sizeof(buf),"%s",p);
1239
    for(j=0, p1=buf; j<pm->pcnt; j++, p1=p2) {
7675 bpr 1240
      p2=find_item_end(p1); if(*p2) *p2++=0;
1241
      p1=find_word_start(p1);
8076 bpr 1242
      if(*p1) pm->pd[j]=strevalue(p1); else pm->pd[j]=0;
8171 bpr 1243
      if(!isfinite(pm->pd[j])) {
7675 bpr 1244
          if(j<o->required_parms) return -1;
1245
          else {pm->pd[j]=0;break;}
1246
      }
10 reyssat 1247
    }
1248
    collapse_item(p,o->required_parms);
1249
    if(c1>0) {
7675 bpr 1250
      for(j=0;j<c1 && j<2; j++) pm->color[j]=calc_color(p,o);
10 reyssat 1251
    }
1252
    if(width>1 && o->subst&1 && pm->color[0]!=gdBrushed
1253
       && pm->color[0]!=gdStyled && pm->color[0]!=gdTiled) {
7675 bpr 1254
      pm->color[1]=pm->color[0];
1255
      pm->color[0]=widthcolor(width,pm->color[0]);
10 reyssat 1256
    }
1257
    pm->fill=o->fill_tag;
3718 reyssat 1258
    ovlstrcpy(pm->str,p); return 0;
10 reyssat 1259
}
1260
 
8068 bpr 1261
/* Create the struct objparm pm corresponding to the objparm p
1262
 * Execute a command. Returns 0 if OK.
1263
 */
10 reyssat 1264
int obj_main(char *p)
1265
{
1266
    int i;
1267
    char *pp,*name,*pt;
1268
    char tbuf2[MAX_LINELEN+1];
1269
    struct objparm pm;
1270
 
1271
    p=find_word_start(p);
1272
    if(*p==exec_prefix_char || *p==0) return 0; /* comment */
1273
    name=p;
1274
    pp=find_name_end(p);
1275
    pt=find_word_start(pp); if(*pt=='=') *pt=' ';
1276
    if(*pt==':' && *(pt+1)=='=') *pt=*(pt+1)=' ';
1277
    pp=find_word_end(p);
1278
    if(*pp!=0) {
7675 bpr 1279
      *(pp++)=0; pp=find_word_start(pp);
10 reyssat 1280
    }
1281
    if(strlen(p)==1 || (strlen(p)==2 && isdigit(*(p+1)))) {
8076 bpr 1282
      setvar(p,strevalue(pp)); return 0;
10 reyssat 1283
    }
8068 bpr 1284
/* search the number of the object */
10 reyssat 1285
    i=search_list(objtab,obj_no,sizeof(objtab[0]),name);
1286
    if(i<0) {
7675 bpr 1287
      error("bad_cmd"); return 1;
10 reyssat 1288
    }
1289
    if(image==NULL && (objtab[i].color_pos || objtab[i].required_parms>2)) {
7675 bpr 1290
      error("image_not_defined"); return 1;
10 reyssat 1291
    }
3718 reyssat 1292
    ovlstrcpy(tbuf2,pp);
10 reyssat 1293
    if(objtab[i].color_pos || objtab[i].routine==obj_setstyle) {
7675 bpr 1294
      substit(tbuf2);
10 reyssat 1295
    }
1296
    if(parse_parms(tbuf2,&pm,objtab+i)!=0) error("bad_parms");
1297
    else objtab[i].routine(&pm);
1298
    return 0;
1299
}
1300