~ml-launchpad/ubuntu/natty/gcompris/fix-for-777349

« back to all changes in this revision

Viewing changes to src/boards/gtans.c

  • Committer: Bazaar Package Importer
  • Author(s): Marc Gariepy, Marc Gariepy, Stephane Graber
  • Date: 2010-01-04 17:42:49 UTC
  • mfrom: (1.1.14 upstream)
  • Revision ID: james.westby@ubuntu.com-20100104174249-7bupatd9dtxyhvs4
Tags: 9.0-0ubuntu1
[Marc Gariepy]
* New upstream release (9.0).
* Remove cache.c from POTFILES to avoid FTBFS
* Remove unneeded rm in debian/rules (file no longer exists upstream)

[Stephane Graber]
* Bump Debian standards to 3.8.3
* Add patch system (dpatch)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 1999  Philippe Banwarth
3
 
 * email: bwt@altern.org
4
 
 * smail: Philippe Banwarth, 8 sente du milieu des Gaudins, 95150 Taverny, France.
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU General Public License as published by
8
 
 * the Free Software Foundation; either version 3 of the License, or
9
 
 * (at your option) any later version.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 * GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
18
 
 */
19
 
 
20
 
#include "gcompris/gcompris.h"
21
 
 
22
 
#include <glib/gstdio.h>
23
 
#include <string.h>
24
 
 
25
 
/* Added by Florian Ernst <florian_ernst@gmx.net> for lines 193 and 194 */
26
 
//#include <string.h>
27
 
/* End of added section */
28
 
 
29
 
#include "gtans.h"
30
 
#include "gtans_interface.h"
31
 
#include "gtans_support.h"
32
 
 
33
 
void taninitstart(void);
34
 
 
35
 
/* GCompris */
36
 
 
37
 
static void start_board (GcomprisBoard *agcomprisBoard);
38
 
static void pause_board (gboolean pause);
39
 
static void end_board (void);
40
 
static gboolean is_our_board (GcomprisBoard *gcomprisBoard);
41
 
 
42
 
static gint actual_figure = -2;
43
 
 
44
 
/* Description of this plugin */
45
 
 
46
 
 
47
 
static BoardPlugin menu_bp =
48
 
  {
49
 
    NULL,
50
 
    NULL,
51
 
    "GTans",
52
 
    "Tangram",
53
 
    "Bruno Coudoin <bruno.coudoin@free.fr>",
54
 
    NULL,
55
 
    NULL,
56
 
    NULL,
57
 
    NULL,
58
 
    start_board,
59
 
    pause_board,
60
 
    end_board,
61
 
    is_our_board,
62
 
    NULL,
63
 
    NULL,
64
 
    NULL,
65
 
    NULL,
66
 
    NULL,
67
 
    NULL,
68
 
    NULL
69
 
  };
70
 
 
71
 
GET_BPLUGIN_INFO(gtans)
72
 
 
73
 
static GcomprisBoard *gcomprisBoard = NULL;
74
 
 
75
 
static GnomeCanvasGroup *boardRootItem = NULL;
76
 
 
77
 
static gboolean board_paused = FALSE;
78
 
 
79
 
static void start_board (GcomprisBoard *agcomprisBoard)
80
 
{
81
 
 
82
 
  if(agcomprisBoard!=NULL)
83
 
    {
84
 
      gcomprisBoard=agcomprisBoard;
85
 
 
86
 
      gcomprisBoard->level = 1;
87
 
      gcomprisBoard->maxlevel = 1;
88
 
      gc_bar_set(0);
89
 
 
90
 
      gc_set_background(gnome_canvas_root(gcomprisBoard->canvas),
91
 
                        "opt/gtans_bg.png");
92
 
 
93
 
      selectedgrande = FALSE;
94
 
      taninitstart();
95
 
    }
96
 
}
97
 
 
98
 
static void end_board (void)
99
 
{
100
 
  gtk_object_destroy (GTK_OBJECT(boardRootItem));
101
 
  boardRootItem = NULL;
102
 
 
103
 
  widgetpetite = NULL;
104
 
  widgetgrande = NULL;
105
 
 
106
 
 
107
 
  pixmapgrande1=NULL;
108
 
  pixmapgrande2=NULL;
109
 
  pixmappetite=NULL;
110
 
  pixmappiece1=NULL;
111
 
  pixmappiece2=NULL;
112
 
  pixmapfond=NULL;
113
 
  colselwin=NULL;
114
 
  filselwin=NULL;
115
 
 
116
 
  selectedgrande = FALSE;
117
 
}
118
 
 
119
 
static gboolean
120
 
is_our_board (GcomprisBoard *gcomprisBoard)
121
 
{
122
 
  if (gcomprisBoard)
123
 
    {
124
 
      if(g_strcasecmp(gcomprisBoard->type, "gtans")==0)
125
 
        {
126
 
          /* Set the plugin entry */
127
 
          gcomprisBoard->plugin=&menu_bp;
128
 
 
129
 
          return TRUE;
130
 
        }
131
 
    }
132
 
  return FALSE;
133
 
}
134
 
 
135
 
static void pause_board (gboolean pause)
136
 
{
137
 
 
138
 
  if(gcomprisBoard==NULL)
139
 
    return;
140
 
 
141
 
  board_paused = pause;
142
 
 
143
 
  if ((!pause) && figpetite.reussi) {
144
 
    gtk_widget_show(widgetgrande);
145
 
    gtk_widget_show(widgetpetite);
146
 
 
147
 
    actual_figure++;
148
 
    tansetnewfigurepart1(actual_figure);
149
 
    tansetnewfigurepart2();
150
 
  } else {
151
 
    if (pause) {
152
 
      gtk_widget_hide(widgetgrande);
153
 
      gtk_widget_hide(widgetpetite);
154
 
 
155
 
    } else {
156
 
      gtk_widget_show(widgetgrande);
157
 
      gtk_widget_show(widgetpetite);
158
 
    }
159
 
  }
160
 
 
161
 
}
162
 
 
163
 
void change_figure(gboolean next){
164
 
  if (next)
165
 
    tansetnewfigurepart1((actual_figure+1)%figtabsize);
166
 
  else
167
 
    tansetnewfigurepart1((actual_figure + figtabsize -1)%figtabsize);
168
 
  tansetnewfigurepart2();
169
 
}
170
 
 
171
 
 
172
 
 
173
 
/********************************/
174
 
GtkWidget *mainwindow;
175
 
GtkWidget *widgetgrande;        /* widget de la grande drawarea */
176
 
GtkWidget *widgetpetite;        /* widget de la petite drawarea */
177
 
GtkStatusbar *widgetstat;       /* widget de la statusbar */
178
 
GtkSpinButton *spinner=NULL;
179
 
 
180
 
gint statconid;                 /* context id de la statusbar */
181
 
GdkRectangle selbackrect;       /* rectangle a redessiner pour effacer la piece selected */
182
 
 
183
 
GdkPixmap *pixmapgrande1=NULL,*pixmapgrande2;
184
 
GdkPixmap *pixmappetite=NULL;
185
 
GdkPixmap *pixmappiece1=NULL,*pixmappiece2=NULL,*pixmapfond=NULL;
186
 
 
187
 
GtkWidget *colselwin=NULL,*filselwin=NULL;
188
 
 
189
 
 
190
 
/* les polygones doivent etre clockwise */
191
 
tanpiecedef piecesdef[]={
192
 
 {2.0/3,2.0/3,   4,{{1,0,6*HT},{1,0,0},{0,1,2*HT},{0,1,0}},     3,{{0,0},{2,0},{0,2},{0,0}}},
193
 
 {CL/3,CL/3,     2,{{CC,CC,5*HT},{CC,CC,3*HT},{0,0,0},{0,0,0}}, 3,{{0,0},{CL,0},{0,CL},{0,0}}},
194
 
 {0.5,0.5,       2,{{0,0,0},{1,1,4*HT},{0,0,0},{0,0,0}},        4,{{0,0},{1,0},{1,1},{0,1}}},
195
 
 {CC/2,(CC+CL)/2,2,{{0,CC,1*HT},{CC,CL,5*HT},{0,0,0},{0,0,0}},4,{{0,CC},{CC,0},{CC,CL},{0,CC+CL}}},
196
 
 {1.0/3,1.0/3,   1,{{0,0,0},{0,0,0},{0,0,0},{0,0,0}},           3,{{0,0},{1,0},{0,1},{0,0}}}
197
 
};
198
 
 
199
 
tanfigure figuredebut={
200
 
  0.125,1,TOUR/64,FALSE,
201
 
  {{0,0,0.8,0.8,0},
202
 
   {0,0,3.3,0.8,0},
203
 
   {1,0,1.5,1.5,HT*4},
204
 
   {2,0,6,0.6,0},
205
 
   {3,0,6,1.6,HT*2},
206
 
   {4,0,3.6,1.8,HT*7},
207
 
   {4,0,4.1,1.3,HT*1}}
208
 
};
209
 
 
210
 
tanfigure *figtab=NULL;
211
 
int figtabsize;                    /* ==0 : pas de figure */
212
 
char *figfilename=NULL;
213
 
int figactualnr;                   /* nr de la figure dans le figtab (-1=figuredebut, -2=figpetite) */
214
 
 
215
 
tantinytri tinytabpe[TINYNBR],tinytabgr[TINYNBR];
216
 
tanfigure figgrande,figpetite;
217
 
int selectedgrande=FALSE;
218
 
int xact,yact,xoth,yoth,xold,yold;
219
 
int actiongrande=AN_none;
220
 
int selpossible=TRUE;
221
 
int rotact,rotnew,rotold;
222
 
 
223
 
int rotstepnbr=TOUR/32;            /* nb. de pas de rotation affiches */
224
 
int initcbgr=FALSE,initcbpe=FALSE; /* init cb deja appellee ? */
225
 
 
226
 
GdkGC *invertgc;
227
 
int invx2,invy2;
228
 
 
229
 
GdkGC *tabgc[GCNBR];
230
 
GdkColor colortab[GCNBR];
231
 
GdkPixmap *dumtabpxpx[3],**tabpxpx=dumtabpxpx-PXSTART;
232
 
char *dumtabpxnam[3],**tabpxnam=dumtabpxnam-PXSTART;
233
 
 
234
 
gboolean helpoutset=FALSE;
235
 
gboolean helptanset=PIECENBR;
236
 
int accuracy;                          /* precision de reconaissance */
237
 
 
238
 
gboolean editmode;
239
 
 
240
 
#define FLPNTMAX PIECENBR*(PNTNBRMAX+1)*2
241
 
static gboolean dumtabpxpixmode[3],*tabpxpixmode=dumtabpxpixmode-PXSTART; /* mode VOULU */
242
 
static gboolean tabcolalloc[GCNBR];   /* couleur allouee ? */
243
 
static gchar *userconf=NULL;          /* nom complet du fichier de config local */
244
 
static tanflfig flfigpetite;
245
 
static tanfpnt fpntspetite[FLPNTMAX];
246
 
 
247
 
static double dxout,dyout,dxpetite,dypetite;
248
 
 
249
 
