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

« back to all changes in this revision

Viewing changes to src/tangram-activity/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, 2008  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 GooCanvasItem *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(goo_canvas_get_root_item(gcomprisBoard->canvas),
 
91
                        "tangram/gtans_bg.svgz");
 
92
 
 
93
      selectedgrande = FALSE;
 
94
      taninitstart();
 
95
    }
 
96
}
 
97
 
 
98
static void end_board (void)
 
99
{
 
100
  goo_canvas_item_remove(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, "tangram")==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,
 
1218
                                  "/tangram/default.figures", NULL);
 
1219
 
 
1220
  tanallocname(&figfilename, deffigfile);
 
1221
 
 
1222
  g_free(deffigfile);
 
1223
 
 
1224
  accuracy = 1;
 
1225
  rotstepnbr = TOUR/32;
 
1226
 
 
1227
  figgrande.zoom = 0.125;
 
1228
 
 
1229
  return;
 
1230
}
 
1231
 
 
1232
 
 
1233
/********************************/
 
1234
/* supprime 2 points successifs identiques (en principe inutile) */
 
1235
gboolean tanremsame(tanflfig *flfig, tanpoly *polys, int *pntsuiv, tanfpnt *fpnts, double seuil){
 
1236
  int i,k;
 
1237
  gboolean trouve, ret;
 
1238
  int polynbr;
 
1239
  int act;
 
1240
  int suiv;
 
1241
 
 
1242
  polynbr = flfig->flpiecenbr;
 
1243
 
 
1244
  ret = FALSE;
 
1245
  trouve = TRUE;
 
1246
  while (trouve){
 
1247
    trouve = FALSE;
 
1248
    for (i = 0; i<polynbr && !trouve; i++){
 
1249
      act = polys[i].firstpnt;
 
1250
      for (k = 0; k<polys[i].pntnbr && !trouve; k++){
 
1251
        suiv = pntsuiv[act];
 
1252
        if ( tandistcar(&fpnts[act],&fpnts[suiv])<seuil ){
 
1253
          pntsuiv[act] = pntsuiv[suiv];
 
1254
          polys[i].pntnbr--;
 
1255
          polys[i].firstpnt = act;
 
1256
          trouve = ret = TRUE;
 
1257
          printf ("j'en ai trouve un.\n");
 
1258
        }
 
1259
        act = suiv;
 
1260
      }
 
1261
    }
 
1262
  }
 
1263
 
 
1264
  return (ret);
 
1265
}
 
1266
 
 
1267
 
 
1268
/* ajoute des point intermediaire */
 
1269
gboolean tanajoute(tanflfig *flfig,
 
1270
                   tanpoly *polys,
 
1271
                   int *pntsuiv,
 
1272
                   tanfpnt *fpnts,
 
1273
                   double seuil,
 
1274
                   int flptnew){
 
1275
  int i, j, k, l;
 
1276
  gboolean trouve, ret;
 
1277
  tanfpnt segment[2];
 
1278
  double dx, dy;
 
1279
  int polynbr;
 
1280
  int act1, act2;
 
1281
  int suiv1, suiv2;
 
1282
 
 
1283
  polynbr = flfig->flpiecenbr;
 
1284
 
 
1285
  ret = FALSE;
 
1286
  trouve = TRUE;
 
1287
  while ( trouve && flptnew<FLPNTMAX ){
 
1288
    trouve = FALSE;
 
1289
    for (i = 0; i<polynbr && !trouve; i++){
 
1290
      for (j = 0; j<polynbr && !trouve; j++){
 
1291
        if (i!=j){
 
1292
          act1 = polys[i].firstpnt;
 
1293
          segment[0] = fpnts[act1];
 
1294
          for (k = 0; k<polys[i].pntnbr && !trouve; k++){
 
1295
            suiv1 = pntsuiv[act1];
 
1296
            segment[1] = fpnts[suiv1];
 
1297
            act2 = polys[j].firstpnt;
 
1298
            for (l = 0; l<polys[j].pntnbr && !trouve; l++){
 
1299
              suiv2 = pntsuiv[act2];
 
1300
              if ( tandistcar(&segment[0], &fpnts[act2])>seuil &&
 
1301
                   tandistcar(&segment[1], &fpnts[act2])>seuil &&
 
1302
                   tandistcarsegpnt(segment, &fpnts[act2], &dx, &dy)<seuil/4 ){
 
1303
                fpnts[flptnew].posx = fpnts[act2].posx-dx;
 
1304
                fpnts[flptnew].posy = fpnts[act2].posy-dy;
 
1305
                pntsuiv[flptnew] = pntsuiv[act1];
 
1306
                pntsuiv[act1] = flptnew;
 
1307
                flptnew++;
 
1308
                polys[i].pntnbr++;
 
1309
                polys[i].firstpnt = act1;
 
1310
                trouve = ret = TRUE;
 
1311
              }
 
1312
              act2 = suiv2;
 
1313
            }
 
1314
            act1 = suiv1;
 
1315
            segment[0] = segment[1];
 
1316
          }
 
1317
        }
 
1318
      }
 
1319
    }
 
1320
  }
 
1321
 
 
1322
  flfig->flpiecenbr = polynbr;
 
1323
 
 
1324
  return (ret);
 
1325
}
 
