1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2006 - INRIA - Fabrice Leray
4  * Copyright (C) 2006 - INRIA - Jean-Baptiste Silvy
5  * Copyright (C) 2011 - DIGITEO - Manuel Juliachs
6  * Copyright (C) 2011 - DIGITEO - Bruno JOFRET
7  *
8  * Copyright (C) 2012 - 2016 - Scilab Enterprises
9  *
10  * This file is hereby licensed under the terms of the GNU GPL v2.0,
11  * pursuant to article 5.3.4 of the CeCILL v.2.1.
12  * This file was originally licensed under the terms of the CeCILL v2.1,
13  * and continues to be available under such terms.
14  * For more information, see the COPYING file which you should have received
15  * along with this program.
16  *
17  */
18 
19 /*------------------------------------------------------------------------*/
20 /* file: sci_drawaxis.c                                                   */
21 /* desc : interface for sci_drawaxis routine                              */
22 /*------------------------------------------------------------------------*/
23 
24 #include "gw_graphics.h"
25 #include "api_scilab.h"
26 #include "GetProperty.h"
27 #include "sciCall.h"
28 #include "Scierror.h"
29 #include "localization.h"
30 #include "BuildObjects.h"
31 
32 #include "getGraphicObjectProperty.h"
33 #include "graphicObjectProperties.h"
34 #include "CurrentSubwin.h"
35 #include "HandleManagement.h"
36 
37 /*--------------------------------------------------------------------------*/
38 // get_optionals not yet managed
39 /*--------------------------------------------------------------------------*/
40 static int check_xy(char *fname, char dir, int mn, int xpos, int xm, int xn,
41                     double* pdblX, int ypos, int yRow, int yCol, double* pdblY, int *ntics);
42 
43 /*--------------------------------------------------------------------------*/
sci_drawaxis(char * fname,void * pvApiCtx)44 int sci_drawaxis(char *fname, void* pvApiCtx)
45 {
46     /** XXXXX : un point en suspens c'est le "S" ou une adresse est
47      *  stockees ds un unsigned long : est ce sufisant ?
48      */
49     static rhs_opts opts[] =
50     {
51         { -1, "dir", -1, 0, 0, NULL},
52         { -1, "fontsize", -1, 0, 0, NULL},
53         { -1, "format_n", -1, 0, 0, NULL},
54         { -1, "seg", -1, 0, 0, NULL},
55         { -1, "sub_int", -1, 0, 0, NULL},
56         { -1, "textcolor", -1, 0, 0, NULL},
57         { -1, "tics", -1, 0, 0, NULL},
58         { -1, "ticscolor", -1, 0, 0, NULL},
59         { -1, "val", -1, 0, 0, NULL},
60         { -1, "x", -1, 0, 0, NULL},
61         { -1, "y", -1, 0, 0, NULL},
62         { -1, NULL, -1, 0, 0, NULL}
63     };
64 
65     int iSubwinUID = 0;
66     int minrhs = -1, maxrhs = 0, minlhs = 0, maxlhs = 1, nopt = 0;
67     char dir = 'l', *format = NULL, tics = 'v', **val = NULL;
68     int fontsize = -1, sub_int = 2, seg_flag = 1, textcolor = -1, ticscolor = -1;
69     double *x = NULL, *y = NULL;
70     int nx = 0, ny = 0, ntics;
71     int nb_tics_labels = -1;
72     int iRhs = nbInputArgument(pvApiCtx);
73 
74     nopt = NumOpt(pvApiCtx);
75 
76     CheckInputArgument(pvApiCtx, minrhs, maxrhs + nopt);
77     CheckOutputArgument(pvApiCtx, minlhs, maxlhs);
78 
79     if (getOptionals(pvApiCtx, fname, opts) == 0)
80     {
81         /* error */
82         return 0;
83     }
84 
85     iSubwinUID = getOrCreateDefaultSubwin();
86 
87     if (opts[0].iPos != -1)
88     {
89         char* pstDir = NULL;
90         //CheckLength
91         if (opts[0].iRows != 1 || opts[0].iCols != 1)
92         {
93             Scierror(999, _("%s: Wrong size for input argument #%d: %d expected.\n"), fname, opts[0].iPos, opts[0].iRows);
94             return 1;
95         }
96 
97         if (getAllocatedSingleString(pvApiCtx, opts[0].piAddr, &pstDir))
98         {
99             return 1;
100         }
101         dir = pstDir[0];
102         freeAllocatedSingleString(pstDir);
103     }
104     if (opts[1].iPos != -1)
105     {
106         double dblSize = 0;
107         //CheckScalar
108         if (opts[1].iRows != 1 || opts[1].iCols != 1)
109         {
110             Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), fname, opts[1].iPos);
111             return 1;
112         }
113 
114         getScalarDouble(pvApiCtx, opts[1].piAddr, &dblSize);
115         fontsize = (int)dblSize;
116     }
117     if (opts[2].iPos != -1)
118     {
119         /* verfier ce que l'on recoit avec "" XXX */
120         if (getAllocatedSingleString(pvApiCtx, opts[2].piAddr, &format))
121         {
122             return 1;
123         }
124     }
125 
126     if (opts[3].iPos != -1)
127     {
128         double dblSeq = 0;
129         //CheckScalar
130         if (opts[3].iRows != 1 || opts[3].iCols != 1)
131         {
132             Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), fname, opts[3].iPos);
133             freeAllocatedSingleString(format);
134             return 1;
135         }
136 
137 
138         getScalarDouble(pvApiCtx, opts[3].piAddr, &dblSeq);
139         seg_flag = (int)dblSeq;
140     }
141 
142     if (opts[4].iPos != -1)
143     {
144         double dblSub = 0;
145         //CheckScalar
146         if (opts[4].iRows != 1 || opts[4].iCols != 1)
147         {
148             Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), fname, opts[4].iPos);
149             freeAllocatedSingleString(format);
150             return 1;
151         }
152 
153         getScalarDouble(pvApiCtx, opts[4].piAddr, &dblSub);
154         sub_int = (int)dblSub;
155     }
156 
157     if (opts[5].iPos != -1)
158     {
159         double dblColor = 0;
160         //CheckScalar
161         if (opts[5].iRows != 1 || opts[5].iCols != 1)
162         {
163             Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), fname, opts[5].iPos);
164             freeAllocatedSingleString(format);
165             return 1;
166         }
167 
168         getScalarDouble(pvApiCtx, opts[5].piAddr, &dblColor);
169         textcolor = (int)dblColor;
170     }
171 
172     if (opts[6].iPos != -1)
173     {
174         char* pstTics = NULL;
175         //CheckLength
176         if (opts[6].iRows != 1 || opts[6].iCols != 1)
177         {
178             Scierror(999, _("%s: Wrong size for input argument #%d: %d expected.\n"), fname, opts[6].iPos, opts[6].iRows);
179             freeAllocatedSingleString(format);
180             return 1;
181         }
182 
183         if (getAllocatedSingleString(pvApiCtx, opts[6].piAddr, &pstTics))
184         {
185             freeAllocatedSingleString(format);
186             return 1;
187         }
188         tics = pstTics[0];
189         freeAllocatedSingleString(pstTics);
190     }
191 
192     if (opts[7].iPos != -1)
193     {
194         double dblColor = 0;
195         //CheckScalar
196         if (opts[7].iRows != 1 || opts[7].iCols != 1)
197         {
198             Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), fname, opts[7].iPos);
199             freeAllocatedSingleString(format);
200             return 1;
201         }
202 
203         getScalarDouble(pvApiCtx, opts[7].piAddr, &dblColor);
204         ticscolor = (int)dblColor;
205     }
206 
207     if (opts[8].iPos != -1)
208     {
209         if (getAllocatedMatrixOfString(pvApiCtx, opts[8].piAddr, &opts[8].iRows, &opts[8].iCols, &val))
210         {
211             freeAllocatedSingleString(format);
212             return 1;
213         }
214     }
215 
216     if (opts[9].iPos != -1)
217     {
218         getMatrixOfDouble(pvApiCtx, opts[9].piAddr, &opts[9].iRows, &opts[9].iCols, &x);
219         nx = opts[9].iRows * opts[9].iCols; /* F.Leray OK here opts[9].iRows and opts[9].iCols are integers. */
220     }
221     else
222     {
223         static double x_def[1];
224         double *bounds;
225         int iCurrentSubwinUID = getCurrentSubWin();
226 
227         getGraphicObjectProperty(iCurrentSubwinUID, __GO_DATA_BOUNDS__, jni_double_vector, (void **)&bounds);
228         if (!bounds)
229         {
230             freeAllocatedSingleString(format);
231             freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
232             return 1;
233         }
234         nx = 1;
235         x = x_def;
236         if (dir == 'l')
237         {
238             x_def[0] = bounds[0];    /* xMin */
239         }
240         else if (dir == 'r')
241         {
242             x_def[0] = bounds[1];    /* xMax */
243         }
244     }
245 
246     if (opts[10].iPos != -1)
247     {
248         getMatrixOfDouble(pvApiCtx, opts[10].piAddr, &opts[10].iRows, &opts[10].iCols, &y);
249         ny = opts[10].iRows * opts[10].iCols;
250     }
251     else
252     {
253         static double y_def[1];
254         double *bounds;
255         int iCurrentSubwinUID = getCurrentSubWin();
256 
257         getGraphicObjectProperty(iCurrentSubwinUID, __GO_DATA_BOUNDS__, jni_double_vector, (void **)&bounds);
258         if (!bounds)
259         {
260             freeAllocatedSingleString(format);
261             freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
262             return 1;
263         }
264         ny = 1;
265         y = y_def;
266         if (dir == 'd')
267         {
268             y_def[0] = bounds[2];    /* yMin */
269         }
270         else if (dir == 'u')
271         {
272             y_def[0] = bounds[3];    /* yMax */
273         }
274     }
275 
276     /* compatibility test */
277     switch (tics)
278     {
279         case 'r':
280             if (check_xy(fname, dir, 3, opts[9].iPos, opts[9].iRows, opts[9].iCols, x,
281                          opts[10].iPos, opts[10].iRows, opts[10].iCols, y, &ntics) == 0)
282             {
283                 ReturnArguments(pvApiCtx);
284                 freeAllocatedSingleString(format);
285                 freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
286                 return 0;
287             }
288             break;
289         case 'i':
290             if (check_xy(fname, dir, 4, opts[9].iPos, opts[9].iRows, opts[9].iCols, x,
291                          opts[10].iPos, opts[10].iRows, opts[10].iCols, y, &ntics) == 0)
292             {
293                 ReturnArguments(pvApiCtx);
294                 freeAllocatedSingleString(format);
295                 freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
296                 return 0;
297             }
298             break;
299         case 'v':
300             if (check_xy(fname, dir, -1, opts[9].iPos, opts[9].iRows, opts[9].iCols, x,
301                          opts[10].iPos, opts[10].iRows, opts[10].iCols, y, &ntics) == 0)
302             {
303                 ReturnArguments(pvApiCtx);
304                 freeAllocatedSingleString(format);
305                 freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
306                 return 0;
307             }
308             break;
309         default:
310             Scierror(999, _("%s: Wrong value for %s '%c': '%s', '%s' and '%s' expected.\n"), fname, "tics", dir, "r", "v", "i");
311             freeAllocatedSingleString(format);
312             freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
313             return 0;
314     }
315 
316     if (val != NULL)
317     {
318         //CheckLength
319         if (opts[8].iRows * opts[8].iCols != ntics)
320         {
321             Scierror(999, _("%s: Wrong size for input argument #%d: %d expected.\n"), fname, opts[8].iPos, opts[8].iRows * opts[8].iCols);
322             freeAllocatedSingleString(format);
323             freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
324             return 1;
325         }
326 
327         nb_tics_labels = opts[8].iRows * opts[8].iCols;
328     }
329 
330     Objdrawaxis(dir, tics, x, &nx, y, &ny, val, sub_int, format, fontsize, textcolor, ticscolor, 'n', seg_flag, nb_tics_labels);
331 
332     freeAllocatedSingleString(format);
333     if (val != NULL)
334     {
335         freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
336     }
337     createScalarHandle(pvApiCtx, iRhs + 1, getHandle(getCurrentObject()));
338     AssignOutputVariable(pvApiCtx, 1) = iRhs + 1;
339     ReturnArguments(pvApiCtx);
340     return 0;
341 }
342 
343 /*--------------------------------------------------------------------------*/
check_xy(char * fname,char dir,int mn,int xpos,int xm,int xn,double * pdblX,int ypos,int yRow,int yCol,double * pdblY,int * ntics)344 static int check_xy(char *fname, char dir, int mn, int xpos,
345                     int xm, int xn, double* pdblX,
346                     int ypos, int yRow, int yCol, double* pdblY,
347                     int *ntics)
348 {
349     switch (dir)
350     {
351         case 'l':
352         case 'r':
353             /* x must be scalar */
354             if (xpos != -1)
355                 //CheckScalar
356                 if (xm != 1 || xn != 1)
357                 {
358                     Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), fname, xpos);
359                     return 1;
360                 }
361 
362             /* y must be of size mn */
363             if (mn != -1)
364                 //CheckDims
365                 if (yRow != 1 || yCol != mn)
366                 {
367                     Scierror(999, _("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"), fname, ypos, 1, mn);
368                     return 1;
369                 }
370 
371             switch (mn)
372             {
373                 case 3:
374                     *ntics = (int)pdblY[2] + 1;
375                     break;
376                 case 4:
377                     *ntics = (int)pdblY[3] + 1;
378                     break;
379                 case -1:
380                     *ntics = yRow * yCol;
381                     break;
382             }
383             break;
384         case 'u':
385         case 'd':
386             /* y must be scalar */
387             if (ypos != -1)
388                 //CheckScalar
389                 if (yRow != 1 || yCol != 1)
390                 {
391                     Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), fname, ypos);
392                     return 1;
393                 }
394 
395             /* x must be of size mn */
396             if (mn != -1)
397                 //CheckDims
398                 if (xm != 1 || xn != mn)
399                 {
400                     Scierror(999, _("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"), fname, xpos, 1, mn);
401                     return 1;
402                 }
403 
404             switch (mn)
405             {
406                 case 3:
407                     *ntics = (int)pdblX[2] + 1;
408                     break;
409                 case 4:
410                     *ntics = (int)pdblX[3] + 1;
411                     break;
412                 case -1:
413                     *ntics = xm * xn;
414                     break;
415             }
416             break;
417         default:
418             Scierror(999, "%s: Wrong value for %s '%c': '%s','%s','%s' and '%s' expected.\n", fname, "dir", dir, "u", "d", "r", "l");
419             return 0;
420     }
421     return 1;
422 }
423 
424 /*--------------------------------------------------------------------------*/
425