static double selposxnc,selposync;      /* position de la piece actuelle non limitee */
250
 
 
251
 
 
252
 
/********************************/
253
 
/* change la valeur max du spinbutton (si il existe) */
254
 
void tanspinsetvalmax (int val){
255
 
  GtkAdjustment *adj;
256
 
 
257
 
  if (spinner!=NULL){
258
 
    adj = gtk_spin_button_get_adjustment(spinner);
259
 
    adj->upper = (gfloat)val;
260
 
    gtk_adjustment_changed(adj);
261
 
    if (gtk_spin_button_get_value_as_int(spinner)){
262
 
      gtk_spin_button_set_value(spinner, 0);
263
 
    }
264
 
    else{
265
 
      tansetnewfigurepart1(0);
266
 
      tansetnewfigurepart2();
267
 
    }
268
 
  } else
269
 
    {
270
 
      tansetnewfigurepart1(0);
271
 
      tansetnewfigurepart2();
272
 
    }
273
 
 
274
 
}
275
 
 
276
 
 
277
 
/********************************/
278
 
void tanallocname (char **pnt, char *name){
279
 
  if (*pnt!=name){
280
 
    if (*pnt!=NULL)
281
 
      g_free(*pnt);
282
 
    *pnt=(char *)g_malloc(strlen(name)+1);
283
 
    strcpy(*pnt,name);
284
 
  }
285
 
}
286
 
 
287
 
 
288
 
 
289
 
/********************************/
290
 
/* maintien les pieces dans les limites */
291
 
void tanclampgrandefig (void){
292
 
 
293
 
  tanpiecepos *piecepos;
294
 
  int i;
295
 
  double dumzoom;
296
 
 
297
 
  dumzoom = 1.0/figgrande.zoom;
298
 
  piecepos = figgrande.piecepos;
299
 
  for (i = 0; i<PIECENBR; i++){
300
 
    piecepos->posx = CLAMP(piecepos->posx, 0.0, dumzoom);
301
 
    piecepos->posy = CLAMP(piecepos->posy, 0.0, dumzoom);
302
 
    piecepos++;
303
 
  }
304
 
 
305
 
  return;
306
 
}
307
 
 
308
 
 
309
 
/********************************/
310
 
/* renvoi la direction d'un segment */
311
 
int tanangle (double dx, double dy){
312
 
  int ret;
313
 
 
314
 
  ret = (int)(atan2(dy,dx)/PASTOUR);
315
 
  ret = (ret+TOUR)%TOUR;
316
 
 
317
 
  return (ret);
318
 
 
319
 
}
320
 
 
321
 
 
322
 
/********************************/
323
 
gboolean tantinytabcompare (tantinytri *tinys1, tantinytri *tinys2, int accuracy){
324
 
 
325
 
  gboolean libre[TINYNBR];
326
 
  int i,j,jmin;
327
 
  double dist,mindist,mindistmax,xi,yi;
328
 
  int drot,drotmax,roti;
329
 
  double flaccur;
330
 
 
331
 
  switch (accuracy){
332
 
  case 0 :
333
 
    flaccur = 1.0;
334
 
    drotmax = (int)(TOUR/64)+1;
335
 
    break;
336
 
  case 2 :
337
 
    flaccur = 4.0;
338
 
    drotmax = (int)(TOUR/32)+1;
339
 
    break;
340
 
  default :
341
 
    flaccur = 2.0;
342
 
    drotmax = (int)(TOUR/64)+1;
343
 
  }
344
 
 
345
 
  /* drotmax=figpetite.drotmax; */
346
 
  mindistmax=pow(figpetite.distmax*0.10*flaccur,2);
347
 
 
348
 
  for (i=0; i<TINYNBR; i++)
349
 
    libre[i]=TRUE;
350
 
 
351
 
  for (i=0; i<TINYNBR; i++){
352
 
    jmin=0;
353
 
    mindist=100000;
354
 
    xi=tinys1[i].posx;
355
 
    yi=tinys1[i].posy;
356
 
    roti=tinys1[i].rot;
357
 
 
358
 
    for (j=0; j<TINYNBR; j++){
359
 
      if (libre[j]){
360
 
        dist=pow(xi-tinys2[j].posx,2)+pow(yi-tinys2[j].posy,2);
361
 
        drot=ABS(roti-tinys2[j].rot);
362
 
        if ( drot>TOUR/2 )
363
 
          drot = TOUR-drot;
364
 
        if ( dist<mindist && drot<drotmax ){
365
 
          mindist=dist;
366
 
          jmin=j;
367
 
        }
368
 
      }
369
 
    }
370
 
    libre[jmin]=FALSE;
371
 
    if ( mindist>mindistmax )
372
 
      return FALSE;
373
 
  }
374
 
 
375
 
  return TRUE;
376
 
 
377
 
}
378
 
 
379
 
 
380
 
/********************************/
381
 
void tansmall2tiny (tansmalltri *small, tantinytri *tiny1, tantinytri *tiny2){
382
 
 
383
 
  double cosrot,sinrot;
384
 
  int rot;
385
 
 
386
 
  rot=small->rot;
387
 
  cosrot=cos(rot*PASTOUR);
388
 
  sinrot=sin(rot*PASTOUR);
389
 
 
390
 
  tiny1->rot=(rot+HT*3)%TOUR;
391
 
  tiny1->posx=small->posx+0.5*cosrot       +0.16666666*sinrot;
392
 
  tiny1->posy=small->posy+0.16666666*cosrot-0.5*sinrot;
393
 
 
394
 
  tiny2->rot=(rot+HT*5)%TOUR;
395
 
  tiny2->posx=small->posx+0.16666666*cosrot+0.5*sinrot;
396
 
  tiny2->posy=small->posy+0.5*cosrot       -0.16666666*sinrot;
397
 
 
398
 
}
399
 
 
400
 
 
401
 
/********************************/
402
 
void tanmaketinytabnotr (tanfigure *figure, tantinytri *tinys){
403
 
 
404
 
  int i,j;
405
 
  tansmalltri dusmall,*small=&dusmall;
406
 
  tanpiecepos *piecepos;
407
 
  tanpiecedef *piecedat;
408
 
  double ly,lx2,cosrot,sinrot;
409
 
  int rot,rottri;
410
 
 
411
 
  piecepos=figure->piecepos;
412
 
 
413
 
  for (j=0; j<PIECENBR; j++){
414
 
 
415
 
    piecedat=&piecesdef[piecepos->type];
416
 
    rot=piecepos->rot;
417
 
    cosrot=cos(rot*PASTOUR);
418
 
    sinrot=sin(rot*PASTOUR);
419
 
 
420
 
    for (i=0; i<piecedat->trinbr; i++){
421
 
      lx2=piecedat->tri[i].posx-piecedat->handlex;
422
 
      ly=piecedat->tri[i].posy-piecedat->handley;
423
 
      rottri=piecedat->tri[i].rot;
424
 
 
425
 
      if (piecepos->flipped){
426
 
        lx2=-lx2;
427
 
        rottri=TOUR+6*HT-rottri;
428
 
      }
429
 
 
430
 
      small->posx=piecepos->posx+lx2*cosrot+ly*sinrot;
431
 
      small->posy=piecepos->posy+ly*cosrot-lx2*sinrot;
432
 
      small->rot=(rottri+rot)%TOUR;
433
 
      tansmall2tiny(small,tinys,tinys+1);
434
 
      tinys+=2;
435
 
    }
436
 
    piecepos++;
437
 
  }
438
 
 
439
 
}
440
 
 
441
 
 
442
 
/********************************/
443
 
void tantranstinytab (tantinytri *tinys){
444
 
 
445
 
  int i;
446
 
  double moyx=0,moyy=0;
447
 
 
448
 
  for (i=0; i<TINYNBR; i++){
449
 
    moyx+=tinys->posx;
450
 
    moyy+=tinys->posy;
451
 
    tinys++;
452
 
  }
453
 
 
454
 
  moyx/=TINYNBR;
455
 
  moyy/=TINYNBR;
456
 
 
457
 
  for (i=0; i<TINYNBR; i++){
458
 
    (--tinys)->posx-=moyx;
459
 
    tinys->posy-=moyy;
460
 
  }
461
 
 
462
 
}
463
 
 
464
 
 
465
 
/********************************/
466
 
/* termine la rotation (lorsque le mouse button est relache) */
467
 
/* est appele par redrawgrande et on_buttonpress au cas ou le signal a ete masque par*/
468
 
/* l'appui sur un bouton */
469
 
void tanreleaseifrot (void){
470
 
  if (actiongrande==AN_rot){
471
 
    gdk_draw_line (widgetgrande->window,
472
 
                   invertgc,
473
 
                   xact,yact,invx2,invy2);
474
 
 
475
 
    figgrande.piecepos[PIECENBR-1].rot=(rotnew+TOUR*5)%TOUR;
476
 
  }
477
 
 
478
 
  actiongrande = AN_none;
479
 
 
480
 
  return;
481
 
}
482
 
 
483
 
 
484
 
/********************************/
485
 
/* calcule une serie de GdkPoint correspondant au polygone de la piece */
486
 
/* + un point correspondand au centre de la piece */
487
 
int tanplacepiece (tanpiecepos *piecepos, GdkPoint *pnts, double zoom){
488
 
 
489
 
  int i;
490
 
  tanpiecedef *piecedat;
491
 
  double lx,ly,lx2,cosrot,sinrot;
492
 
  int rot;
493
 
 
494
 
  piecedat=&piecesdef[piecepos->type];
495
 
  rot=piecepos->rot;
496
 
  cosrot=cos(rot*PASTOUR);
497
 
  sinrot=sin(rot*PASTOUR);
498
 
 
499
 
  for(i=0; i<piecedat->pntnbr; i++){
500
 
    lx2=piecedat->pnt[i].posx-piecedat->handlex;
501
 
    ly=piecedat->pnt[i].posy-piecedat->handley;
502
 
    if (piecepos->flipped)
503
 
      lx2=-lx2;
504
 
    lx=(piecepos->posx+lx2*cosrot+ly*sinrot)*zoom;
505
 
    ly=(piecepos->posy+ly*cosrot-lx2*sinrot)*zoom;
506
 
    pnts->x=(gint16)(lx+ARON);
507
 
    pnts->y=(gint16)(ly+ARON);
508
 
    pnts++;
509
 
  }
510
 
 
511
 
  pnts->x=(gint16)(piecepos->posx*zoom+ARON);
512
 
  pnts->y=(gint16)(piecepos->posy*zoom+ARON);
513
 
 
514
 
  return(piecedat->pntnbr);
515
 
 
516
 
}
517
 
 
518
 
 
519
 
/********************************/
520
 
/* calcule une serie de point en flottant correspondant au polygone de la piece */
521
 
/* pas de point central */
522
 
/* copie le premier points derriere le dernier */
523
 
/* le polygone retourne est clockwise (si la def l'est) */
524
 