1326
 
 
1327
 
 
1328
/* "tasse" les fpnt et recree la floatfig */
 
1329
/* copie les point de ref dans cop */
 
1330
/* en sortie les 2 sont identiques mais la floatfig pointe sur cop */
 
1331
int tantasse(tanflfig *flfig,
 
1332
             tanpoly *polys,
 
1333
             int *pntsuiv,
 
1334
             tanfpnt *fpntsref,
 
1335
             tanfpnt *fpntscop){
 
1336
  int i, j;
 
1337
  int act, pntnbr;
 
1338
  tanfpnt *fpnts;
 
1339
 
 
1340
  fpnts=fpntscop;
 
1341
  for (i = 0; i<flfig->flpiecenbr; i++){
 
1342
    pntnbr = polys[i].pntnbr;
 
1343
    flfig->flpieces[i].flpntnbr = pntnbr;
 
1344
    flfig->flpieces[i].flpnts = fpnts;
 
1345
    flfig->flpieces[i].polytype = polys[i].polytype;
 
1346
    act = polys[i].firstpnt;
 
1347
    for (j = 0; j<pntnbr+1; j++){
 
1348
      *fpnts++ = fpntsref[act];
 
1349
      act = pntsuiv[act];
 
1350
    }
 
1351
  }
 
1352
 
 
1353
  act=0;
 
1354
  for (i = 0; i<flfig->flpiecenbr; i++){
 
1355
    pntnbr = polys[i].pntnbr;
 
1356
    polys[i].firstpnt = act;
 
1357
    for (j = 0; j<pntnbr-1; j++)
 
1358
      pntsuiv[act+j] = act+j+1;
 
1359
    pntsuiv[act+j] = act;
 
1360
    act += pntnbr+1;
 
1361
  }
 
1362
 
 
1363
  pntnbr = fpnts-fpntscop;
 
1364
  for (i = 0; i<pntnbr; i++)
 
1365
    *fpntsref++ = *fpntscop++;
 
1366
 
 
1367
  return (pntnbr);
 
1368
}
 
1369
 
 
1370
 
 
1371
/* supprime les points intermediaires de segments alignes */
 
1372
gboolean tanalign(tanflfig *flfig, tanpoly *polys, int *pntsuiv, tanfpnt *fpnts){
 
1373
  int i,k;
 
1374
  gboolean trouve, ret;
 
1375
  int polynbr;
 
1376
  int act;
 
1377
  int suiva,suivb;
 
1378
  int diract,dirsuiv;
 
1379
  int dumi;
 
1380
 
 
1381
  polynbr = flfig->flpiecenbr;
 
1382
 
 
1383
  ret = FALSE;
 
1384
  trouve = TRUE;
 
1385
  while (trouve){
 
1386
    trouve = FALSE;
 
1387
    for (i = 0; i<polynbr && !trouve; i++){
 
1388
      act = polys[i].firstpnt;
 
1389
      suiva = pntsuiv[act];
 
1390
      dumi = tanangle(fpnts[suiva].posx-fpnts[act].posx, fpnts[suiva].posy-fpnts[act].posy);
 
1391
      diract = (int)((dumi+rotstepnbr/2)/rotstepnbr);
 
1392
      for (k = 0; k<polys[i].pntnbr && !trouve; k++){
 
1393
        suiva = pntsuiv[act];
 
1394
        suivb = pntsuiv[suiva];
 
1395
        dumi = tanangle(fpnts[suivb].posx-fpnts[suiva].posx, fpnts[suivb].posy-fpnts[suiva].posy);
 
1396
        dirsuiv = (int)((dumi+rotstepnbr/2)/rotstepnbr);
 
1397
        if ( diract==dirsuiv ){
 
1398
          pntsuiv[act] = suivb;
 
1399
          polys[i].pntnbr--;
 
1400
          polys[i].firstpnt = act;
 
1401
          trouve = ret = TRUE;
 
1402
        }
 
1403
        act = suiva;
 
1404
        diract = dirsuiv;
 
1405
      }
 
1406
    }
 
1407
  }
 
1408
 
 
1409
  return (ret);
 
1410
}
 
