fe5aeb8cadc43dc5bfc9c44cf0bc2752a0077c6c
[scilab.git] / scilab / modules / graphics / sci_gateway / c / sci_drawaxis.c
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 /*--------------------------------------------------------------------------*/
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             return 1;
186         }
187         tics = pstTics[0];
188         freeAllocatedSingleString(pstTics);
189     }
190
191     if (opts[7].iPos != -1)
192     {
193         double dblColor = 0;
194         //CheckScalar
195         if (opts[7].iRows != 1 || opts[7].iCols != 1)
196         {
197             Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), fname, opts[7].iPos);
198             freeAllocatedSingleString(format);
199             return 1;
200         }
201
202         getScalarDouble(pvApiCtx, opts[7].piAddr, &dblColor);
203         ticscolor = (int)dblColor;
204     }
205
206     if (opts[8].iPos != -1)
207     {
208         if (getAllocatedMatrixOfString(pvApiCtx, opts[8].piAddr, &opts[8].iRows, &opts[8].iCols, &val))
209         {
210             return 1;
211         }
212     }
213
214     if (opts[9].iPos != -1)
215     {
216         getMatrixOfDouble(pvApiCtx, opts[9].piAddr, &opts[9].iRows, &opts[9].iCols, &x);
217         nx = opts[9].iRows * opts[9].iCols; /* F.Leray OK here opts[9].iRows and opts[9].iCols are integers. */
218     }
219     else
220     {
221         static double x_def[1];
222         double *bounds;
223         int iCurrentSubwinUID = getCurrentSubWin();
224
225         getGraphicObjectProperty(iCurrentSubwinUID, __GO_DATA_BOUNDS__, jni_double_vector, (void **)&bounds);
226         nx = 1;
227         x = x_def;
228         if (dir == 'l')
229         {
230             x_def[0] = bounds[0];    /* xMin */
231         }
232         else if (dir == 'r')
233         {
234             x_def[0] = bounds[1];    /* xMax */
235         }
236     }
237
238     if (opts[10].iPos != -1)
239     {
240         getMatrixOfDouble(pvApiCtx, opts[10].piAddr, &opts[10].iRows, &opts[10].iCols, &y);
241         ny = opts[10].iRows * opts[10].iCols;
242     }
243     else
244     {
245         static double y_def[1];
246         double *bounds;
247         int iCurrentSubwinUID = getCurrentSubWin();
248
249         getGraphicObjectProperty(iCurrentSubwinUID, __GO_DATA_BOUNDS__, jni_double_vector, (void **)&bounds);
250         ny = 1;
251         y = y_def;
252         if (dir == 'd')
253         {
254             y_def[0] = bounds[2];    /* yMin */
255         }
256         else if (dir == 'u')
257         {
258             y_def[0] = bounds[3];    /* yMax */
259         }
260     }
261
262     /* compatibility test */
263     switch (tics)
264     {
265         case 'r':
266             if (check_xy(fname, dir, 3, opts[9].iPos, opts[9].iRows, opts[9].iCols, x,
267                          opts[10].iPos, opts[10].iRows, opts[10].iCols, y, &ntics) == 0)
268             {
269                 ReturnArguments(pvApiCtx);
270                 freeAllocatedSingleString(format);
271                 freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
272                 return 0;
273             }
274             break;
275         case 'i':
276             if (check_xy(fname, dir, 4, opts[9].iPos, opts[9].iRows, opts[9].iCols, x,
277                          opts[10].iPos, opts[10].iRows, opts[10].iCols, y, &ntics) == 0)
278             {
279                 ReturnArguments(pvApiCtx);
280                 freeAllocatedSingleString(format);
281                 freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
282                 return 0;
283             }
284             break;
285         case 'v':
286             if (check_xy(fname, dir, -1, opts[9].iPos, opts[9].iRows, opts[9].iCols, x,
287                          opts[10].iPos, opts[10].iRows, opts[10].iCols, y, &ntics) == 0)
288             {
289                 ReturnArguments(pvApiCtx);
290                 freeAllocatedSingleString(format);
291                 freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
292                 return 0;
293             }
294             break;
295         default:
296             Scierror(999, _("%: Wrong value for %s '%c': '%s', '%s' and '%s' expected.\n"), fname, "tics", dir, "r", "v", "i");
297             freeAllocatedSingleString(format);
298             freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
299             return 0;
300     }
301
302     if (val != NULL)
303     {
304         //CheckLength
305         if (opts[8].iRows * opts[8].iCols != ntics)
306         {
307             Scierror(999, _("%s: Wrong size for input argument #%d: %d expected.\n"), fname, opts[8].iPos, opts[8].iRows * opts[8].iCols);
308             freeAllocatedSingleString(format);
309             freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
310             return 1;
311         }
312
313         nb_tics_labels = opts[8].iRows * opts[8].iCols;
314     }
315
316     Objdrawaxis(dir, tics, x, &nx, y, &ny, val, sub_int, format, fontsize, textcolor, ticscolor, 'n', seg_flag, nb_tics_labels);
317
318     freeAllocatedSingleString(format);
319     if (val != NULL)
320     {
321         freeAllocatedMatrixOfString(opts[8].iRows, opts[8].iCols, val);
322     }
323     createScalarHandle(pvApiCtx, iRhs + 1, getHandle(getCurrentObject()));
324     AssignOutputVariable(pvApiCtx, 1) = iRhs + 1;
325     ReturnArguments(pvApiCtx);
326     return 0;
327 }
328
329 /*--------------------------------------------------------------------------*/
330 static int check_xy(char *fname, char dir, int mn, int xpos,
331                     int xm, int xn, double* pdblX,
332                     int ypos, int yRow, int yCol, double* pdblY,
333                     int *ntics)
334 {
335     switch (dir)
336     {
337         case 'l':
338         case 'r':
339             /* x must be scalar */
340             if (xpos != -1)
341                 //CheckScalar
342                 if (xm != 1 || xn != 1)
343                 {
344                     Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), fname, xpos);
345                     return 1;
346                 }
347
348             /* y must be of size mn */
349             if (mn != -1)
350                 //CheckDims
351                 if (yRow != 1 || yCol != mn)
352                 {
353                     Scierror(999, _("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"), fname, ypos, 1, mn);
354                     return 1;
355                 }
356
357             switch (mn)
358             {
359                 case 3:
360                     *ntics = (int)pdblY[2] + 1;
361                     break;
362                 case 4:
363                     *ntics = (int)pdblY[3] + 1;
364                     break;
365                 case -1:
366                     *ntics = yRow * yCol;
367                     break;
368             }
369             break;
370         case 'u':
371         case 'd':
372             /* y must be scalar */
373             if (ypos != -1)
374                 //CheckScalar
375                 if (yRow != 1 || yCol != 1)
376                 {
377                     Scierror(999, _("%s: Wrong size for input argument #%d: A real scalar expected.\n"), fname, ypos);
378                     return 1;
379                 }
380
381             /* x must be of size mn */
382             if (mn != -1)
383                 //CheckDims
384                 if (xm != 1 || xn != mn)
385                 {
386                     Scierror(999, _("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"), fname, xpos, 1, mn);
387                     return 1;
388                 }
389
390             switch (mn)
391             {
392                 case 3:
393                     *ntics = (int)pdblX[2] + 1;
394                     break;
395                 case 4:
396                     *ntics = (int)pdblX[3] + 1;
397                     break;
398                 case -1:
399                     *ntics = xm * xn;
400                     break;
401             }
402             break;
403         default:
404             Scierror(999, "%s: Wrong value for %s '%c': '%s','%s','%s' and '%s' expected.\n", fname, "dir", dir, "u", "d", "r", "l");
405             return 0;
406     }
407     return 1;
408 }
409
410 /*--------------------------------------------------------------------------*/