int tanplacepiecefloat (tanpiecepos *piecepos, tanfpnt *fpnts, double zoom){
525
 
 
526
 
  int i;
527
 
  tanpiecedef *piecedat;
528
 
  double lx,ly,lx2,cosrot,sinrot;
529
 
  int rot;
530
 
  int nbr;
531
 
 
532
 
  piecedat=&piecesdef[piecepos->type];
533
 
  nbr=piecedat->pntnbr;
534
 
  rot=piecepos->rot;
535
 
  cosrot=cos(rot*PASTOUR);
536
 
  sinrot=sin(rot*PASTOUR);
537
 
 
538
 
  for(i=0; i<nbr; i++){
539
 
    lx2=piecedat->pnt[i].posx-piecedat->handlex;
540
 
    ly=piecedat->pnt[i].posy-piecedat->handley;
541
 
    if (piecepos->flipped)
542
 
      lx2=-lx2;
543
 
    lx=(piecepos->posx+lx2*cosrot+ly*sinrot)*zoom;
544
 
    ly=(piecepos->posy+ly*cosrot-lx2*sinrot)*zoom;
545
 
    fpnts->posx=lx;
546
 
    fpnts++->posy=ly;
547
 
  }
548
 
  fpnts -=nbr;
549
 
 
550
 
  if (piecepos->flipped){
551
 
    tanfpnt dumfpnt;
552
 
    for (i = 0; i<nbr/2 ;i++){
553
 
      dumfpnt = fpnts[i];
554
 
      fpnts[i] = fpnts[nbr-i-1];
555
 
      fpnts[nbr-i-1] = dumfpnt;
556
 
    }
557
 
  }
558
 
 
559
 
  *(fpnts+nbr)=*fpnts;
560
 
 
561
 
  return(nbr);
562
 
 
563
 
}
564
 
 
565
 
 
566
 
/********************************/
567
 
/* calcule le carre de la distance et le deplacement entre un point et un segment */
568
 
/* renvoie 100000.0 si la projection sur la droite du point n'est pas sur le segment */
569
 
/* resultat : vecteur du segment au point */
570
 
double tandistcarsegpnt (tanfpnt *segment, tanfpnt *point, double *pdx, double *pdy){
571
 
 
572
 
  double segdx,segdy;
573
 
  double seglencar,scal,dum;
574
 
 
575
 
  segdx=segment[1].posx-segment[0].posx;
576
 
  segdy=segment[1].posy-segment[0].posy;
577
 
  *pdx=point->posx-segment->posx;
578
 
  *pdy=point->posy-segment->posy;
579
 
 
580
 
  seglencar=segdx*segdx+segdy*segdy;
581
 
  if ( (scal=(*pdx*segdx)+(*pdy*segdy))<0 || (dum=scal/seglencar)>1 )
582
 
    return (1000000.0);
583
 
 
584
 
  *pdx-=segdx*dum;
585
 
  *pdy-=segdy*dum;
586
 
 
587
 
  return (*pdx*(*pdx)+*pdy*(*pdy));
588
 
 
589
 
}
590
 
 
591
 
 
592
 
/********************************/
593
 
double tandistcar (tanfpnt *pnt1, tanfpnt *pnt2){
594
 
 
595
 
  double dx,dy;
596
 
 
597
 
  dx=(pnt1->posx-pnt2->posx);
598
 
  dy=(pnt1->posy-pnt2->posy);
599
 
  return (dx*dx+dy*dy);
600
 
 
601
 
}
602
 
 
603
 
 
604
 
/********************************/
605
 
void tancolle (tanfigure *figure, double seuil){
606
 
 
607
 
  tanpiecepos *piecepos;
608
 
  tanfpnt pnts1[PNTNBRMAX+1],pnts2[PNTNBRMAX+1];
609
 
  int pntnbr1,pntnbr2;
610
 
  int i,j,k,l;
611
 
  int nbrcommun;
612
 
  double dx,dy,dx2,dy2,dxtot,dytot;
613
 
 
614
 
  seuil*=seuil;
615
 
  piecepos=figure->piecepos;
616
 
 
617
 
  for (i=0; i<PIECENBR-1; i++){
618
 
    for (j=i+1; j<PIECENBR; j++) {
619
 
      pntnbr1=tanplacepiecefloat(&piecepos[i],pnts1,1);
620
 
      pntnbr2=tanplacepiecefloat(&piecepos[j],pnts2,1);
621
 
      nbrcommun=0;
622
 
      dxtot=dytot=0;
623
 
      for (k=0; k<pntnbr1; k++){
624
 
        for (l=0; l<pntnbr2; l++){
625
 
          dx=pnts1[k+1].posx-pnts2[l].posx;
626
 
          dy=pnts1[k+1].posy-pnts2[l].posy;
627
 
          dx2=pnts1[k].posx-pnts2[l+1].posx;
628
 
          dy2=pnts1[k].posy-pnts2[l+1].posy;
629
 
          if ( (dx*dx+dy*dy)>seuil && (dx2*dx2+dy2*dy2)>seuil ){
630
 
            if ( tandistcarsegpnt(&pnts1[k],&pnts2[l],&dx,&dy)<seuil/4 ){
631
 
              nbrcommun++;
632
 
              dxtot-=dx;
633
 
              dytot-=dy;
634
 
            }
635
 
            if ( tandistcarsegpnt(&pnts2[l],&pnts1[k],&dx,&dy)<seuil/4 ){
636
 
              nbrcommun++;
637
 
              dxtot+=dx;
638
 
              dytot+=dy;
639
 
            }
640
 
          }
641
 
        }
642
 
      }
643
 
      if (nbrcommun){
644
 
        piecepos[j].posx+=dxtot/nbrcommun;
645
 
        piecepos[j].posy+=dytot/nbrcommun;
646
 
      }
647
 
 
648
 
      pntnbr2=tanplacepiecefloat(&piecepos[j],pnts2,1);
649
 
      nbrcommun=0;
650
 
      dxtot=dytot=0;
651
 
      for (k=0; k<pntnbr1; k++){
652
 
        for (l=0; l<pntnbr2; l++){
653
 
          dx=(pnts1[k].posx-pnts2[l].posx);
654
 
          dy=(pnts1[k].posy-pnts2[l].posy);
655
 
          if ( (dx*dx+dy*dy)<seuil ){
656
 
            nbrcommun++;
657
 
            dxtot+=dx;
658
 
            dytot+=dy;
659
 
          }
660
 
/*        else{
661
 
            dx=(pnts1[(k+1)*2]-pnts2[l*2]);
662
 
            dy=(pnts1[(k+1)*2+1]-pnts2[l*2+1]);
663
 
            dx2=(pnts1[k*2]-pnts2[(l+1)*2]);
664
 
            dy2=(pnts1[k*2+1]-pnts2[(l+1)*2+1]);
665
 
            if ( (dx*dx+dy*dy)>seuil && (dx2*dx2+dy2*dy2)>seuil ){
666
 
              if ( tandistcarsegpnt(pnts1+k*2,pnts2+l*2,&dx,&dy)<seuil/100 ){
667
 
                nbrcommun++;
668
 
                dxtot-=dx;
669
 
                dytot-=dy;
670
 
              }
671
 
              if ( tandistcarsegpnt(pnts2+l*2,pnts1+k*2,&dx,&dy)<seuil/100 ){
672
 
                nbrcommun++;
673
 
                dxtot+=dx;
674
 
                dytot+=dy;
675
 
              }
676
 
            }
677
 
          }         */
678
 
        }
679
 
      }
680
 
 
681
 
      if (nbrcommun){
682
 
        piecepos[j].posx+=dxtot/nbrcommun;
683
 
        piecepos[j].posy+=dytot/nbrcommun;
684
 
      }
685
 
    }
686
 
  }
687
 
}
688
 
 
689
 
 
690
 
/********************************/
691
 
GdkRectangle tandrawpiece (GtkWidget *widget,GdkPixmap *pixmap,
692
 
                           tanpiecepos *piecepos,
693
 
                           double zoom, tanremplis remplis){
694
 
 
695
 
  GdkPoint pnt[PNTNBRMAX+1];
696
 
  int i,pntnbr,ix,iy,ixmax=-20000,ixmin=20000,iymax=-20000,iymin=20000;
697
 
  GdkRectangle update_rect;
698
 
  GdkGC *gc;
699
 
  double gris,rx,ry;
700
 
 
701
 
  pntnbr=tanplacepiece(piecepos,pnt,zoom);
702
 
 
703
 
  for(i=0; i<pntnbr; i++){
704
 
    ix=pnt[i].x;
705
 
    iy=pnt[i].y;
706
 
    if (ix<ixmin)
707
 
      ixmin=ix;
708
 
    if (ix>ixmax)
709
 
      ixmax=ix;
710
 
    if (iy<iymin)
711
 
      iymin=iy;
712
 
    if (iy>iymax)
713
 
      iymax=iy;
714
 
  }
715
 
 
716
 
  update_rect.x=ixmin;
717
 
  update_rect.y=iymin;
718
 
  update_rect.width=ixmax-ixmin+1;
719
 
  update_rect.height=iymax-iymin+1;
720
 
 
721
 
  switch (remplis){
722
 
  case TAN_PETITEHLP:
723
 
    gc=tabgc[GCPETITEHLP];
724
 
    break;
725
 
  case TAN_PIECENOR:
726
 
    gc=tabgc[GCPIECENOR];
727
 
    gdk_gc_set_ts_origin (gc,pnt[pntnbr].x,pnt[pntnbr].y);
728
 
    break;
729
 
  case TAN_PIECEHI:
730
 
    gc=tabgc[GCPIECEHI];
731
 
    gdk_gc_set_ts_origin (gc,pnt[pntnbr].x,pnt[pntnbr].y);
732
 
    break;
733
 
  default:
734
 
    gc=widget->style->white_gc;
735
 
    break;
736
 
  }
737
 
 
738
 
  gdk_draw_polygon (pixmap,
739
 
                    gc,
740
 
                    TRUE,
741
 
                    pnt,
742
 
                    pntnbr);
743
 
 
744
 
  if ( remplis==TAN_PIECENOR || remplis==TAN_PIECEHI ){
745
 
    pnt[pntnbr]=pnt[0];                 /* ecrase le point du centre */
746
 
    for (i=0; i<pntnbr; i++){
747
 
      rx=pnt[i+1].x-pnt[i].x;
748
 
      ry=pnt[i].y-pnt[i+1].y;
749
 
      gris=(ry+rx)*0.35355339/sqrt(rx*rx+ry*ry);
750
 
      if (piecepos->flipped)
751
 
        gris=-gris;
752
 
      gris=gris+0.5;
753
 
      gdk_draw_line (pixmap,
754
 
                     tabgc[(int)(gris*(GRISNBR))],
755
 
                     pnt[i].x,pnt[i].y,pnt[i+1].x,pnt[i+1].y);
756
 
    }
757
 
  }
758
 
  return(update_rect);
759
 
 
760
 
}
761
 
 
762
 
 
763
 
/********************************/
764
 