1411
 
 
1412
 
 
1413
/* supprime les segments consecutifs superposes */
 
1414
gboolean tanconseq(tanflfig *flfig, tanpoly *polys, int *pntsuiv, tanfpnt *fpnts, double seuil){
 
1415
  int i,k;
 
1416
  gboolean trouve, ret;
 
1417
  int polynbr;
 
1418
  int act;
 
1419
  int suiva,suivb;
 
1420
 
 
1421
  polynbr = flfig->flpiecenbr;
 
1422
 
 
1423
  ret = FALSE;
 
1424
  trouve = TRUE;
 
1425
  while (trouve){
 
1426
    trouve = FALSE;
 
1427
    for (i = 0; i<polynbr && !trouve; i++){
 
1428
      act = polys[i].firstpnt;
 
1429
      for (k = 0; k<polys[i].pntnbr && !trouve; k++){
 
1430
        suiva = pntsuiv[act];
 
1431
        suivb = pntsuiv[suiva];
 
1432
        if ( tandistcar(&fpnts[act],&fpnts[suivb])<seuil ){
 
1433
          pntsuiv[act] = pntsuiv[suivb];
 
1434
          polys[i].pntnbr -= 2;
 
1435
          polys[i].firstpnt = act;
 
1436
          trouve = ret = TRUE;
 
1437
        }
 
1438
        act = suiva;
 
1439
      }
 
1440
    }
 
1441
  }
 
1442
 
 
1443
  return (ret);
 
1444
}
 
1445
 
 
1446
 
 
1447
/* concatene les poly ayant 1 segment commun */
 
1448
gboolean tanconcat(tanflfig *flfig, tanpoly *polys, int *pntsuiv, tanfpnt *fpnts, double seuil){
 
1449
  int i,j,k,l,m;
 
1450
  gboolean trouve, ret;
 
1451
  int polynbr;
 
1452
  int act1,act2;
 
1453
  int suiv1,suiv2;
 
1454
 
 
1455
  polynbr = flfig->flpiecenbr;
 
1456
 
 
1457
  ret = FALSE;
 
1458
  trouve = TRUE;
 
1459
  while (trouve){
 
1460
    trouve = FALSE;
 
1461
    for (i = 0; i<polynbr-1 && !trouve; i++){
 
1462
      for (j = i+1; j<polynbr && !trouve; j++){
 
1463
        act1 = polys[i].firstpnt;
 
1464
        for (k = 0; k<polys[i].pntnbr && !trouve; k++){
 
1465
          suiv1 = pntsuiv[act1];
 
1466
          act2 = polys[j].firstpnt;
 
1467
          for (l = 0; l<polys[j].pntnbr && !trouve; l++){
 
1468
            suiv2 = pntsuiv[act2];
 
1469
            if ( tandistcar(&fpnts[act1],&fpnts[suiv2])<seuil &&
 
1470
                 tandistcar(&fpnts[suiv1],&fpnts[act2])<seuil ){
 
1471
              pntsuiv[act1] = pntsuiv[suiv2];
 
1472
              pntsuiv[act2] = pntsuiv[suiv1];
 
1473
              polys[i].pntnbr += polys[j].pntnbr-2;
 
1474
              polys[i].firstpnt = act1;
 
1475
              for (m = j; m<polynbr-1; m++)
 
1476
                polys[m] = polys[m+1];
 
1477
              polynbr--;
 
1478
              trouve = ret = TRUE;
 
1479
            }
 
1480
            act2 = suiv2;
 
1481
          }
 
1482
          act1 = suiv1;
 
1483
        }
 
1484
      }
 
1485
    }
 
1486
  }
 
1487
 
 
1488
  flfig->flpiecenbr = polynbr;
 
1489
 
 
1490
  return (ret);
 
1491
}
 
1492
 
 
1493
 
 
1494
/* detecte les poly "inclus" */
 
1495
/* probleme potentiel : pourrait ne pas detecter une inclusion
 
1496
car on n'ajoute pas de points pour les 'auto-corespondance' */
 
