Back to index

gcompris  8.2.2
gtans.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1999  Philippe Banwarth
00003  * email: bwt@altern.org
00004  * smail: Philippe Banwarth, 8 sente du milieu des Gaudins, 95150 Taverny, France.
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00021 #include "gcompris/gcompris.h"
00022 
00023 #include <math.h>
00024 #include <stdio.h>
00025 #include <string.h>
00026 
00027 /* Added by Florian Ernst <florian_ernst@gmx.net> for lines 193 and 194 */
00028 //#include <string.h>
00029 /* End of added section */
00030 
00031 /* uniquement pour mkdir() */
00032 #include <sys/stat.h>
00033 #include <sys/types.h>
00034 #include <fcntl.h>
00035 #include <unistd.h> 
00036 
00037 #include "gtans.h"
00038 #include "gtans_interface.h"
00039 #include "gtans_support.h"
00040 
00041 void taninitstart(void);
00042 
00043 /* GCompris */
00044 
00045 static void start_board (GcomprisBoard *agcomprisBoard);
00046 static void pause_board (gboolean pause);
00047 static void end_board (void);
00048 static gboolean is_our_board (GcomprisBoard *gcomprisBoard);
00049 
00050 static gint actual_figure = -2;
00051 
00052 /* Description of this plugin */
00053 
00054 
00055 static BoardPlugin menu_bp =
00056   {
00057     NULL,
00058     NULL,
00059     "GTans",
00060     "Tangram",
00061     "Bruno Coudoin <bruno.coudoin@free.fr>",
00062     NULL,
00063     NULL,
00064     NULL,
00065     NULL,
00066     start_board,
00067     pause_board,
00068     end_board,
00069     is_our_board,
00070     NULL,
00071     NULL,
00072     NULL,
00073     NULL,
00074     NULL,
00075     NULL,
00076     NULL
00077   };
00078 
00079 GET_BPLUGIN_INFO(gtans)
00080 
00081 static GcomprisBoard *gcomprisBoard = NULL;
00082 
00083 static GnomeCanvasGroup *boardRootItem = NULL;
00084 
00085 static gboolean board_paused = FALSE;
00086 
00087 static void start_board (GcomprisBoard *agcomprisBoard)
00088 {
00089 
00090   if(agcomprisBoard!=NULL)
00091     {
00092       gcomprisBoard=agcomprisBoard;
00093 
00094       gcomprisBoard->level = 1;
00095       gcomprisBoard->maxlevel = 1;
00096       gc_bar_set(0);
00097 
00098       gc_set_background(gnome_canvas_root(gcomprisBoard->canvas), "images/gtans_bg.png");
00099 
00100       selectedgrande = FALSE;
00101       taninitstart();
00102     }
00103 }
00104 
00105 static void end_board (void)
00106 {
00107   gtk_object_destroy (GTK_OBJECT(boardRootItem));
00108   boardRootItem = NULL;
00109 
00110   widgetpetite = NULL;
00111   widgetgrande = NULL;
00112 
00113 
00114   pixmapgrande1=NULL;
00115   pixmapgrande2=NULL;
00116   pixmappetite=NULL;
00117   pixmappiece1=NULL;
00118   pixmappiece2=NULL;
00119   pixmapfond=NULL;
00120   colselwin=NULL;
00121   filselwin=NULL;
00122 
00123   selectedgrande = FALSE;
00124 }
00125 
00126 static gboolean
00127 is_our_board (GcomprisBoard *gcomprisBoard)
00128 {
00129   if (gcomprisBoard)
00130     {
00131       if(g_strcasecmp(gcomprisBoard->type, "gtans")==0)
00132        {
00133          /* Set the plugin entry */
00134          gcomprisBoard->plugin=&menu_bp;
00135 
00136          return TRUE;
00137        }
00138     }
00139   return FALSE;
00140 }
00141 
00142 static void pause_board (gboolean pause)
00143 {
00144 
00145   if(gcomprisBoard==NULL)
00146     return;
00147 
00148   board_paused = pause;
00149 
00150   if ((!pause) && figpetite.reussi) {
00151     gtk_widget_show(widgetgrande);
00152     gtk_widget_show(widgetpetite);
00153 
00154     actual_figure++;
00155     tansetnewfigurepart1(actual_figure);
00156     tansetnewfigurepart2();
00157   } else {
00158     if (pause) {
00159       gtk_widget_hide(widgetgrande);
00160       gtk_widget_hide(widgetpetite);
00161     
00162     } else {
00163       gtk_widget_show(widgetgrande);
00164       gtk_widget_show(widgetpetite);
00165     }
00166   }
00167     
00168 }
00169 
00170 void change_figure(gboolean next){
00171   if (next)
00172     tansetnewfigurepart1((actual_figure+1)%figtabsize);
00173   else
00174     tansetnewfigurepart1((actual_figure + figtabsize -1)%figtabsize);
00175   tansetnewfigurepart2();
00176 }
00177 
00178 
00179 
00180 /********************************/
00181 GtkWidget *mainwindow;
00182 GtkWidget *widgetgrande;        /* widget de la grande drawarea */
00183 GtkWidget *widgetpetite;        /* widget de la petite drawarea */
00184 GtkStatusbar *widgetstat;       /* widget de la statusbar */
00185 GtkSpinButton *spinner=NULL;
00186 
00187 gint statconid;                 /* context id de la statusbar */
00188 GdkRectangle selbackrect;       /* rectangle a redessiner pour effacer la piece selected */
00189 
00190 GdkPixmap *pixmapgrande1=NULL,*pixmapgrande2;
00191 GdkPixmap *pixmappetite=NULL;
00192 GdkPixmap *pixmappiece1=NULL,*pixmappiece2=NULL,*pixmapfond=NULL;
00193 
00194 GtkWidget *colselwin=NULL,*filselwin=NULL;
00195 
00196 
00197 /* les polygones doivent etre clockwise */
00198 tanpiecedef piecesdef[]={
00199  {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}}},
00200  {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}}},
00201  {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}}},
00202  {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}}},
00203  {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}}}
00204 };
00205 
00206 tanfigure figuredebut={
00207   0.125,1,TOUR/64,FALSE,
00208   {{0,0,0.8,0.8,0},
00209    {0,0,3.3,0.8,0},
00210    {1,0,1.5,1.5,HT*4},
00211    {2,0,6,0.6,0},
00212    {3,0,6,1.6,HT*2},
00213    {4,0,3.6,1.8,HT*7},
00214    {4,0,4.1,1.3,HT*1}}
00215 };
00216 
00217 tanfigure *figtab=NULL;
00218 int figtabsize;                    /* ==0 : pas de figure */
00219 char *figfilename=NULL;
00220 int figactualnr;                   /* nr de la figure dans le figtab (-1=figuredebut, -2=figpetite) */
00221 
00222 tantinytri tinytabpe[TINYNBR],tinytabgr[TINYNBR];
00223 tanfigure figgrande,figpetite;
00224 int selectedgrande=FALSE;
00225 int xact,yact,xoth,yoth,xold,yold;
00226 int actiongrande=AN_none;
00227 int selpossible=TRUE;
00228 int rotact,rotnew,rotold;
00229 
00230 int rotstepnbr=TOUR/32;            /* nb. de pas de rotation affiches */
00231 int initcbgr=FALSE,initcbpe=FALSE; /* init cb deja appellee ? */
00232 
00233 GdkGC *invertgc;
00234 int invx2,invy2;
00235 
00236 GdkGC *tabgc[GCNBR];
00237 GdkColor colortab[GCNBR];
00238 GdkPixmap *dumtabpxpx[3],**tabpxpx=dumtabpxpx-PXSTART;
00239 char *dumtabpxnam[3],**tabpxnam=dumtabpxnam-PXSTART;
00240 
00241 gboolean helpoutset=FALSE;
00242 gboolean helptanset=PIECENBR;
00243 int accuracy;                          /* precision de reconaissance */
00244 
00245 gboolean editmode;
00246 
00247 #define FLPNTMAX PIECENBR*(PNTNBRMAX+1)*2
00248 static gboolean dumtabpxpixmode[3],*tabpxpixmode=dumtabpxpixmode-PXSTART; /* mode VOULU */
00249 static gboolean tabcolalloc[GCNBR];   /* couleur allouee ? */
00250 static gchar *userconf=NULL;          /* nom complet du fichier de config local */
00251 static gchar *usergtdir=NULL;         /* nom du home directory local */
00252 static tanflfig flfigpetite;
00253 static tanfpnt fpntspetite[FLPNTMAX];
00254 
00255 static double dxout,dyout,dxpetite,dypetite;
00256 
00257 static double selposxnc,selposync;      /* position de la piece actuelle non limitee */
00258 
00259 
00260 /********************************/
00261 /* change la valeur max du spinbutton (si il existe) */
00262 void tanspinsetvalmax (int val){
00263   GtkAdjustment *adj;
00264 
00265   if (spinner!=NULL){
00266     adj = gtk_spin_button_get_adjustment(spinner);
00267     adj->upper = (gfloat)val;
00268     gtk_adjustment_changed(adj);
00269     if (gtk_spin_button_get_value_as_int(spinner)){
00270       gtk_spin_button_set_value(spinner, 0);
00271     }
00272     else{
00273       tansetnewfigurepart1(0);
00274       tansetnewfigurepart2();
00275     }      
00276   } else
00277     {
00278       tansetnewfigurepart1(0);
00279       tansetnewfigurepart2();
00280     }
00281 
00282 }
00283 
00284 
00285 /********************************/
00286 void tanallocname (char **pnt, char *name){
00287   if (*pnt!=name){
00288     if (*pnt!=NULL)
00289       g_free(*pnt);
00290     *pnt=(char *)g_malloc(strlen(name)+1);
00291     strcpy(*pnt,name);
00292   }
00293 }
00294 
00295 
00296 
00297 /********************************/
00298 /* maintien les pieces dans les limites */
00299 void tanclampgrandefig (void){
00300   
00301   tanpiecepos *piecepos;
00302   int i;
00303   double dumzoom;
00304   
00305   dumzoom = 1.0/figgrande.zoom;
00306   piecepos = figgrande.piecepos;
00307   for (i = 0; i<PIECENBR; i++){
00308     piecepos->posx = CLAMP(piecepos->posx, 0.0, dumzoom);
00309     piecepos->posy = CLAMP(piecepos->posy, 0.0, dumzoom);
00310     piecepos++;
00311   }
00312   
00313   return;
00314 }
00315 
00316 
00317 /********************************/
00318 /* renvoi la direction d'un segment */
00319 int tanangle (double dx, double dy){
00320   int ret;
00321 
00322   ret = (int)(atan2(dy,dx)/PASTOUR);
00323   ret = (ret+TOUR)%TOUR;
00324 
00325   return (ret);
00326 
00327 }
00328 
00329 
00330 /********************************/
00331 gboolean tantinytabcompare (tantinytri *tinys1, tantinytri *tinys2, int accuracy){
00332 
00333   gboolean libre[TINYNBR];
00334   int i,j,jmin;
00335   double dist,mindist,mindistmax,xi,yi;
00336   int drot,drotmax,roti;
00337   double flaccur;
00338 
00339   switch (accuracy){
00340   case 0 :
00341     flaccur = 1.0;
00342     drotmax = (int)(TOUR/64)+1;
00343     break;
00344   case 2 :
00345     flaccur = 4.0;
00346     drotmax = (int)(TOUR/32)+1;
00347     break;
00348   default :
00349     flaccur = 2.0;
00350     drotmax = (int)(TOUR/64)+1;
00351   }
00352   
00353   /* drotmax=figpetite.drotmax; */
00354   mindistmax=pow(figpetite.distmax*0.10*flaccur,2);
00355 
00356   for (i=0; i<TINYNBR; i++)
00357     libre[i]=TRUE;
00358 
00359   for (i=0; i<TINYNBR; i++){
00360     jmin=0;
00361     mindist=100000;
00362     xi=tinys1[i].posx;
00363     yi=tinys1[i].posy;
00364     roti=tinys1[i].rot;
00365 
00366     for (j=0; j<TINYNBR; j++){
00367       if (libre[j]){
00368        dist=pow(xi-tinys2[j].posx,2)+pow(yi-tinys2[j].posy,2);
00369        drot=ABS(roti-tinys2[j].rot);
00370        if ( drot>TOUR/2 )
00371          drot = TOUR-drot;
00372        if ( dist<mindist && drot<drotmax ){
00373          mindist=dist;
00374          jmin=j;
00375        }
00376       }
00377     }
00378     libre[jmin]=FALSE;
00379     if ( mindist>mindistmax )
00380       return FALSE;
00381   }
00382 
00383   return TRUE;
00384 
00385 }
00386 
00387 
00388 /********************************/
00389 void tansmall2tiny (tansmalltri *small, tantinytri *tiny1, tantinytri *tiny2){
00390 
00391   double cosrot,sinrot;
00392   int rot;
00393 
00394   rot=small->rot;
00395   cosrot=cos(rot*PASTOUR);
00396   sinrot=sin(rot*PASTOUR);
00397 
00398   tiny1->rot=(rot+HT*3)%TOUR;
00399   tiny1->posx=small->posx+0.5*cosrot       +0.16666666*sinrot;
00400   tiny1->posy=small->posy+0.16666666*cosrot-0.5*sinrot;
00401 
00402   tiny2->rot=(rot+HT*5)%TOUR;
00403   tiny2->posx=small->posx+0.16666666*cosrot+0.5*sinrot;
00404   tiny2->posy=small->posy+0.5*cosrot       -0.16666666*sinrot;
00405 
00406 }
00407 
00408 
00409 /********************************/
00410 void tanmaketinytabnotr (tanfigure *figure, tantinytri *tinys){
00411 
00412   int i,j;
00413   tansmalltri dusmall,*small=&dusmall;
00414   tanpiecepos *piecepos;
00415   tanpiecedef *piecedat;
00416   double ly,lx2,cosrot,sinrot;
00417   int rot,rottri;
00418 
00419   piecepos=figure->piecepos;
00420 
00421   for (j=0; j<PIECENBR; j++){
00422 
00423     piecedat=&piecesdef[piecepos->type];
00424     rot=piecepos->rot;
00425     cosrot=cos(rot*PASTOUR);
00426     sinrot=sin(rot*PASTOUR);
00427 
00428     for (i=0; i<piecedat->trinbr; i++){
00429       lx2=piecedat->tri[i].posx-piecedat->handlex;
00430       ly=piecedat->tri[i].posy-piecedat->handley;
00431       rottri=piecedat->tri[i].rot;
00432 
00433       if (piecepos->flipped){
00434        lx2=-lx2;
00435        rottri=TOUR+6*HT-rottri;
00436       }
00437       
00438       small->posx=piecepos->posx+lx2*cosrot+ly*sinrot;
00439       small->posy=piecepos->posy+ly*cosrot-lx2*sinrot;
00440       small->rot=(rottri+rot)%TOUR;
00441       tansmall2tiny(small,tinys,tinys+1);
00442       tinys+=2;
00443     }
00444     piecepos++;
00445   }
00446 
00447 }
00448 
00449 
00450 /********************************/
00451 void tantranstinytab (tantinytri *tinys){
00452 
00453   int i;
00454   double moyx=0,moyy=0;
00455 
00456   for (i=0; i<TINYNBR; i++){
00457     moyx+=tinys->posx;
00458     moyy+=tinys->posy;
00459     tinys++;
00460   }
00461 
00462   moyx/=TINYNBR;
00463   moyy/=TINYNBR;
00464 
00465   for (i=0; i<TINYNBR; i++){
00466     (--tinys)->posx-=moyx;
00467     tinys->posy-=moyy;
00468   }
00469 
00470 }
00471 
00472 
00473 /********************************/
00474 /* termine la rotation (lorsque le mouse button est relache) */
00475 /* est appele par redrawgrande et on_buttonpress au cas ou le signal a ete masque par*/
00476 /* l'appui sur un bouton */
00477 void tanreleaseifrot (void){
00478   if (actiongrande==AN_rot){
00479     gdk_draw_line (widgetgrande->window,
00480                  invertgc,
00481                  xact,yact,invx2,invy2);
00482     
00483     figgrande.piecepos[PIECENBR-1].rot=(rotnew+TOUR*5)%TOUR;
00484   }
00485   
00486   actiongrande = AN_none;
00487   
00488   return;
00489 }
00490 
00491 
00492 /********************************/
00493 /* calcule une serie de GdkPoint correspondant au polygone de la piece */
00494 /* + un point correspondand au centre de la piece */
00495 int tanplacepiece (tanpiecepos *piecepos, GdkPoint *pnts, double zoom){
00496 
00497   int i;
00498   tanpiecedef *piecedat;
00499   double lx,ly,lx2,cosrot,sinrot;
00500   int rot;
00501 
00502   piecedat=&piecesdef[piecepos->type];
00503   rot=piecepos->rot;
00504   cosrot=cos(rot*PASTOUR);
00505   sinrot=sin(rot*PASTOUR);
00506 
00507   for(i=0; i<piecedat->pntnbr; i++){
00508     lx2=piecedat->pnt[i].posx-piecedat->handlex;
00509     ly=piecedat->pnt[i].posy-piecedat->handley;
00510     if (piecepos->flipped)
00511       lx2=-lx2;
00512     lx=(piecepos->posx+lx2*cosrot+ly*sinrot)*zoom;
00513     ly=(piecepos->posy+ly*cosrot-lx2*sinrot)*zoom;
00514     pnts->x=(gint16)(lx+ARON);
00515     pnts->y=(gint16)(ly+ARON);
00516     pnts++;
00517   }
00518 
00519   pnts->x=(gint16)(piecepos->posx*zoom+ARON);
00520   pnts->y=(gint16)(piecepos->posy*zoom+ARON);
00521 
00522   return(piecedat->pntnbr);
00523 
00524 }
00525 
00526 
00527 /********************************/
00528 /* calcule une serie de point en flottant correspondant au polygone de la piece */
00529 /* pas de point central */
00530 /* copie le premier points derriere le dernier */
00531 /* le polygone retourne est clockwise (si la def l'est) */
00532 int tanplacepiecefloat (tanpiecepos *piecepos, tanfpnt *fpnts, double zoom){
00533 
00534   int i;
00535   tanpiecedef *piecedat;
00536   double lx,ly,lx2,cosrot,sinrot;
00537   int rot;
00538   int nbr;
00539 
00540   piecedat=&piecesdef[piecepos->type];
00541   nbr=piecedat->pntnbr;
00542   rot=piecepos->rot;
00543   cosrot=cos(rot*PASTOUR);
00544   sinrot=sin(rot*PASTOUR);
00545 
00546   for(i=0; i<nbr; i++){
00547     lx2=piecedat->pnt[i].posx-piecedat->handlex;
00548     ly=piecedat->pnt[i].posy-piecedat->handley;
00549     if (piecepos->flipped)
00550       lx2=-lx2;
00551     lx=(piecepos->posx+lx2*cosrot+ly*sinrot)*zoom;
00552     ly=(piecepos->posy+ly*cosrot-lx2*sinrot)*zoom;
00553     fpnts->posx=lx;
00554     fpnts++->posy=ly;
00555   }
00556   fpnts -=nbr;
00557 
00558   if (piecepos->flipped){
00559     tanfpnt dumfpnt;
00560     for (i = 0; i<nbr/2 ;i++){
00561       dumfpnt = fpnts[i];
00562       fpnts[i] = fpnts[nbr-i-1];
00563       fpnts[nbr-i-1] = dumfpnt;
00564     }
00565   }
00566 
00567   *(fpnts+nbr)=*fpnts;
00568 
00569   return(nbr);
00570 
00571 }
00572 
00573 
00574 /********************************/
00575 /* calcule le carre de la distance et le deplacement entre un point et un segment */
00576 /* renvoie 100000.0 si la projection sur la droite du point n'est pas sur le segment */
00577 /* resultat : vecteur du segment au point */
00578 double tandistcarsegpnt (tanfpnt *segment, tanfpnt *point, double *pdx, double *pdy){
00579 
00580   double segdx,segdy;
00581   double seglencar,scal,dum;
00582 
00583   segdx=segment[1].posx-segment[0].posx;
00584   segdy=segment[1].posy-segment[0].posy;
00585   *pdx=point->posx-segment->posx;
00586   *pdy=point->posy-segment->posy;
00587 
00588   seglencar=segdx*segdx+segdy*segdy;
00589   if ( (scal=(*pdx*segdx)+(*pdy*segdy))<0 || (dum=scal/seglencar)>1 )
00590     return (1000000.0);
00591 
00592   *pdx-=segdx*dum;
00593   *pdy-=segdy*dum;
00594 
00595   return (*pdx*(*pdx)+*pdy*(*pdy));
00596 
00597 }
00598 
00599 
00600 /********************************/
00601 double tandistcar (tanfpnt *pnt1, tanfpnt *pnt2){
00602 
00603   double dx,dy;
00604 
00605   dx=(pnt1->posx-pnt2->posx);
00606   dy=(pnt1->posy-pnt2->posy);
00607   return (dx*dx+dy*dy);
00608 
00609 }
00610 
00611 
00612 /********************************/
00613 void tancolle (tanfigure *figure, double seuil){
00614 
00615   tanpiecepos *piecepos;
00616   tanfpnt pnts1[PNTNBRMAX+1],pnts2[PNTNBRMAX+1];
00617   int pntnbr1,pntnbr2;
00618   int i,j,k,l;
00619   int nbrcommun;
00620   double dx,dy,dx2,dy2,dxtot,dytot;
00621 
00622   seuil*=seuil;
00623   piecepos=figure->piecepos;
00624 
00625   for (i=0; i<PIECENBR-1; i++){
00626     for (j=i+1; j<PIECENBR; j++) {
00627       pntnbr1=tanplacepiecefloat(&piecepos[i],pnts1,1);
00628       pntnbr2=tanplacepiecefloat(&piecepos[j],pnts2,1);
00629       nbrcommun=0;
00630       dxtot=dytot=0;
00631       for (k=0; k<pntnbr1; k++){
00632        for (l=0; l<pntnbr2; l++){
00633          dx=pnts1[k+1].posx-pnts2[l].posx;
00634          dy=pnts1[k+1].posy-pnts2[l].posy;
00635          dx2=pnts1[k].posx-pnts2[l+1].posx;
00636          dy2=pnts1[k].posy-pnts2[l+1].posy;
00637          if ( (dx*dx+dy*dy)>seuil && (dx2*dx2+dy2*dy2)>seuil ){
00638            if ( tandistcarsegpnt(&pnts1[k],&pnts2[l],&dx,&dy)<seuil/4 ){
00639              nbrcommun++;
00640              dxtot-=dx;
00641              dytot-=dy;
00642            }
00643            if ( tandistcarsegpnt(&pnts2[l],&pnts1[k],&dx,&dy)<seuil/4 ){
00644              nbrcommun++;
00645              dxtot+=dx;
00646              dytot+=dy;
00647            }
00648          }
00649        }
00650       }
00651       if (nbrcommun){
00652        piecepos[j].posx+=dxtot/nbrcommun;
00653        piecepos[j].posy+=dytot/nbrcommun;
00654       }
00655       
00656       pntnbr2=tanplacepiecefloat(&piecepos[j],pnts2,1);
00657       nbrcommun=0;
00658       dxtot=dytot=0;
00659       for (k=0; k<pntnbr1; k++){
00660        for (l=0; l<pntnbr2; l++){
00661          dx=(pnts1[k].posx-pnts2[l].posx);
00662          dy=(pnts1[k].posy-pnts2[l].posy);
00663          if ( (dx*dx+dy*dy)<seuil ){
00664            nbrcommun++;
00665            dxtot+=dx;
00666            dytot+=dy;
00667          }
00668 /*       else{
00669            dx=(pnts1[(k+1)*2]-pnts2[l*2]);
00670            dy=(pnts1[(k+1)*2+1]-pnts2[l*2+1]);
00671            dx2=(pnts1[k*2]-pnts2[(l+1)*2]);
00672            dy2=(pnts1[k*2+1]-pnts2[(l+1)*2+1]);
00673            if ( (dx*dx+dy*dy)>seuil && (dx2*dx2+dy2*dy2)>seuil ){
00674              if ( tandistcarsegpnt(pnts1+k*2,pnts2+l*2,&dx,&dy)<seuil/100 ){
00675               nbrcommun++;
00676               dxtot-=dx;
00677               dytot-=dy;
00678              }
00679              if ( tandistcarsegpnt(pnts2+l*2,pnts1+k*2,&dx,&dy)<seuil/100 ){
00680               nbrcommun++;
00681               dxtot+=dx;
00682               dytot+=dy;
00683              }
00684            }
00685          }         */
00686        }
00687       }
00688       
00689       if (nbrcommun){
00690        piecepos[j].posx+=dxtot/nbrcommun;
00691        piecepos[j].posy+=dytot/nbrcommun;
00692       }
00693     }
00694   }
00695 }
00696 
00697 
00698 /********************************/
00699 GdkRectangle tandrawpiece (GtkWidget *widget,GdkPixmap *pixmap,
00700                         tanpiecepos *piecepos,
00701                         double zoom, tanremplis remplis){
00702 
00703   GdkPoint pnt[PNTNBRMAX+1];
00704   int i,pntnbr,ix,iy,ixmax=-20000,ixmin=20000,iymax=-20000,iymin=20000;
00705   GdkRectangle update_rect;
00706   GdkGC *gc;
00707   double gris,rx,ry;
00708 
00709   pntnbr=tanplacepiece(piecepos,pnt,zoom);
00710 
00711   for(i=0; i<pntnbr; i++){
00712     ix=pnt[i].x;
00713     iy=pnt[i].y;
00714     if (ix<ixmin)
00715       ixmin=ix;
00716     if (ix>ixmax)
00717       ixmax=ix;
00718     if (iy<iymin)
00719       iymin=iy;
00720     if (iy>iymax)
00721       iymax=iy;
00722   }
00723 
00724   update_rect.x=ixmin;
00725   update_rect.y=iymin;
00726   update_rect.width=ixmax-ixmin+1;
00727   update_rect.height=iymax-iymin+1;
00728 
00729   switch (remplis){
00730   case TAN_PETITEHLP:
00731     gc=tabgc[GCPETITEHLP];
00732     break;
00733   case TAN_PIECENOR:
00734     gc=tabgc[GCPIECENOR];
00735     gdk_gc_set_ts_origin (gc,pnt[pntnbr].x,pnt[pntnbr].y);
00736     break;
00737   case TAN_PIECEHI:
00738     gc=tabgc[GCPIECEHI];
00739     gdk_gc_set_ts_origin (gc,pnt[pntnbr].x,pnt[pntnbr].y);
00740     break;
00741   default:
00742     gc=widget->style->white_gc;
00743     break;
00744   }
00745 
00746   gdk_draw_polygon (pixmap,
00747                   gc,
00748                   TRUE,
00749                   pnt,
00750                   pntnbr);
00751 
00752   if ( remplis==TAN_PIECENOR || remplis==TAN_PIECEHI ){
00753     pnt[pntnbr]=pnt[0];                 /* ecrase le point du centre */
00754     for (i=0; i<pntnbr; i++){
00755       rx=pnt[i+1].x-pnt[i].x;
00756       ry=pnt[i].y-pnt[i+1].y;
00757       gris=(ry+rx)*0.35355339/sqrt(rx*rx+ry*ry);
00758       if (piecepos->flipped)
00759        gris=-gris;
00760       gris=gris+0.5;
00761       gdk_draw_line (pixmap,
00762                    tabgc[(int)(gris*(GRISNBR))],
00763                    pnt[i].x,pnt[i].y,pnt[i+1].x,pnt[i+1].y);
00764     }
00765   }
00766   return(update_rect);
00767 
00768 }
00769 
00770 
00771 /********************************/
00772 void tandrawfigure (GtkWidget *widget,GdkPixmap *pixmap,
00773                   tanfigure *figure,int exclue, tanremplis remplis){
00774 
00775   double zoom;
00776   int i;
00777   tanpiecepos *piecepos;
00778 
00779   zoom=widget->allocation.width*figure->zoom;
00780   piecepos=figure->piecepos;
00781 
00782   for (i=0; i<PIECENBR; i++){
00783     if (i!=exclue)
00784       tandrawpiece(widget,pixmap,piecepos,zoom,remplis);
00785     piecepos++;
00786   }
00787 }
00788 
00789 
00790 /********************************/
00791 /* affiche flfigpetite dans le pixmap */
00792 void tandrawfloat (GdkPixmap *pixmap, gboolean isoutline){
00793 
00794   tanflfig *flfig=&flfigpetite;
00795   double dx,dy;
00796   GdkPoint pnts[PIECENBR*(PNTNBRMAX+1)];
00797   int flpntnbr;
00798   int flpiecenbr;
00799   int i,j;
00800   tanfpnt *figfpnts;
00801   double zoom;
00802   tanpolytype polytype;
00803   
00804   
00805   if (isoutline){
00806     zoom = widgetgrande->allocation.width*figgrande.zoom;
00807     dx=dxout;
00808     dy=dyout;
00809   }
00810   else{
00811     zoom = widgetpetite->allocation.width*figpetite.zoom;
00812     dx=dxpetite;
00813     dy=dypetite;
00814   }  
00815   
00816   flpiecenbr = flfig->flpiecenbr;
00817   for (i = 0; i<flpiecenbr; i++){
00818     figfpnts = flfig->flpieces[i].flpnts;
00819     flpntnbr = flfig->flpieces[i].flpntnbr;
00820     polytype = flfig->flpieces[i].polytype;
00821     for (j = 0; j<flpntnbr; j++){
00822       pnts[j].x = (gint16)(zoom*(figfpnts[j].posx-dx)+ARON);
00823       pnts[j].y = (gint16)(zoom*(figfpnts[j].posy-dy)+ARON);
00824     }
00825     if (isoutline){
00826       pnts[flpntnbr] = pnts[0];
00827       gdk_draw_lines(pixmap, tabgc[GCPIECEHLP], pnts, flpntnbr+1);
00828     }
00829     else {
00830       gdk_draw_polygon(pixmap,
00831                      (polytype==TAN_POLYON) ? ( figpetite.reussi ? tabgc[GCPETITECHK] : tabgc[GCPETITEBG] ) : tabgc[GCPETITEFG],
00832                      TRUE, pnts, flpntnbr);
00833     }
00834   }
00835 }
00836 
00837 
00838 /********************************/
00839 /* affiche le fond de la widgetgrande */
00840 void tandrawbgndgr (GdkPixmap *pixmap){
00841   
00842 
00843   gdk_draw_rectangle (pixmap,
00844                     tabgc[GCPIECEBG],
00845                     TRUE,
00846                     0, 0,
00847                     widgetgrande->allocation.width,
00848                     widgetgrande->allocation.height);
00849 
00850   if ( helpoutset && figtabsize )
00851     tandrawfloat(pixmap, TRUE);
00852 
00853 }
00854 
00855 
00856 /********************************/
00857 void taninitselect(int selected, gboolean force){
00858 
00859   int i;
00860   tanpiecepos dum;
00861 
00862   if ( force ||
00863        selected != PIECENBR-1 ||
00864        !selectedgrande ){
00865 
00866     tandrawbgndgr(pixmapgrande2);
00867 
00868     tandrawfigure(widgetgrande,pixmapgrande2,&figgrande,
00869                 selected,TAN_PIECENOR);
00870 
00871     selbackrect.x=0;
00872     selbackrect.y=0;
00873     selbackrect.width=widgetgrande->allocation.width;
00874     selbackrect.height=widgetgrande->allocation.height;
00875 
00876     dum=figgrande.piecepos[selected];
00877     for (i=selected; i<PIECENBR-1; i++)
00878       figgrande.piecepos[i]=figgrande.piecepos[i+1];
00879     figgrande.piecepos[PIECENBR-1]=dum;
00880   }
00881 
00882   selposxnc = figgrande.piecepos[PIECENBR-1].posx;
00883   selposync = figgrande.piecepos[PIECENBR-1].posy;
00884 
00885 }
00886 
00887 /********************************/
00888 void tandrawselect(int dx, int dy, int drot){
00889   tanpiecepos *selpiece;
00890   double zoom;
00891   int dumrot;
00892   GdkRectangle selbk2;
00893 
00894   selpiece=&(figgrande.piecepos[PIECENBR-1]);
00895   zoom=widgetgrande->allocation.width*figgrande.zoom;
00896   
00897   selposxnc += dx/zoom;
00898   selposync += dy/zoom;
00899 
00900   selpiece->posx = CLAMP(selposxnc, 0, 1.0/figgrande.zoom);
00901   selpiece->posy = CLAMP(selposync, 0, 1.0/figgrande.zoom);
00902   dumrot=selpiece->rot;
00903   rotnew=selpiece->rot-=drot;
00904 
00905   gdk_draw_pixmap(pixmapgrande1,
00906                 widgetgrande->style->fg_gc[GTK_WIDGET_STATE (widgetgrande)],
00907                 pixmapgrande2,
00908                 selbackrect.x,selbackrect.y,
00909                 selbackrect.x,selbackrect.y,
00910                 selbackrect.width,selbackrect.height);
00911 
00912   selbk2=tandrawpiece(widgetgrande,pixmapgrande1,
00913                     selpiece,
00914                     zoom,
00915                     TAN_PIECEHI);
00916 
00917   gtk_widget_draw (widgetgrande, &selbackrect);
00918   gtk_widget_draw (widgetgrande, &selbk2);
00919 
00920   selbackrect=selbk2;
00921 
00922   selpiece->rot=dumrot;
00923 
00924 }
00925 
00926 
00927 /********************************/
00928 void tanredrawgrande (void){
00929 
00930   GdkRectangle rect={0,0,0,0};
00931   GtkWidget *widget=NULL;
00932 
00933 
00934   tanreleaseifrot();
00935 
00936   if (selectedgrande){
00937     taninitselect(PIECENBR-1, TRUE);
00938     tandrawselect(0,0,0);
00939   }
00940   else{
00941     widget=widgetgrande;
00942     tandrawbgndgr(pixmapgrande1);
00943     tandrawfigure(widget, pixmapgrande1, &figgrande, PIECENBR+1, TAN_PIECENOR);
00944     rect.width=widget->allocation.width;
00945     rect.height=widget->allocation.height;
00946     gtk_widget_draw (widget, &rect);
00947   }
00948   
00949 }
00950 
00951 
00952 /********************************/
00953 void tanclearreussinr (int fignr){
00954 
00955   if ( fignr>= 0 && fignr<figtabsize )
00956     (figtab+fignr)->reussi = FALSE;
00957   
00958 }
00959 
00960 
00961 /********************************/
00962 void tansetreussiactual (void){
00963 
00964   figpetite.reussi = TRUE;
00965   if ( figactualnr>= 0 && figactualnr<figtabsize )
00966     (figtab+figactualnr)->reussi = TRUE;
00967   
00968 }
00969 
00970 
00971 /********************************/
00972 void tanredrawpetite (void){
00973 
00974   GdkRectangle rect={0,0,0,0};
00975   int wid,hei;
00976 
00977   /* in case we are called before widget configured */
00978   if (!widgetpetite)
00979     return;
00980 
00981   wid = widgetpetite->allocation.width;
00982   hei = widgetpetite->allocation.height;
00983 
00984   gdk_draw_rectangle (pixmappetite,
00985                     figpetite.reussi ? tabgc[GCPETITECHK] : tabgc[GCPETITEBG],
00986                     TRUE,
00987                     0, 0, wid, hei);
00988 
00989   if (!figtabsize)
00990     return;
00991 
00992   tandrawfloat (pixmappetite, FALSE);
00993 
00994   if (helptanset<PIECENBR)
00995     tandrawpiece(widgetpetite,
00996                pixmappetite,
00997                &figpetite.piecepos[helptanset],
00998                widgetpetite->allocation.width*figpetite.zoom,
00999                TAN_PETITEHLP);
01000 
01001   /* tandrawfigure(widget, pixmappetite, &figpetite, PIECENBR+1, TAN_PETITEFG); */
01002 
01003   rect.width=wid;
01004   rect.height=hei;
01005   gtk_widget_draw (widgetpetite, &rect);
01006 
01007 }
01008 
01009 
01010 /********************************/
01011 void tanunselect (void){
01012   
01013   if (selectedgrande){
01014     selectedgrande=FALSE;
01015     tanredrawgrande();
01016   }
01017 }
01018 
01019 
01020 /********************************/
01021 void tanloadfigstatus (char *name, tanfigure *nfigtab, int nfigsize){
01022 
01023   int i;
01024   FILE *hand=NULL;
01025   gchar *statusfilename;
01026   
01027   statusfilename = g_strconcat(usergtdir, G_DIR_SEPARATOR_S, g_basename(name), ".status", NULL);
01028   
01029   if ( (hand = fopen(statusfilename, "r"))!=NULL ){
01030     for (i=0; i<nfigsize; i++)
01031       if ( fgetc(hand)=='y' )
01032        (nfigtab+i)->reussi = TRUE;
01033     fclose(hand);
01034   }
01035   
01036   g_free(statusfilename);
01037   
01038 }
01039 
01040 
01041 /********************************/
01042 void tansavefigstatus (char *name, tanfigure *nfigtab, int nfigsize){
01043 
01044   int i;
01045   FILE *hand=NULL;
01046   gchar *statusfilename;
01047   
01048   if(figtabsize){
01049     statusfilename = g_strconcat(usergtdir, G_DIR_SEPARATOR_S, g_basename(name), ".status", NULL);
01050     
01051     if ( (hand = fopen(statusfilename, "w"))!=NULL ){
01052       for (i=0; i<nfigsize; i++)
01053        if ( (nfigtab+i)->reussi )
01054          fputc ('y', hand);
01055        else
01056          fputc ('n', hand);
01057       fclose(hand);
01058     }
01059     
01060     g_free(statusfilename);
01061   }
01062 }
01063 
01064 
01065 /********************************/
01066 gdouble tanreadfloat(FILE *fhd, int *lres)
01067 {
01068   gdouble pouet;
01069   char buf[100];
01070 
01071   pouet = 1;
01072   if (*lres==1){
01073     *lres = fscanf(fhd, "%99s",buf);
01074     pouet=g_strtod(buf,NULL);
01075   }
01076 
01077   return pouet;
01078 
01079 }
01080 
01081 
01082 /********************************/
01083 #define SPESC if (lres==1) lres = fscanf
01084 
01085 gboolean tanloadfigtab (char *name){
01086 
01087  FILE *hand=NULL;
01088  int i,j;
01089  gboolean succes;
01090  int newfigtabsize;
01091  tanfigure *newfigtab=NULL,*figs;
01092  int lres;
01093 
01094  lres=0;
01095 
01096  if ( (hand = fopen(name, "r"))!=NULL &&
01097       fscanf(hand, "gTans v1.0 %d \n", &newfigtabsize)==1 &&
01098       (newfigtab = (tanfigure *)g_malloc(sizeof(tanfigure)*newfigtabsize))!=NULL ){
01099 
01100    lres=1;
01101    figs = newfigtab;
01102    for (i = 0; i<newfigtabsize; i++){
01103      *figs = figuredebut;
01104      figs->zoom = tanreadfloat(hand, &lres);
01105      figs->distmax = tanreadfloat(hand, &lres);
01106      SPESC(hand,"%d \n", &figs->drotmax);
01107      /*fscanf(hand,"%le %le %d \n",&figs->zoom,&figs->distmax,&figs->drotmax);*/
01108      for (j=0; j<PIECENBR; j++){
01109        SPESC(hand,"p %d", &figs->piecepos[j].type);
01110        SPESC(hand,"%d", &figs->piecepos[j].flipped);
01111        figs->piecepos[j].posx = tanreadfloat(hand, &lres);
01112        figs->piecepos[j].posy = tanreadfloat(hand, &lres);
01113        SPESC(hand,"%d \n", &figs->piecepos[j].rot);
01114        /*fscanf(hand,"%d %d %le %le %d \n",&figs->piecepos[j].type,&figs->piecepos[j].flipped,
01115         &figs->piecepos[j].posx,&figs->piecepos[j].posy,&figs->piecepos[j].rot);*/
01116      }
01117      figs++;
01118    }
01119  } else
01120       g_warning("Opening file %s fails",name);
01121  
01122  if (hand!=NULL)
01123    fclose(hand);
01124 
01125  succes=FALSE;
01126  if (lres==1){
01127    succes=TRUE;
01128 
01129    tansavefigstatus(figfilename, figtab, figtabsize);
01130    
01131    if(figtab!=NULL)
01132      g_free(figtab);
01133    
01134    tanloadfigstatus(name, newfigtab, newfigtabsize);
01135 
01136    figtab=newfigtab;
01137    figtabsize=newfigtabsize;
01138 
01139    actual_figure = 0;
01140 
01141    tansetnewfigurepart1(actual_figure);
01142    tansetnewfigurepart2();
01143 
01144    //tanspinsetvalmax(figtabsize-1);
01145  }
01146 
01147  if (succes || figfilename==NULL)
01148    tanallocname(&figfilename, name);
01149  
01150  return(succes);
01151 
01152 }
01153 
01154 
01155 /********************************/
01156 /* charge un pixmap, si necessaire desalloue et/ou (re)alloue la couleur */
01157 gboolean tansetpixmapmode(GtkWidget *widget, char *aname, int gcnbr){
01158 
01159   GdkPixmap *pixmap;
01160   GdkGC *gc;
01161   char *pname;
01162   gboolean ret;
01163   
01164 
01165   pixmap=tabpxpx[gcnbr];
01166   pname=tabpxnam[gcnbr];
01167   gc=tabgc[gcnbr];
01168 
01169   if (tabcolalloc[gcnbr]){
01170     gdk_colormap_free_colors (gdk_colormap_get_system(), &colortab[gcnbr], 1);
01171     tabcolalloc[gcnbr] = FALSE;
01172   }
01173   
01174   if (pixmap!=NULL)
01175     gdk_pixmap_unref(pixmap);
01176   
01177   ret=FALSE;
01178   if ( (pixmap=gdk_pixmap_create_from_xpm (widget->window, NULL, NULL, aname))!=NULL ){
01179     tanallocname(&pname,aname);
01180     gdk_gc_set_fill (gc, GDK_TILED);
01181     gdk_gc_set_tile (gc, pixmap);
01182     ret=TRUE;
01183   }
01184   
01185   if (pname==NULL)
01186     tanallocname(&pname,"LoadPixmapFailed");
01187   
01188   tabpxpx[gcnbr] = pixmap;
01189   tabpxnam[gcnbr] = pname;
01190   tabpxpixmode[gcnbr] = ret;
01191 
01192   if (!ret)
01193     tansetcolormode(&colortab[gcnbr],gcnbr);
01194   
01195   return (ret);
01196   
01197 }
01198 
01199 
01200 /********************************/
01201 /* passe en mode color, decharge le pixmap (mais pas le nom) */
01202 void tansetcolormode(GdkColor *acolor, int gcnbr){
01203 
01204   GdkPixmap *pixmap;
01205   GdkGC *gc;
01206   GdkColor *pcolor;
01207   GdkColormap *syscmap;
01208   
01209   gc = tabgc[gcnbr];
01210   pcolor = &colortab[gcnbr];
01211   syscmap = gdk_colormap_get_system();
01212 
01213   if (tabcolalloc[gcnbr])
01214     gdk_colormap_free_colors (syscmap, pcolor, 1);
01215   
01216   if ( gcnbr>=PXSTART && gcnbr<PXSTART+PXNBR ){
01217     tabpxpixmode[gcnbr] = FALSE;
01218     if ( (pixmap = tabpxpx[gcnbr])!=NULL ){
01219       tabpxpx[gcnbr] = NULL;
01220       gdk_pixmap_unref(pixmap);
01221     }  
01222   }
01223   
01224   pcolor->red = acolor->red;
01225   pcolor->green = acolor->green;
01226   pcolor->blue = acolor->blue;
01227   tabcolalloc[gcnbr] = gdk_colormap_alloc_color (syscmap, pcolor, FALSE, TRUE);
01228   gdk_gc_set_fill (gc, GDK_SOLID);
01229   gdk_gc_set_foreground (gc, pcolor);
01230   
01231 }
01232 
01233 /********************************/
01234 /* config par defaut */
01235 void tansetdefconfig (void){
01236   int i;
01237 
01238   guint backgroung_color_red   = 0xe8<<8;
01239   guint backgroung_color_green = 0xe7<<8;
01240   guint backgroung_color_blue  = 0xe2<<8;
01241 
01242   for (i = PXSTART; i<PXNBR+PXSTART; i++){
01243     tabpxpixmode[i] = FALSE;
01244     tanallocname(&tabpxnam[i], "NoConfigFile");
01245   }
01246 
01247   colortab[GCPETITEFG].red   = colortab[GCPETITEFG].green = colortab[GCPETITEFG].blue = 0;
01248   colortab[GCPETITEBG].red   = backgroung_color_red;
01249   colortab[GCPETITEBG].green = backgroung_color_green;
01250   colortab[GCPETITEBG].blue  = backgroung_color_blue;
01251 
01252   colortab[GCPIECENOR].red = colortab[GCPIECENOR].green = 32768;
01253   colortab[GCPIECENOR].blue = 50000;
01254 
01255   colortab[GCPIECEHI].red = colortab[GCPIECEHI].green = 40000;
01256   colortab[GCPIECEHI].blue = 65535;
01257 
01258   colortab[GCPIECEBG].red   = backgroung_color_red;
01259   colortab[GCPIECEBG].green = backgroung_color_green;
01260   colortab[GCPIECEBG].blue  = backgroung_color_blue;
01261 
01262   colortab[GCPIECEHLP].blue = colortab[GCPIECEHLP].green = 0;
01263   colortab[GCPIECEHLP].red = 65535;
01264 
01265   colortab[GCPETITECHK].blue = colortab[GCPETITECHK].red = 40000;
01266   colortab[GCPETITECHK].green = 60000;
01267 
01268   colortab[GCPETITEHLP].red = (colortab[GCPETITEFG].red+colortab[GCPETITEBG].red)/2;
01269   colortab[GCPETITEHLP].green = (colortab[GCPETITEFG].green+colortab[GCPETITEBG].green)/2;
01270   colortab[GCPETITEHLP].blue = (colortab[GCPETITEFG].blue+colortab[GCPETITEBG].blue)/2;
01271   
01272   /* Gcompris */
01273   GcomprisProperties *properties = gc_prop_get();
01274   gchar *deffigfile = g_strconcat(properties->package_data_dir,"/gtans/figures/default.figures", NULL); 
01275 
01276   tanallocname(&figfilename, deffigfile);
01277 
01278   g_free(deffigfile);
01279 
01280   accuracy = 1;
01281   rotstepnbr = TOUR/32;
01282 
01283   figgrande.zoom = 0.125;
01284 
01285   return;
01286 }
01287 
01288 
01289 /********************************/
01290 /* supprime 2 points successifs identiques (en principe inutile) */
01291 gboolean tanremsame(tanflfig *flfig, tanpoly *polys, int *pntsuiv, tanfpnt *fpnts, double seuil){
01292   int i,k;
01293   gboolean trouve, ret;
01294   int polynbr;
01295   int act;
01296   int suiv;
01297   
01298   polynbr = flfig->flpiecenbr;
01299 
01300   ret = FALSE;
01301   trouve = TRUE;
01302   while (trouve){
01303     trouve = FALSE;
01304     for (i = 0; i<polynbr && !trouve; i++){
01305       act = polys[i].firstpnt;
01306       for (k = 0; k<polys[i].pntnbr && !trouve; k++){
01307        suiv = pntsuiv[act];
01308        if ( tandistcar(&fpnts[act],&fpnts[suiv])<seuil ){
01309          pntsuiv[act] = pntsuiv[suiv];
01310          polys[i].pntnbr--;
01311          polys[i].firstpnt = act;
01312          trouve = ret = TRUE;
01313          printf ("j'en ai trouve un.\n");
01314        }
01315        act = suiv;
01316       }
01317     }
01318   }
01319   
01320   return (ret);
01321 }
01322 
01323 
01324 /* ajoute des point intermediaire */
01325 gboolean tanajoute(tanflfig *flfig,
01326                  tanpoly *polys,
01327                  int *pntsuiv,
01328                  tanfpnt *fpnts,
01329                  double seuil,
01330                  int flptnew){
01331   int i, j, k, l;
01332   gboolean trouve, ret;
01333   tanfpnt segment[2];
01334   double dx, dy;
01335   int polynbr;
01336   int act1, act2;
01337   int suiv1, suiv2;
01338   
01339   polynbr = flfig->flpiecenbr;
01340 
01341   ret = FALSE;
01342   trouve = TRUE;
01343   while ( trouve && flptnew<FLPNTMAX ){
01344     trouve = FALSE;
01345     for (i = 0; i<polynbr && !trouve; i++){
01346       for (j = 0; j<polynbr && !trouve; j++){
01347        if (i!=j){
01348          act1 = polys[i].firstpnt;
01349          segment[0] = fpnts[act1];
01350          for (k = 0; k<polys[i].pntnbr && !trouve; k++){
01351            suiv1 = pntsuiv[act1];
01352            segment[1] = fpnts[suiv1];
01353            act2 = polys[j].firstpnt;
01354            for (l = 0; l<polys[j].pntnbr && !trouve; l++){
01355              suiv2 = pntsuiv[act2];
01356              if ( tandistcar(&segment[0], &fpnts[act2])>seuil &&
01357                  tandistcar(&segment[1], &fpnts[act2])>seuil &&
01358                  tandistcarsegpnt(segment, &fpnts[act2], &dx, &dy)<seuil/4 ){
01359               fpnts[flptnew].posx = fpnts[act2].posx-dx;
01360               fpnts[flptnew].posy = fpnts[act2].posy-dy;
01361               pntsuiv[flptnew] = pntsuiv[act1];
01362               pntsuiv[act1] = flptnew;
01363               flptnew++;
01364               polys[i].pntnbr++;
01365               polys[i].firstpnt = act1;
01366               trouve = ret = TRUE;
01367              }
01368              act2 = suiv2;
01369            }
01370            act1 = suiv1;
01371            segment[0] = segment[1];
01372          }
01373        }
01374       }
01375     }
01376   }
01377   
01378   flfig->flpiecenbr = polynbr;
01379 
01380   return (ret);
01381 }  
01382 
01383 
01384 /* "tasse" les fpnt et recree la floatfig */
01385 /* copie les point de ref dans cop */
01386 /* en sortie les 2 sont identiques mais la floatfig pointe sur cop */
01387 int tantasse(tanflfig *flfig,
01388             tanpoly *polys,
01389             int *pntsuiv,
01390             tanfpnt *fpntsref,
01391             tanfpnt *fpntscop){
01392   int i, j;
01393   int act, pntnbr;
01394   tanfpnt *fpnts;
01395   
01396   fpnts=fpntscop;
01397   for (i = 0; i<flfig->flpiecenbr; i++){
01398     pntnbr = polys[i].pntnbr;
01399     flfig->flpieces[i].flpntnbr = pntnbr;
01400     flfig->flpieces[i].flpnts = fpnts;
01401     flfig->flpieces[i].polytype = polys[i].polytype;
01402     act = polys[i].firstpnt;
01403     for (j = 0; j<pntnbr+1; j++){
01404       *fpnts++ = fpntsref[act];
01405       act = pntsuiv[act];
01406     }
01407   }
01408 
01409   act=0;
01410   for (i = 0; i<flfig->flpiecenbr; i++){
01411     pntnbr = polys[i].pntnbr;
01412     polys[i].firstpnt = act;
01413     for (j = 0; j<pntnbr-1; j++)
01414       pntsuiv[act+j] = act+j+1;
01415     pntsuiv[act+j] = act;
01416     act += pntnbr+1;
01417   }
01418 
01419   pntnbr = fpnts-fpntscop;
01420   for (i = 0; i<pntnbr; i++)
01421     *fpntsref++ = *fpntscop++;
01422 
01423   return (pntnbr);
01424 }
01425 
01426 
01427 /* supprime les points intermediaires de segments alignes */
01428 gboolean tanalign(tanflfig *flfig, tanpoly *polys, int *pntsuiv, tanfpnt *fpnts){
01429   int i,k;
01430   gboolean trouve, ret;
01431   int polynbr;
01432   int act;
01433   int suiva,suivb;
01434   int diract,dirsuiv;
01435   int dumi;
01436   
01437   polynbr = flfig->flpiecenbr;
01438 
01439   ret = FALSE;
01440   trouve = TRUE;
01441   while (trouve){
01442     trouve = FALSE;
01443     for (i = 0; i<polynbr && !trouve; i++){
01444       act = polys[i].firstpnt;
01445       suiva = pntsuiv[act];
01446       dumi = tanangle(fpnts[suiva].posx-fpnts[act].posx, fpnts[suiva].posy-fpnts[act].posy);
01447       diract = (int)((dumi+rotstepnbr/2)/rotstepnbr);
01448       for (k = 0; k<polys[i].pntnbr && !trouve; k++){
01449        suiva = pntsuiv[act];
01450        suivb = pntsuiv[suiva];
01451        dumi = tanangle(fpnts[suivb].posx-fpnts[suiva].posx, fpnts[suivb].posy-fpnts[suiva].posy);
01452        dirsuiv = (int)((dumi+rotstepnbr/2)/rotstepnbr);
01453        if ( diract==dirsuiv ){
01454          pntsuiv[act] = suivb;
01455          polys[i].pntnbr--;
01456          polys[i].firstpnt = act;
01457          trouve = ret = TRUE;
01458        }
01459        act = suiva;
01460        diract = dirsuiv;
01461       }
01462     }
01463   }
01464   
01465   return (ret);
01466 }
01467 
01468 
01469 /* supprime les segments consecutifs superposes */
01470 gboolean tanconseq(tanflfig *flfig, tanpoly *polys, int *pntsuiv, tanfpnt *fpnts, double seuil){
01471   int i,k;
01472   gboolean trouve, ret;
01473   int polynbr;
01474   int act;
01475   int suiva,suivb;
01476   
01477   polynbr = flfig->flpiecenbr;
01478 
01479   ret = FALSE;
01480   trouve = TRUE;
01481   while (trouve){
01482     trouve = FALSE;
01483     for (i = 0; i<polynbr && !trouve; i++){
01484       act = polys[i].firstpnt;
01485       for (k = 0; k<polys[i].pntnbr && !trouve; k++){
01486        suiva = pntsuiv[act];
01487        suivb = pntsuiv[suiva];
01488        if ( tandistcar(&fpnts[act],&fpnts[suivb])<seuil ){
01489          pntsuiv[act] = pntsuiv[suivb];
01490          polys[i].pntnbr -= 2;
01491          polys[i].firstpnt = act;
01492          trouve = ret = TRUE;
01493        }
01494        act = suiva;
01495       }
01496     }
01497   }
01498   
01499   return (ret);
01500 }
01501 
01502 
01503 /* concatene les poly ayant 1 segment commun */
01504 gboolean tanconcat(tanflfig *flfig, tanpoly *polys, int *pntsuiv, tanfpnt *fpnts, double seuil){
01505   int i,j,k,l,m;
01506   gboolean trouve, ret;
01507   int polynbr;
01508   int act1,act2;
01509   int suiv1,suiv2;
01510   
01511   polynbr = flfig->flpiecenbr;
01512 
01513   ret = FALSE;
01514   trouve = TRUE;
01515   while (trouve){
01516     trouve = FALSE;
01517     for (i = 0; i<polynbr-1 && !trouve; i++){
01518       for (j = i+1; j<polynbr && !trouve; j++){
01519        act1 = polys[i].firstpnt;
01520        for (k = 0; k<polys[i].pntnbr && !trouve; k++){
01521          suiv1 = pntsuiv[act1];
01522          act2 = polys[j].firstpnt;
01523          for (l = 0; l<polys[j].pntnbr && !trouve; l++){
01524            suiv2 = pntsuiv[act2];
01525            if ( tandistcar(&fpnts[act1],&fpnts[suiv2])<seuil &&
01526                tandistcar(&fpnts[suiv1],&fpnts[act2])<seuil ){
01527              pntsuiv[act1] = pntsuiv[suiv2];
01528              pntsuiv[act2] = pntsuiv[suiv1];
01529              polys[i].pntnbr += polys[j].pntnbr-2;
01530              polys[i].firstpnt = act1;
01531              for (m = j; m<polynbr-1; m++)
01532               polys[m] = polys[m+1];
01533              polynbr--;
01534              trouve = ret = TRUE;
01535            }
01536            act2 = suiv2;
01537          }
01538          act1 = suiv1;
01539        }
01540       }
01541     }
01542   }
01543 
01544   flfig->flpiecenbr = polynbr;
01545 
01546   return (ret);
01547 }  
01548 
01549 
01550 /* detecte les poly "inclus" */
01551 /* probleme potentiel : pourrait ne pas detecter une inclusion
01552 car on n'ajoute pas de points pour les 'auto-corespondance' */
01553 gboolean taninclus(tanflfig *flfig, tanpoly *polys, int *pntsuiv, tanfpnt *fpnts, double seuil){
01554   int i,k,l,m,n;
01555   gboolean trouve, ret;
01556   int polynbr;
01557   int act1,act2;
01558   int suiv1,suiv2;
01559   int pntnbr;
01560   tanpoly dumpoly;
01561   double dumposxmin;
01562   int dumpntposxmin = 0;
01563   
01564   polynbr = flfig->flpiecenbr;
01565 
01566   trouve = ret = FALSE;
01567   for (i = 0; i<polynbr && !trouve; i++){
01568     pntnbr = polys[i].pntnbr;
01569 
01570     /*pour etre sur de partir de l'exterieur*/
01571     act1 = polys[i].firstpnt;
01572     dumposxmin = 99999999.0;
01573     for (m=0; m<pntnbr; m++){
01574       if ( fpnts[act1].posx<dumposxmin ){
01575        dumposxmin = fpnts[act1].posx;
01576        dumpntposxmin = act1;
01577       }
01578       act1 = pntsuiv[act1];
01579     }
01580     act1 = dumpntposxmin;
01581 
01582     for (k = 0; k<pntnbr-2 && !trouve; k++){
01583       suiv1 = pntsuiv[act1];
01584       act2 = pntsuiv[suiv1];
01585       for (l = k+2; l<pntnbr && !trouve; l++){
01586        suiv2 = pntsuiv[act2];
01587        if ( tandistcar(&fpnts[act1],&fpnts[suiv2])<seuil &&
01588             tandistcar(&fpnts[suiv1],&fpnts[act2])<seuil ){
01589          
01590          pntsuiv[act1] = pntsuiv[suiv2];
01591          pntsuiv[act2] = pntsuiv[suiv1];
01592          
01593          dumpoly = polys[i];
01594          for (n = i; n<polynbr-1; n++)
01595            polys[n] = polys[n+1];
01596          
01597          polynbr--;
01598          
01599          for (m = 0; polys[m].polytype==TAN_POLYBACK && m<polynbr; m++);
01600          
01601          /*     printf("inclusion trouvee\n");*/
01602 
01603          for (n = polynbr+1; n>m+1; n--)
01604            polys[n] = polys[n-2];
01605          
01606          dumpoly.pntnbr -= l-k+1;
01607          dumpoly.firstpnt = act1;
01608          if (dumpoly.polytype!=TAN_POLYON)
01609            dumpoly.polytype = TAN_POLYBACK;
01610          else
01611            dumpoly.polytype = TAN_POLYON;
01612          
01613          polys[m] = dumpoly;
01614          
01615          polys[m+1].pntnbr = l-k-1; 
01616          polys[m+1].firstpnt = act2;
01617          polys[m+1].polytype = TAN_POLYON;
01618          
01619          polynbr += 2;
01620 
01621          trouve = ret = TRUE;
01622 
01623 
01624        }
01625        act2 = suiv2;
01626       }
01627       act1 = suiv1;
01628     }
01629   }
01630   
01631   
01632   flfig->flpiecenbr = polynbr;
01633 
01634   return (ret);
01635 }  
01636 
01637 
01638 /* change de petite figure */
01639 /* pas d'acces gtk */
01640 void tansetnewfigurepart1(int nrfig){
01641 
01642   tanfigure *figure;
01643   int i,j;
01644   double xmin=10000,xmax=-10000,ymin=10000,ymax=-10000;
01645   tanpiecepos *piecepos;
01646   tanflfig *flfig=&flfigpetite;
01647   int flpiecenbr,flpntnbr;
01648   tanfpnt *fpnts;
01649   tanfpnt dumfpnts[FLPNTMAX];
01650   tanpoly polys[PIECENBR];
01651   int polypntact,polypntnbr;
01652   int pntsuivants[FLPNTMAX];
01653   double seuil=0.00000000001;
01654   int pntnew;
01655 
01656   if ( nrfig>=0 && figtabsize ){
01657     nrfig %= figtabsize;
01658     actual_figure = nrfig;
01659     figure = figtab+nrfig;
01660   } else {
01661     if (nrfig==-1)
01662       figure = &figuredebut;
01663     else
01664       figure = &figpetite;
01665     nrfig = -1;
01666   }
01667 
01668   figactualnr = nrfig;
01669 
01670   helptanset=PIECENBR;
01671   figpetite=*figure;
01672   tancolle(&figpetite,0.02);
01673   tanmaketinytabnotr(&figpetite,tinytabpe);
01674   tantranstinytab(tinytabpe);
01675 
01676   /* la floatfig et preparation de la concatenation */
01677   flfig->flpiecenbr = PIECENBR;
01678   flfig->figure = figure;
01679   fpnts = dumfpnts;
01680   polypntact = 0;
01681   for (i = 0; i<PIECENBR; i++){
01682     polypntnbr = piecesdef[figure->piecepos[i].type].pntnbr;
01683     polys[i].pntnbr = polypntnbr;
01684     polys[i].firstpnt = polypntact;
01685     polys[i].polytype = TAN_POLYNORMAL;
01686 
01687     for (j = 0; j<polypntnbr-1; j++)
01688       pntsuivants[polypntact+j] = polypntact+j+1;
01689     pntsuivants[polypntact+j] = polypntact;
01690     polypntact += polypntnbr+1;
01691 
01692     tanplacepiecefloat(&figure->piecepos[i], fpnts,1);
01693     fpnts += polypntnbr+1;
01694   }  
01695   
01696   tanconcat(flfig, polys, pntsuivants, dumfpnts, seuil);
01697   tanconseq(flfig, polys, pntsuivants, dumfpnts, seuil);
01698 
01699   pntnew = tantasse(flfig, polys, pntsuivants, dumfpnts, fpntspetite);
01700   tanajoute(flfig, polys, pntsuivants, dumfpnts, seuil, pntnew);
01701   tanconcat(flfig, polys, pntsuivants, dumfpnts, seuil);
01702   tanconseq(flfig, polys, pntsuivants, dumfpnts, seuil);
01703   if (taninclus(flfig, polys, pntsuivants, dumfpnts, seuil))
01704     taninclus(flfig, polys, pntsuivants, dumfpnts, seuil);
01705   tanalign(flfig, polys, pntsuivants, dumfpnts);
01706   tanremsame(flfig, polys, pntsuivants, dumfpnts, seuil);
01707   
01708   pntnew = tantasse(flfig, polys, pntsuivants, dumfpnts, fpntspetite);
01709   tanajoute(flfig, polys, pntsuivants, dumfpnts, seuil, pntnew);
01710   tanconcat(flfig, polys, pntsuivants, dumfpnts, seuil);
01711   tanconseq(flfig, polys, pntsuivants, dumfpnts, seuil);
01712   if (taninclus(flfig, polys, pntsuivants, dumfpnts, seuil))
01713     taninclus(flfig, polys, pntsuivants, dumfpnts, seuil);
01714   tanalign(flfig, polys, pntsuivants, dumfpnts);
01715   tanremsame(flfig, polys, pntsuivants, dumfpnts, seuil);
01716 
01717   tantasse(flfig, polys, pntsuivants, dumfpnts, fpntspetite);
01718 
01719   /* calcul du centrage */
01720   flpiecenbr = flfig->flpiecenbr;
01721   for (i = 0; i<flpiecenbr; i++){
01722     fpnts = flfig->flpieces[i].flpnts;
01723     flpntnbr = flfig->flpieces[i].flpntnbr;
01724     for (j = 0; j<flpntnbr; j++){
01725       if (fpnts[j].posx>xmax)
01726        xmax=fpnts[j].posx;
01727       if (fpnts[j].posy>ymax)
01728        ymax=fpnts[j].posy;
01729       if (fpnts[j].posx<xmin)
01730        xmin=fpnts[j].posx;
01731       if (fpnts[j].posy<ymin)
01732        ymin=fpnts[j].posy;
01733     }
01734   }
01735   
01736   figpetite.zoom = 1/(( (xmax-xmin)>(ymax-ymin) ? (xmax-xmin) : (ymax-ymin) )+0.25);
01737   dxpetite = 0.5*(xmax+xmin)-(0.5/figpetite.zoom);
01738   dypetite = 0.5*(ymax+ymin)-(0.5/figpetite.zoom);
01739   
01740   dxout = 0.5*(xmax+xmin)-(0.5/figgrande.zoom);    /* cf tanrecentreout pour correction */
01741   dyout = 0.5*(ymax+ymin)-(0.5/figgrande.zoom);
01742   
01743   /* centrage des pieces petite */
01744   piecepos=figpetite.piecepos;
01745   for (i=0; i<PIECENBR; i++){
01746     piecepos->posx-=dxpetite;
01747     piecepos->posy-=dypetite;
01748     piecepos++;
01749   }
01750 }
01751 
01752 
01753 /********************************/
01754 /* corrige dxout et dyout pour les changement de zoom de figgrande */
01755 void tanrecentreout(double oldzoom, double newzoom){
01756 
01757   tanpiecepos *piecepos;
01758   int i;
01759   double correction;
01760   
01761   correction = 0.5*(1/oldzoom-1/newzoom);
01762 
01763   dxout += correction;
01764   dyout += correction;
01765 
01766   piecepos = figgrande.piecepos;
01767   for (i = 0; i<PIECENBR; i++){
01768     piecepos->posx -= correction;
01769     piecepos->posy -= correction;
01770     piecepos++;
01771   }
01772   
01773   return;
01774 }
01775 
01776 
01777 /********************************/
01778 /* change de petite figure */
01779 void tansetnewfigurepart2(void){
01780   
01781   if (selectedgrande){
01782     helpoutset=FALSE;
01783     tanunselect();
01784   }
01785   else if (helpoutset){       /* pour eviter 2 appels successif a tanredrawgrande */
01786     helpoutset=FALSE;
01787     tanredrawgrande();
01788   }
01789 
01790   tanredrawpetite();
01791 
01792   selpossible=TRUE;
01793 
01794 }
01795 
01796 
01797 /********************************/
01798 void spesavefig (void){
01799 
01800  FILE *hand;
01801  int j;
01802  tanfigure *fig=NULL; /*juste pour eviter un warning*/
01803 
01804  if ( (hand=fopen("pouet.fig", "w"))!=NULL){
01805 
01806    fprintf(hand, "gTans v1.0 %d \n",figtabsize);
01807 
01808    fig=&figgrande;
01809    fprintf(hand,"%e %e %d \n",1.0,fig->distmax,fig->drotmax);
01810    for (j=0; j<PIECENBR; j++)
01811      fprintf(hand,"p %d %d %e %e %d \n",fig->piecepos[j].type,fig->piecepos[j].flipped,
01812             fig->piecepos[j].posx,fig->piecepos[j].posy,fig->piecepos[j].rot);
01813  }
01814 
01815  if (hand!=NULL){
01816    fclose(hand);
01817    figpetite=*fig;
01818    figpetite.zoom=1;
01819    tansetnewfigurepart1(-2);
01820    tansetnewfigurepart2();
01821  }
01822 
01823 }
01824 
01825 /********************************/
01826 void taninitstart(void){
01827 
01828   int i;
01829   char* accurstr;
01830 
01831   usergtdir = gc_prop_current_board_dirname_get();
01832 
01833   for (i = PXSTART; i<PXNBR+PXSTART; i++){
01834     tabpxnam[i] = NULL;
01835     tabpxpx[i] = NULL;
01836   }
01837 
01838   for (i = 0; i<GCNBR; i++)
01839     tabcolalloc[i] = FALSE;
01840   
01841   editmode = FALSE;
01842   figgrande = figuredebut;
01843   figtabsize = 0;
01844 
01845   tansetnewfigurepart1(-1);
01846 
01847   tansetdefconfig();
01848 
01849   tanclampgrandefig();
01850 
01851 
01852   boardRootItem = GNOME_CANVAS_GROUP(gnome_canvas_item_new (gnome_canvas_root(gcomprisBoard->canvas),
01853                                                      gnome_canvas_group_get_type(),
01854                                                      "x", 0.0,
01855                                                      "y", 0.0,
01856                                                      NULL
01857                                                      ));
01858 
01859   create_mainwindow(boardRootItem);
01860 
01861   switch (accuracy){
01862   case 0:
01863     accurstr = "maccuracy1";
01864     break;
01865   case 2:
01866     accurstr = "maccuracy3";
01867     break;
01868   default :
01869     accurstr = "maccuracy2";
01870   }
01871 
01872   if (rotstepnbr==TOUR/256)
01873     accurstr = "mrotcont";
01874   else
01875     accurstr = "mrotstp";
01876 
01877   tanloadfigtab(figfilename);
01878 
01879 }
01880 
01881 
01882 /********************************/
01883 void tanend(void){
01884   int i;
01885   GdkColormap *syscmap;
01886 
01887   syscmap = gdk_colormap_get_system();
01888 
01889   tansavefigstatus(figfilename, figtab, figtabsize);
01890 
01891   if (usergtdir!=NULL)
01892     g_free(usergtdir);
01893 
01894   if (userconf!=NULL)
01895     g_free(userconf);
01896 
01897   if (figfilename!=NULL)
01898     g_free(figfilename);
01899 
01900   if (figtab!=NULL)
01901     g_free(figtab);
01902   
01903   if (pixmappetite!=NULL)
01904     gdk_pixmap_unref(pixmappetite);
01905   if (pixmapgrande1!=NULL)
01906     gdk_pixmap_unref(pixmapgrande1);
01907   if (pixmapgrande2!=NULL)
01908     gdk_pixmap_unref(pixmapgrande2);
01909   if (pixmappiece1!=NULL)
01910     gdk_pixmap_unref(pixmappiece1);
01911   if (pixmappiece2!=NULL)
01912     gdk_pixmap_unref(pixmappiece2);
01913   if (pixmapfond!=NULL)
01914     gdk_pixmap_unref(pixmapfond);
01915   
01916   for (i=PXSTART; i<PXSTART+PXNBR; i++){
01917     if (tabpxpx[i]!=NULL)
01918       gdk_pixmap_unref(tabpxpx[i]);
01919     if (tabpxnam[i]!=NULL)
01920       g_free(tabpxnam[i]);
01921   }
01922 
01923   for (i = 0; i<GCNBR; i++){
01924     if (tabgc[i]!=NULL)
01925       gdk_gc_unref(tabgc[i]);
01926     if (tabcolalloc[i])
01927       gdk_colormap_free_colors (syscmap, &colortab[i], 1);
01928   }  
01929 
01930   gdk_gc_unref(invertgc);
01931 
01932   gtk_main_quit ();
01933 }
01934 
01935 
01936 /********************************/
01937 void taninitcbcommun(void){
01938 
01939 }
01940 
01941 
01942 /********************************/
01943 void taninitcbgr(void){
01944   int i;
01945   GdkColor *color;
01946 
01947   initcbgr = TRUE; /* pour ne pas initialiser 2 fois */
01948 
01949   for (i=PXSTART; i<PXSTART+PXNBR; i++){
01950     tabgc[i] = gdk_gc_new(widgetgrande->window);
01951     if (tabpxpixmode[i])
01952       tansetpixmapmode(widgetgrande,tabpxnam[i],i);
01953     else
01954       tansetcolormode(&colortab[i],i);
01955   }
01956 
01957   for (i=0; i<GRISNBR; i++){
01958     color = &colortab[i];
01959     color->red = color->green = color->blue = (gushort)(65535.0/(GRISNBR-1)*i);
01960     tabgc[i] = gdk_gc_new(widgetgrande->window);
01961     tansetcolormode(color,i);
01962   }
01963 
01964   invertgc=gdk_gc_new(widgetgrande->window);
01965   gdk_gc_set_function(invertgc,GDK_INVERT);
01966   tabgc[GCPIECEHLP]=gdk_gc_new(widgetgrande->window);
01967   tansetcolormode(&colortab[GCPIECEHLP],GCPIECEHLP);
01968   /* les line attribute sont dans le callback */
01969 
01970   if (initcbpe)
01971     taninitcbcommun();
01972 
01973 }
01974 
01975 
01976 /********************************/
01977 void taninitcbpe(void){
01978 
01979   initcbpe=TRUE; /* pour ne pas initialiser 2 fois (c'est pas propre, mais bon) */
01980 
01981   tabgc[GCPETITEFG]=gdk_gc_new(widgetpetite->window);
01982   tansetcolormode(&colortab[GCPETITEFG],GCPETITEFG);
01983 
01984   tabgc[GCPETITEBG]=gdk_gc_new(widgetpetite->window);
01985   tansetcolormode(&colortab[GCPETITEBG],GCPETITEBG);
01986 
01987   tabgc[GCPETITEHLP]=gdk_gc_new(widgetpetite->window);
01988   tansetcolormode(&colortab[GCPETITEHLP],GCPETITEHLP);
01989 
01990   tabgc[GCPETITECHK]=gdk_gc_new(widgetpetite->window);
01991   tansetcolormode(&colortab[GCPETITECHK],GCPETITECHK);
01992 
01993   if (initcbgr)
01994     taninitcbcommun();
01995 
01996 }
01997 
01998 
01999 /********************************/
02000 /* determine si le point x,y est dans la piece */
02001 gboolean tanpntisinpiece(int x, int y, tanpiecepos *piecepos){
02002 
02003   int i;
02004   gboolean in;
02005   GdkPoint pnt[PNTNBRMAX+2];
02006   int nbrpnt;
02007   
02008   nbrpnt=tanplacepiece(piecepos,pnt,widgetgrande->allocation.width*figgrande.zoom);
02009   pnt[nbrpnt]=pnt[0];
02010 
02011   in=TRUE;
02012   if (piecepos->flipped){
02013     for (i=0; (i<nbrpnt && in); i++)
02014       if ( (x-pnt[i].x)*(pnt[i+1].y-pnt[i].y)-(y-pnt[i].y)*(pnt[i+1].x-pnt[i].x)<0 )
02015        in=FALSE;
02016   }
02017   else{
02018     for (i=0; (i<nbrpnt && in); i++)
02019       if ( (x-pnt[i].x)*(pnt[i+1].y-pnt[i].y)-(y-pnt[i].y)*(pnt[i+1].x-pnt[i].x)>0 )
02020        in=FALSE;
02021   }
02022 
02023 
02024   return (in);
02025 
02026 }
02027 
02028 
02029 /********************************/
02030 /* determine dans quelle piece se trouve le point (-1=aucune) */
02031 int tanwichisselect(int x, int y){
02032   
02033   int i;
02034   gboolean trouve;
02035 
02036   trouve=FALSE;
02037   for (i=PIECENBR-1; i>=0 && !trouve; i--)
02038     trouve=tanpntisinpiece(x,y,figgrande.piecepos+i);
02039 
02040   if (trouve)
02041     i++;
02042 
02043   return (i);
02044 
02045 }
02046 
02047 
02048 
02049 
02050 
02051 
02052 
02053 
02054 
02055 
02056 
02057 
02058 
02059 
02060 
02061 
02062 
02063 
02064 
02065 
02066 
02067 
02068