void tandrawfigure (GtkWidget *widget,GdkPixmap *pixmap,
765
 
                    tanfigure *figure,int exclue, tanremplis remplis){
766
 
 
767
 
  double zoom;
768
 
  int i;
769
 
  tanpiecepos *piecepos;
770
 
 
771
 
  zoom=widget->allocation.width*figure->zoom;
772
 
  piecepos=figure->piecepos;
773
 
 
774
 
  for (i=0; i<PIECENBR; i++){
775
 
    if (i!=exclue)
776
 
      tandrawpiece(widget,pixmap,piecepos,zoom,remplis);
777
 
    piecepos++;
778
 
  }
779
 
}
780
 
 
781
 
 
782
 
/********************************/
783
 
/* affiche flfigpetite dans le pixmap */
784
 
void tandrawfloat (GdkPixmap *pixmap, gboolean isoutline){
785
 
 
786
 
  tanflfig *flfig=&flfigpetite;
787
 
  double dx,dy;
788
 
  GdkPoint pnts[PIECENBR*(PNTNBRMAX+1)];
789
 
  int flpntnbr;
790
 
  int flpiecenbr;
791
 
  int i,j;
792
 
  tanfpnt *figfpnts;
793
 
  double zoom;
794
 
  tanpolytype polytype;
795
 
 
796
 
 
797
 
  if (isoutline){
798
 
    zoom = widgetgrande->allocation.width*figgrande.zoom;
799
 
    dx=dxout;
800
 
    dy=dyout;
801
 
  }
802
 
  else{
803
 
    zoom = widgetpetite->allocation.width*figpetite.zoom;
804
 
    dx=dxpetite;
805
 
    dy=dypetite;
806
 
  }
807
 
 
808
 
  flpiecenbr = flfig->flpiecenbr;
809
 
  for (i = 0; i<flpiecenbr; i++){
810
 
    figfpnts = flfig->flpieces[i].flpnts;
811
 
    flpntnbr = flfig->flpieces[i].flpntnbr;
812
 
    polytype = flfig->flpieces[i].polytype;
813
 
    for (j = 0; j<flpntnbr; j++){
814
 
      pnts[j].x = (gint16)(zoom*(figfpnts[j].posx-dx)+ARON);
815
 
      pnts[j].y = (gint16)(zoom*(figfpnts[j].posy-dy)+ARON);
816
 
    }
817
 
    if (isoutline){
818
 
      pnts[flpntnbr] = pnts[0];
819
 
      gdk_draw_lines(pixmap, tabgc[GCPIECEHLP], pnts, flpntnbr+1);
820
 
    }
821
 
    else {
822
 
      gdk_draw_polygon(pixmap,
823
 
                       (polytype==TAN_POLYON) ? ( figpetite.reussi ? tabgc[GCPETITECHK] : tabgc[GCPETITEBG] ) : tabgc[GCPETITEFG],
824
 
                       TRUE, pnts, flpntnbr);
825
 
    }
826
 
  }
827
 
}
828
 
 
829
 
 
830
 
/********************************/
831
 
/* affiche le fond de la widgetgrande */
832
 
void tandrawbgndgr (GdkPixmap *pixmap){
833
 
 
834
 
 
835
 
  gdk_draw_rectangle (pixmap,
836
 
                      tabgc[GCPIECEBG],
837
 
                      TRUE,
838
 
                      0, 0,
839
 
                      widgetgrande->allocation.width,
840
 
                      widgetgrande->allocation.height);
841
 
 
842
 
  if ( helpoutset && figtabsize )
843
 
    tandrawfloat(pixmap, TRUE);
844
 
 
845
 
}
846
 
 
847
 
 
848
 
/********************************/
849
 
void taninitselect(int selected, gboolean force){
850
 
 
851
 
  int i;
852
 
  tanpiecepos dum;
853
 
 
854
 
  if ( force ||
855
 
       selected != PIECENBR-1 ||
856
 
       !selectedgrande ){
857
 
 
858
 
    tandrawbgndgr(pixmapgrande2);
859
 
 
860
 
    tandrawfigure(widgetgrande,pixmapgrande2,&figgrande,
861
 
                  selected,TAN_PIECENOR);
862
 
 
863
 
    selbackrect.x=0;
864
 
    selbackrect.y=0;
865
 
    selbackrect.width=widgetgrande->allocation.width;
866
 
    selbackrect.height=widgetgrande->allocation.height;
867
 
 
868
 
    dum=figgrande.piecepos[selected];
869
 
    for (i=selected; i<PIECENBR-1; i++)
870
 
      figgrande.piecepos[i]=figgrande.piecepos[i+1];
871
 
    figgrande.piecepos[PIECENBR-1]=dum;
872
 
  }
873
 
 
874
 
  selposxnc = figgrande.piecepos[PIECENBR-1].posx;
875
 
  selposync = figgrande.piecepos[PIECENBR-1].posy;
876
 
 
877
 
}
878
 
 
879
 
/********************************/
880
 
void tandrawselect(int dx, int dy, int drot){
881
 
  tanpiecepos *selpiece;
882
 
  double zoom;
883
 
  int dumrot;
884
 
  GdkRectangle selbk2;
885
 
 
886
 
  selpiece=&(figgrande.piecepos[PIECENBR-1]);
887
 
  zoom=widgetgrande->allocation.width*figgrande.zoom;
888
 
 
889
 
  selposxnc += dx/zoom;
890
 
  selposync += dy/zoom;
891
 
 
892
 
  selpiece->posx = CLAMP(selposxnc, 0, 1.0/figgrande.zoom);
893
 
  selpiece->posy = CLAMP(selposync, 0, 1.0/figgrande.zoom);
894
 
  dumrot=selpiece->rot;
895
 
  rotnew=selpiece->rot-=drot;
896
 
 
897
 
  gdk_draw_pixmap(pixmapgrande1,
898
 
                  widgetgrande->style->fg_gc[GTK_WIDGET_STATE (widgetgrande)],
899
 
                  pixmapgrande2,
900
 
                  selbackrect.x,selbackrect.y,
901
 
                  selbackrect.x,selbackrect.y,
902
 
                  selbackrect.width,selbackrect.height);
903
 
 
904
 
  selbk2=tandrawpiece(widgetgrande,pixmapgrande1,
905
 
                      selpiece,
906
 
                      zoom,
907
 
                      TAN_PIECEHI);
908
 
 
909
 
  gtk_widget_draw (widgetgrande, &selbackrect);
910
 
  gtk_widget_draw (widgetgrande, &selbk2);
911
 
 
912
 
  selbackrect=selbk2;
913
 
 
914
 
  selpiece->rot=dumrot;
915
 
 
916
 
}
917
 
 
918
 
 
919
 
/********************************/
920
 
void tanredrawgrande (void){
921
 
 
922
 
  GdkRectangle rect={0,0,0,0};
923
 
  GtkWidget *widget=NULL;
924
 
 
925
 
 
926
 
  tanreleaseifrot();
927
 
 
928
 
  if (selectedgrande){
929
 
    taninitselect(PIECENBR-1, TRUE);
930
 
    tandrawselect(0,0,0);
931
 
  }
932
 
  else{
933
 
    widget=widgetgrande;
934
 
    tandrawbgndgr(pixmapgrande1);
935
 
    tandrawfigure(widget, pixmapgrande1, &figgrande, PIECENBR+1, TAN_PIECENOR);
936
 
    rect.width=widget->allocation.width;
937
 
    rect.height=widget->allocation.height;
938
 
    gtk_widget_draw (widget, &rect);
939
 
  }
940
 
 
941
 
}
942
 
 
943
 
 
944
 
/********************************/
945
 
void tanclearreussinr (int fignr){
946
 
 
947
 
  if ( fignr>= 0 && fignr<figtabsize )
948
 
    (figtab+fignr)->reussi = FALSE;
949
 
 
950
 
}
951
 
 
952
 
 
953
 
/********************************/
954
 
void tansetreussiactual (void){
955
 
 
956
 
  figpetite.reussi = TRUE;
957
 
  if ( figactualnr>= 0 && figactualnr<figtabsize )
958
 
    (figtab+figactualnr)->reussi = TRUE;
959
 
 
960
 
}
961
 
 
962
 
 
963
 
/********************************/
964
 
void tanredrawpetite (void){
965
 
 
966
 
  GdkRectangle rect={0,0,0,0};
967
 
  int wid,hei;
968
 
 
969
 
  /* in case we are called before widget configured */
970
 
  if (!widgetpetite)
971
 
    return;
972
 
 
973
 
  wid = widgetpetite->allocation.width;
974
 
  hei = widgetpetite->allocation.height;
975
 
 
976
 
  gdk_draw_rectangle (pixmappetite,
977
 
                      figpetite.reussi ? tabgc[GCPETITECHK] : tabgc[GCPETITEBG],
978
 
                      TRUE,
979
 
                      0, 0, wid, hei);
980
 
 
981
 
  if (!figtabsize)
982
 
    return;
983
 
 
984
 
  tandrawfloat (pixmappetite, FALSE);
985
 
 
986
 
  if (helptanset<PIECENBR)
987
 
    tandrawpiece(widgetpetite,
988
 
                 pixmappetite,
989
 
                 &figpetite.piecepos[helptanset],
990
 
                 widgetpetite->allocation.width*figpetite.zoom,
991
 
                 TAN_PETITEHLP);
992
 
 
993
 
  /* tandrawfigure(widget, pixmappetite, &figpetite, PIECENBR+1, TAN_PETITEFG); */
994
 
 
995
 
  rect.width=wid;
996
 
  rect.height=hei;
997
 
  gtk_widget_draw (widgetpetite, &rect);
998
 
 
999
 
}
1000
 
 
1001
 
 
1002
 
/********************************/
1003
 
void tanunselect (void){
1004
 
 
1005
 
  if (selectedgrande){
1006
 
    selectedgrande=FALSE;
1007
 
    tanredrawgrande();
1008
 
  }
1009
 
}
1010
 
 
1011
 
 
1012
 
/********************************/
1013
 
gdouble tanreadfloat(FILE *fhd, int *lres)
1014
 
{
1015
 
  gdouble pouet;
1016
 
  char buf[100];
1017
 
 
1018
 
  pouet = 1;
1019
 
  if (*lres==1){
1020
 
    *lres = fscanf(fhd, "%99s",buf);
1021
 
    pouet=g_strtod(buf,NULL);
1022
 
  }
1023
 
 
1024
 
  return pouet;
1025
 
 
1026
 
}
1027
 
 
1028
 
 
1029
 
/********************************/
1030
 
#define SPESC if (lres==1) lres = fscanf
1031
 
 
1032
 