1497
gboolean taninclus(tanflfig *flfig, tanpoly *polys, int *pntsuiv, tanfpnt *fpnts, double seuil){
 
1498
  int i,k,l,m,n;
 
1499
  gboolean trouve, ret;
 
1500
  int polynbr;
 
1501
  int act1,act2;
 
1502
  int suiv1,suiv2;
 
1503
  int pntnbr;
 
1504
  tanpoly dumpoly;
 
1505
  double dumposxmin;
 
1506
  int dumpntposxmin = 0;
 
1507
 
 
1508
  polynbr = flfig->flpiecenbr;
 
1509
 
 
1510
  trouve = ret = FALSE;
 
1511
  for (i = 0; i<polynbr && !trouve; i++){
 
1512
    pntnbr = polys[i].pntnbr;
 
1513
 
 
1514
    /*pour etre sur de partir de l'exterieur*/
 
1515
    act1 = polys[i].firstpnt;
 
1516
    dumposxmin = 99999999.0;
 
1517
    for (m=0; m<pntnbr; m++){
 
1518
      if ( fpnts[act1].posx<dumposxmin ){
 
1519
        dumposxmin = fpnts[act1].posx;
 
1520
        dumpntposxmin = act1;
 
1521
      }
 
1522
      act1 = pntsuiv[act1];
 
1523
    }
 
1524
    act1 = dumpntposxmin;
 
1525
 
 
1526
    for (k = 0; k<pntnbr-2 && !trouve; k++){
 
1527
      suiv1 = pntsuiv[act1];
 
1528
      act2 = pntsuiv[suiv1];
 
1529
      for (l = k+2; l<pntnbr && !trouve; l++){
 
1530
        suiv2 = pntsuiv[act2];
 
1531
        if ( tandistcar(&fpnts[act1],&fpnts[suiv2])<seuil &&
 
1532
             tandistcar(&fpnts[suiv1],&fpnts[act2])<seuil ){
 
1533
 
 
1534
          pntsuiv[act1] = pntsuiv[suiv2];
 
1535
          pntsuiv[act2] = pntsuiv[suiv1];
 
1536
 
 
1537
          dumpoly = polys[i];
 
1538
          for (n = i; n<polynbr-1; n++)
 
1539
            polys[n] = polys[n+1];
 
1540
 
 
1541
          polynbr--;
 
1542
 
 
1543
          for (m = 0; polys[m].polytype==TAN_POLYBACK && m<polynbr; m++);
 
1544
 
 
1545
          /*      printf("inclusion trouvee\n");*/
 
1546
 
 
1547
          for (n = polynbr+1; n>m+1; n--)
 
1548
            polys[n] = polys[n-2];
 
1549
 
 
1550
          dumpoly.pntnbr -= l-k+1;
 
1551
          dumpoly.firstpnt = act1;
 
1552
          if (dumpoly.polytype!=TAN_POLYON)
 
1553
            dumpoly.polytype = TAN_POLYBACK;
 
1554
          else
 
1555
            dumpoly.polytype = TAN_POLYON;
 
1556
 
 
1557
          polys[m] = dumpoly;
 
1558
 
 
1559
          polys[m+1].pntnbr = l-k-1;
 
1560
          polys[m+1].firstpnt = act2;
 
1561
          polys[m+1].polytype = TAN_POLYON;
 
1562
 
 
1563
          polynbr += 2;
 
1564
 
 
1565
          trouve = ret = TRUE;
 
1566
 
 
1567
 
 
1568
        }
 
1569
        act2 = suiv2;
 
1570
      }
 
1571
      act1 = suiv1;
 
1572
    }
 
1573
  }
 
1574
 
 
1575
 
 
1576
  flfig->flpiecenbr = polynbr;
 
1577
 
 
1578
  return (ret);
 
1579
}
 
1580
 
 
1581
 
 
1582
/* change de petite figure */
 
1583
/* pas d'acces gtk */
 
