0b72de2a52d411cad8b10eec74babb3a9405b4ba
[scilab.git] / scilab / modules / graphics / src / c / Plo2dn.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2002-2004 - INRIA - Djalel Abdemouche
4  * Copyright (C) 2004-2006 - INRIA - Fabrice Leray
5  * Copyright (C) 2010-2011 - DIGITEO - Manuel Juliachs
6  * Copyright (C) 2011 - DIGITEO - Bruno JOFRET
7  * Copyright (C) 2012 - Scilab Enterprises - Cedric Delamarre
8  *
9  * This file must be used under the terms of the CeCILL.
10  * This source file is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution.  The terms
12  * are also available at
13  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
14  *
15  */
16
17 /*------------------------------------------------------------------------
18  *    Graphic library
19  --------------------------------------------------------------------------*/
20 #include <stdio.h>
21 #include <string.h>
22 #include "math_graphics.h"
23 #include "PloEch.h"
24 #include "Plot2d.h"
25
26 #define spINSIDE_SPARSE
27 #include "../../sparse/includes/spConfig.h"
28 #include "isanan.h"
29
30 #include "SetProperty.h"
31 #include "DrawObjects.h"
32 #include "BuildObjects.h"
33 #include "Axes.h"
34 #include "BasicAlgos.h"
35 #include "sciprint.h"
36 #include "Scierror.h"
37
38 #include "MALLOC.h"             /* MALLOC */
39 #include "scitokenize.h"
40 #include "localization.h"
41 #include "get_ticks_utils.h"
42 #include "HandleManagement.h"
43 #include "freeArrayOfString.h"
44
45 #include "createGraphicObject.h"
46 #include "getGraphicObjectProperty.h"
47 #include "setGraphicObjectProperty.h"
48 #include "graphicObjectProperties.h"
49 #include "CurrentFigure.h"
50 #include "CurrentSubwin.h"
51 #include "CurrentObject.h"
52
53 /*--------------------------------------------------------------------
54  *  plot2dn(ptype,Logflags,x,y,n1,n2,style,strflag,legend,brect,aaint,lstr1,lstr2)
55  *
56  *  Draw *n1 curves of *n2 points each
57  *
58  *  ptype is an int which gives the polyline drawind mode (0,1,2,3,4)
59  *
60  *  Logflags is a two character string
61  *
62  *  (x[i+(*n2)*j] ,y[i+(*n2)*j]) Double values giving the point
63  *  position of point i of curve j (i=0,*n2-1 j=0,*n1-1)
64  *
65  *  style[*n1]-> give the style to use for each curve
66  *     if style is positive --> a mark is used (mark id = style[i])
67  *     if style is strictly negative --> a dashed line is used
68  *        (dash id = abs(style[i])
69  *     if there's only one curve, style can be of type style[0]=style,
70  *     style[1]=pos (pos in [1,6])
71  *     pos give the legend position (1 to 6) (this can be iteresting
72  *     if you want to superpose curves with different legends by
73  *     calling plot2d more than one time.
74  *
75  *  strflag[3] is a string
76  *
77  *     if strflag[0] == '1' then legends are added
78  *        legend = "leg1@leg2@....@legn"; gives the legend for each curve
79  *      else no legend
80  *
81  *     if strflag[1] == '1' then  the values of brect are used to fix
82  *        the drawing boundaries :  brect[]= <xmin,ymin,xmax,ymax>;
83  *      if strflag[1] == '2' then the values  are computed from data
84  *      else if strflag[1]=='0' the previous values
85  *                (previous call or defaut values) are used
86  *
87  *     if  strflag[2] == '1' ->then an axis is added
88  *        the number of intervals
89  *        is specified by the vector aaint[4] of integers
90  *         <aaint[0],aaint[1]> specifies the x-axis number of  points
91  *         <aaint[2],aaint[3]> same for y-axis
92  *     if  strflag[2] == '2' -> no axis, only a box around the curves
93  *     else no box and no axis
94
95  * lstr* : unused (but used by Fortran)
96  *--------------------------------------------------------------------------*/
97
98 int plot2dn(int ptype, char *logflags, double *x, double *y, int *n1, int *n2, int *style, char *strflag, char *legend, double *brect, int *aaint,
99             BOOL flagNax, int lstr1, int lstr2)
100 {
101     int iSubwinUID = 0;
102     int iCurFigureUID = 0;
103     int closeflag = 0;
104     int jj = 0;
105     long hdl = 0;
106     int *pObj = NULL;
107     int cmpt = 0;
108     int with_leg = 0;
109     double drect[6];
110     char dataflag = 0;
111
112     BOOL bounds_changed = FALSE;
113     BOOL axes_properties_changed = FALSE;
114
115     double rotationAngles[2];
116     int clipState = 0;
117     int autoScale = 0;
118     int logFlags[3];
119     int iTmp = 0;
120     int *piTmp = &iTmp;
121     char textLogFlags[3];
122     int firstPlot = 0;
123     int newFirstPlot = 0;
124     int autoSubticks = 0;
125
126     iSubwinUID = getOrCreateDefaultSubwin();
127
128     /*
129      * Check if the auto_clear property is on and then erase everything
130      * To be implemented
131      */
132     checkRedrawing();
133
134     rotationAngles[0] = 0.0;
135     rotationAngles[1] = 270.0;
136
137     setGraphicObjectProperty(iSubwinUID, __GO_ROTATION_ANGLES__, rotationAngles, jni_double_vector, 2);
138
139     /* Force logflags to those given by argument */
140
141     getGraphicObjectProperty(iSubwinUID, __GO_FIRST_PLOT__, jni_bool, (void **)&piTmp);
142     firstPlot = iTmp;
143
144     /* Reset x and y logflags */
145     if (firstPlot)
146     {
147         logFlags[0] = getBooleanLogFlag(logflags[1]);
148         logFlags[1] = getBooleanLogFlag(logflags[2]);
149
150         setGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_LOG_FLAG__, &logFlags[0], jni_bool, 1);
151         setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_LOG_FLAG__, &logFlags[1], jni_bool, 1);
152     }
153
154     /* Forces "clipgrf" clipping (1) */
155     clipState = 1;
156     setGraphicObjectProperty(iSubwinUID, __GO_CLIP_STATE__, &clipState, jni_int, 1);
157
158     getGraphicObjectProperty(iSubwinUID, __GO_AUTO_SCALE__, jni_bool, (void **)&piTmp);
159     autoScale = iTmp;
160
161     if (autoScale)
162     {
163         /* compute and merge new specified bounds with the data bounds */
164         switch (strflag[1])
165         {
166             case '0':
167                 /* do not change data bounds */
168                 break;
169             case '1':
170             case '3':
171             case '5':
172             case '7':
173                 /* Force data bounds=brect */
174                 re_index_brect(brect, drect);
175                 break;
176             case '2':
177             case '4':
178             case '6':
179             case '8':
180             case '9':
181                 /* Force data bounds to the x and y bounds */
182                 if ((int)strlen(logflags) < 1)
183                 {
184                     dataflag = 'g';
185                 }
186                 else
187                 {
188                     dataflag = logflags[0];
189                 }
190
191                 getGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
192                 logFlags[0] = iTmp;
193                 getGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
194                 logFlags[1] = iTmp;
195                 getGraphicObjectProperty(iSubwinUID, __GO_Z_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
196                 logFlags[2] = iTmp;
197
198                 /* Conversion required by compute_data_bounds2 */
199                 textLogFlags[0] = getTextLogFlag(logFlags[0]);
200                 textLogFlags[1] = getTextLogFlag(logFlags[1]);
201                 textLogFlags[2] = getTextLogFlag(logFlags[2]);
202
203                 compute_data_bounds2(0, dataflag, textLogFlags, x, y, *n1, *n2, drect);
204
205                 break;
206         }
207
208         /* merge data bounds and drect */
209         if (!firstPlot && (strflag[1] == '5' || strflag[1] == '7' || strflag[1] == '8' || strflag[1] == '9'))
210         {
211             double *dataBounds;
212
213             getGraphicObjectProperty(iSubwinUID, __GO_DATA_BOUNDS__, jni_double_vector, (void **)&dataBounds);
214
215             drect[0] = Min(dataBounds[0], drect[0]);    /*xmin */
216             drect[2] = Min(dataBounds[2], drect[2]);    /*ymin */
217             drect[1] = Max(dataBounds[1], drect[1]);    /*xmax */
218             drect[3] = Max(dataBounds[3], drect[3]);    /*ymax */
219         }
220
221         if (strflag[1] != '0')
222         {
223             bounds_changed = update_specification_bounds(iSubwinUID, drect, 2);
224         }
225     }
226
227     if (firstPlot)
228     {
229         bounds_changed = TRUE;
230     }
231
232     /* Adapted to the MVC */
233     axes_properties_changed = strflag2axes_properties(iSubwinUID, strflag);
234
235     /* just after strflag2axes_properties */
236     newFirstPlot = 0;
237     setGraphicObjectProperty(iSubwinUID, __GO_FIRST_PLOT__, &newFirstPlot, jni_bool, 1);
238
239     with_leg = (strflag[0] == '1');
240
241     /* F.Leray 07.10.04 : trigger algo to init. manual graduation u_xgrads and
242      * u_ygrads if nax (in matdes.c which is == aaint HERE) was specified */
243
244     /* The MVC AUTO_SUBTICKS property corresponds to !flagNax */
245     autoSubticks = !flagNax;
246     setGraphicObjectProperty(iSubwinUID, __GO_AUTO_SUBTICKS__, &autoSubticks, jni_bool, 1);
247
248     if (flagNax == TRUE)
249     {
250         getGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
251         logFlags[0] = iTmp;
252         getGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_LOG_FLAG__, jni_bool, (void **)&piTmp);
253         logFlags[1] = iTmp;
254
255         if (logFlags[0] == 0 && logFlags[1] == 0)
256         {
257             int autoTicks = 0;
258             int i = 0;
259             int iSize = 0;
260             double dblFabs = 0;
261             char** stringVector = NULL;
262
263             if (aaint[1] == -1)
264             {
265                 autoTicks = 1;
266                 setGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_AUTO_TICKS__, &autoTicks, jni_bool, 1);
267             }
268             else if (aaint[1] == 0)
269             {
270                 setGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_TICKS_LOCATIONS__, NULL, jni_double_vector, 0);
271                 autoTicks = 0;
272                 setGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_AUTO_TICKS__, &autoTicks, jni_bool, 1);
273             }
274             else
275             {
276                 double* dXGrads = (double*) MALLOC(aaint[1] * sizeof(double));
277
278                 // Compute X grads
279                 dXGrads[0] = drect[0];
280                 if (aaint[1] > 1)
281                 {
282                     double pas = (drect[1] - drect[0]) / (aaint[1] - 1);
283                     for (i = 0; i < aaint[1]; i++)
284                     {
285                         dXGrads[i] = drect[0] + pas * i;
286                     }
287                 }
288
289                 autoTicks = 0;
290                 setGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_AUTO_TICKS__, &autoTicks, jni_bool, 1);
291                 setGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_TICKS_LOCATIONS__, dXGrads, jni_double_vector, aaint[1]);
292                 // Create X Labels
293                 stringVector = (char **) MALLOC(aaint[1] * sizeof(char*));
294                 for (i = 0; i < aaint[1]; i++)
295                 {
296                     iSize = 6;
297                     if (dXGrads[i] < 0)
298                     {
299                         iSize += 2;
300                     }
301                     dblFabs = fabs(dXGrads[i]);
302                     if (dblFabs >= 10)
303                     {
304                         iSize = iSize + (int)floor(log10(dblFabs));
305                     }
306
307                     stringVector[i] = (char*) MALLOC(iSize * sizeof(char));
308                     sprintf(stringVector[i], "%.3f", dXGrads[i]);
309                     stringVector[i][iSize - 1] = '\0';
310                 }
311
312                 setGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_TICKS_LABELS__, stringVector, jni_string_vector, aaint[1]);
313
314                 for (i = 0; i < aaint[1]; i++)
315                 {
316                     FREE(stringVector[i]);
317                 }
318
319                 FREE(stringVector);
320                 FREE(dXGrads);
321                 stringVector = NULL;
322             }
323
324             if (aaint[3] == -1)
325             {
326                 autoTicks = 1;
327                 setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_AUTO_TICKS__, &autoTicks, jni_bool, 1);
328             }
329             else if (aaint[3] == 0)
330             {
331                 setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_TICKS_LOCATIONS__, NULL, jni_double_vector, 0);
332                 autoTicks = 0;
333                 setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_AUTO_TICKS__, &autoTicks, jni_bool, 1);
334             }
335             else
336             {
337                 double* dYGrads = (double*) MALLOC(aaint[3] * sizeof(double));
338
339                 // Compute Y grads
340                 dYGrads[0] = drect[2];
341                 if (aaint[3] > 1)
342                 {
343                     double pas = (drect[3] - drect[2]) / (aaint[3] - 1);
344                     for (i = 0; i < aaint[3]; i++)
345                     {
346                         dYGrads[i] = drect[2] + pas * i;
347                     }
348                 }
349
350                 autoTicks = 0;
351                 setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_AUTO_TICKS__, &autoTicks, jni_bool, 1);
352                 setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_TICKS_LOCATIONS__, dYGrads, jni_double_vector, aaint[3]);
353
354                 // Create Y Labels
355                 stringVector = (char**) MALLOC(aaint[3] * sizeof(char*));
356                 for (i = 0; i < aaint[3]; i++)
357                 {
358                     iSize = 6;
359                     if (dYGrads[i] < 0)
360                     {
361                         iSize += 2;
362                     }
363                     dblFabs = fabs(dYGrads[i]);
364                     if (dblFabs >= 10)
365                     {
366                         iSize = iSize + (int)floor(log10(dblFabs));
367                     }
368                     stringVector[i] = (char*) MALLOC(iSize * sizeof(char));
369                     sprintf(stringVector[i], "%.3f", dYGrads[i]);
370                     stringVector[i][iSize - 1] = '\0';
371                 }
372
373                 setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_TICKS_LABELS__, stringVector, jni_string_vector, aaint[3]);
374
375                 for (i = 0; i < aaint[3]; i++)
376                 {
377                     FREE(stringVector[i]);
378                 }
379
380                 FREE(stringVector);
381                 FREE(dYGrads);
382                 stringVector = NULL;
383             }
384
385             // X and Y subticks
386             setGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_SUBTICKS__, aaint, jni_int, 1);
387             setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_SUBTICKS__, &aaint[2], jni_int, 1);
388         }
389         else
390         {
391             sciprint(_("Warning: Nax does not work with logarithmic scaling.\n"));
392         }
393
394     }
395
396     /*---- Drawing the curves and the legends ----*/
397     if (*n1 != 0)
398     {
399         if ((pObj = (int*)MALLOC((*n1 + 1) * sizeof(int))) == NULL)
400         {
401             Scierror(999, _("%s: No more memory.\n"), "plot2d");
402             return -1;
403         }
404
405         /*A.Djalel 3D axes */
406         for (jj = 0; jj < *n1; jj++)
407         {
408             int iObjUID = 0;
409
410             if (style[jj] > 0)
411             {
412                 BOOL isline = TRUE;
413
414                 if (ptype == 3)
415                 {
416                     isline = FALSE;
417                 }
418                 iObjUID = ConstructPolyline(getCurrentSubWin(), &(x[jj * (*n2)]),
419                                             &(y[jj * (*n2)]), PD0, closeflag, *n2, ptype,
420                                             &style[jj], NULL, NULL, NULL, NULL, isline, FALSE, FALSE, FALSE);
421             }
422             else
423             {
424                 int minusstyle = -style[jj];
425
426                 iObjUID = ConstructPolyline(getCurrentSubWin(), &(x[jj * (*n2)]),
427                                             &(y[jj * (*n2)]), PD0, closeflag, *n2, ptype,
428                                             NULL, NULL, &minusstyle, NULL, NULL, FALSE, FALSE, TRUE, FALSE);
429             }
430             if (iObjUID == 0)
431             {
432                 // skip
433                 Scierror(999, _("%s: No more memory.\n"), "plot2d");
434             }
435             else
436             {
437                 setCurrentObject(iObjUID);
438
439                 pObj[cmpt] = iObjUID;
440                 cmpt++;
441             }
442
443         }
444
445         /*---- Drawing the Legends ----*/
446         if (with_leg)
447         {
448             int iLegUID = 0;
449             char **Str;
450             int nleg;
451
452             if (scitokenize(legend, &Str, &nleg))
453             {
454                 FREE(pObj);
455                 Scierror(999, _("%s: No more memory.\n"), "plot2d");
456                 return 0;
457             }
458
459             iLegUID = ConstructLegend(getCurrentSubWin(), Str, pObj, Min(nleg, cmpt));
460
461             if (iLegUID != 0)
462             {
463                 int legendLocation;
464                 int contourMode;
465
466                 /* 9: LOWER_CAPTION */
467                 legendLocation = 9;
468                 setGraphicObjectProperty(iLegUID, __GO_LEGEND_LOCATION__, &legendLocation, jni_int, 1);
469
470                 contourMode = 0;
471
472                 setGraphicObjectProperty(iLegUID, __GO_FILL_MODE__, &contourMode, jni_bool, 1);
473                 setGraphicObjectProperty(iLegUID, __GO_LINE_MODE__, &contourMode, jni_bool, 1);
474             }
475
476             freeArrayOfString(Str, nleg);
477         }
478
479         /*---- construct Compound ----*/
480         if (cmpt > 0)
481         {
482             int parentVisible = 0;
483             int *piParentVisible = &parentVisible;
484             int iCompoundUID = createCompound(iSubwinUID, pObj, cmpt);
485             setCurrentObject(iCompoundUID);
486         }
487         FREE(pObj);
488
489     }
490     /* End of the curves and legend block */
491
492     return 0;
493 }
494
495 /* Given two set of coordinates x and y this routine computes the corresponding
496  *  data bounds rectangle drect=[xmin,ymin,xmax,ymax] taking into account the logflag
497  *  -> means we have to find among the data the min > 0.
498  */
499 void compute_data_bounds2(int cflag, char dataflag, char *logflags, double *x, double *y, int n1, int n2, double *drect)
500 {
501     int size_x = 0, size_y = 0;
502     double xd[2];
503     double *x1 = NULL;
504
505     switch (dataflag)
506     {
507         case 'e':
508             xd[0] = 1.0;
509             xd[1] = (double)n2;
510             x1 = xd;
511             size_x = (n2 != 0) ? 2 : 0;
512             break;
513         case 'o':
514             x1 = x;
515             size_x = n2;
516             break;
517         case 'g':
518         default:
519             x1 = x;
520             size_x = (cflag == 1) ? n1 : (n1 * n2);
521             break;
522     }
523
524     if (size_x != 0)
525     {
526         if (logflags[0] != 'l')
527         {
528             MiniMaxi(x1, size_x, drect, drect + 1);
529             //drect[0] = Mini(x1, size_x);
530             //drect[1] = Maxi(x1, size_x);
531         }
532         else
533         {
534             /* log. case */
535             drect[0] = sciFindStPosMin(x1, size_x);
536             drect[1] = Maxi(x1, size_x);
537         }
538
539     }
540     else
541     {
542         if (logflags[0] != 'l')
543         {
544             drect[0] = 0.0;
545             drect[1] = 10.0;
546         }
547         else
548         {
549             /* log. case */
550             drect[0] = 1.0;
551             drect[1] = 10.0;
552         }
553     }
554
555     size_y = (cflag == 1) ? n2 : (n1 * n2);
556     if (size_y != 0)
557     {
558         if (logflags[1] != 'l')
559         {
560             MiniMaxi(y, size_y, drect + 2, drect + 3);
561             //drect[2] = Mini(y, size_y);
562             //drect[3] = Maxi(y, size_y);
563         }
564         else
565         {
566             /* log. case */
567             drect[2] = sciFindStPosMin(y, size_y);
568             drect[3] = Maxi(y, size_y);
569         }
570     }
571     else
572     {
573         if (logflags[1] != 'l')
574         {
575             drect[2] = 0.0;
576             drect[3] = 10.0;
577         }
578         else
579         {
580             /* log. case */
581             drect[2] = 1.0;
582             drect[3] = 10.0;
583         }
584     }
585
586     /* back to default values for  x=[] and y = [] */
587     if (drect[2] == LARGEST_REAL || drect[3] == -LARGEST_REAL || C2F(isanan)(&drect[2]) || C2F(isanan)(&drect[3]))
588     {
589         if (logflags[1] != 'l')
590         {
591             drect[2] = 0.0;
592         }
593         else
594         {
595             drect[2] = 1.0;
596         }
597
598         drect[3] = 10.0;
599     }
600
601     if (drect[0] == LARGEST_REAL || drect[1] == -LARGEST_REAL || C2F(isanan)(&drect[0]) || C2F(isanan)(&drect[1]))
602     {
603         if (logflags[0] != 'l')
604         {
605             drect[0] = 0.0;
606         }
607         else
608         {
609             drect[0] = 1.0;
610         }
611
612         drect[1] = 10.0;
613     }
614 }
615
616 BOOL update_specification_bounds(int iSubwinUID, double rect[6], int flag)
617 {
618     double *dataBounds = NULL;
619
620     /*
621      * 2D: keep the existing zmin and zmax
622      * which is why they must be fetched
623      */
624     if (flag != 3)
625     {
626         getGraphicObjectProperty(iSubwinUID, __GO_DATA_BOUNDS__, jni_double_vector, (void **)&dataBounds);
627
628         rect[4] = dataBounds[4];
629         rect[5] = dataBounds[5];
630     }
631
632     setGraphicObjectProperty(iSubwinUID, __GO_DATA_BOUNDS__, rect, jni_double_vector, 6);
633
634     return TRUE;
635 }
636
637 /* F.Leray */
638 /* brect must have the same format as drect i.e.: [xmin,xmax,ymin,ymax] */
639 /* brect = INPUT ; drect = OUTPUT (warning drect is dim 6) */
640 int re_index_brect(double *brect, double *drect)
641 {
642     drect[0] = brect[0];
643     drect[1] = brect[2];
644     drect[2] = brect[1];
645     drect[3] = brect[3];
646
647     return 0;
648 }
649
650 /* F.Leray 07.05.04 */
651 /* Dispatch info contained in strflag to all the flag available in
652    sciSubwin object (tight_limits, isoview, isaxes...) */
653 /*
654  * This function has been adapted to the MVC framework
655  */
656 BOOL strflag2axes_properties(int iSubwinUID, char *strflag)
657 {
658     BOOL haschanged = FALSE;
659     BOOL tightLimitsPrev = FALSE;
660     BOOL isoviewPrev = FALSE;
661     int boxPrev = 0;
662     int tightLimits = 0;
663     int firstPlot = 0;
664     int axisVisible = 0;
665     int boxType = 0;
666     int xLocationPrev = 0;
667     int yLocationPrev = 0;
668     int xLocation = 0;
669     int yLocation = 0;
670     int isoview = 0;
671     int axesVisiblePrev[3];
672     int axesVisible[3];
673
674     int iTmp = 0;
675     int *piTmp = &iTmp;
676
677     getGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
678     axesVisiblePrev[0] = iTmp;
679     getGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
680     axesVisiblePrev[1] = iTmp;
681     getGraphicObjectProperty(iSubwinUID, __GO_Z_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
682     axesVisiblePrev[2] = iTmp;
683
684     getGraphicObjectProperty(iSubwinUID, __GO_BOX_TYPE__, jni_int, (void**)&piTmp);
685     boxPrev = iTmp;
686
687     getGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_LOCATION__, jni_int, (void**)&piTmp);
688     xLocationPrev = iTmp;
689     getGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_LOCATION__, jni_int, (void**)&piTmp);
690     yLocationPrev = iTmp;
691
692     getGraphicObjectProperty(iSubwinUID, __GO_TIGHT_LIMITS__, jni_bool, (void **)&piTmp);
693     tightLimitsPrev = iTmp;
694     getGraphicObjectProperty(iSubwinUID, __GO_ISOVIEW__, jni_bool, (void **)&piTmp);
695     isoviewPrev = iTmp;
696
697     /* F.Leray 07.05.04 */
698     /* strflag[1] Isoview & tight_limits flags management */
699     switch (strflag[1])
700     {
701         case '0':
702         case '9':
703             /* no changes */
704             break;
705         case '1':
706         case '2':
707         case '7':
708         case '8':
709             tightLimits = 1;
710             setGraphicObjectProperty(iSubwinUID, __GO_TIGHT_LIMITS__, &tightLimits, jni_bool, 1);
711             break;
712         case '3':
713         case '4':
714             isoview = 1;
715             setGraphicObjectProperty(iSubwinUID, __GO_ISOVIEW__, &isoview, jni_bool, 1);
716             break;
717         case '5':
718         case '6':
719             /* pretty axes */
720             tightLimits = 0;
721             setGraphicObjectProperty(iSubwinUID, __GO_TIGHT_LIMITS__, &tightLimits, jni_bool, 1);
722             break;
723     }
724
725     /* F.Leray 07.05.04 */
726     /* strflag[2] */
727     switch (strflag[2])
728     {
729
730         case '0':
731             getGraphicObjectProperty(iSubwinUID, __GO_FIRST_PLOT__, jni_bool, (void **)&piTmp);
732             firstPlot = iTmp;
733
734             if (firstPlot)
735             {
736                 axisVisible = 0;
737                 /* 0: OFF */
738                 boxType = 0;
739
740                 setGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
741                 setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
742                 /* also trigger z axis */
743                 setGraphicObjectProperty(iSubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
744                 setGraphicObjectProperty(iSubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
745             }
746             /*else no changes : the isaxes properties is driven by the previous plot */
747             break;
748         case '1':
749             axisVisible = 1;
750             /* 1: ON */
751             boxType = 1;
752             /* 4: LEFT */
753             yLocation = 4;
754
755             setGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
756             setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
757             setGraphicObjectProperty(iSubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
758             setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_LOCATION__, &yLocation, jni_int, 1);
759             setGraphicObjectProperty(iSubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
760
761             break;
762         case '2':
763             axisVisible = 0;
764             boxType = 1;
765
766             setGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
767             setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
768             /* also trigger z axis */
769             setGraphicObjectProperty(iSubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
770             setGraphicObjectProperty(iSubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
771
772             break;
773         case '3':
774             axisVisible = 1;
775             boxType = 0;
776             /* 5: RIGHT */
777             yLocation = 5;
778
779             setGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
780             setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
781             setGraphicObjectProperty(iSubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
782             setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_LOCATION__, &yLocation, jni_int, 1);
783             setGraphicObjectProperty(iSubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
784
785             break;
786         case '4':
787             axisVisible = 1;
788             /* 2: MIDDLE */
789             xLocation = 2;
790             yLocation = 2;
791             boxType = 0;
792
793             setGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
794             setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
795             /* also trigger z axis */
796             setGraphicObjectProperty(iSubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
797             setGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_LOCATION__, &xLocation, jni_int, 1);
798             setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_LOCATION__, &yLocation, jni_int, 1);
799             setGraphicObjectProperty(iSubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
800
801             break;
802         case '5':
803             axisVisible = 1;
804             xLocation = 2;
805             yLocation = 2;
806             boxType = 1;
807
808             setGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
809             setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
810             /* also trigger z axis */
811             setGraphicObjectProperty(iSubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
812             setGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_LOCATION__, &xLocation, jni_int, 1);
813             setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_LOCATION__, &yLocation, jni_int, 1);
814             setGraphicObjectProperty(iSubwinUID, __GO_BOX_TYPE__, &boxType, jni_int, 1);
815
816             break;
817         case '9':
818             axisVisible = 1;
819
820             setGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
821             setGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
822             /* also trigger z axis */
823             setGraphicObjectProperty(iSubwinUID, __GO_Z_AXIS_VISIBLE__, &axisVisible, jni_bool, 1);
824     }
825
826     getGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
827     axesVisible[0] = iTmp;
828     getGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
829     axesVisible[1] = iTmp;
830     getGraphicObjectProperty(iSubwinUID, __GO_Z_AXIS_VISIBLE__, jni_bool, (void **)&piTmp);
831     axesVisible[2] = iTmp;
832
833     getGraphicObjectProperty(iSubwinUID, __GO_BOX_TYPE__, jni_int, (void**)&piTmp);
834     boxType = iTmp;
835
836     getGraphicObjectProperty(iSubwinUID, __GO_X_AXIS_LOCATION__, jni_int, (void**)&piTmp);
837     xLocation = iTmp;
838     getGraphicObjectProperty(iSubwinUID, __GO_Y_AXIS_LOCATION__, jni_int, (void**)&piTmp);
839     yLocation = iTmp;
840
841     getGraphicObjectProperty(iSubwinUID, __GO_TIGHT_LIMITS__, jni_bool, (void **)&piTmp);
842     tightLimits = iTmp;
843     getGraphicObjectProperty(iSubwinUID, __GO_ISOVIEW__, jni_bool, (void **)&piTmp);
844     isoview = iTmp;
845
846     /* Find if something has changed */
847     if (axesVisible[0] != axesVisiblePrev[0]
848             || axesVisible[1] != axesVisiblePrev[1]
849             || axesVisible[2] != axesVisiblePrev[2]
850             || xLocation != xLocationPrev || yLocation != yLocationPrev || boxType != boxPrev || tightLimits != tightLimitsPrev || isoview != isoviewPrev)
851     {
852         haschanged = TRUE;
853     }
854     else
855     {
856         haschanged = FALSE;
857     }
858
859     return haschanged;
860 }