gboolean tanloadfigtab (char *name){
1033
 
 
1034
 
 FILE *hand=NULL;
1035
 
 int i,j;
1036
 
 gboolean succes;
1037
 
 int newfigtabsize;
1038
 
 tanfigure *newfigtab=NULL,*figs;
1039
 
 int lres;
1040
 
 
1041
 
 lres=0;
1042
 
 
1043
 
 if ( (hand = g_fopen(name, "r"))!=NULL &&
1044
 
      fscanf(hand, "gTans v1.0 %d \n", &newfigtabsize)==1 &&
1045
 
      (newfigtab = (tanfigure *)g_malloc(sizeof(tanfigure)*newfigtabsize))!=NULL ){
1046
 
 
1047
 
   lres=1;
1048
 
   figs = newfigtab;
1049
 
   for (i = 0; i<newfigtabsize; i++){
1050
 
     *figs = figuredebut;
1051
 
     figs->zoom = tanreadfloat(hand, &lres);
1052
 
     figs->distmax = tanreadfloat(hand, &lres);
1053
 
     SPESC(hand,"%d \n", &figs->drotmax);
1054
 
     /*fscanf(hand,"%le %le %d \n",&figs->zoom,&figs->distmax,&figs->drotmax);*/
1055
 
     for (j=0; j<PIECENBR; j++){
1056
 
       SPESC(hand,"p %d", &figs->piecepos[j].type);
1057
 
       SPESC(hand,"%d", &figs->piecepos[j].flipped);
1058
 
       figs->piecepos[j].posx = tanreadfloat(hand, &lres);
1059
 
       figs->piecepos[j].posy = tanreadfloat(hand, &lres);
1060
 
       SPESC(hand,"%d \n", &figs->piecepos[j].rot);
1061
 
       /*fscanf(hand,"%d %d %le %le %d \n",&figs->piecepos[j].type,&figs->piecepos[j].flipped,
1062
 
         &figs->piecepos[j].posx,&figs->piecepos[j].posy,&figs->piecepos[j].rot);*/
1063
 
     }
1064
 
     figs++;
1065
 
   }
1066
 
 } else
1067
 
      g_warning("Opening file %s fails",name);
1068
 
 
1069
 
 if (hand!=NULL)
1070
 
   fclose(hand);
1071
 
 
1072
 
 succes=FALSE;
1073
 
 if (lres==1){
1074
 
   succes=TRUE;
1075
 
 
1076
 
   if(figtab!=NULL)
1077
 
     g_free(figtab);
1078
 
 
1079
 
   figtab=newfigtab;
1080
 
   figtabsize=newfigtabsize;
1081
 
 
1082
 
   actual_figure = 0;
1083
 
 
1084
 
   tansetnewfigurepart1(actual_figure);
1085
 
   tansetnewfigurepart2();
1086
 
 
1087
 
   //tanspinsetvalmax(figtabsize-1);
1088
 
 }
1089
 
 
1090
 
 if (succes || figfilename==NULL)
1091
 
   tanallocname(&figfilename, name);
1092
 
 
1093
 
 return(succes);
1094
 
 
1095
 
}
1096
 
 
1097
 
 
1098
 
/********************************/
1099
 
/* charge un pixmap, si necessaire desalloue et/ou (re)alloue la couleur */
1100
 
gboolean tansetpixmapmode(GtkWidget *widget, char *aname, int gcnbr){
1101
 
 
1102
 
  GdkPixmap *pixmap;
1103
 
  GdkGC *gc;
1104
 
  char *pname;
1105
 
  gboolean ret;
1106
 
 
1107
 
 
1108
 
  pixmap=tabpxpx[gcnbr];
1109
 
  pname=tabpxnam[gcnbr];
1110
 
  gc=tabgc[gcnbr];
1111
 
 
1112
 
  if (tabcolalloc[gcnbr]){
1113
 
    gdk_colormap_free_colors (gdk_colormap_get_system(), &colortab[gcnbr], 1);
1114
 
    tabcolalloc[gcnbr] = FALSE;
1115
 
  }
1116
 
 
1117
 
  if (pixmap!=NULL)
1118
 
    gdk_pixmap_unref(pixmap);
1119
 
 
1120
 
  ret=FALSE;
1121
 
  if ( (pixmap=gdk_pixmap_create_from_xpm (widget->window, NULL, NULL, aname))!=NULL ){
1122
 
    tanallocname(&pname,aname);
1123
 
    gdk_gc_set_fill (gc, GDK_TILED);
1124
 
    gdk_gc_set_tile (gc, pixmap);
1125
 
    ret=TRUE;
1126
 
  }
1127
 
 
1128
 
  if (pname==NULL)
1129
 
    tanallocname(&pname,"LoadPixmapFailed");
1130
 
 
1131
 
  tabpxpx[gcnbr] = pixmap;
1132
 
  tabpxnam[gcnbr] = pname;
1133
 
  tabpxpixmode[gcnbr] = ret;
1134
 
 
1135
 
  if (!ret)
1136
 
    tansetcolormode(&colortab[gcnbr],gcnbr);
1137
 
 
1138
 
  return (ret);
1139
 
 
1140
 
}
1141
 
 
1142
 
 
1143
 
/********************************/
1144
 
/* passe en mode color, decharge le pixmap (mais pas le nom) */
1145
 
void tansetcolormode(GdkColor *acolor, int gcnbr){
1146
 
 
1147
 
  GdkPixmap *pixmap;
1148
 
  GdkGC *gc;
1149
 
  GdkColor *pcolor;
1150
 
  GdkColormap *syscmap;
1151
 
 
1152
 
  gc = tabgc[gcnbr];
1153
 
  pcolor = &colortab[gcnbr];
1154
 
  syscmap = gdk_colormap_get_system();
1155
 
 
1156
 
  if (tabcolalloc[gcnbr])
1157
 
    gdk_colormap_free_colors (syscmap, pcolor, 1);
1158
 
 
1159
 
  if ( gcnbr>=PXSTART && gcnbr<PXSTART+PXNBR ){
1160
 
    tabpxpixmode[gcnbr] = FALSE;
1161
 
    if ( (pixmap = tabpxpx[gcnbr])!=NULL ){
1162
 
      tabpxpx[gcnbr] = NULL;
1163
 
      gdk_pixmap_unref(pixmap);
1164
 
    }
1165
 
  }
1166
 
 
1167
 
  pcolor->red = acolor->red;
1168
 
  pcolor->green = acolor->green;
1169
 
  pcolor->blue = acolor->blue;
1170
 
  tabcolalloc[gcnbr] = gdk_colormap_alloc_color (syscmap, pcolor, FALSE, TRUE);
1171
 
  gdk_gc_set_fill (gc, GDK_SOLID);
1172
 
  gdk_gc_set_foreground (gc, pcolor);
1173
 
 
1174
 
}
1175
 
 
1176
 
/********************************/
1177
 
/* config par defaut */
1178
 
void tansetdefconfig (void){
1179
 
  int i;
1180
 
 
1181
 
  guint backgroung_color_red   = 0xe8<<8;
1182
 
  guint backgroung_color_green = 0xe7<<8;
1183
 
  guint backgroung_color_blue  = 0xe2<<8;
1184
 
 
1185
 
  for (i = PXSTART; i<PXNBR+PXSTART; i++){
1186
 
    tabpxpixmode[i] = FALSE;
1187
 
    tanallocname(&tabpxnam[i], "NoConfigFile");
1188
 
  }
1189
 
 
1190
 
  colortab[GCPETITEFG].red   = colortab[GCPETITEFG].green = colortab[GCPETITEFG].blue = 0;
1191
 
  colortab[GCPETITEBG].red   = backgroung_color_red;
1192
 
  colortab[GCPETITEBG].green = backgroung_color_green;
1193
 
  colortab[GCPETITEBG].blue  = backgroung_color_blue;
1194
 
 
1195
 
  colortab[GCPIECENOR].red = colortab[GCPIECENOR].green = 32768;
1196
 
  colortab[GCPIECENOR].blue = 50000;
1197
 
 
1198
 
  colortab[GCPIECEHI].red = colortab[GCPIECEHI].green = 40000;
1199
 
  colortab[GCPIECEHI].blue = 65535;
1200
 
 
1201
 
  colortab[GCPIECEBG].red   = backgroung_color_red;
1202
 
  colortab[GCPIECEBG].green = backgroung_color_green;
1203
 
  colortab[GCPIECEBG].blue  = backgroung_color_blue;
1204
 
 
1205
 
  colortab[GCPIECEHLP].blue = colortab[GCPIECEHLP].green = 0;
1206
 
  colortab[GCPIECEHLP].red = 65535;
1207
 
 
1208
 
  colortab[GCPETITECHK].blue = colortab[GCPETITECHK].red = 40000;
1209
 
  colortab[GCPETITECHK].green = 60000;
1210
 
 
1211
 
  colortab[GCPETITEHLP].red = (colortab[GCPETITEFG].red+colortab[GCPETITEBG].red)/2;
1212
 
  colortab[GCPETITEHLP].green = (colortab[GCPETITEFG].green+colortab[GCPETITEBG].green)/2;
1213
 
  colortab[GCPETITEHLP].blue = (colortab[GCPETITEFG].blue+colortab[GCPETITEBG].blue)/2;
1214
 
 
1215
 
  /* Gcompris */
1216
 
  GcomprisProperties    *properties = gc_prop_get();
1217
 
  gchar *deffigfile = g_strconcat(properties->package_data_dir,"/gtans/figures/default.figures", NULL);
1218
 
 
1219
 
  tanallocname(&figfilename, deffigfile);
1220
 
 
1221
 
  g_free(deffigfile);
1222
 
 
1223
 
  accuracy = 1;
1224
 
  rotstepnbr = TOUR/32;
1225
 
 
1226
 
  figgrande.zoom = 0.125;
1227
 
 
1228
 
  return;
1229
 
}
1230
 
 
1231
 
 
1232
 
/********************************/
1233
 
/* supprime 2 points successifs identiques (en principe inutile) */
1234
 
gboolean tanremsame(tanflfig *flfig, tanpoly *polys, int *pntsuiv, tanfpnt *fpnts, double seuil){
1235
 
  int i,k;
1236
 
  gboolean trouve, ret;
1237
 
  int polynbr;
1238
 
  int act;
1239
 
  int suiv;
1240
 
 
1241
 
  polynbr = flfig->flpiecenbr;
1242
 
 
1243
 
  ret = FALSE;
1244
 
  trouve = TRUE;
1245
 
  while (trouve){
1246
 
    trouve = FALSE;
1247
 
    for (i = 0; i<polynbr && !trouve; i++){
1248
 
      act = polys[i].firstpnt;
1249
 
      for (k = 0; k<polys[i].pntnbr && !trouve; k++){
1250
 
        suiv = pntsuiv[act];
1251
 
        if ( tandistcar(&fpnts[act],&fpnts[suiv])<seuil ){
1252
 
          pntsuiv[act] = pntsuiv[suiv];
1253
 
          polys[i].pntnbr--;
1254
 
          polys[i].firstpnt = act;
1255
 
          trouve = ret = TRUE;
1256
 
          printf ("j'en ai trouve un.\n");
1257
 
        }
1258
 
        act = suiv;
1259
 
      }
1260
 
    }
1261
 
  }
1262
 
 
1263
 
  return (ret);
1264
 
}
1265
 
 
1266
 
 
1267
 
/* ajoute des point intermediaire */
1268
 