1584
void tansetnewfigurepart1(int nrfig){
 
1585
 
 
1586
  tanfigure *figure;
 
1587
  int i,j;
 
1588
  double xmin=10000,xmax=-10000,ymin=10000,ymax=-10000;
 
1589
  tanpiecepos *piecepos;
 
1590
  tanflfig *flfig=&flfigpetite;
 
1591
  int flpiecenbr,flpntnbr;
 
1592
  tanfpnt *fpnts;
 
1593
  tanfpnt dumfpnts[FLPNTMAX];
 
1594
  tanpoly polys[PIECENBR];
 
1595
  int polypntact,polypntnbr;
 
1596
  int pntsuivants[FLPNTMAX];
 
1597
  double seuil=0.00000000001;
 
1598
  int pntnew;
 
1599
 
 
1600
  if ( nrfig>=0 && figtabsize ){
 
1601
    nrfig %= figtabsize;
 
1602
    actual_figure = nrfig;
 
1603
    figure = figtab+nrfig;
 
1604
  } else {
 
1605
    if (nrfig==-1)
 
1606
      figure = &figuredebut;
 
1607
    else
 
1608
      figure = &figpetite;
 
1609
    nrfig = -1;
 
1610
  }
 
1611
 
 
1612
  figactualnr = nrfig;
 
1613
 
 
1614
  helptanset=PIECENBR;
 
1615
  figpetite=*figure;
 
1616
  tancolle(&figpetite,0.02);
 
1617
  tanmaketinytabnotr(&figpetite,tinytabpe);
 
1618
  tantranstinytab(tinytabpe);
 
1619
 
 
1620
  /* la floatfig et preparation de la concatenation */
 
1621
  flfig->flpiecenbr = PIECENBR;
 
1622
  flfig->figure = figure;
 
1623
  fpnts = dumfpnts;
 
1624
  polypntact = 0;
 
1625
  for (i = 0; i<PIECENBR; i++){
 
1626
    polypntnbr = piecesdef[figure->piecepos[i].type].pntnbr;
 
1627
    polys[i].pntnbr = polypntnbr;
 
1628
    polys[i].firstpnt = polypntact;
 
1629
    polys[i].polytype = TAN_POLYNORMAL;
 
1630
 
 
1631
    for (j = 0; j<polypntnbr-1; j++)
 
1632
      pntsuivants[polypntact+j] = polypntact+j+1;
 
1633
    pntsuivants[polypntact+j] = polypntact;
 
1634
    polypntact += polypntnbr+1;
 
1635
 
 
1636
    tanplacepiecefloat(&figure->piecepos[i], fpnts,1);
 
1637
    fpnts += polypntnbr+1;
 
1638
  }
 
1639
 
 
1640
  tanconcat(flfig, polys, pntsuivants, dumfpnts, seuil);
 
1641
  tanconseq(flfig, polys, pntsuivants, dumfpnts, seuil);
 
1642
 
 
1643
  pntnew = tantasse(flfig, polys, pntsuivants, dumfpnts, fpntspetite);
 
1644
  tanajoute(flfig, polys, pntsuivants, dumfpnts, seuil, pntnew);
 
1645
  tanconcat(flfig, polys, pntsuivants, dumfpnts, seuil);
 
1646
  tanconseq(flfig, polys, pntsuivants, dumfpnts, seuil);
 
1647
  if (taninclus(flfig, polys, pntsuivants, dumfpnts, seuil))
 
1648
    taninclus(flfig, polys, pntsuivants, dumfpnts, seuil);
 
1649
  tanalign(flfig, polys, pntsuivants, dumfpnts);
 
1650
  tanremsame(flfig, polys, pntsuivants, dumfpnts, seuil);
 
1651
 
 
1652
  pntnew = tantasse(flfig, polys, pntsuivants, dumfpnts, fpntspetite);
 
1653
  tanajoute(flfig, polys, pntsuivants, dumfpnts, seuil, pntnew);
 
1654
  tanconcat(flfig, polys, pntsuivants, dumfpnts, seuil);
 
1655
  tanconseq(flfig, polys, pntsuivants, dumfpnts, seuil);
 
1656
  if (taninclus(flfig, polys, pntsuivants, dumfpnts, seuil))
 
1657
    taninclus(flfig, polys, pntsuivants, dumfpnts, seuil);
 
1658
  tanalign(flfig, polys, pntsuivants, dumfpnts);
 
1659
  tanremsame(flfig, polys, pntsuivants, dumfpnts, seuil);
 
1660
 
 
1661
  tantasse(flfig, polys, pntsuivants, dumfpnts, fpntspetite);
 
1662
 
 
1663
  /* calcul du centrage */
 
1664
  flpiecenbr = flfig->flpiecenbr;
 
1665
  for (i = 0; i<flpiecenbr; i++){
 
1666
    fpnts = flfig->flpieces[i].flpnts;
 
1667
    flpntnbr = flfig->flpieces[i].flpntnbr;
 
1668
    for (j = 0; j<flpntnbr; j++){
 
1669
      if (fpnts[j].posx>xmax)
 
1670
        xmax=fpnts[j].posx;
 
1671
      if (fpnts[j].posy>ymax)
 
1672
        ymax=fpnts[j].posy;
 
1673
      if (fpnts[j].posx<xmin)
 
1674
        xmin=fpnts[j].posx;
 
1675
      if (fpnts[j].posy<ymin)
 
1676
        ymin=fpnts[j].posy;
 
1677
    }
 
1678
  }
 
1679
 
 
1680
  figpetite.zoom = 1/(( (xmax-xmin)>(ymax-ymin) ? (xmax-xmin) : (ymax-ymin) )+0.25);
 
1681
  dxpetite = 0.5*(xmax+xmin)-(0.5/figpetite.zoom);
 
1682
  dypetite = 0.5*(ymax+ymin)-(0.5/figpetite.zoom);
 
1683
 
 
1684
  dxout = 0.5*(xmax+xmin)-(0.5/figgrande.zoom);    /* cf tanrecentreout pour correction */
 
1685
  dyout = 0.5*(ymax+ymin)-(0.5/figgrande.zoom);
 
1686
 
 
1687
  /* centrage des pieces petite */
 
1688
  piecepos=figpetite.piecepos;
 
1689
  for (i=0; i<PIECENBR; i++){
 
1690
    piecepos->posx-=dxpetite;
 
1691
    piecepos->posy-=dypetite;
 
1692
    piecepos++;
 
1693
  }
 
1694
}
 
