Graphics: return a null pointer in C when property does not exist
[scilab.git] / scilab / modules / graphics / src / c / GetProperty.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2001 - 2002 - INRIA - Mathieu Philipe
4  * Copyright (C) 2002 - 2004 - INRIA - Djalel Abdemouche
5  * Copyright (C) 2002 - 2004 - INRIA - Serge Steer
6  * Copyright (C) 2004 - 2006 - INRIA - Fabrice Leray
7  * Copyright (C) 2005 - INRIA - Jean-Baptiste Silvy
8  * Copyright (C) 2010-2012 - DIGITEO - Manuel Juliachs
9  * Copyright (C) 2010 - Paul Griffiths
10  *
11  * This file must be used under the terms of the CeCILL.
12  * This source file is licensed as described in the file COPYING, which
13  * you should have received as part of this distribution.  The terms
14  * are also available at
15  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
16  *
17  */
18
19 /*------------------------------------------------------------------------
20  *    Graphic library
21  *    newGraph Library header
22  *    Comment:
23  *    This file contains all functions used to GET the properties of graphics
24  *    objects.
25  --------------------------------------------------------------------------*/
26
27 #include <stdio.h>
28 #include <string.h>
29
30 #include "GetProperty.h"
31 #include "Scierror.h"
32 #include "InitObjects.h"
33 #include "CurrentFigure.h"
34 #include "GetJavaProperty.h"
35 #include "BasicAlgos.h"
36 #include "localization.h"
37 #include "Axes.h"
38 #include "stack-c.h"
39 #include "HandleManagement.h"
40
41 #include "MALLOC.h" /* MALLOC */
42
43 #include "graphicObjectProperties.h"
44 #include "getGraphicObjectProperty.h"
45 #include "FigureModel.h"
46
47 /**sciGetNumColors
48 * This function gets the number of the color defined in colormap
49 */
50 int
51 sciGetNumColors (char *pobjUID)
52 {
53     if (pobjUID)
54     {
55         char* parentFigure = NULL;
56         int iNumColors = 0;
57         int* piNumColors = &iNumColors;
58
59         getGraphicObjectProperty(pobjUID, __GO_PARENT_FIGURE__, jni_string, (void **)&parentFigure);
60         getGraphicObjectProperty(parentFigure, __GO_COLORMAP_SIZE__, jni_int, (void**)&piNumColors);
61
62         return iNumColors;
63     }
64     return -1;
65 }
66
67 /****************************************** TEXT ******************************
68
69 /**
70 * Checks if a text object is empty #rows*#columns==0 or #rows*#columns==1 and entry is  zero length
71 * This function has been adapted to the MVC: its parameter's type has been changed from sciPointObj to char*
72 * (MVC identifier), the reason being that it is exclusively used to get the properties of Label objects,
73 * which can be only be known by their MVC identifiers at the present moment.
74 */
75 //BOOL sciisTextEmpty(sciPointObj * pobj)
76
77 BOOL sciisTextEmpty(char* identifier)
78 {
79     int nbElements = 0;
80     int* dimensions = NULL;
81
82     getGraphicObjectProperty(identifier, __GO_TEXT_ARRAY_DIMENSIONS__, jni_int_vector, (void **)&dimensions);
83
84     if (dimensions == NULL)
85     {
86         return TRUE;
87     }
88
89     nbElements = dimensions[0] * dimensions[1];
90
91     if (nbElements == 0)
92     {
93         return TRUE;
94     }
95
96     if (nbElements == 1)
97     {
98         char** textMatrix = NULL;
99         getGraphicObjectProperty(identifier, __GO_TEXT_STRINGS__, jni_string_vector, (void **) &textMatrix);
100
101         if (textMatrix[0] == NULL)
102         {
103             return TRUE;
104         }
105         else if (strcmp(textMatrix[0], "") == 0)
106         {
107             /* empty string */
108             return TRUE;
109         }
110
111     }
112
113     return FALSE;
114 }
115
116 /*--------------------------------------------------------------------------*/
117
118 /**sciGetPoint
119 * returns pointer to the points of the entity, and a pointer to the number of points. This function allocates memory for the tab of point, so after using the tab don't forget to free it
120 */
121
122 /**MAJ pour le 3D DJ.Abdemouche 2003**/
123 double *sciGetPoint(char * pthis, int *numrow, int *numcol)
124 {
125     int iType = -1;
126     int *piType = &iType;
127     double *tab = NULL;
128     int i = 0;
129
130     getGraphicObjectProperty(pthis, __GO_TYPE__, jni_int, (void **)&piType);
131
132     /*
133      * Object type determined by string comparisons
134      * Required as we have no better way to do this for the moment
135      */
136
137     switch (iType)
138     {
139         case __GO_FIGURE__ :
140         {
141             int* figurePosition = NULL;
142             int* axesSize = NULL;
143
144             *numrow = 2;
145             *numcol = 2;
146             if ((tab = (double*)CALLOC((*numrow) * (*numcol), sizeof(double))) == NULL)
147             {
148                 *numrow = -1;
149                 *numcol = -1;
150                 return NULL;
151             }
152
153             getGraphicObjectProperty(pthis, __GO_POSITION__, jni_int_vector, (void **)&figurePosition);
154             getGraphicObjectProperty(pthis, __GO_AXES_SIZE__, jni_int_vector, (void **)&axesSize);
155
156             tab[0] = (double) figurePosition[0];
157             tab[1] = (double) figurePosition[1];
158             tab[2] = (double) axesSize[0];
159             tab[3] = (double) axesSize[1];
160
161             return tab;
162         }
163         case __GO_POLYLINE__ :
164         {
165             char* parentAxes = NULL;
166             double* dataX = NULL;
167             double* dataY = NULL;
168             double* dataZ = NULL;
169             int iTmp = 0;
170             int* piTmp = &iTmp;
171             int iView = 0;
172             int *piView = &iView;
173
174             /*
175              * Testing whether data properties exist for this object
176              * is currently done only for this property. The type comparison already
177              * ensures that this is the case, though doing so is awkward.
178              */
179             getGraphicObjectProperty(pthis, __GO_DATA_MODEL_NUM_ELEMENTS__, jni_int, (void**)&piTmp);
180
181             if (piTmp == NULL)
182             {
183                 *numrow = -2;
184                 *numcol = -2;
185                 return NULL;
186             }
187
188             *numrow = iTmp;
189
190             getGraphicObjectProperty(pthis, __GO_DATA_MODEL_Z_COORDINATES_SET__, jni_int, (void**)&piTmp);
191
192             if (iTmp)
193             {
194                 *numcol = 3;
195             }
196             else
197             {
198                 *numcol = 2;
199             }
200
201             if ((*numrow) * (*numcol) == 0)
202             {
203                 /* empty data, no warnings */
204                 *numrow = 0;
205                 *numcol = 0;
206                 return NULL;
207             }
208
209             getGraphicObjectProperty(pthis, __GO_PARENT_AXES__, jni_string, (void **)&parentAxes);
210             getGraphicObjectProperty(parentAxes, __GO_VIEW__, jni_int, (void**)&piView);
211
212             getGraphicObjectProperty(pthis, __GO_DATA_MODEL_X__, jni_double_vector, (void **)&dataX);
213             getGraphicObjectProperty(pthis, __GO_DATA_MODEL_Y__, jni_double_vector, (void **)&dataY);
214
215             if (*numcol == 2 && iView)
216             {
217                 *numcol = (*numcol) + 1; /* colonne de 0. a prendre en compte / afficher => numcol+1*/
218                 if ((tab = (double*)CALLOC((*numrow) * (*numcol), sizeof(double))) == NULL)
219                 {
220                     *numrow = -1;
221                     *numcol = -1;
222                     return NULL;
223                 }
224
225                 for (i = 0 ; i < *numrow ; i++)
226                 {
227                     tab[i] = dataX[i];
228                     tab[*numrow + i] = dataY[i];
229                     tab[(2 * (*numrow)) + i] = 0.;
230                 }
231             }
232             else
233             {
234                 if ((tab = (double*)CALLOC((*numrow) * (*numcol), sizeof(double))) == NULL)
235                 {
236                     *numrow = -1;
237                     *numcol = -1;
238                     return NULL;
239                 }
240
241                 if (*numcol == 3)
242                 {
243                     getGraphicObjectProperty(pthis, __GO_DATA_MODEL_Z__, jni_double_vector, (void **)&dataZ);
244                 }
245
246                 for (i = 0 ; i < *numrow ; i++)
247                 {
248                     tab[i] = dataX[i];
249                     tab[*numrow + i] = dataY[i];
250                     if (*numcol == 3)
251                     {
252                         tab[(2 * (*numrow)) + i] = dataZ[i];
253                     }
254                 }
255
256             }
257             return tab;
258         }
259         case __GO_RECTANGLE__ :
260         {
261             char* parentAxes = NULL;
262             double* upperLeftPoint = NULL;
263             double width = 0.0;
264             double *pdblWidth = &width;
265             double height = 0.0;
266             double *pdblHeight = &height;
267             int iView = 0;
268             int *piView = &iView;
269
270             *numrow = 1;
271
272             getGraphicObjectProperty(pthis, __GO_PARENT_AXES__, jni_string, (void **)&parentAxes);
273             getGraphicObjectProperty(parentAxes, __GO_VIEW__, jni_int, (void**)&piView);
274
275             *numcol = iView ? 5 : 4;
276
277             if ((tab = (double*)CALLOC((*numrow) * (*numcol), sizeof(double))) == NULL)
278             {
279                 *numrow = -1;
280                 *numcol = -1;
281                 return NULL;
282             }
283
284             getGraphicObjectProperty(pthis, __GO_UPPER_LEFT_POINT__, jni_double_vector, (void **)&upperLeftPoint);
285
286             getGraphicObjectProperty(pthis, __GO_WIDTH__, jni_double, (void**)&pdblWidth);
287             getGraphicObjectProperty(pthis, __GO_HEIGHT__, jni_double, (void **)&pdblHeight);
288
289             tab[0] = upperLeftPoint[0];
290             tab[1] = upperLeftPoint[1];
291
292             if (iView)
293             {
294                 tab[2] = upperLeftPoint[2];
295                 tab[3] = width;
296                 tab[4] = height;
297             }
298             else
299             {
300                 tab[2] = width;
301                 tab[3] = height;
302             }
303             return (double*)tab;
304         }
305         case __GO_ARC__ :
306         {
307             char* parentAxes = NULL;
308             double* upperLeftPoint = NULL;
309             double width = 0.0;
310             double *pdblWidth = &width;
311
312             double height = 0.;
313             double *pdblHeight = &height;
314
315             double startAngle = 0.;
316             double *pdblStartAngle = &startAngle;
317             double endAngle = 0.;
318             double *pdblEndAngle = &endAngle;
319             int view = 0;
320             int *piView = &view;
321
322             *numrow = 1;
323
324             getGraphicObjectProperty(pthis, __GO_PARENT_AXES__, jni_string, (void **)&parentAxes);
325             getGraphicObjectProperty(parentAxes, __GO_VIEW__, jni_int, (void**)&piView);
326
327             *numcol = view ? 7 : 6;
328
329             if ((tab = (double*)CALLOC((*numrow) * (*numcol), sizeof(double))) == NULL)
330             {
331                 *numrow = -1;
332                 *numcol = -1;
333                 return NULL;
334             }
335
336             getGraphicObjectProperty(pthis, __GO_UPPER_LEFT_POINT__, jni_double_vector, (void **)&upperLeftPoint);
337
338             getGraphicObjectProperty(pthis, __GO_WIDTH__, jni_double, (void **)&pdblWidth);
339             getGraphicObjectProperty(pthis, __GO_HEIGHT__, jni_double, (void **)&pdblHeight);
340
341             getGraphicObjectProperty(pthis, __GO_START_ANGLE__, jni_double, (void **)&pdblStartAngle);
342             getGraphicObjectProperty(pthis, __GO_END_ANGLE__, jni_double, (void **)&pdblEndAngle);
343
344             tab[0] = upperLeftPoint[0];
345             tab[1] = upperLeftPoint[1];
346
347             if (view)
348             {
349                 tab[2] = upperLeftPoint[2];
350                 tab[3] = width;
351                 tab[4] = height;
352                 tab[5] = RAD2DEG(startAngle);
353                 tab[6] = RAD2DEG(endAngle);
354             }
355             else
356             {
357                 tab[2] = width;
358                 tab[3] = height;
359                 tab[4] = RAD2DEG(startAngle);
360                 tab[5] = RAD2DEG(endAngle);
361             }
362
363             return (double*)tab;
364         }
365         case __GO_COMPOUND__ :
366         {
367             return (double*)NULL;
368         }
369         case __GO_TEXT__ :
370         {
371             char* parentAxes = NULL;
372             double* textPosition = NULL;
373             int iView = 0;
374             int* piView = &iView;
375
376             *numrow = 1;
377
378             getGraphicObjectProperty(pthis, __GO_PARENT_AXES__, jni_string, (void **)&parentAxes);
379             getGraphicObjectProperty(parentAxes, __GO_VIEW__, jni_int, (void**)&piView);
380
381             *numcol = iView ? 3 : 2;
382
383             if ((tab = (double*)CALLOC((*numrow) * (*numcol), sizeof(double))) == NULL)
384             {
385                 *numrow = -1;
386                 *numcol = -1;
387                 return NULL;
388             }
389
390             getGraphicObjectProperty(pthis, __GO_POSITION__, jni_double_vector, (void **)&textPosition);
391
392             tab[0] = textPosition[0];
393             tab[1] = textPosition[1];
394
395             if (iView)
396             {
397                 tab[2] = textPosition[2];
398             }
399
400             return (double*)tab;
401         }
402         case __GO_SEGS__ :
403         {
404             int iView = 0;
405             int* piView = &iView;
406             int iNumArrows = 0;
407             int* piNumArrows = &iNumArrows;
408             char* parentAxes = NULL;
409             double* arrowBases = NULL;
410             double* arrowDirections = NULL;
411
412             getGraphicObjectProperty(pthis, __GO_NUMBER_ARROWS__, jni_int, (void**)&piNumArrows);
413             *numrow = iNumArrows;
414
415             /* only two coordinates are displayed if the axe is in 2d
416             and the z coordinates has never been modified */
417
418             getGraphicObjectProperty(pthis, __GO_PARENT_AXES__, jni_string, (void **)&parentAxes);
419
420             getGraphicObjectProperty(parentAxes, __GO_VIEW__, jni_int, (void**)&piView);
421
422             if (iView == 0) // 2-D
423             {
424                 *numcol = 2;
425             }
426             else // 3-D
427             {
428                 *numcol = 3;
429             }
430
431             if ((tab = (double*)CALLOC(2 * (*numrow) * (*numcol), sizeof(double))) == NULL)
432             {
433                 *numrow = -1;
434                 *numcol = -1;
435                 return NULL;
436             }
437
438             getGraphicObjectProperty(pthis, __GO_BASE__, jni_double_vector, (void **)&arrowBases);
439             getGraphicObjectProperty(pthis, __GO_DIRECTION__, jni_double_vector, (void **)&arrowDirections);
440
441             for (i = 0; i < *numrow; i++)
442             {
443                 tab[2 * i] = arrowBases[3 * i];
444                 tab[2 * i + 1] = arrowDirections[3 * i];
445                 tab[2 * (*numrow) + 2 * i] = arrowBases[3 * i + 1];
446                 tab[2 * (*numrow) + 2 * i + 1] = arrowDirections[3 * i + 1];
447                 if (*numcol == 3)
448                 {
449                     tab[4 * (*numrow) + 2 * i] = arrowBases[3 * i + 2];
450                     tab[4 * (*numrow) + 2 * i + 1] = arrowDirections[3 * i + 2];
451                 }
452             }
453
454             /* There are twice as many points as arrows (2 endpoints) */
455             *numrow = 2 * (*numrow);
456
457             return (double*)tab;
458         }
459         case __GO_FAC3D__ :
460         case __GO_PLOT3D__ :
461         {
462             *numrow = -1;
463             *numcol = -1;
464             return (double*) NULL;
465         }
466         case __GO_MATPLOT__ :
467         {
468             int nx = 0;
469             int *piNx = &nx;
470             int ny = 0;
471             int *piNy = &ny;
472             double* data;
473
474             getGraphicObjectProperty(pthis, __GO_DATA_MODEL_NUM_X__, jni_int, (void**)&piNx);
475
476             getGraphicObjectProperty(pthis, __GO_DATA_MODEL_NUM_Y__, jni_int, (void**)&piNy);
477
478             /* The z data matrix has (ny-1) rows and (nx-1) cols */
479             nx = nx - 1;
480             ny = ny - 1;
481
482             *numrow = ny;
483             *numcol = nx;
484
485             if ((tab = (double*)CALLOC(nx * ny, sizeof(double))) == NULL)
486             {
487                 *numrow = -1;
488                 *numcol = -1;
489                 return (double*)NULL;
490             }
491
492             getGraphicObjectProperty(pthis, __GO_DATA_MODEL_Z__, jni_double_vector, (void **)&data);
493
494             for (i = 0; i < nx * ny; i++)
495             {
496                 tab[i] = data[i];
497             }
498
499             return (double*)tab;
500         }
501         case __GO_FEC__ :
502         {
503             double* coordinates = NULL;
504             double* values = NULL;
505             int iTmp = 0;
506             int* piTmp = &iTmp;
507
508             *numcol = 3;
509
510             getGraphicObjectProperty(pthis, __GO_DATA_MODEL_NUM_VERTICES__, jni_int, (void**)&piTmp);
511             *numrow = iTmp;
512
513             if ((tab = (double*)CALLOC(*numrow * 3, sizeof(double))) == NULL)
514             {
515                 *numrow = -1;
516                 *numcol = -1;
517                 return (double*)NULL;
518             }
519
520             getGraphicObjectProperty(pthis, __GO_DATA_MODEL_COORDINATES__, jni_double_vector, (void **)&coordinates);
521             getGraphicObjectProperty(pthis, __GO_DATA_MODEL_VALUES__, jni_double_vector, (void **)&values);
522
523             for (i = 0; i < *numrow; i++)
524             {
525                 tab[i] = coordinates[3 * i];
526                 tab[*numrow + i] = coordinates[3 * i + 1];
527                 tab[*numrow * 2 + i] = values[i];
528
529             }
530
531             return (double*)tab;
532         }
533         case __GO_LEGEND__ :
534         case __GO_AXES__ :
535         case __GO_LABEL__ :
536         default :
537         {
538             *numrow = -2;
539             *numcol = -2;
540             return (double*)NULL;
541         }
542     }
543 #if 0
544 case SCI_UIMENU:
545 #endif
546     return (double*)NULL;
547 }
548
549 /*-------------------------------------------------------------------------------*/
550 BOOL sciGetLegendDefined(char * pObjUID)
551 {
552     char* xLabelId = NULL;
553     char* yLabelId = NULL;
554     char* zLabelId = NULL;
555
556     if (pObjUID == NULL)
557     {
558         return FALSE;
559     }
560
561     getGraphicObjectProperty(pObjUID, __GO_X_AXIS_LABEL__, jni_string, (void **)&xLabelId);
562     getGraphicObjectProperty(pObjUID, __GO_Y_AXIS_LABEL__, jni_string, (void **)&yLabelId);
563     getGraphicObjectProperty(pObjUID, __GO_Z_AXIS_LABEL__, jni_string, (void **)&zLabelId);
564
565     /* get the text size of labels */
566     if (sciisTextEmpty(xLabelId) &&
567             sciisTextEmpty(yLabelId) &&
568             sciisTextEmpty(zLabelId))
569     {
570         return FALSE;
571     }
572     else
573     {
574         return TRUE;
575     }
576 }
577 /*-----------------------------------------------------------------------------------*/
578 /**
579 * Copy the logflags of a subwin to an array of size 3.
580 */
581 void sciGetLogFlags(char * pObjUID, char flags[3])
582 {
583     int const logflagPropertyNames[3] = {__GO_X_AXIS_LOG_FLAG__, __GO_Y_AXIS_LOG_FLAG__, __GO_Z_AXIS_LOG_FLAG__};
584     int i = 0;
585     int iLogFlag = 0;
586     int* piLogFlag = &iLogFlag;
587
588     for (i = 0; i < 3; i++)
589     {
590         getGraphicObjectProperty(pObjUID, logflagPropertyNames[i], jni_bool, (void **)&piLogFlag);
591
592         if (piLogFlag == NULL)
593         {
594             printSetGetErrorMessage("log_flags");
595             return;
596         }
597
598         if (iLogFlag)
599         {
600             flags[i] = 'l';
601         }
602         else
603         {
604             flags[i] = 'n';
605         }
606     }
607 }
608 /*----------------------------------------------------------------------------------*/
609 /**
610 * Convert user coordinates to user cooordinates (2D).
611 * @param pObjUID subwindow identifier
612 * @param userCoord3D user coordinates
613 * @param userCoords2D result in user coordinates in the default 2D plane.
614 */
615 void sciGet2dViewCoordinate(char * pObjUID, const double userCoords3D[3], double userCoords2D[2])
616 {
617     int iType = -1;
618     int *piType = &iType;
619
620     getGraphicObjectProperty(pObjUID, __GO_TYPE__, jni_int, (void **)&piType);
621
622     if (iType == __GO_AXES__)
623     {
624         sciGetJava2dViewCoordinates(pObjUID, userCoords3D, userCoords2D);
625     }
626     else
627     {
628         Scierror(999, _("Coordinates modifications are only applicable on axes objects.\n"));
629         userCoords2D[0] = 0.0;
630         userCoords2D[1] = 0.0;
631     }
632 }
633 /*----------------------------------------------------------------------------------*/
634 /**
635 * Convert pixel coordinates to 2D view coordinate
636 * @param pObjUID subwindow identifier
637 * @param userCoord pixel coordinates
638 * @param userCoords2D user coordinates in default 2D plane
639 */
640 void sciGet2dViewCoordFromPixel(char * pObjUID, const int pixelCoords[2], double userCoords2D[2])
641 {
642     int iType = -1;
643     int *piType = &iType;
644
645     getGraphicObjectProperty(pObjUID, __GO_TYPE__, jni_int, (void **)&piType);
646
647     if (iType == __GO_AXES__)
648     {
649         sciGetJava2dViewCoordFromPixel(pObjUID, pixelCoords, userCoords2D);
650     }
651     else
652     {
653         Scierror(999, _("Coordinates modifications are only applicable on axes objects.\n"));
654         userCoords2D[0] = 0.0;
655         userCoords2D[1] = 0.0;
656     }
657 }
658 /*----------------------------------------------------------------------------------*/
659 /**
660 * Convert 2d view coordinates to pixel coordinates
661 * @param pObjUID subwindow identifier
662 * @param userCoords2D coordinates in the default 2D plane
663 * @param pixelsCoords pixel coordinates
664 */
665 void sciGet2dViewPixelCoordinates(char * pObjUID, const double userCoords2D[2], int pixelCoords[2])
666 {
667     int iType = -1;
668     int *piType = &iType;
669
670     getGraphicObjectProperty(pObjUID, __GO_TYPE__, jni_int, (void **)&piType);
671
672     if (iType == __GO_AXES__)
673     {
674         /* create a 3d user coord */
675         double userCoord3D[3] = {userCoords2D[0], userCoords2D[1], 0.0};
676         sciGetJava2dViewPixelCoordinates(pObjUID, userCoord3D, pixelCoords);
677     }
678     else
679     {
680         Scierror(999, _("Coordinates modifications are only applicable on axes objects.\n"));
681         pixelCoords[0] = -1;
682         pixelCoords[1] = -1;
683     }
684 }
685 /*----------------------------------------------------------------------------------*/
686 /**
687 * Get the viewing area of a subwindow acoording to its axes scale and margins
688 * result is in pixels
689 */
690 void sciGetViewingArea(char * pObjUID, int * xPos, int * yPos, int * width, int * height)
691 {
692     int iType = -1;
693     int *piType = &iType;
694
695     getGraphicObjectProperty(pObjUID, __GO_TYPE__, jni_int, (void **)&piType);
696
697     if (iType == __GO_AXES__)
698     {
699         sciGetJavaViewingArea(pObjUID, xPos, yPos, width, height);
700     }
701     else
702     {
703         *xPos = -1;
704         *yPos = -1;
705         *width = -1;
706         *height = -1;
707         Scierror(999, _("Only axes handles have a viewing area."));
708     }
709 }
710 /*----------------------------------------------------------------------------------*/
711 /**
712 * Print the message "This object has no xxx property." in Scilab.
713 */
714 void printSetGetErrorMessage(const char * propertyName)
715 {
716     Scierror(999, _("This object has no %s property.\n"), propertyName);
717 }
718 /*----------------------------------------------------------------------------------*/
719