gboolean tanajoute(tanflfig *flfig,
1269
 
                   tanpoly *polys,
1270
 
                   int *pntsuiv,
1271
 
                   tanfpnt *fpnts,
1272
 
                   double seuil,
1273
 
                   int flptnew){
1274
 
  int i, j, k, l;
1275
 
  gboolean trouve, ret;
1276
 
  tanfpnt segment[2];
1277
 
  double dx, dy;
1278
 
  int polynbr;
1279
 
  int act1, act2;
1280
 
  int suiv1, suiv2;
1281
 
 
1282
 
  polynbr = flfig->flpiecenbr;
1283
 
 
1284
 
  ret = FALSE;
1285
 
  trouve = TRUE;
1286
 
  while ( trouve && flptnew<FLPNTMAX ){
1287
 
    trouve = FALSE;
1288
 
    for (i = 0; i<polynbr && !trouve; i++){
1289
 
      for (j = 0; j<polynbr && !trouve; j++){
1290
 
        if (i!=j){
1291
 
          act1 = polys[i].firstpnt;
1292
 
          segment[0] = fpnts[act1];
1293
 
          for (k = 0; k<polys[i].pntnbr && !trouve; k++){
1294
 
            suiv1 = pntsuiv[act1];
1295
 
            segment[1] = fpnts[suiv1];
1296
 
            act2 = polys[j].firstpnt;
1297
 
            for (l = 0; l<polys[j].pntnbr && !trouve; l++){
1298
 
              suiv2 = pntsuiv[act2];
1299
 
              if ( tandistcar(&segment[0], &fpnts[act2])>seuil &&
1300
 
                   tandistcar(&segment[1], &fpnts[act2])>seuil &&
1301
 
                   tandistcarsegpnt(segment, &fpnts[act2], &dx, &dy)<seuil/4 ){
1302
 
                fpnts[flptnew].posx = fpnts[act2].posx-dx;
1303
 
                fpnts[flptnew].posy = fpnts[act2].posy-dy;
1304
 
                pntsuiv[flptnew] = pntsuiv[act1];
1305
 
                pntsuiv[act1] = flptnew;
1306
 
                flptnew++;
1307
 
                polys[i].pntnbr++;
1308
 
                polys[i].firstpnt = act1;
1309
 
                trouve = ret = TRUE;
1310
 
              }
1311
 
              act2 = suiv2;
1312
 
            }
1313
 
            act1 = suiv1;
1314
 
            segment[0] = segment[1];
1315
 
          }
1316
 
        }
1317
 
      }
1318
 
    }
1319
 
  }
1320
 
 
1321
 
  flfig->flpiecenbr = polynbr;
1322
 
 
1323
 
  return (ret);
1324
 
}
1325
 
 
1326
 
 
1327
 
/* "tasse" les fpnt et recree la floatfig */
1328
 
/* copie les point de ref dans cop */
1329
 
/* en sortie les 2 sont identiques mais la floatfig pointe sur cop */
1330
 
int tantasse(tanflfig *flfig,
1331
 
             tanpoly *polys,
1332
 
             int *pntsuiv,
1333
 
             tanfpnt *fpntsref,
1334
 
             tanfpnt *fpntscop){
1335
 
  int i, j;
1336
 
  int act, pntnbr;
1337
 
  tanfpnt *fpnts;
1338
 
 
1339
 
  fpnts=fpntscop;
1340
 
  for (i = 0; i<flfig->flpiecenbr; i++){
1341
 
    pntnbr = polys[i].pntnbr;
1342
 
    flfig->flpieces[i].flpntnbr = pntnbr;
1343
 
    flfig->flpieces[i].flpnts = fpnts;
1344
 
    flfig->flpieces[i].polytype = polys[i].polytype;
1345
 
    act = polys[i].firstpnt;
1346
 
    for (j = 0; j<pntnbr+1; j++){
1347
 
      *fpnts++ = fpntsref[act];
1348
 
      act = pntsuiv[act];
1349
 
    }
1350
 
  }
1351
 
 
1352
 
  act=0;
1353
 
  for (i = 0; i<flfig->flpiecenbr; i++){
1354
 
    pntnbr = polys[i].pntnbr;
1355
 
    polys[i].firstpnt = act;
1356
 
    for (j = 0; j<pntnbr-1; j++)
1357
 
      pntsuiv[act+j] = act+j+1;
1358
 
    pntsuiv[act+j] = act;
1359
 
    act += pntnbr+1;
1360
 
  }
1361
 
 
1362
 
  pntnbr = fpnts-fpntscop;
1363
 
  for (i = 0; i<pntnbr; i++)
1364
 
    *fpntsref++ = *fpntscop++;
1365
 
 
1366
 
  return (pntnbr);
1367
 
}
1368
 
 
1369
 
 
1370
 
/* supprime les points intermediaires de segments alignes */
1371
 
gboolean tanalign(tanflfig *flfig, tanpoly *polys, int *pntsuiv, tanfpnt *fpnts){
1372
 
  int i,k;
1373
 
  gboolean trouve, ret;
1374
 
  int polynbr;
1375
 
  int act;
1376
 
  int suiva,suivb;
1377
 
  int diract,dirsuiv;
1378
 
  int dumi;
1379
 
 
1380
 
  polynbr = flfig->flpiecenbr;
1381
 
 
1382
 
  ret = FALSE;
1383
 
  trouve = TRUE;
1384
 
  while (trouve){
1385
 
    trouve = FALSE;
1386
 
    for (i = 0; i<polynbr && !trouve; i++){
1387
 
      act = polys[i].firstpnt;
1388
 
      suiva = pntsuiv[act];
1389
 
      dumi = tanangle(fpnts[suiva].posx-fpnts[act].posx, fpnts[suiva].posy-fpnts[act].posy);
1390
 
      diract = (int)((dumi+rotstepnbr/2)/rotstepnbr);
1391
 
      for (k = 0; k<polys[i].pntnbr && !trouve; k++){
1392
 
        suiva = pntsuiv[act];
1393
 
        suivb = pntsuiv[suiva];
1394
 
        dumi = tanangle(fpnts[suivb].posx-fpnts[suiva].posx, fpnts[suivb].posy-fpnts[suiva].posy);
1395
 
        dirsuiv = (int)((dumi+rotstepnbr/2)/rotstepnbr);
1396
 
        if ( diract==dirsuiv ){
1397
 
          pntsuiv[act] = suivb;
1398
 
          polys[i].pntnbr--;
1399
 
          polys[i].firstpnt = act;
1400
 
          trouve = ret = TRUE;
1401
 
        }
1402
 
        act = suiva;
1403
 
        diract = dirsuiv;
1404
 
      }
1405
 
    }
1406
 
  }
1407
 
 
1408
 
  return (ret);
1409
 
}
1410
 
 
1411
 
 
1412
 
/* supprime les segments consecutifs superposes */
1413
 
gboolean tanconseq(tanflfig *flfig, tanpoly *polys, int *pntsuiv, tanfpnt *fpnts, double seuil){
1414
 
  int i,k;
1415
 
  gboolean trouve, ret;
1416
 
  int polynbr;
1417
 
  int act;
1418
 
  int suiva,suivb;
1419
 
 
1420
 
  polynbr = flfig->flpiecenbr;
1421
 
 
1422
 
  ret = FALSE;
1423
 
  trouve = TRUE;
1424
 
  while (trouve){
1425
 
    trouve = FALSE;
1426
 
    for (i = 0; i<polynbr && !trouve; i++){
1427
 
      act = polys[i].firstpnt;
1428
 
      for (k = 0; k<polys[i].pntnbr && !trouve; k++){
1429
 
        suiva = pntsuiv[act];
1430
 
        suivb = pntsuiv[suiva];
1431
 
        if ( tandistcar(&fpnts[act],&fpnts[suivb])<seuil ){
1432
 
          pntsuiv[act] = pntsuiv[suivb];
1433
 
          polys[i].pntnbr -= 2;
1434
 
          polys[i].firstpnt = act;
1435
 
          trouve = ret = TRUE;
1436
 
        }
1437
 
        act = suiva;
1438
 
      }
1439
 
    }
1440
 
  }
1441
 
 
1442
 
  return (ret);
1443
 
}
1444
 
 
1445
 
 
1446
 
/* concatene les poly ayant 1 segment commun */
1447
 
gboolean tanconcat(tanflfig *flfig, tanpoly *polys, int *pntsuiv, tanfpnt *fpnts, double seuil){
1448
 
  int i,j,k,l,m;
1449
 
  gboolean trouve, ret;
1450
 
  int polynbr;
1451
 
  int act1,act2;
1452
 
  int suiv1,suiv2;
1453
 
 
1454
 
  polynbr = flfig->flpiecenbr;
1455
 
 
1456
 
  ret = FALSE;
1457
 
  trouve = TRUE;
1458
 
  while (trouve){
1459
 
    trouve = FALSE;
1460
 
    for (i = 0; i<polynbr-1 && !trouve; i++){
1461
 
      for (j = i+1; j<polynbr && !trouve; j++){
1462
 
        act1 = polys[i].firstpnt;
1463
 
        for (k = 0; k<polys[i].pntnbr && !trouve; k++){
1464
 
          suiv1 = pntsuiv[act1];
1465
 
          act2 = polys[j].firstpnt;
1466
 
          for (l = 0; l<polys[j].pntnbr && !trouve; l++){
1467
 
            suiv2 = pntsuiv[act2];
1468
 
            if ( tandistcar(&fpnts[act1],&fpnts[suiv2])<seuil &&
1469
 
                 tandistcar(&fpnts[suiv1],&fpnts[act2])<seuil ){
1470
 
              pntsuiv[act1] = pntsuiv[suiv2];
1471
 
              pntsuiv[act2] = pntsuiv[suiv1];
1472
 
              polys[i].pntnbr += polys[j].pntnbr-2;
1473
 
              polys[i].firstpnt = act1;
1474
 
              for (m = j; m<polynbr-1; m++)
1475
 
                polys[m] = polys[m+1];
1476
 
              polynbr--;
1477
 
              trouve = ret = TRUE;
1478
 
            }
1479
 
            act2 = suiv2;
1480
 
          }
1481
 
          act1 = suiv1;
1482
 
        }
1483
 
      }
1484
 
    }
1485
 
  }
1486
 
 
1487
 
  flfig->flpiecenbr = polynbr;
1488
 
 
1489
 
  return (ret);
1490
 
}
1491
 
 
1492
 
 
1493
 
/* detecte les poly "inclus" */
1494
 
/* probleme potentiel : pourrait ne pas detecter une inclusion
1495
 
car on n'ajoute pas de points pour les 'auto-corespondance' */
1496
 