1695
 
 
1696
 
 
1697
/********************************/
 
1698
/* corrige dxout et dyout pour les changement de zoom de figgrande */
 
1699
void tanrecentreout(double oldzoom, double newzoom){
 
1700
 
 
1701
  tanpiecepos *piecepos;
 
1702
  int i;
 
1703
  double correction;
 
1704
 
 
1705
  correction = 0.5*(1/oldzoom-1/newzoom);
 
1706
 
 
1707
  dxout += correction;
 
1708
  dyout += correction;
 
1709
 
 
1710
  piecepos = figgrande.piecepos;
 
1711
  for (i = 0; i<PIECENBR; i++){
 
1712
    piecepos->posx -= correction;
 
1713
    piecepos->posy -= correction;
 
1714
    piecepos++;
 
1715
  }
 
1716
 
 
1717
  return;
 
1718
}
 
1719
 
 
1720
 
 
1721
/********************************/
 
1722
/* change de petite figure */
 
1723
void tansetnewfigurepart2(void){
 
1724
 
 
1725
  if (selectedgrande){
 
1726
    helpoutset=FALSE;
 
1727
    tanunselect();
 
1728
  }
 
1729
  else if (helpoutset){       /* pour eviter 2 appels successif a tanredrawgrande */
 
1730
    helpoutset=FALSE;
 
1731
    tanredrawgrande();
 
1732
  }
 
1733
 
 
1734
  tanredrawpetite();
 
1735
 
 
1736
  selpossible=TRUE;
 
1737
 
 
1738
}
 
1739
 
 
1740
 
 
1741
/********************************/
 
1742
void spesavefig (void){
 
1743
 
 
1744
 FILE *hand;
 
1745
 int j;
 
1746
 tanfigure *fig=NULL; /*juste pour eviter un warning*/
 
1747
 
 
1748
 if ( (hand=g_fopen("pouet.fig", "w"))!=NULL){
 
1749
 
 
1750
   fprintf(hand, "gTans v1.0 %d \n",figtabsize);
 
1751
 
 
1752
   fig=&figgrande;
 
1753
   fprintf(hand,"%e %e %d \n",1.0,fig->distmax,fig->drotmax);
 
1754
   for (j=0; j<PIECENBR; j++)
 
1755
     fprintf(hand,"p %d %d %e %e %d \n",fig->piecepos[j].type,fig->piecepos[j].flipped,
 
1756
             fig->piecepos[j].posx,fig->piecepos[j].posy,fig->piecepos[j].rot);
 
1757
 }
 
1758
 
 
1759
 if (hand!=NULL){
 
1760
   fclose(hand);
 
1761
   figpetite=*fig;
 
1762
   figpetite.zoom=1;
 
1763
   tansetnewfigurepart1(-2);
 
1764
   tansetnewfigurepart2();
 
1765
 }
 
1766
 
 
1767
}
 
1768
 
 
1769
/********************************/
 