gboolean taninclus(tanflfig *flfig, tanpoly *polys, int *pntsuiv, tanfpnt *fpnts, double seuil){
1497
 
  int i,k,l,m,n;
1498
 
  gboolean trouve, ret;
1499
 
  int polynbr;
1500
 
  int act1,act2;
1501
 
  int suiv1,suiv2;
1502
 
  int pntnbr;
1503
 
  tanpoly dumpoly;
1504
 
  double dumposxmin;
1505
 
  int dumpntposxmin = 0;
1506
 
 
1507
 
  polynbr = flfig->flpiecenbr;
1508
 
 
1509
 
  trouve = ret = FALSE;
1510
 
  for (i = 0; i<polynbr && !trouve; i++){
1511
 
    pntnbr = polys[i].pntnbr;
1512
 
 
1513
 
    /*pour etre sur de partir de l'exterieur*/
1514
 
    act1 = polys[i].firstpnt;
1515
 
    dumposxmin = 99999999.0;
1516
 
    for (m=0; m<pntnbr; m++){
1517
 
      if ( fpnts[act1].posx<dumposxmin ){
1518
 
        dumposxmin = fpnts[act1].posx;
1519
 
        dumpntposxmin = act1;
1520
 
      }
1521
 
      act1 = pntsuiv[act1];
1522
 
    }
1523
 
    act1 = dumpntposxmin;
1524
 
 
1525
 
    for (k = 0; k<pntnbr-2 && !trouve; k++){
1526
 
      suiv1 = pntsuiv[act1];
1527
 
      act2 = pntsuiv[suiv1];
1528
 
      for (l = k+2; l<pntnbr && !trouve; l++){
1529
 
        suiv2 = pntsuiv[act2];
1530
 
        if ( tandistcar(&fpnts[act1],&fpnts[suiv2])<seuil &&
1531
 
             tandistcar(&fpnts[suiv1],&fpnts[act2])<seuil ){
1532
 
 
1533
 
          pntsuiv[act1] = pntsuiv[suiv2];
1534
 
          pntsuiv[act2] = pntsuiv[suiv1];
1535
 
 
1536
 
          dumpoly = polys[i];
1537
 
          for (n = i; n<polynbr-1; n++)
1538
 
            polys[n] = polys[n+1];
1539
 
 
1540
 
          polynbr--;
1541
 
 
1542
 
          for (m = 0; polys[m].polytype==TAN_POLYBACK && m<polynbr; m++);
1543
 
 
1544
 
          /*      printf("inclusion trouvee\n");*/
1545
 
 
1546
 
          for (n = polynbr+1; n>m+1; n--)
1547
 
            polys[n] = polys[n-2];
1548
 
 
1549
 
          dumpoly.pntnbr -= l-k+1;
1550
 
          dumpoly.firstpnt = act1;
1551
 
          if (dumpoly.polytype!=TAN_POLYON)
1552
 
            dumpoly.polytype = TAN_POLYBACK;
1553
 
          else
1554
 
            dumpoly.polytype = TAN_POLYON;
1555
 
 
1556
 
          polys[m] = dumpoly;
1557
 
 
1558
 
          polys[m+1].pntnbr = l-k-1;
1559
 
          polys[m+1].firstpnt = act2;
1560
 
          polys[m+1].polytype = TAN_POLYON;
1561
 
 
1562
 
          polynbr += 2;
1563
 
 
1564
 
          trouve = ret = TRUE;
1565
 
 
1566
 
 
1567
 
        }
1568
 
        act2 = suiv2;
1569
 
      }
1570
 
      act1 = suiv1;
1571
 
    }
1572
 
  }
1573
 
 
1574
 
 
1575
 
  flfig->flpiecenbr = polynbr;
1576
 
 
1577
 
  return (ret);
1578
 
}
1579
 
 
1580
 
 
1581
 
/* change de petite figure */
1582
 
/* pas d'acces gtk */
1583
 
void tansetnewfigurepart1(int nrfig){
1584
 
 
1585
 
  tanfigure *figure;
1586
 
  int i,j;
1587
 
  double xmin=10000,xmax=-10000,ymin=10000,ymax=-10000;
1588
 
  tanpiecepos *piecepos;
1589
 
  tanflfig *flfig=&flfigpetite;
1590
 
  int flpiecenbr,flpntnbr;
1591
 
  tanfpnt *fpnts;
1592
 
  tanfpnt dumfpnts[FLPNTMAX];
1593
 
  tanpoly polys[PIECENBR];
1594
 
  int polypntact,polypntnbr;
1595
 
  int pntsuivants[FLPNTMAX];
1596
 
  double seuil=0.00000000001;
1597
 
  int pntnew;
1598
 
 
1599
 
  if ( nrfig>=0 && figtabsize ){
1600
 
    nrfig %= figtabsize;
1601
 
    actual_figure = nrfig;
1602
 
    figure = figtab+nrfig;
1603
 
  } else {
1604
 
    if (nrfig==-1)
1605
 
      figure = &figuredebut;
1606
 
    else
1607
 
      figure = &figpetite;
1608
 
    nrfig = -1;
1609
 
  }
1610
 
 
1611
 
  figactualnr = nrfig;
1612
 
 
1613
 
  helptanset=PIECENBR;
1614
 
  figpetite=*figure;
1615
 
  tancolle(&figpetite,0.02);
1616
 
  tanmaketinytabnotr(&figpetite,tinytabpe);
1617
 
  tantranstinytab(tinytabpe);
1618
 
 
1619
 
  /* la floatfig et preparation de la concatenation */
1620
 
  flfig->flpiecenbr = PIECENBR;
1621
 
  flfig->figure = figure;
1622
 
  fpnts = dumfpnts;
1623
 
  polypntact = 0;
1624
 
  for (i = 0; i<PIECENBR; i++){
1625
 
    polypntnbr = piecesdef[figure->piecepos[i].type].pntnbr;
1626
 
    polys[i].pntnbr = polypntnbr;
1627
 
    polys[i].firstpnt = polypntact;
1628
 
    polys[i].polytype = TAN_POLYNORMAL;
1629
 
 
1630
 
    for (j = 0; j<polypntnbr-1; j++)
1631
 
      pntsuivants[polypntact+j] = polypntact+j+1;
1632
 
    pntsuivants[polypntact+j] = polypntact;
1633
 
    polypntact += polypntnbr+1;
1634
 
 
1635
 
    tanplacepiecefloat(&figure->piecepos[i], fpnts,1);
1636
 
    fpnts += polypntnbr+1;
1637
 
  }
1638
 
 
1639
 
  tanconcat(flfig, polys, pntsuivants, dumfpnts, seuil);
1640
 
  tanconseq(flfig, polys, pntsuivants, dumfpnts, seuil);
1641
 
 
1642
 
  pntnew = tantasse(flfig, polys, pntsuivants, dumfpnts, fpntspetite);
1643
 
  tanajoute(flfig, polys, pntsuivants, dumfpnts, seuil, pntnew);
1644
 
  tanconcat(flfig, polys, pntsuivants, dumfpnts, seuil);
1645
 
  tanconseq(flfig, polys, pntsuivants, dumfpnts, seuil);
1646
 
  if (taninclus(flfig, polys, pntsuivants, dumfpnts, seuil))
1647
 
    taninclus(flfig, polys, pntsuivants, dumfpnts, seuil);
1648
 
  tanalign(flfig, polys, pntsuivants, dumfpnts);
1649
 
  tanremsame(flfig, polys, pntsuivants, dumfpnts, seuil);
1650
 
 
1651
 
  pntnew = tantasse(flfig, polys, pntsuivants, dumfpnts, fpntspetite);
1652
 
  tanajoute(flfig, polys, pntsuivants, dumfpnts, seuil, pntnew);
1653
 
  tanconcat(flfig, polys, pntsuivants, dumfpnts, seuil);
1654
 
  tanconseq(flfig, polys, pntsuivants, dumfpnts, seuil);
1655
 
  if (taninclus(flfig, polys, pntsuivants, dumfpnts, seuil))
1656
 
    taninclus(flfig, polys, pntsuivants, dumfpnts, seuil);
1657
 
  tanalign(flfig, polys, pntsuivants, dumfpnts);
1658
 
  tanremsame(flfig, polys, pntsuivants, dumfpnts, seuil);
1659
 
 
1660
 
  tantasse(flfig, polys, pntsuivants, dumfpnts, fpntspetite);
1661
 
 
1662
 
  /* calcul du centrage */
1663
 
  flpiecenbr = flfig->flpiecenbr;
1664
 
  for (i = 0; i<flpiecenbr; i++){
1665
 
    fpnts = flfig->flpieces[i].flpnts;
1666
 
    flpntnbr = flfig->flpieces[i].flpntnbr;
1667
 
    for (j = 0; j<flpntnbr; j++){
1668
 
      if (fpnts[j].posx>xmax)
1669
 
        xmax=fpnts[j].posx;
1670
 
      if (fpnts[j].posy>ymax)
1671
 
        ymax=fpnts[j].posy;
1672
 
      if (fpnts[j].posx<xmin)
1673
 
        xmin=fpnts[j].posx;
1674
 
      if (fpnts[j].posy<ymin)
1675
 
        ymin=fpnts[j].posy;
1676
 
    }
1677
 
  }
1678
 
 
1679
 
  figpetite.zoom = 1/(( (xmax-xmin)>(ymax-ymin) ? (xmax-xmin) : (ymax-ymin) )+0.25);
1680
 
  dxpetite = 0.5*(xmax+xmin)-(0.5/figpetite.zoom);
1681
 
  dypetite = 0.5*(ymax+ymin)-(0.5/figpetite.zoom);
1682
 
 
1683
 
  dxout = 0.5*(xmax+xmin)-(0.5/figgrande.zoom);    /* cf tanrecentreout pour correction */
1684
 
  dyout = 0.5*(ymax+ymin)-(0.5/figgrande.zoom);
1685
 
 
1686
 
  /* centrage des pieces petite */
1687
 
  piecepos=figpetite.piecepos;
1688
 
  for (i=0; i<PIECENBR; i++){
1689
 
    piecepos->posx-=dxpetite;
1690
 
    piecepos->posy-=dypetite;
1691
 
    piecepos++;
1692
 
  }
1693
 
}
1694
 
 
1695
 
 
1696
 
/********************************/
1697
 
/* corrige dxout et dyout pour les changement de zoom de figgrande */
1698
 
void tanrecentreout(double oldzoom, double newzoom){
1699
 
 
1700
 
  tanpiecepos *piecepos;
1701
 
  int i;
1702
 
  double correction;
1703
 
 
1704
 
  correction = 0.5*(1/oldzoom-1/newzoom);
1705
 
 
1706
 
  dxout += correction;
1707
 
  dyout += correction;
1708
 
 
1709
 
  piecepos = figgrande.piecepos;
1710
 
  for (i = 0; i<PIECENBR; i++){
1711
 
    piecepos->posx -= correction;
1712
 
    piecepos->posy -= correction;
1713
 
    piecepos++;
1714
 
  }
1715
 
 
1716
 
  return;
1717
 
}
1718
 
 
1719
 
 
1720
 
/********************************/
1721
 
/* change de petite figure */
1722
 
void tansetnewfigurepart2(void){
1723
 
 
1724
 
  if (selectedgrande){
1725
 
    helpoutset=FALSE;
1726
 
    tanunselect();
1727
 
  }
1728
 
  else if (helpoutset){       /* pour eviter 2 appels successif a tanredrawgrande */
1729
 
    helpoutset=FALSE;
1730
 
    tanredrawgrande();
1731
 
  }
1732
 
 
1733
 
  tanredrawpetite();
1734
 
 
1735
 
  selpossible=TRUE;
1736
 
 
1737
 
}
1738
 
 
1739
 
 
1740
 