1770
void taninitstart(void){
 
1771
 
 
1772
  int i;
 
1773
  char* accurstr;
 
1774
 
 
1775
  for (i = PXSTART; i<PXNBR+PXSTART; i++){
 
1776
    tabpxnam[i] = NULL;
 
1777
    tabpxpx[i] = NULL;
 
1778
  }
 
1779
 
 
1780
  for (i = 0; i<GCNBR; i++)
 
1781
    tabcolalloc[i] = FALSE;
 
1782
 
 
1783
  editmode = FALSE;
 
1784
  figgrande = figuredebut;
 
1785
  figtabsize = 0;
 
1786
 
 
1787
  tansetnewfigurepart1(-1);
 
1788
 
 
1789
  tansetdefconfig();
 
1790
 
 
1791
  tanclampgrandefig();
 
1792
 
 
1793
 
 
1794
  boardRootItem = goo_canvas_group_new (goo_canvas_get_root_item(gcomprisBoard->canvas),
 
1795
                                        NULL);
 
1796
 
 
1797
 
 
1798
  create_mainwindow(boardRootItem);
 
1799
 
 
1800
  switch (accuracy){
 
1801
  case 0:
 
1802
    accurstr = "maccuracy1";
 
1803
    break;
 
1804
  case 2:
 
1805
    accurstr = "maccuracy3";
 
1806
    break;
 
1807
  default :
 
1808
    accurstr = "maccuracy2";
 
1809
  }
 
1810
 
 
1811
  if (rotstepnbr==TOUR/256)
 
1812
    accurstr = "mrotcont";
 
1813
  else
 
1814
    accurstr = "mrotstp";
 
1815
 
 
1816
  tanloadfigtab(figfilename);
 
1817
 
 
1818
}
 
1819
 
 
1820
 
 
1821
/********************************/
 
1822
void tanend(void){
 
1823
  int i;
 
1824
  GdkColormap *syscmap;
 
1825
 
 
1826
  syscmap = gdk_colormap_get_system();
 
1827
 
 
1828
  if (userconf!=NULL)
 
1829
    g_free(userconf);
 
1830
 
 
1831
  if (figfilename!=NULL)
 
1832
    g_free(figfilename);
 
1833
 
 
1834
  if (figtab!=NULL)
 
1835
    g_free(figtab);
 
1836
 
 
1837
  if (pixmappetite!=NULL)
 
1838
    gdk_pixmap_unref(pixmappetite);
 
1839
  if (pixmapgrande1!=NULL)
 
1840
    gdk_pixmap_unref(pixmapgrande1);
 
1841
  if (pixmapgrande2!=NULL)
 
1842
    gdk_pixmap_unref(pixmapgrande2);
 
1843
  if (pixmappiece1!=NULL)
 
1844
    gdk_pixmap_unref(pixmappiece1);
 
1845
  if (pixmappiece2!=NULL)
 
1846
    gdk_pixmap_unref(pixmappiece2);
 
1847
  if (pixmapfond!=NULL)
 
1848
    gdk_pixmap_unref(pixmapfond);
 
1849
 
 
1850
  for (i=PXSTART; i<PXSTART+PXNBR; i++){
 
1851
    if (tabpxpx[i]!=NULL)
 
1852
      gdk_pixmap_unref(tabpxpx[i]);
 
1853
    if (tabpxnam[i]!=NULL)
 
1854
      g_free(tabpxnam[i]);
 
1855
  }
 
1856
 
 
1857
  for (i = 0; i<GCNBR; i++){
 
1858
    if (tabgc[i]!=NULL)
 
1859
      gdk_gc_unref(tabgc[i]);
 
1860
    if (tabcolalloc[i])
 
1861
      gdk_colormap_free_colors (syscmap, &colortab[i], 1);
 
1862
  }
 
1863
 
 
1864
  gdk_gc_unref(invertgc);
 
1865
 
 
1866
  gtk_main_quit ();
 
1867
}
 
1868
 
 
1869
 
 
1870
/********************************/
 
1871
void taninitcbcommun(void){
 
1872
 
 
1873
}
 
1874
 
 
1875
 
 
1876
/********************************/
 
1877
void taninitcbgr(void){
 
1878
  int i;
 
1879
  GdkColor *color;
 
1880
 
 
1881
  initcbgr = TRUE; /* pour ne pas initialiser 2 fois */
 
1882
 
 
1883
  for (i=PXSTART; i<PXSTART+PXNBR; i++){
 
1884
    tabgc[i] = gdk_gc_new(widgetgrande->window);
 
1885
    if (tabpxpixmode[i])
 
1886
      tansetpixmapmode(widgetgrande,tabpxnam[i],i);
 
1887
    else
 
1888
      tansetcolormode(&colortab[i],i);
 
1889
  }
 
1890
 
 
1891
  for (i=0; i<GRISNBR; i++){
 
1892
    color = &colortab[i];
 
1893
    color->red = color->green = color->blue = (gushort)(65535.0/(GRISNBR-1)*i);
 
1894
    tabgc[i] = gdk_gc_new(widgetgrande->window);
 
1895
    tansetcolormode(color,i);
 
1896
  }
 
1897
 
 
1898
  invertgc=gdk_gc_new(widgetgrande->window);
 
1899
  gdk_gc_set_function(invertgc,GDK_INVERT);
 
1900
  tabgc[GCPIECEHLP]=gdk_gc_new(widgetgrande->window);
 
1901
  tansetcolormode(&colortab[GCPIECEHLP],GCPIECEHLP);
 
1902
  /* les line attribute sont dans le callback */
 
1903
 
 
1904
  if (initcbpe)
 
1905
    taninitcbcommun();
 
1906
 
 
1907
}
 