/********************************/
1741
 
void spesavefig (void){
1742
 
 
1743
 
 FILE *hand;
1744
 
 int j;
1745
 
 tanfigure *fig=NULL; /*juste pour eviter un warning*/
1746
 
 
1747
 
 if ( (hand=g_fopen("pouet.fig", "w"))!=NULL){
1748
 
 
1749
 
   fprintf(hand, "gTans v1.0 %d \n",figtabsize);
1750
 
 
1751
 
   fig=&figgrande;
1752
 
   fprintf(hand,"%e %e %d \n",1.0,fig->distmax,fig->drotmax);
1753
 
   for (j=0; j<PIECENBR; j++)
1754
 
     fprintf(hand,"p %d %d %e %e %d \n",fig->piecepos[j].type,fig->piecepos[j].flipped,
1755
 
             fig->piecepos[j].posx,fig->piecepos[j].posy,fig->piecepos[j].rot);
1756
 
 }
1757
 
 
1758
 
 if (hand!=NULL){
1759
 
   fclose(hand);
1760
 
   figpetite=*fig;
1761
 
   figpetite.zoom=1;
1762
 
   tansetnewfigurepart1(-2);
1763
 
   tansetnewfigurepart2();
1764
 
 }
1765
 
 
1766
 
}
1767
 
 
1768
 
/********************************/
1769
 
void taninitstart(void){
1770
 
 
1771
 
  int i;
1772
 
  char* accurstr;
1773
 
 
1774
 
  for (i = PXSTART; i<PXNBR+PXSTART; i++){
1775
 
    tabpxnam[i] = NULL;
1776
 
    tabpxpx[i] = NULL;
1777
 
  }
1778
 
 
1779
 
  for (i = 0; i<GCNBR; i++)
1780
 
    tabcolalloc[i] = FALSE;
1781
 
 
1782
 
  editmode = FALSE;
1783
 
  figgrande = figuredebut;
1784
 
  figtabsize = 0;
1785
 
 
1786
 
  tansetnewfigurepart1(-1);
1787
 
 
1788
 
  tansetdefconfig();
1789
 
 
1790
 
  tanclampgrandefig();
1791
 
 
1792
 
 
1793
 
  boardRootItem = GNOME_CANVAS_GROUP(gnome_canvas_item_new (gnome_canvas_root(gcomprisBoard->canvas),
1794
 
                                                            gnome_canvas_group_get_type(),
1795
 
                                                            "x", 0.0,
1796
 
                                                            "y", 0.0,
1797
 
                                                            NULL
1798
 
                                                            ));
1799
 
 
1800
 
  create_mainwindow(boardRootItem);
1801
 
 
1802
 
  switch (accuracy){
1803
 
  case 0:
1804
 
    accurstr = "maccuracy1";
1805
 
    break;
1806
 
  case 2:
1807
 
    accurstr = "maccuracy3";
1808
 
    break;
1809
 
  default :
1810
 
    accurstr = "maccuracy2";
1811
 
  }
1812
 
 
1813
 
  if (rotstepnbr==TOUR/256)
1814
 
    accurstr = "mrotcont";
1815
 
  else
1816
 
    accurstr = "mrotstp";
1817
 
 
1818
 
  tanloadfigtab(figfilename);
1819
 
 
1820
 
}
1821
 
 
1822
 
 
1823
 
/********************************/
1824
 
void tanend(void){
1825
 
  int i;
1826
 
  GdkColormap *syscmap;
1827
 
 
1828
 
  syscmap = gdk_colormap_get_system();
1829
 
 
1830
 
  if (userconf!=NULL)
1831
 
    g_free(userconf);
1832
 
 
1833
 
  if (figfilename!=NULL)
1834
 
    g_free(figfilename);
1835
 
 
1836
 
  if (figtab!=NULL)
1837
 
    g_free(figtab);
1838
 
 
1839
 
  if (pixmappetite!=NULL)
1840
 
    gdk_pixmap_unref(pixmappetite);
1841
 
  if (pixmapgrande1!=NULL)
1842
 
    gdk_pixmap_unref(pixmapgrande1);
1843
 
  if (pixmapgrande2!=NULL)
1844
 
    gdk_pixmap_unref(pixmapgrande2);
1845
 
  if (pixmappiece1!=NULL)
1846
 
    gdk_pixmap_unref(pixmappiece1);
1847
 
  if (pixmappiece2!=NULL)
1848
 
    gdk_pixmap_unref(pixmappiece2);
1849
 
  if (pixmapfond!=NULL)
1850
 
    gdk_pixmap_unref(pixmapfond);
1851
 
 
1852
 
  for (i=PXSTART; i<PXSTART+PXNBR; i++){
1853
 
    if (tabpxpx[i]!=NULL)
1854
 
      gdk_pixmap_unref(tabpxpx[i]);
1855
 
    if (tabpxnam[i]!=NULL)
1856
 
      g_free(tabpxnam[i]);
1857
 
  }
1858
 
 
1859
 
  for (i = 0; i<GCNBR; i++){
1860
 
    if (tabgc[i]!=NULL)
1861
 
      gdk_gc_unref(tabgc[i]);
1862
 
    if (tabcolalloc[i])
1863
 
      gdk_colormap_free_colors (syscmap, &colortab[i], 1);
1864
 
  }
1865
 
 
1866
 
  gdk_gc_unref(invertgc);
1867
 
 
1868
 
  gtk_main_quit ();
1869
 
}
1870
 
 
1871
 
 
1872
 
/********************************/
1873
 
void taninitcbcommun(void){
1874
 
 
1875
 
}
1876
 
 
1877
 
 
1878
 
/********************************/
1879
 
void taninitcbgr(void){
1880
 
  int i;
1881
 
  GdkColor *color;
1882
 
 
1883
 
  initcbgr = TRUE; /* pour ne pas initialiser 2 fois */
1884
 
 
1885
 
  for (i=PXSTART; i<PXSTART+PXNBR; i++){
1886
 
    tabgc[i] = gdk_gc_new(widgetgrande->window);
1887
 
    if (tabpxpixmode[i])
1888
 
      tansetpixmapmode(widgetgrande,tabpxnam[i],i);
1889
 
    else
1890
 
      tansetcolormode(&colortab[i],i);
1891
 
  }
1892
 
 
1893
 
  for (i=0; i<GRISNBR; i++){
1894
 
    color = &colortab[i];
1895
 
    color->red = color->green = color->blue = (gushort)(65535.0/(GRISNBR-1)*i);
1896
 
    tabgc[i] = gdk_gc_new(widgetgrande->window);
1897
 
    tansetcolormode(color,i);
1898
 
  }
1899
 
 
1900
 
  invertgc=gdk_gc_new(widgetgrande->window);
1901
 
  gdk_gc_set_function(invertgc,GDK_INVERT);
1902
 
  tabgc[GCPIECEHLP]=gdk_gc_new(widgetgrande->window);
1903
 
  tansetcolormode(&colortab[GCPIECEHLP],GCPIECEHLP);
1904
 
  /* les line attribute sont dans le callback */
1905
 
 
1906
 
  if (initcbpe)
1907
 
    taninitcbcommun();
1908
 
 
1909
 
}
1910
 
 
1911
 
 
1912
 
/********************************/
1913
 
void taninitcbpe(void){
1914
 
 
1915
 
  initcbpe=TRUE; /* pour ne pas initialiser 2 fois (c'est pas propre, mais bon) */
1916
 
 
1917
 
  tabgc[GCPETITEFG]=gdk_gc_new(widgetpetite->window);
1918
 
  tansetcolormode(&colortab[GCPETITEFG],GCPETITEFG);
1919
 
 
1920
 
  tabgc[GCPETITEBG]=gdk_gc_new(widgetpetite->window);
1921
 
  tansetcolormode(&colortab[GCPETITEBG],GCPETITEBG);
1922
 
 
1923
 
  tabgc[GCPETITEHLP]=gdk_gc_new(widgetpetite->window);
1924
 
  tansetcolormode(&colortab[GCPETITEHLP],GCPETITEHLP);
1925
 
 
1926
 
  tabgc[GCPETITECHK]=gdk_gc_new(widgetpetite->window);
1927
 
  tansetcolormode(&colortab[GCPETITECHK],GCPETITECHK);
1928
 
 
1929
 
  if (initcbgr)
1930
 
    taninitcbcommun();
1931
 
 
1932
 
}
1933
 
 
1934
 
 
1935
 
/********************************/
1936
 
/* determine si le point x,y est dans la piece */
1937
 
gboolean tanpntisinpiece(int x, int y, tanpiecepos *piecepos){
1938
 
 
1939
 
  int i;
1940
 
  gboolean in;
1941
 
  GdkPoint pnt[PNTNBRMAX+2];
1942
 
  int nbrpnt;
1943
 
 
1944
 
  nbrpnt=tanplacepiece(piecepos,pnt,widgetgrande->allocation.width*figgrande.zoom);
1945
 
  pnt[nbrpnt]=pnt[0];
1946
 
 
1947
 
  in=TRUE;
1948
 
  if (piecepos->flipped){
1949
 
    for (i=0; (i<nbrpnt && in); i++)
1950
 
      if ( (x-pnt[i].x)*(pnt[i+1].y-pnt[i].y)-(y-pnt[i].y)*(pnt[i+1].x-pnt[i].x)<0 )
1951
 
        in=FALSE;
1952
 
  }
1953
 
  else{
1954
 
    for (i=0; (i<nbrpnt && in); i++)
1955
 
      if ( (x-pnt[i].x)*(pnt[i+1].y-pnt[i].y)-(y-pnt[i].y)*(pnt[i+1].x-pnt[i].x)>0 )
1956
 
        in=FALSE;
1957
 
  }
1958
 
 
1959
 
 
1960
 
  return (in);
1961
 
 
1962
 
}
1963
 
 
1964
 
 
1965
 
/********************************/
1966
 
/* determine dans quelle piece se trouve le point (-1=aucune) */
1967
 
int tanwichisselect(int x, int y){
1968
 
 
1969
 
  int i;
1970
 
  gboolean trouve;
1971
 
 
1972
 
  trouve=FALSE;
1973
 
  for (i=PIECENBR-1; i>=0 && !trouve; i--)
1974
 
    trouve=tanpntisinpiece(x,y,figgrande.piecepos+i);
1975
 
 
1976
 
  if (trouve)
1977
 
    i++;
1978
 
 
1979
 
  return (i);
1980
 
 
1981
 
}
1982
 
 
1983
 
 
1984
 
 
1985
 
 
1986
 
 
1987
 
 
1988
 
 
1989
 
 
1990
 
 
1991
 
 
1992
 
 
1993
 
 
1994
 
 
1995
 
 
1996
 
 
1997
 
 
1998
 
 
1999
 
 
2000
 
 
2001
 
 
2002
 
 
2003
 
 
2004