1908
 
 
1909
 
 
1910
/********************************/
 
1911
void taninitcbpe(void){
 
1912
 
 
1913
  initcbpe=TRUE; /* pour ne pas initialiser 2 fois (c'est pas propre, mais bon) */
 
1914
 
 
1915
  tabgc[GCPETITEFG]=gdk_gc_new(widgetpetite->window);
 
1916
  tansetcolormode(&colortab[GCPETITEFG],GCPETITEFG);
 
1917
 
 
1918
  tabgc[GCPETITEBG]=gdk_gc_new(widgetpetite->window);
 
1919
  tansetcolormode(&colortab[GCPETITEBG],GCPETITEBG);
 
1920
 
 
1921
  tabgc[GCPETITEHLP]=gdk_gc_new(widgetpetite->window);
 
1922
  tansetcolormode(&colortab[GCPETITEHLP],GCPETITEHLP);
 
1923
 
 
1924
  tabgc[GCPETITECHK]=gdk_gc_new(widgetpetite->window);
 
1925
  tansetcolormode(&colortab[GCPETITECHK],GCPETITECHK);
 
1926
 
 
1927
  if (initcbgr)
 
1928
    taninitcbcommun();
 
1929
 
 
1930
}
 
1931
 
 
1932
 
 
1933
/********************************/
 
1934
/* determine si le point x,y est dans la piece */
 
1935
gboolean tanpntisinpiece(int x, int y, tanpiecepos *piecepos){
 
1936
 
 
1937
  int i;
 
1938
  gboolean in;
 
1939
  GdkPoint pnt[PNTNBRMAX+2];
 
1940
  int nbrpnt;
 
1941
 
 
1942
  nbrpnt=tanplacepiece(piecepos,pnt,widgetgrande->allocation.width*figgrande.zoom);
 
1943
  pnt[nbrpnt]=pnt[0];
 
1944
 
 
1945
  in=TRUE;
 
1946
  if (piecepos->flipped){
 
1947
    for (i=0; (i<nbrpnt && in); i++)
 
1948
      if ( (x-pnt[i].x)*(pnt[i+1].y-pnt[i].y)-(y-pnt[i].y)*(pnt[i+1].x-pnt[i].x)<0 )
 
1949
        in=FALSE;
 
1950
  }
 
1951
  else{
 
1952
    for (i=0; (i<nbrpnt && in); i++)
 
1953
      if ( (x-pnt[i].x)*(pnt[i+1].y-pnt[i].y)-(y-pnt[i].y)*(pnt[i+1].x-pnt[i].x)>0 )
 
1954
        in=FALSE;
 
1955
  }
 
1956
 
 
1957
 
 
1958
  return (in);
 
1959
 
 
1960
}
 
1961
 
 
1962
 
 
1963
/********************************/
 
1964
/* determine dans quelle piece se trouve le point (-1=aucune) */
 
1965
int tanwichisselect(int x, int y){
 
1966
 
 
1967
  int i;
 
1968
  gboolean trouve;
 
1969
 
 
1970
  trouve=FALSE;
 
1971
  for (i=PIECENBR-1; i>=0 && !trouve; i--)
 
1972
    trouve=tanpntisinpiece(x,y,figgrande.piecepos+i);
 
1973
 
 
1974
  if (trouve)
 
1975
    i++;
 
1976
 
 
1977
  return (i);
 
1978
 
 
1979
}
 
1980
 
 
1981
 
 
1982
 
 
1983
 
 
1984
 
 
1985
 
 
1986
 
 
1987
 
 
1988
 
 
1989
 
 
1990
 
 
1991
 
 
1992
 
 
1993
 
 
1994
 
 
1995
 
 
1996
 
 
1997
 
 
1998
 
 
1999
 
 
2000
 
 
2001
 
 
2002