Code coverage tests

This page documents the degree to which the PARI/GP source code is tested by our public test suite, distributed with the source distribution in directory src/test/. This is measured by the gcov utility; we then process gcov output using the lcov frond-end.

We test a few variants depending on Configure flags on the pari.math.u-bordeaux1.fr machine (x86_64 architecture), and agregate them in the final report:

The target is 90% coverage for all mathematical modules (given that branches depending on DEBUGLEVEL or DEBUGMEM are not covered). This script is run to produce the results below.

LCOV - code coverage report
Current view: top level - graph - plotport.c (source / functions) Hit Total Coverage
Test: PARI/GP v2.8.0 lcov report (development 17240-4611fa9) Lines: 896 1269 70.6 %
Date: 2014-12-21 Functions: 79 95 83.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 372 753 49.4 %

           Branch data     Line data    Source code
       1                 :            : /* Copyright (C) 2000  The PARI group.
       2                 :            : 
       3                 :            : This file is part of the PARI/GP package.
       4                 :            : 
       5                 :            : PARI/GP is free software; you can redistribute it and/or modify it under the
       6                 :            : terms of the GNU General Public License as published by the Free Software
       7                 :            : Foundation. It is distributed in the hope that it will be useful, but WITHOUT
       8                 :            : ANY WARRANTY WHATSOEVER.
       9                 :            : 
      10                 :            : Check the License for details. You should have received a copy of it, along
      11                 :            : with the package; see the file 'COPYING'. If not, write to the Free Software
      12                 :            : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
      13                 :            : 
      14                 :            : /*******************************************************************/
      15                 :            : /*                                                                 */
      16                 :            : /*                         PLOT ROUTINES                           */
      17                 :            : /*                                                                 */
      18                 :            : /*******************************************************************/
      19                 :            : #include "pari.h"
      20                 :            : #include "paripriv.h"
      21                 :            : #include "rect.h"
      22                 :            : 
      23                 :            : void postdraw0(long *w, long *x, long *y, long lw, long scale);
      24                 :            : static void PARI_get_psplot(void);
      25                 :            : 
      26                 :            : /* no need for THREAD: OK to share this */
      27                 :            : static hashtable *rgb_colors = NULL;
      28                 :            : PariRect *rectgraph[18]; /*NUMRECT*/
      29                 :            : 
      30                 :            : /* no need for THREAD: gp-specific */
      31                 :            : static long current_color[18]; /*NUMRECT*/
      32                 :            : 
      33                 :            : PARI_plot pari_plot, pari_psplot;
      34                 :            : PARI_plot *pari_plot_engine = &pari_plot;
      35                 :            : long rectpoint_itype = 0, rectline_itype  = 0;
      36                 :            : 
      37                 :            : const long NUMRECT = 18;
      38                 :            : const long RECUR_MAXDEPTH = 10;
      39                 :            : const double RECUR_PREC = 0.001;
      40                 :            : const long DEFAULT_COLOR = 1, AXIS_COLOR = 2;
      41                 :            : 
      42                 :            : INLINE long
      43                 :     131936 : DTOL(double t) { return (long)(t + 0.5); }
      44                 :            : 
      45                 :            : /********************************************************************/
      46                 :            : /**                                                                **/
      47                 :            : /**                         LOW-RES PLOT                           **/
      48                 :            : /**                                                                **/
      49                 :            : /********************************************************************/
      50                 :            : #define ISCR 64
      51                 :            : #define JSCR 22
      52                 :            : static char
      53                 :       1984 : PICT(long j) {
      54      [ +  +  + ]:       1984 :   switch(j%3) {
      55                 :        651 :     case 0:  return '_';
      56                 :        682 :     case 1:  return 'x';
      57                 :       1984 :     default: return '"';
      58                 :            :   }
      59                 :            : }
      60                 :            : static char
      61                 :         31 : PICTZERO(long j) {
      62      [ -  -  + ]:         31 :   switch(j%3) {
      63                 :          0 :     case 0:  return ',';
      64                 :          0 :     case 1:  return '-';
      65                 :         31 :     default: return '`';
      66                 :            :   }
      67                 :            : }
      68                 :            : 
      69                 :            : static char *
      70                 :         62 : dsprintf9(double d, char *buf)
      71                 :            : {
      72                 :         62 :   int i = 10;
      73                 :            : 
      74         [ +  - ]:        182 :   while (--i >= 0) {
      75                 :        182 :     sprintf(buf, "%9.*g", i, d);
      76         [ +  + ]:        182 :     if (strlen(buf) <= 9) return buf;
      77                 :            :   }
      78                 :         62 :   return buf; /* Should not happen? */
      79                 :            : }
      80                 :            : 
      81                 :            : typedef unsigned char screen[ISCR+1][JSCR+1];
      82                 :            : 
      83                 :            : static void
      84                 :       1953 : fill_gap(screen scr, long i, int jnew, int jpre)
      85                 :            : {
      86                 :            :   int mid, i_up, i_lo, up, lo;
      87                 :            : 
      88         [ -  + ]:       1953 :   if (jpre < jnew - 2) {
      89                 :          0 :     up = jnew - 1; i_up = i;
      90                 :          0 :     lo = jpre + 1; i_lo = i - 1;
      91         [ -  + ]:       1953 :   } else if (jnew < jpre - 2) {
      92                 :          0 :     up = jpre - 1; i_up = i - 1;
      93                 :          0 :     lo = jnew + 1; i_lo = i;
      94                 :       1953 :   } else return; /* if gap < 2, leave it as it is. */
      95                 :            : 
      96                 :          0 :   mid = (jpre+jnew)/2;
      97 [ #  # ][ #  # ]:          0 :   if (mid>JSCR) mid=JSCR; else if (mid<0) mid=0;
      98         [ #  # ]:          0 :   if (lo<0) lo=0;
      99 [ #  # ][ #  # ]:          0 :   if (lo<=JSCR) while (lo <= mid) scr[i_lo][lo++] = ':';
     100         [ #  # ]:          0 :   if (up>JSCR) up=JSCR;
     101 [ #  # ][ #  # ]:          0 :   if (up>=0) while (up > mid) scr[i_up][up--] = ':';
     102                 :            : }
     103                 :            : 
     104                 :            : static double
     105                 :         62 : todbl(GEN x) { return rtodbl(gtofp(x, LOWDEFAULTPREC)); }
     106                 :            : 
     107                 :            : /* code is either a t_CLOSURE (from GP: ploth, etc.) or a t_POL/t_VEC of
     108                 :            :  * two t_POLs from rectsplines */
     109                 :            : static GEN
     110                 :     118650 : READ_EXPR(GEN code, GEN x) {
     111         [ -  + ]:     118650 :   if (typ(code)!=t_CLOSURE) return gsubst(code,0,x);
     112                 :     118650 :   set_lex(-1, x); return closure_evalgen(code);
     113                 :            : }
     114                 :            : 
     115                 :            : void
     116                 :         31 : plot(GEN a, GEN b, GEN code, GEN ysmlu,GEN ybigu, long prec)
     117                 :            : {
     118                 :         31 :   const char BLANK = ' ', YY = '|', XX_UPPER = '\'', XX_LOWER = '.';
     119                 :            :   long jz, j, i, sig;
     120                 :         31 :   pari_sp av = avma, av2;
     121                 :         31 :   int jnew, jpre = 0; /* for lint */
     122                 :            :   GEN x, dx;
     123                 :            :   double diff, dyj, ysml, ybig, y[ISCR+1];
     124                 :            :   screen scr;
     125                 :            :   char buf[80], z;
     126                 :            : 
     127         [ +  - ]:         62 :   sig=gcmp(b,a); if (!sig) return;
     128         [ -  + ]:         31 :   if (sig<0) { x=a; a=b; b=x; }
     129                 :         31 :   x = gtofp(a, prec); push_lex(x, code);
     130                 :         31 :   dx = divru(gtofp(gsub(b,a),prec), ISCR-1);
     131         [ +  + ]:        713 :   for (j=1; j<=JSCR; j++) scr[1][j]=scr[ISCR][j]=YY;
     132         [ +  + ]:       1953 :   for (i=2; i<ISCR; i++)
     133                 :            :   {
     134                 :       1922 :     scr[i][1]   = XX_LOWER;
     135                 :       1922 :     scr[i][JSCR]= XX_UPPER;
     136         [ +  + ]:      40362 :     for (j=2; j<JSCR; j++) scr[i][j] = BLANK;
     137                 :            :   }
     138                 :         31 :   av2 = avma;
     139                 :         31 :   ysml = ybig = 0.; /* -Wall */
     140         [ +  + ]:       2015 :   for (i=1; i<=ISCR; i++)
     141                 :            :   {
     142                 :       1984 :     y[i] = gtodouble( READ_EXPR(code,x) );
     143         [ +  + ]:       1984 :     if (i == 1)
     144                 :         31 :       ysml = ybig = y[1];
     145                 :            :     else
     146                 :            :     {
     147         [ +  + ]:       1953 :       if (y[i] < ysml) ysml = y[i];
     148         [ +  + ]:       1953 :       if (y[i] > ybig) ybig = y[i];
     149                 :            :     }
     150                 :       1984 :     x = addrr(x,dx);
     151         [ -  + ]:       1984 :     if (gc_needed(av2,1))
     152                 :            :     {
     153         [ #  # ]:          0 :       if (DEBUGMEM>1) pari_warn(warnmem,"plot");
     154                 :          0 :       x = gerepileuptoleaf(av2, x);
     155                 :            :     }
     156                 :            :   }
     157                 :         31 :   avma = av;
     158         [ +  + ]:         31 :   if (ysmlu) ysml = gtodouble(ysmlu);
     159         [ +  + ]:         31 :   if (ybigu) ybig = gtodouble(ybigu);
     160                 :         31 :   diff = ybig - ysml;
     161         [ -  + ]:         31 :   if (!diff) { ybig += 1; diff= 1.; }
     162                 :         31 :   dyj = ((JSCR-1)*3+2) / diff;
     163                 :            :   /* work around bug in gcc-4.8 (32bit): plot(x=-5,5,sin(x)))) */
     164                 :         31 :   jz = 3 - (long)(ysml*dyj + 0.5); /* 3 - DTOL(ysml*dyj) */
     165                 :         31 :   z = PICTZERO(jz); jz /= 3;
     166         [ +  + ]:       2015 :   for (i=1; i<=ISCR; i++, avma = av2)
     167                 :            :   {
     168 [ +  - ][ +  - ]:       1984 :     if (0<=jz && jz<=JSCR) scr[i][jz]=z;
     169                 :       1984 :     j = 3 + DTOL((y[i]-ysml)*dyj);
     170                 :       1984 :     jnew = j/3;
     171         [ +  + ]:       1984 :     if (i > 1) fill_gap(scr, i, jnew, jpre);
     172 [ +  - ][ +  - ]:       1984 :     if (0<=jnew && jnew<=JSCR) scr[i][jnew] = PICT(j);
     173                 :       1984 :     jpre = jnew;
     174                 :            :   }
     175                 :         31 :   pari_putc('\n');
     176                 :         31 :   pari_printf("%s ", dsprintf9(ybig, buf));
     177         [ +  + ]:       2015 :   for (i=1; i<=ISCR; i++) pari_putc(scr[i][JSCR]);
     178                 :         31 :   pari_putc('\n');
     179         [ +  + ]:        651 :   for (j=(JSCR-1); j>=2; j--)
     180                 :            :   {
     181                 :        620 :     pari_puts("          ");
     182         [ +  + ]:      40300 :     for (i=1; i<=ISCR; i++) pari_putc(scr[i][j]);
     183                 :        620 :     pari_putc('\n');
     184                 :            :   }
     185                 :         31 :   pari_printf("%s ", dsprintf9(ysml, buf));
     186         [ +  + ]:       2015 :   for (i=1; i<=ISCR; i++)  pari_putc(scr[i][1]);
     187                 :         31 :   pari_putc('\n');
     188                 :            :   {
     189                 :            :     char line[10 + 32 + 32 + ISCR - 9];
     190                 :         31 :     sprintf(line, "%10s%-9.7g%*.7g\n"," ",todbl(a),ISCR-9,todbl(b));
     191                 :         31 :     pari_printf(line);
     192                 :            :   }
     193                 :         31 :   pop_lex(1);
     194                 :            : }
     195                 :            : 
     196                 :            : /********************************************************************/
     197                 :            : /**                                                                **/
     198                 :            : /**                      RECTPLOT FUNCTIONS                        **/
     199                 :            : /**                                                                **/
     200                 :            : /********************************************************************/
     201                 :            : void
     202                 :       1243 : init_graph(void)
     203                 :            : {
     204                 :            :   long n;
     205         [ +  + ]:      23617 :   for (n=0; n<NUMRECT; n++)
     206                 :            :   {
     207                 :      22374 :     PariRect *e = (PariRect*) pari_malloc(sizeof(PariRect));
     208                 :      22374 :     e->head = e->tail = NULL;
     209                 :      22374 :     e->sizex = e->sizey = 0;
     210                 :      22374 :     current_color[n] = DEFAULT_COLOR;
     211                 :      22374 :     rectgraph[n] = e;
     212                 :            :   }
     213                 :       1243 : }
     214                 :            : 
     215                 :            : void
     216                 :       1231 : free_graph(void)
     217                 :            : {
     218                 :            :   int i;
     219         [ +  + ]:      23389 :   for (i=0; i<NUMRECT; i++)
     220                 :            :   {
     221                 :      22158 :     PariRect *e = rectgraph[i];
     222         [ +  + ]:      22158 :     if (RHead(e)) killrect(i);
     223                 :      22158 :     pari_free((void *)e);
     224                 :            :   }
     225         [ +  + ]:       1231 :   if (rgb_colors)
     226                 :            :   {
     227                 :         23 :     pari_free((void*)rgb_colors->table);
     228                 :         23 :     pari_free((void*)rgb_colors);
     229                 :            :   }
     230         [ +  - ]:       1231 :   if (GP_DATA->colormap) pari_free(GP_DATA->colormap);
     231         [ +  - ]:       1231 :   if (GP_DATA->graphcolors) pari_free(GP_DATA->graphcolors);
     232                 :       1231 : }
     233                 :            : 
     234                 :            : static PariRect *
     235                 :       2750 : check_rect(long ne)
     236                 :            : {
     237                 :       2750 :   const long m = NUMRECT-1;
     238         [ -  + ]:       2750 :   if (ne < 0)
     239                 :          0 :     pari_err_DOMAIN("graphic function", "rectwindow", "<", gen_0, stoi(ne));
     240         [ -  + ]:       2750 :   if (ne > m)
     241                 :          0 :     pari_err_DOMAIN("graphic function", "rectwindow", ">", stoi(m), stoi(ne));
     242                 :       2750 :   return rectgraph[ne];
     243                 :            : }
     244                 :            : 
     245                 :            : static PariRect *
     246                 :       2361 : check_rect_init(long ne)
     247                 :            : {
     248                 :       2361 :   PariRect *e = check_rect(ne);
     249         [ +  + ]:       2361 :   if (!RHead(e))
     250                 :        344 :     pari_err_TYPE("graphic function [use plotinit() first]", stoi(ne));
     251                 :       2017 :   return e;
     252                 :            : }
     253                 :            : 
     254                 :            : static long
     255                 :         42 : initrect_get_arg(GEN x, long flag, long *dft)
     256                 :            : { /* FIXME: gequal0(x) undocumented backward compatibility hack */
     257 [ +  - ][ +  - ]:         42 :   if (!x || gequal0(x) || flag) { PARI_get_plot(); return *dft - 1; }
                 [ -  + ]
     258         [ -  + ]:         42 :   if (typ(x) != t_INT) pari_err_TYPE("initrect",x);
     259                 :         42 :   return itos(x);
     260                 :            : }
     261                 :            : void
     262                 :         21 : initrect_gen(long ne, GEN x, GEN y, long flag)
     263                 :            : {
     264                 :         21 :   const long m = NUMRECT-3;
     265                 :            :   long xi, yi;
     266                 :            : 
     267                 :         21 :   xi = initrect_get_arg(x, flag, &pari_plot.width);
     268                 :         21 :   yi = initrect_get_arg(y, flag, &pari_plot.height);
     269         [ -  + ]:         21 :   if (flag) {
     270         [ #  # ]:          0 :     if (x) xi = DTOL(xi * gtodouble(x));
     271         [ #  # ]:          0 :     if (y) yi = DTOL(yi * gtodouble(y));
     272                 :            :   }
     273         [ -  + ]:         21 :   if (ne > m)
     274                 :          0 :     pari_err_DOMAIN("graphic function", "rectwindow", ">", stoi(m), stoi(ne));
     275                 :         21 :   initrect(ne, xi, yi);
     276                 :         21 : }
     277                 :            : 
     278                 :            : static void
     279                 :      11114 : Rchain(PariRect *e, RectObj *z)
     280                 :            : {
     281         [ +  + ]:      11114 :   if (!RHead(e)) RHead(e) = z; else RoNext(RTail(e)) = z;
     282                 :      11114 :   RTail(e) = z;
     283                 :      11114 :   RoNext(z) = NULL;
     284                 :      11114 : }
     285                 :            : 
     286                 :            : void
     287                 :        159 : initrect(long ne, long x, long y)
     288                 :            : {
     289                 :            :   PariRect *e;
     290                 :            :   RectObj *z;
     291                 :            : 
     292         [ -  + ]:        159 :   if (x <= 1) pari_err_DOMAIN("initrect", "x", "<=", gen_1, stoi(x));
     293         [ -  + ]:        159 :   if (y <= 1) pari_err_DOMAIN("initrect", "y", "<=", gen_1, stoi(y));
     294         [ -  + ]:        159 :   e = check_rect(ne); if (RHead(e)) killrect(ne);
     295                 :            : 
     296                 :        159 :   z = (RectObj*) pari_malloc(sizeof(RectObj));
     297                 :        159 :   RoType(z) = ROt_NULL;
     298                 :        159 :   Rchain(e, z);
     299                 :        159 :   RXsize(e) = x; RXcursor(e) = 0;
     300                 :        159 :   RYsize(e) = y; RYcursor(e) = 0;
     301                 :        159 :   RXscale(e) = 1; RXshift(e) = 0;
     302                 :        159 :   RYscale(e) = 1; RYshift(e) = 0;
     303                 :        159 :   RHasGraph(e) = 0;
     304                 :        159 : }
     305                 :            : 
     306                 :            : GEN
     307                 :         59 : rectcursor(long ne)
     308                 :            : {
     309                 :         59 :   PariRect *e = check_rect_init(ne);
     310                 :         35 :   return mkvec2s((long)RXcursor(e), (long)RYcursor(e));
     311                 :            : }
     312                 :            : 
     313                 :            : static void
     314                 :        104 : rectscale0(long ne, double x1, double x2, double y1, double y2)
     315                 :            : {
     316                 :        104 :   PariRect *e = check_rect_init(ne);
     317                 :            :   double x, y;
     318                 :            : 
     319                 :         76 :   x = RXshift(e) + RXscale(e) * RXcursor(e);
     320                 :         76 :   y = RYshift(e) + RYscale(e) * RYcursor(e);
     321                 :         76 :   RXscale(e) = RXsize(e)/(x2-x1); RXshift(e) = -x1*RXscale(e);
     322                 :         76 :   RYscale(e) = RYsize(e)/(y1-y2); RYshift(e) = -y2*RYscale(e);
     323                 :         76 :   RXcursor(e) = (x - RXshift(e)) / RXscale(e);
     324                 :         76 :   RYcursor(e) = (y - RYshift(e)) / RYscale(e);
     325                 :         76 : }
     326                 :            : 
     327                 :            : void
     328                 :         35 : rectscale(long ne, GEN x1, GEN x2, GEN y1, GEN y2)
     329                 :            : {
     330                 :         35 :   rectscale0(ne, gtodouble(x1), gtodouble(x2), gtodouble(y1), gtodouble(y2));
     331                 :          7 : }
     332                 :            : 
     333                 :            : static void
     334                 :        669 : rectmove0(long ne, double x, double y, long relative)
     335                 :            : {
     336                 :        669 :   PariRect *e = check_rect_init(ne);
     337                 :        525 :   RectObj *z = (RectObj*) pari_malloc(sizeof(RectObj1P));
     338                 :            : 
     339         [ +  + ]:        525 :   if (relative) { RXcursor(e) += x; RYcursor(e) += y; }
     340                 :        518 :   else          { RXcursor(e) = x; RYcursor(e) = y; }
     341                 :        525 :   RoType(z) = ROt_MV;
     342                 :        525 :   RoMVx(z) = RXcursor(e) * RXscale(e) + RXshift(e);
     343                 :        525 :   RoMVy(z) = RYcursor(e) * RYscale(e) + RYshift(e);
     344                 :        525 :   Rchain(e, z);
     345                 :        525 : }
     346                 :            : 
     347                 :            : void
     348                 :        169 : rectmove(long ne, GEN x, GEN y)
     349                 :            : {
     350                 :        169 :   rectmove0(ne,gtodouble(x),gtodouble(y),0);
     351                 :         49 : }
     352                 :            : 
     353                 :            : void
     354                 :         31 : rectrmove(long ne, GEN x, GEN y)
     355                 :            : {
     356                 :         31 :   rectmove0(ne,gtodouble(x),gtodouble(y),1);
     357                 :          7 : }
     358                 :            : 
     359                 :            : void
     360                 :         62 : rectpoint0(long ne, double x, double y,long relative) /* code = ROt_MV/ROt_PT */
     361                 :            : {
     362                 :         62 :   PariRect *e = check_rect_init(ne);
     363                 :         14 :   RectObj *z = (RectObj*) pari_malloc(sizeof(RectObj1P));
     364                 :            : 
     365         [ +  + ]:         14 :   if (relative) { RXcursor(e) += x; RYcursor(e) += y; }
     366                 :          7 :   else          { RXcursor(e) = x; RYcursor(e) = y; }
     367                 :         14 :   RoPTx(z) = RXcursor(e)*RXscale(e) + RXshift(e);
     368                 :         14 :   RoPTy(z) = RYcursor(e)*RYscale(e) + RYshift(e);
     369         [ +  - ]:         16 :   RoType(z) = ( DTOL(RoPTx(z)) < 0
     370 [ +  - ][ +  - ]:         14 :                 || DTOL(RoPTy(z)) < 0 || DTOL(RoPTx(z)) > RXsize(e)
     371         [ +  - ]:         26 :                 || DTOL(RoPTy(z)) > RYsize(e) ) ? ROt_MV : ROt_PT;
           [ +  -  +  - ]
     372                 :         14 :   Rchain(e, z);
     373                 :         14 :   RoCol(z) = current_color[ne];
     374                 :         14 : }
     375                 :            : 
     376                 :            : void
     377                 :         31 : rectpoint(long ne, GEN x, GEN y)
     378                 :            : {
     379                 :         31 :   rectpoint0(ne,gtodouble(x),gtodouble(y),0);
     380                 :          7 : }
     381                 :            : 
     382                 :            : void
     383                 :         31 : rectrpoint(long ne, GEN x, GEN y)
     384                 :            : {
     385                 :         31 :   rectpoint0(ne,gtodouble(x),gtodouble(y),1);
     386                 :          7 : }
     387                 :            : 
     388                 :            : void
     389                 :         48 : rectcolor(long ne, long c)
     390                 :            : {
     391                 :         48 :   long n = lg(GP_DATA->colormap)-2;
     392                 :         48 :   check_rect(ne);
     393         [ -  + ]:         48 :   if (c < 1) pari_err_DOMAIN("rectcolor", "color", "<", gen_1, stoi(c));
     394         [ -  + ]:         48 :   if (c > n) pari_err_DOMAIN("rectcolor", "color", ">", stoi(n), stoi(c));
     395                 :         48 :   current_color[ne] = c;
     396                 :         48 : }
     397                 :            : 
     398                 :            : void
     399                 :        162 : rectline0(long ne, double gx2, double gy2, long relative) /* code = ROt_MV/ROt_LN */
     400                 :            : {
     401                 :            :   double dx,dy,dxy,xmin,xmax,ymin,ymax,x1,y1,x2,y2;
     402                 :        162 :   PariRect *e = check_rect_init(ne);
     403                 :        138 :   RectObj *z = (RectObj*) pari_malloc(sizeof(RectObj2P));
     404                 :        138 :   const double c = 1 + 1e-10;
     405                 :            : 
     406                 :        138 :   x1 = RXcursor(e)*RXscale(e) + RXshift(e);
     407                 :        138 :   y1 = RYcursor(e)*RYscale(e) + RYshift(e);
     408         [ +  + ]:        138 :   if (relative)
     409                 :          7 :     { RXcursor(e)+=gx2; RYcursor(e)+=gy2; }
     410                 :            :   else
     411                 :        131 :     { RXcursor(e)=gx2; RYcursor(e)=gy2; }
     412                 :        138 :   x2 = RXcursor(e)*RXscale(e) + RXshift(e);
     413                 :        138 :   y2 = RYcursor(e)*RYscale(e) + RYshift(e);
     414                 :        138 :   xmin = maxdd(mindd(x1,x2),0); xmax = mindd(maxdd(x1,x2),RXsize(e));
     415                 :        138 :   ymin = maxdd(mindd(y1,y2),0); ymax = mindd(maxdd(y1,y2),RYsize(e));
     416                 :        138 :   dxy = x1*y2 - y1*x2; dx = x2-x1; dy = y2-y1;
     417         [ +  + ]:        138 :   if (dy)
     418                 :            :   {
     419         [ +  + ]:         76 :     if (dx*dy<0)
     420                 :          7 :       { xmin = maxdd(xmin,(dxy+RYsize(e)*dx)/dy); xmax=mindd(xmax,dxy/dy); }
     421                 :            :     else
     422                 :         69 :       { xmin=maxdd(xmin,dxy/dy); xmax=mindd(xmax,(dxy+RYsize(e)*dx)/dy); }
     423                 :            :   }
     424         [ +  + ]:        138 :   if (dx)
     425                 :            :   {
     426         [ +  + ]:         76 :     if (dx*dy<0)
     427                 :          7 :       { ymin=maxdd(ymin,(RXsize(e)*dy-dxy)/dx); ymax=mindd(ymax,-dxy/dx); }
     428                 :            :     else
     429                 :         69 :       { ymin=maxdd(ymin,-dxy/dx); ymax=mindd(ymax,(RXsize(e)*dy-dxy)/dx); }
     430                 :            :   }
     431                 :        138 :   RoLNx1(z) = xmin; RoLNx2(z) = xmax;
     432         [ +  + ]:        138 :   if (dx*dy<0) { RoLNy1(z) = ymax; RoLNy2(z) = ymin; }
     433                 :        131 :   else         { RoLNy1(z) = ymin; RoLNy2(z) = ymax; }
     434 [ +  - ][ -  + ]:        138 :   RoType(z) = (xmin>xmax*c || ymin>ymax*c) ? ROt_MV : ROt_LN;
     435                 :        138 :   Rchain(e, z);
     436                 :        138 :   RoCol(z) = current_color[ne];
     437                 :        138 : }
     438                 :            : 
     439                 :            : /* Given coordinates of ends of a line, and labels l1 l2 attached to the
     440                 :            :    ends, plot ticks where the label coordinate takes "round" values */
     441                 :            : 
     442                 :            : static void
     443                 :        276 : rectticks(PARI_plot *WW, long ne,
     444                 :            :           double dx1, double dy1, double dx2, double dy2,
     445                 :            :           double l1, double l2, long flags)
     446                 :            : {
     447                 :            :   long dx,dy,dxy,dxy1,x1,y1,x2,y2,nticks,n,n1,dn;
     448                 :            :   double minstep, maxstep, step, l_min, l_max, minl, maxl, dl, dtx, dty, x, y;
     449                 :            :   double ddx, ddy;
     450                 :        276 :   const double mult[3] = { 2./1., 5./2., 10./5. };
     451                 :        276 :   PariRect *e = check_rect_init(ne);
     452                 :        276 :   int do_double = !(flags & TICKS_NODOUBLE);
     453                 :            : 
     454                 :        276 :   x1 = DTOL(dx1*RXscale(e) + RXshift(e));
     455                 :        276 :   y1 = DTOL(dy1*RYscale(e) + RYshift(e));
     456                 :        276 :   x2 = DTOL(dx2*RXscale(e) + RXshift(e));
     457                 :        276 :   y2 = DTOL(dy2*RYscale(e) + RYshift(e));
     458                 :        276 :   dx = x2 - x1;
     459                 :        276 :   dy = y2 - y1;
     460         [ +  + ]:        276 :   if (dx < 0) dx = -dx;
     461         [ +  + ]:        276 :   if (dy < 0) dy = -dy;
     462                 :        276 :   dxy1 = maxss(dx, dy);
     463                 :        276 :   dx /= WW->hunit;
     464                 :        276 :   dy /= WW->vunit;
     465 [ +  - ][ -  + ]:        276 :   if (dx > 1000 || dy > 1000)
     466                 :          0 :     dxy = 1000; /* avoid overflow */
     467                 :            :   else
     468                 :        276 :     dxy = (long)sqrt(dx*dx + dy*dy);
     469                 :        276 :   nticks = (long) ((dxy + 2.5)/4);
     470         [ +  - ]:        276 :   if (!nticks) return;
     471                 :            : 
     472                 :            :   /* Now we want to find nticks (or less) "round" numbers between l1 and l2.
     473                 :            :      For our purpose round numbers have "last significant" digit either
     474                 :            :         *) any;
     475                 :            :         *) even;
     476                 :            :         *) divisible by 5.
     477                 :            :      We need to choose which alternative is better.
     478                 :            :    */
     479         [ +  + ]:        276 :   if (l1 < l2)
     480                 :        138 :     l_min = l1, l_max = l2;
     481                 :            :   else
     482                 :        138 :     l_min = l2, l_max = l1;
     483                 :        276 :   minstep = (l_max - l_min)/(nticks + 1);
     484                 :        276 :   maxstep = 2.5*(l_max - l_min);
     485                 :        276 :   step = exp(log(10) * floor(log10(minstep)));
     486         [ +  - ]:        276 :   if (!(flags & TICKS_ENDSTOO)) {
     487                 :        276 :     double d = 2*(l_max - l_min)/dxy1;        /* Two pixels off */
     488                 :            : 
     489                 :        276 :     l_min += d;
     490                 :        276 :     l_max -= d;
     491                 :            :   }
     492                 :        276 :   for (n = 0; ; n++) {
     493         [ +  - ]:        828 :     if (step >= maxstep) return;
     494                 :            : 
     495         [ +  + ]:        828 :     if (step >= minstep) {
     496                 :        276 :       minl = ceil(l_min/step);
     497                 :        276 :       maxl = floor(l_max/step);
     498 [ +  - ][ +  - ]:        276 :       if (minl <= maxl && maxl - minl + 1 <= nticks) {
     499                 :        276 :         nticks = (long) (maxl - minl + 1);
     500                 :        276 :         l_min = minl * step;
     501                 :        276 :         l_max = maxl * step; break;
     502                 :            :       }
     503                 :            :     }
     504                 :        552 :     step *= mult[ n % 3 ];
     505                 :        552 :   }
     506                 :            :   /* Where to position doubleticks, variants:
     507                 :            :      small: each 5, double: each 10        (n===2 mod 3)
     508                 :            :      small: each 2, double: each 10        (n===1 mod 3)
     509                 :            :      small: each 1, double: each  5 */
     510         [ +  + ]:        276 :   dn = (n % 3 == 2)? 2: 5;
     511                 :        276 :   n1 = ((long)minl) % dn; /* unused if do_double = FALSE */
     512                 :            : 
     513                 :            :   /* now l_min and l_max keep min/max values of l with ticks, and nticks is
     514                 :            :      the number of ticks to draw. */
     515         [ -  + ]:        276 :   if (nticks == 1) ddx = ddy = 0; /* unused: for lint */
     516                 :            :   else {
     517                 :        276 :     dl = (l_max - l_min)/(nticks - 1);
     518                 :        276 :     ddx = (dx2 - dx1) * dl / (l2 - l1);
     519                 :        276 :     ddy = (dy2 - dy1) * dl / (l2 - l1);
     520                 :            :   }
     521                 :        276 :   x = dx1 + (dx2 - dx1) * (l_min - l1) / (l2 - l1);
     522                 :        276 :   y = dy1 + (dy2 - dy1) * (l_min - l1) / (l2 - l1);
     523                 :            :   /* assume hunit and vunit form a square.  For clockwise ticks: */
     524         [ +  + ]:        276 :   dtx = WW->hunit * dy/dxy * (y2 > y1 ? 1 : -1);        /* y-coord runs down */
     525         [ +  + ]:        276 :   dty = WW->vunit * dx/dxy * (x2 > x1 ? 1 : -1);
     526         [ +  + ]:       9760 :   for (n = 0; n < nticks; n++) {
     527                 :       9484 :     RectObj *z = (RectObj*) pari_malloc(sizeof(RectObj2P));
     528         [ +  - ]:       9484 :     double lunit = WW->hunit > 1 ? 1.5 : 2;
     529 [ +  - ][ +  + ]:       9484 :     double l = (do_double && (n + n1) % dn == 0) ? lunit: 1;
     530                 :            : 
     531                 :       9484 :     RoLNx1(z) = RoLNx2(z) = x*RXscale(e) + RXshift(e);
     532                 :       9484 :     RoLNy1(z) = RoLNy2(z) = y*RYscale(e) + RYshift(e);
     533                 :            : 
     534         [ +  - ]:       9484 :     if (flags & TICKS_CLOCKW) {
     535                 :       9484 :       RoLNx1(z) += dtx*l;
     536                 :       9484 :       RoLNy1(z) -= dty*l; /* y-coord runs down */
     537                 :            :     }
     538         [ -  + ]:       9484 :     if (flags & TICKS_ACLOCKW) {
     539                 :          0 :       RoLNx2(z) -= dtx*l;
     540                 :          0 :       RoLNy2(z) += dty*l; /* y-coord runs down */
     541                 :            :     }
     542                 :       9484 :     RoType(z) = ROt_LN;
     543                 :            : 
     544                 :       9484 :     Rchain(e, z);
     545                 :       9484 :     RoCol(z) = current_color[ne];
     546                 :       9484 :     x += ddx;
     547                 :       9484 :     y += ddy;
     548                 :            :   }
     549                 :            : }
     550                 :            : 
     551                 :            : void
     552                 :          7 : rectline(long ne, GEN gx2, GEN gy2)
     553                 :            : {
     554                 :          7 :   rectline0(ne, gtodouble(gx2), gtodouble(gy2),0);
     555                 :          7 : }
     556                 :            : 
     557                 :            : void
     558                 :         31 : rectrline(long ne, GEN gx2, GEN gy2)
     559                 :            : {
     560                 :         31 :   rectline0(ne, gtodouble(gx2), gtodouble(gy2),1);
     561                 :          7 : }
     562                 :            : 
     563                 :            : void
     564                 :        111 : rectbox0(long ne, double gx2, double gy2, long relative)
     565                 :            : {
     566                 :            :   double x1,y1,x2,y2,xmin,ymin,xmax,ymax;
     567                 :            :   double xx,yy;
     568                 :        111 :   PariRect *e = check_rect_init(ne);
     569                 :         83 :   RectObj *z = (RectObj*) pari_malloc(sizeof(RectObj2P));
     570                 :            : 
     571                 :         83 :   x1 = RXcursor(e)*RXscale(e) + RXshift(e);
     572                 :         83 :   y1 = RYcursor(e)*RYscale(e) + RYshift(e);
     573         [ +  + ]:         83 :   if (relative)
     574                 :          7 :   { xx = RXcursor(e)+gx2; yy = RYcursor(e)+gy2; }
     575                 :            :   else
     576                 :         76 :   {  xx = gx2; yy = gy2; }
     577                 :         83 :   x2 = xx*RXscale(e) + RXshift(e);
     578                 :         83 :   y2 = yy*RYscale(e) + RYshift(e);
     579                 :         83 :   xmin = maxdd(mindd(x1,x2),0); xmax = mindd(maxdd(x1,x2),RXsize(e));
     580                 :         83 :   ymin = maxdd(mindd(y1,y2),0); ymax = mindd(maxdd(y1,y2),RYsize(e));
     581                 :            : 
     582                 :         83 :   RoType(z) = ROt_BX;
     583                 :         83 :   RoBXx1(z) = xmin; RoBXy1(z) = ymin;
     584                 :         83 :   RoBXx2(z) = xmax; RoBXy2(z) = ymax;
     585                 :         83 :   Rchain(e, z);
     586                 :         83 :   RoCol(z) = current_color[ne];
     587                 :         83 : }
     588                 :            : 
     589                 :            : void
     590                 :         35 : rectbox(long ne, GEN gx2, GEN gy2)
     591                 :            : {
     592                 :         35 :   rectbox0(ne, gtodouble(gx2), gtodouble(gy2), 0);
     593                 :          7 : }
     594                 :            : 
     595                 :            : void
     596                 :          7 : rectrbox(long ne, GEN gx2, GEN gy2)
     597                 :            : {
     598                 :          7 :   rectbox0(ne, gtodouble(gx2), gtodouble(gy2), 1);
     599                 :          7 : }
     600                 :            : 
     601                 :            : static void
     602                 :      11114 : freeobj(RectObj *z) {
     603      [ +  +  + ]:      11114 :   switch(RoType(z)) {
     604                 :            :     case ROt_MP: case ROt_ML:
     605                 :         83 :       pari_free(RoMPxs(z));
     606                 :         83 :       pari_free(RoMPys(z)); break;
     607                 :            :     case ROt_ST:
     608                 :        290 :       pari_free(RoSTs(z)); break;
     609                 :            :   }
     610                 :      11114 :   pari_free(z);
     611                 :      11114 : }
     612                 :            : 
     613                 :            : 
     614                 :            : void
     615                 :        159 : killrect(long ne)
     616                 :            : {
     617                 :            :   RectObj *z, *t;
     618                 :        159 :   PariRect *e = check_rect_init(ne);
     619                 :            : 
     620                 :        159 :   current_color[ne]=DEFAULT_COLOR;
     621                 :        159 :   z=RHead(e);
     622                 :        159 :   RHead(e) = RTail(e) = NULL;
     623                 :        159 :   RXsize(e) = RYsize(e) = 0;
     624                 :        159 :   RXcursor(e) = RYcursor(e) = 0;
     625                 :        159 :   RXscale(e) = RYscale(e) = 1;
     626                 :        159 :   RXshift(e) = RYshift(e) = 0;
     627         [ +  + ]:      11273 :   while (z) { t = RoNext(z); freeobj(z); z = t; }
     628                 :        159 : }
     629                 :            : 
     630                 :            : void
     631                 :         38 : rectpoints0(long ne, double *listx, double *listy, long lx) /* code = ROt_MP */
     632                 :            : {
     633                 :            :   double *ptx, *pty, x, y;
     634                 :         38 :   long i, cp=0;
     635                 :         38 :   PariRect *e = check_rect_init(ne);
     636                 :         14 :   RectObj *z = (RectObj*) pari_malloc(sizeof(RectObjMP));
     637                 :            : 
     638                 :         14 :   RoMPxs(z) = ptx = (double*) pari_malloc(lx*sizeof(double));
     639                 :         14 :   RoMPys(z) = pty = (double*) pari_malloc(lx*sizeof(double));
     640         [ +  + ]:        784 :   for (i=0; i<lx; i++)
     641                 :            :   {
     642                 :        770 :     x = RXscale(e)*listx[i] + RXshift(e);
     643                 :        770 :     y = RYscale(e)*listy[i] + RYshift(e);
     644 [ +  - ][ +  + ]:        770 :     if (x>=0 && y>=0 && x<=RXsize(e) && y<=RYsize(e))
         [ +  - ][ +  - ]
     645                 :            :     {
     646                 :        769 :       ptx[cp]=x; pty[cp]=y; cp++;
     647                 :            :     }
     648                 :            :   }
     649                 :         14 :   RoType(z) = ROt_MP;
     650                 :         14 :   RoMPcnt(z) = cp;
     651                 :         14 :   Rchain(e, z);
     652                 :         14 :   RoCol(z) = current_color[ne];
     653                 :         14 : }
     654                 :            : 
     655                 :            : void
     656                 :         62 : rectpoints(long ne, GEN listx, GEN listy)
     657                 :            : {
     658                 :         62 :   long i,lx, tx=typ(listx), ty=typ(listy);
     659                 :            :   double *px,*py;
     660                 :            : 
     661 [ +  + ][ -  + ]:         62 :   if (!is_matvec_t(tx) || !is_matvec_t(ty)) {
     662                 :         31 :     rectpoint(ne, listx, listy); return;
     663                 :            :   }
     664                 :         31 :   lx = lg(listx);
     665         [ -  + ]:         31 :   if (tx == t_MAT) pari_err_TYPE("rectpoints",listx);
     666         [ -  + ]:         31 :   if (ty == t_MAT) pari_err_TYPE("rectpoints",listy);
     667         [ -  + ]:         31 :   if (lg(listy) != lx) pari_err_DIM("rectpoints");
     668         [ -  + ]:         31 :   lx--; if (!lx) return;
     669                 :            : 
     670                 :         31 :   px = (double*) pari_malloc(lx*sizeof(double)); listx++;
     671                 :         31 :   py = (double*) pari_malloc(lx*sizeof(double)); listy++;
     672         [ +  + ]:        341 :   for (i=0; i<lx; i++)
     673                 :            :   {
     674                 :        310 :     px[i] = gtodouble(gel(listx,i));
     675                 :        310 :     py[i] = gtodouble(gel(listy,i));
     676                 :            :   }
     677                 :         31 :   rectpoints0(ne,px,py,lx);
     678                 :         14 :   pari_free(px); pari_free(py);
     679                 :            : }
     680                 :            : 
     681                 :            : void
     682                 :         93 : rectlines0(long ne, double *x, double *y, long lx, long flag) /* code = ROt_ML */
     683                 :            : {
     684                 :            :   long i,I;
     685                 :            :   double *ptx,*pty;
     686                 :         93 :   PariRect *e = check_rect_init(ne);
     687                 :         69 :   RectObj *z = (RectObj*) pari_malloc(sizeof(RectObj2P));
     688                 :            : 
     689         [ -  + ]:         69 :   I = flag ? lx+1 : lx;
     690                 :         69 :   ptx = (double*) pari_malloc(I*sizeof(double));
     691                 :         69 :   pty = (double*) pari_malloc(I*sizeof(double));
     692         [ +  + ]:      43828 :   for (i=0; i<lx; i++)
     693                 :            :   {
     694                 :      43759 :     ptx[i] = RXscale(e)*x[i] + RXshift(e);
     695                 :      43759 :     pty[i] = RYscale(e)*y[i] + RYshift(e);
     696                 :            :   }
     697         [ -  + ]:         69 :   if (flag)
     698                 :            :   {
     699                 :          0 :     ptx[i] = RXscale(e)*x[0] + RXshift(e);
     700                 :          0 :     pty[i] = RYscale(e)*y[0] + RYshift(e);
     701                 :            :   }
     702                 :         69 :   Rchain(e, z);
     703                 :         69 :   RoType(z) = ROt_ML;
     704                 :         69 :   RoMLcnt(z) = lx;
     705                 :         69 :   RoMLxs(z) = ptx;
     706                 :         69 :   RoMLys(z) = pty;
     707                 :         69 :   RoCol(z) = current_color[ne];
     708                 :         69 : }
     709                 :            : 
     710                 :            : void
     711                 :         38 : rectlines(long ne, GEN listx, GEN listy, long flag)
     712                 :            : {
     713                 :         38 :   long tx=typ(listx), ty=typ(listy), lx=lg(listx), i;
     714                 :            :   double *x, *y;
     715                 :            : 
     716 [ +  + ][ -  + ]:         38 :   if (!is_matvec_t(tx) || !is_matvec_t(ty))
     717                 :            :   {
     718                 :          7 :     rectline(ne, listx, listy); return;
     719                 :            :   }
     720         [ -  + ]:         31 :   if (tx == t_MAT) pari_err_TYPE("rectlines",listx);
     721         [ -  + ]:         31 :   if (ty == t_MAT) pari_err_TYPE("rectlines",listy);
     722         [ -  + ]:         31 :   if (lg(listy) != lx) pari_err_DIM("rectlines");
     723         [ -  + ]:         31 :   lx--; if (!lx) return;
     724                 :            : 
     725                 :         31 :   x = (double*) pari_malloc(lx*sizeof(double));
     726                 :         31 :   y = (double*) pari_malloc(lx*sizeof(double));
     727         [ +  + ]:        186 :   for (i=0; i<lx; i++)
     728                 :            :   {
     729                 :        155 :     x[i] = gtodouble(gel(listx,i+1));
     730                 :        155 :     y[i] = gtodouble(gel(listy,i+1));
     731                 :            :   }
     732                 :         31 :   rectlines0(ne,x,y,lx,flag);
     733                 :         14 :   pari_free(x); pari_free(y);
     734                 :            : }
     735                 :            : 
     736                 :            : static void
     737                 :        276 : put_label(long ne, long x, long y, double d, long dir)
     738                 :            : {
     739                 :            :   char c[16];
     740                 :        276 :   sprintf(c,"%.5g", d);
     741                 :        276 :   rectmove0(ne,(double)x,(double)y,0);
     742                 :        276 :   rectstring3(ne, c, dir);
     743                 :        276 : }
     744                 :            : 
     745                 :            : void
     746                 :          0 : rectstring(long ne, char *str)
     747                 :            : {
     748                 :          0 :   rectstring3(ne,str,RoSTdirLEFT);
     749                 :          0 : }
     750                 :            : 
     751                 :            : /* Allocate memory, then put string */
     752                 :            : void
     753                 :        290 : rectstring3(long ne, char *str, long dir) /* code = ROt_ST */
     754                 :            : {
     755                 :        290 :   PariRect *e = check_rect_init(ne);
     756                 :        290 :   RectObj *z = (RectObj*) pari_malloc(sizeof(RectObjST));
     757                 :        290 :   long l = strlen(str);
     758                 :        290 :   char *s = (char *) pari_malloc(l+1);
     759                 :            : 
     760                 :        290 :   memcpy(s,str,l+1);
     761                 :        290 :   RoType(z) = ROt_ST;
     762                 :        290 :   RoSTl(z) = l;
     763                 :        290 :   RoSTs(z) = s;
     764                 :        290 :   RoSTx(z) = RXscale(e)*RXcursor(e)+RXshift(e);
     765                 :        290 :   RoSTy(z) = RYscale(e)*RYcursor(e)+RYshift(e);
     766                 :        290 :   RoSTdir(z) = dir;
     767                 :        290 :   Rchain(e, z);
     768                 :        290 :   RoCol(z) = current_color[ne];
     769                 :        290 : }
     770                 :            : 
     771                 :            : void
     772                 :          7 : rectpointtype(long ne, long type) /* code = ROt_PTT */
     773                 :            : {
     774         [ -  + ]:          7 :  if (ne == -1) {
     775                 :          0 :    rectpoint_itype = type;
     776                 :            :  } else {
     777                 :          7 :    PariRect *e = check_rect_init(ne);
     778                 :          7 :    RectObj *z = (RectObj*) pari_malloc(sizeof(RectObjPN));
     779                 :            : 
     780                 :          7 :    RoType(z) = ROt_PTT;
     781                 :          7 :    RoPTTpen(z) = type;
     782                 :          7 :    Rchain(e, z);
     783                 :            :  }
     784                 :          7 : }
     785                 :            : 
     786                 :            : /*FIXME: this function is a noop, since no graphic driver implement
     787                 :            :  * the ROt_PTS code. ne==-1 is a legacy, meaningless value. */
     788                 :            : void
     789                 :          0 : rectpointsize(long ne, GEN size) /* code = ROt_PTS */
     790                 :            : {
     791         [ #  # ]:          0 :  if (ne == -1) { /*do nothing*/ }
     792                 :            :  else {
     793                 :          0 :    PariRect *e = check_rect_init(ne);
     794                 :          0 :    RectObj *z = (RectObj*) pari_malloc(sizeof(RectObjPS));
     795                 :            : 
     796                 :          0 :    RoType(z) = ROt_PTS;
     797                 :          0 :    RoPTSsize(z) = gtodouble(size);
     798                 :          0 :    Rchain(e, z);
     799                 :            :  }
     800                 :          0 : }
     801                 :            : 
     802                 :            : void
     803                 :        331 : rectlinetype(long ne, long type)
     804                 :            : {
     805         [ -  + ]:        331 :  if (ne == -1) {
     806                 :          0 :    rectline_itype = type;
     807                 :            :  } else {
     808                 :        331 :    PariRect *e = check_rect_init(ne);
     809                 :        331 :    RectObj *z = (RectObj*) pari_malloc(sizeof(RectObjPN));
     810                 :            : 
     811                 :        331 :    RoType(z) = ROt_LNT;
     812                 :        331 :    RoLNTpen(z) = type;
     813                 :        331 :    Rchain(e, z);
     814                 :            :  }
     815                 :        331 : }
     816                 :            : 
     817                 :            : void
     818                 :          0 : rectcopy_gen(long source, long dest, GEN xoff, GEN yoff, long flag)
     819                 :            : {
     820                 :            :   long xi, yi;
     821         [ #  # ]:          0 :   if (flag & RECT_CP_RELATIVE) {
     822                 :          0 :     double xd = gtodouble(xoff), yd = gtodouble(yoff);
     823                 :            : 
     824                 :          0 :     PARI_get_plot();
     825                 :          0 :     xi = pari_plot.width - 1;
     826                 :          0 :     yi = pari_plot.height - 1;
     827                 :          0 :     xi = DTOL(xd*xi);
     828                 :          0 :     yi = DTOL(yd*yi);
     829                 :            :   } else {
     830                 :          0 :     xi = itos(xoff);
     831                 :          0 :     yi = itos(yoff);
     832                 :            :   }
     833         [ #  # ]:          0 :   if (flag & ~RECT_CP_RELATIVE) {
     834                 :          0 :     PariRect *s = check_rect_init(source), *d = check_rect_init(dest);
     835                 :            : 
     836   [ #  #  #  #  :          0 :     switch (flag & ~RECT_CP_RELATIVE) {
                      # ]
     837                 :            :       case RECT_CP_NW:
     838                 :          0 :         break;
     839                 :            :       case RECT_CP_SW:
     840                 :          0 :         yi = RYsize(d) - RYsize(s) - yi;
     841                 :          0 :         break;
     842                 :            :       case RECT_CP_SE:
     843                 :          0 :         yi = RYsize(d) - RYsize(s) - yi;
     844                 :            :         /* FALL THROUGH */
     845                 :            :       case RECT_CP_NE:
     846                 :          0 :         xi = RXsize(d) - RXsize(s) - xi;
     847                 :          0 :         break;
     848                 :            :     }
     849                 :            :   }
     850                 :          0 :   rectcopy(source, dest, xi, yi);
     851                 :          0 : }
     852                 :            : 
     853                 :            : void
     854                 :          0 : rectcopy(long source, long dest, long xoff, long yoff)
     855                 :            : {
     856                 :          0 :   PariRect *s = check_rect_init(source), *d = check_rect_init(dest);
     857                 :          0 :   RectObj *R = RHead(s);
     858                 :          0 :   RectObj *tail = RTail(d);
     859                 :            :   RectObj *next;
     860                 :            :   int i;
     861                 :            : 
     862         [ #  # ]:          0 :   while (R)
     863                 :            :   {
     864   [ #  #  #  #  :          0 :     switch(RoType(R))
                   #  # ]
     865                 :            :     {
     866                 :            :       case ROt_PT:
     867                 :          0 :         next = (RectObj*) pari_malloc(sizeof(RectObj1P));
     868                 :          0 :         memcpy(next,R,sizeof(RectObj1P));
     869                 :          0 :         RoPTx(next) += xoff; RoPTy(next) += yoff;
     870                 :          0 :         RoNext(tail) = next; tail = next;
     871                 :          0 :         break;
     872                 :            :       case ROt_LN: case ROt_BX:
     873                 :          0 :         next = (RectObj*) pari_malloc(sizeof(RectObj2P));
     874                 :          0 :         memcpy(next,R,sizeof(RectObj2P));
     875                 :          0 :         RoLNx1(next) += xoff; RoLNy1(next) += yoff;
     876                 :          0 :         RoLNx2(next) += xoff; RoLNy2(next) += yoff;
     877                 :          0 :         RoNext(tail) = next; tail = next;
     878                 :          0 :         break;
     879                 :            :       case ROt_MP: case ROt_ML:
     880                 :          0 :         next = (RectObj*) pari_malloc(sizeof(RectObjMP));
     881                 :          0 :         memcpy(next,R,sizeof(RectObjMP));
     882                 :          0 :         RoMPxs(next) = (double*) pari_malloc(sizeof(double)*RoMPcnt(next));
     883                 :          0 :         RoMPys(next) = (double*) pari_malloc(sizeof(double)*RoMPcnt(next));
     884                 :          0 :         memcpy(RoMPxs(next),RoMPxs(R),sizeof(double)*RoMPcnt(next));
     885                 :          0 :         memcpy(RoMPys(next),RoMPys(R),sizeof(double)*RoMPcnt(next));
     886         [ #  # ]:          0 :         for (i=0; i<RoMPcnt(next); i++)
     887                 :            :         {
     888                 :          0 :           RoMPxs(next)[i] += xoff; RoMPys(next)[i] += yoff;
     889                 :            :          }
     890                 :          0 :         RoNext(tail) = next; tail = next;
     891                 :          0 :         break;
     892                 :            :       case ROt_ST:
     893                 :          0 :         next = (RectObj*) pari_malloc(sizeof(RectObjST));
     894                 :          0 :         memcpy(next,R,sizeof(RectObjMP));
     895                 :          0 :         RoSTs(next) = (char*) pari_malloc(RoSTl(R)+1);
     896                 :          0 :         memcpy(RoSTs(next),RoSTs(R),RoSTl(R)+1);
     897                 :          0 :         RoSTx(next) += xoff; RoSTy(next) += yoff;
     898                 :          0 :         RoNext(tail) = next; tail = next;
     899                 :          0 :         break;
     900                 :            :       case ROt_PTT: case ROt_LNT: case ROt_PTS:
     901                 :          0 :         next = (RectObj*) pari_malloc(sizeof(RectObjPN));
     902                 :          0 :         memcpy(next,R,sizeof(RectObjPN));
     903                 :          0 :         RoNext(tail) = next; tail = next;
     904                 :          0 :         break;
     905                 :            :     }
     906                 :          0 :     R=RoNext(R);
     907                 :            :   }
     908                 :          0 :   RoNext(tail) = NULL; RTail(d) = tail;
     909                 :          0 : }
     910                 :            : 
     911                 :            : enum {CLIPLINE_NONEMPTY = 1, CLIPLINE_CLIP_1 = 2, CLIPLINE_CLIP_2 = 4};
     912                 :            : /* A simpler way is to clip by 4 half-planes */
     913                 :            : static int
     914                 :          0 : clipline(double xmin, double xmax, double ymin, double ymax,
     915                 :            :          double *x1p, double *y1p, double *x2p, double *y2p)
     916                 :            : {
     917                 :          0 :   int xy_exch = 0, rc = CLIPLINE_NONEMPTY;
     918                 :            :   double t, sl;
     919                 :            :   double xi, xmn, xmx;
     920                 :            :   double yi, ymn, ymx;
     921                 :            :   int x1_is_ymn, x1_is_xmn;
     922                 :          0 :   double x1 = *x1p, x2 = *x2p, y1 = *y1p, y2 = *y2p;
     923                 :            : 
     924 [ #  # ][ #  # ]:          0 :   if ((x1 < xmin &&  x2 < xmin) || (x1 > xmax && x2 > xmax))
         [ #  # ][ #  # ]
     925                 :          0 :     return 0;
     926         [ #  # ]:          0 :   if (fabs(x1 - x2) < fabs(y1 - y2)) { /* Exchange x and y */
     927                 :          0 :     xy_exch = 1;
     928                 :          0 :     dswap(xmin, ymin); dswap(x1, y1);
     929                 :          0 :     dswap(xmax, ymax); dswap(x2, y2);
     930                 :            :   }
     931                 :            : 
     932                 :            :   /* Build y as a function of x */
     933                 :          0 :   xi = x1;
     934                 :          0 :   yi = y1;
     935         [ #  # ]:          0 :   sl = x1==x2? 0: (y2 - yi)/(x2 - xi);
     936                 :            : 
     937         [ #  # ]:          0 :   if (x1 > x2) {
     938                 :          0 :     x1_is_xmn = 0;
     939                 :          0 :     xmn = x2;
     940                 :          0 :     xmx = x1;
     941                 :            :   } else {
     942                 :          0 :     x1_is_xmn = 1;
     943                 :          0 :     xmn = x1;
     944                 :          0 :     xmx = x2;
     945                 :            :   }
     946                 :            : 
     947         [ #  # ]:          0 :   if (xmn < xmin) {
     948                 :          0 :     xmn = xmin;
     949         [ #  # ]:          0 :     rc |= x1_is_xmn? CLIPLINE_CLIP_1: CLIPLINE_CLIP_2;
     950                 :            :   }
     951         [ #  # ]:          0 :   if (xmx > xmax) {
     952                 :          0 :     xmx = xmax;
     953         [ #  # ]:          0 :     rc |= x1_is_xmn? CLIPLINE_CLIP_2: CLIPLINE_CLIP_1;
     954                 :            :   }
     955         [ #  # ]:          0 :   if (xmn > xmx) return 0;
     956                 :            : 
     957                 :          0 :   ymn = yi + (xmn - xi)*sl;
     958                 :          0 :   ymx = yi + (xmx - xi)*sl;
     959                 :            : 
     960         [ #  # ]:          0 :   if (sl < 0) t = ymn, ymn = ymx, ymx = t;
     961 [ #  # ][ #  # ]:          0 :   if (ymn > ymax || ymx < ymin) return 0;
     962                 :            : 
     963 [ #  # ][ #  # ]:          0 :   if (rc & CLIPLINE_CLIP_1) x1 = x1_is_xmn? xmn: xmx;
     964 [ #  # ][ #  # ]:          0 :   if (rc & CLIPLINE_CLIP_2) x2 = x1_is_xmn? xmx: xmn;
     965                 :            : 
     966                 :            :   /* Now we know there is an intersection, need to move x1 and x2 */
     967                 :          0 :   x1_is_ymn = ((sl >= 0) == (x1 < x2));
     968         [ #  # ]:          0 :   if (ymn < ymin) {
     969                 :          0 :     double x = (ymin - yi)/sl + xi; /* slope != 0  ! */
     970         [ #  # ]:          0 :     if (x1_is_ymn) x1 = x, rc |= CLIPLINE_CLIP_1;
     971                 :          0 :     else           x2 = x, rc |= CLIPLINE_CLIP_2;
     972                 :            :   }
     973         [ #  # ]:          0 :   if (ymx > ymax) {
     974                 :          0 :     double x = (ymax - yi)/sl + xi; /* slope != 0  ! */
     975         [ #  # ]:          0 :     if (x1_is_ymn) x2 = x, rc |= CLIPLINE_CLIP_2;
     976                 :          0 :     else           x1 = x, rc |= CLIPLINE_CLIP_1;
     977                 :            :   }
     978         [ #  # ]:          0 :   if (rc & CLIPLINE_CLIP_1) y1 = yi + (x1 - xi)*sl;
     979         [ #  # ]:          0 :   if (rc & CLIPLINE_CLIP_2) y2 = yi + (x2 - xi)*sl;
     980         [ #  # ]:          0 :   if (xy_exch) /* Exchange x and y */
     981                 :          0 :     *x1p = y1, *x2p = y2, *y1p = x1, *y2p = x2;
     982                 :            :   else
     983                 :          0 :     *x1p = x1, *x2p = x2, *y1p = y1, *y2p = y2;
     984                 :          0 :   return rc;
     985                 :            : }
     986                 :            : 
     987                 :            : void
     988                 :          0 : rectclip(long rect)
     989                 :            : {
     990                 :          0 :   PariRect *s = check_rect_init(rect);
     991                 :          0 :   RectObj *next, *R = RHead(s), **prevp = &RHead(s);
     992                 :          0 :   double xmin = 0, xmax = RXsize(s);
     993                 :          0 :   double ymin = 0, ymax = RYsize(s);
     994                 :            : 
     995         [ #  # ]:          0 :   for (; R; R = next) {
     996                 :          0 :     int did_clip = 0;
     997                 :            : #define REMOVE() { *prevp = next; freeobj(R); break; }
     998                 :            : #define NEXT() { prevp = &RoNext(R); break; }
     999                 :            : 
    1000                 :          0 :     next = RoNext(R);
    1001   [ #  #  #  #  :          0 :     switch(RoType(R)) {
                   #  # ]
    1002                 :            :       case ROt_PT:
    1003 [ #  # ][ #  # ]:          0 :         if ( DTOL(RoPTx(R)) < xmin || DTOL(RoPTx(R)) > xmax
    1004 [ #  # ][ #  # ]:          0 :           || DTOL(RoPTy(R)) < ymin || DTOL(RoPTy(R)) > ymax) REMOVE();
    1005                 :          0 :         NEXT();
    1006                 :            :       case ROt_BX:
    1007         [ #  # ]:          0 :         if (RoLNx1(R) < xmin) RoLNx1(R) = xmin, did_clip = 1;
    1008         [ #  # ]:          0 :         if (RoLNx2(R) < xmin) RoLNx2(R) = xmin, did_clip = 1;
    1009         [ #  # ]:          0 :         if (RoLNy1(R) < ymin) RoLNy1(R) = ymin, did_clip = 1;
    1010         [ #  # ]:          0 :         if (RoLNy2(R) < ymin) RoLNy2(R) = ymin, did_clip = 1;
    1011         [ #  # ]:          0 :         if (RoLNx1(R) > xmax) RoLNx1(R) = xmax, did_clip = 1;
    1012         [ #  # ]:          0 :         if (RoLNx2(R) > xmax) RoLNx2(R) = xmax, did_clip = 1;
    1013         [ #  # ]:          0 :         if (RoLNy1(R) > ymax) RoLNy1(R) = ymax, did_clip = 1;
    1014         [ #  # ]:          0 :         if (RoLNy2(R) > ymax) RoLNy2(R) = ymax, did_clip = 1;
    1015                 :            :         /* Remove zero-size clipped boxes */
    1016 [ #  # ][ #  # ]:          0 :         if (did_clip && RoLNx1(R) == RoLNx2(R)
    1017         [ #  # ]:          0 :                      && RoLNy1(R) == RoLNy2(R)) REMOVE();
    1018                 :          0 :         NEXT();
    1019                 :            :       case ROt_LN:
    1020         [ #  # ]:          0 :         if (!clipline(xmin, xmax, ymin, ymax,
    1021                 :            :                       &RoLNx1(R), &RoLNy1(R),
    1022                 :          0 :                       &RoLNx2(R), &RoLNy2(R))) REMOVE();
    1023                 :          0 :         NEXT();
    1024                 :            :       case ROt_MP: {
    1025                 :          0 :         int c = RoMPcnt(R), f = 0, t = 0;
    1026                 :            : 
    1027         [ #  # ]:          0 :         while (f < c) {
    1028 [ #  # ][ #  # ]:          0 :           if ( DTOL(RoMPxs(R)[f]) >= xmin && DTOL(RoMPxs(R)[f]) <= xmax
    1029 [ #  # ][ #  # ]:          0 :             && DTOL(RoMPys(R)[f]) >= ymin && DTOL(RoMPys(R)[f]) <= ymax) {
    1030         [ #  # ]:          0 :             if (t != f) {
    1031                 :          0 :               RoMPxs(R)[t] = RoMPxs(R)[f];
    1032                 :          0 :               RoMPys(R)[t] = RoMPys(R)[f];
    1033                 :            :             }
    1034                 :          0 :             t++;
    1035                 :            :           }
    1036                 :          0 :           f++;
    1037                 :            :         }
    1038         [ #  # ]:          0 :         if (t == 0) REMOVE();
    1039                 :          0 :         RoMPcnt(R) = t;
    1040                 :          0 :         NEXT();
    1041                 :            :       }
    1042                 :            :       case ROt_ML: {
    1043                 :            :         /* Hard case. Break a multiline into several pieces
    1044                 :            :          * if some part is clipped. */
    1045                 :          0 :         int c = RoMPcnt(R) - 1;
    1046                 :          0 :         int f = 0, t = 0, had_lines = 0, had_hole = 0, rc;
    1047                 :          0 :         double ox = RoMLxs(R)[0], oy = RoMLys(R)[0], oxn, oyn;
    1048                 :            : 
    1049         [ #  # ]:          0 :         while (f < c) {
    1050                 :            :         /* Endpoint of this segment is startpoint of next one: need to
    1051                 :            :          * preserve it if it is clipped. */
    1052                 :          0 :           oxn = RoMLxs(R)[f+1];
    1053                 :          0 :           oyn = RoMLys(R)[f+1];
    1054                 :          0 :           rc = clipline(xmin, xmax, ymin, ymax,
    1055                 :            :                   &ox, &oy, /* &RoMLxs(R)[f], &RoMLys(R)[f], */
    1056                 :          0 :                   &RoMLxs(R)[f+1], &RoMLys(R)[f+1]);
    1057                 :          0 :           RoMLxs(R)[f] = ox; ox = oxn;
    1058                 :          0 :           RoMLys(R)[f] = oy; oy = oyn;
    1059         [ #  # ]:          0 :           if (!rc) {
    1060         [ #  # ]:          0 :             if (had_lines) had_hole = 1;
    1061                 :          0 :             f++; continue;
    1062                 :            :           }
    1063                 :            : 
    1064 [ #  # ][ #  # ]:          0 :           if (!had_lines || (!(rc & CLIPLINE_CLIP_1) && !had_hole) ) {
                 [ #  # ]
    1065                 :            :             /* Continuous */
    1066                 :          0 :             had_lines = 1;
    1067         [ #  # ]:          0 :             if (t != f) {
    1068         [ #  # ]:          0 :               if (t == 0) {
    1069                 :          0 :                 RoMPxs(R)[t] = RoMPxs(R)[f];
    1070                 :          0 :                 RoMPys(R)[t] = RoMPys(R)[f];
    1071                 :            :               }
    1072                 :          0 :               RoMPxs(R)[t+1] = RoMPxs(R)[f+1];
    1073                 :          0 :               RoMPys(R)[t+1] = RoMPys(R)[f+1];
    1074                 :            :             }
    1075                 :          0 :             t++;
    1076                 :          0 :             f++;
    1077         [ #  # ]:          0 :             if (rc & CLIPLINE_CLIP_2) had_hole = 1, RoMLcnt(R) = t+1;
    1078                 :          0 :             continue;
    1079                 :            :           }
    1080                 :            :           /* Is not continuous, automatically R is not pari_free()ed.  */
    1081                 :          0 :           t++;
    1082                 :          0 :           RoMLcnt(R) = t;
    1083         [ #  # ]:          0 :           if (rc & CLIPLINE_CLIP_2) { /* Needs separate entry */
    1084                 :          0 :             RectObj *n = (RectObj*) pari_malloc(sizeof(RectObj2P));
    1085                 :            : 
    1086                 :          0 :             RoType(n) = ROt_LN;
    1087                 :          0 :             RoCol(n) = RoCol(R);
    1088                 :          0 :             RoLNx1(n) = RoMLxs(R)[f];        RoLNy1(n) = RoMLys(R)[f];
    1089                 :          0 :             RoLNx2(n) = RoMLxs(R)[f+1];        RoLNy2(n) = RoMLys(R)[f+1];
    1090                 :          0 :             RoNext(n) = next;
    1091                 :          0 :             RoNext(R) = n;
    1092                 :            :             /* Restore the unclipped value: */
    1093                 :          0 :             RoMLxs(R)[f+1] = oxn;        RoMLys(R)[f+1] = oyn;
    1094                 :          0 :             f++;
    1095                 :          0 :             prevp = &RoNext(n);
    1096                 :            :           }
    1097         [ #  # ]:          0 :           if (f + 1 < c) {                /* Are other lines */
    1098                 :          0 :             RectObj *n = (RectObj*) pari_malloc(sizeof(RectObjMP));
    1099                 :          0 :             RoType(n) = ROt_ML;
    1100                 :          0 :             RoCol(n) = RoCol(R);
    1101                 :          0 :             RoMLcnt(n) = c - f;
    1102                 :          0 :             RoMLxs(n) = (double*) pari_malloc(sizeof(double)*(c - f));
    1103                 :          0 :             RoMLys(n) = (double*) pari_malloc(sizeof(double)*(c - f));
    1104                 :          0 :             memcpy(RoMPxs(n),RoMPxs(R) + f, sizeof(double)*(c - f));
    1105                 :          0 :             memcpy(RoMPys(n),RoMPys(R) + f, sizeof(double)*(c - f));
    1106                 :          0 :             RoMPxs(n)[0] = oxn;
    1107                 :          0 :             RoMPys(n)[0] = oyn;
    1108                 :          0 :             RoNext(n) = next;
    1109                 :          0 :             RoNext(R) = n;
    1110                 :          0 :             next = n;
    1111                 :            :           }
    1112                 :          0 :           break;
    1113                 :            :         }
    1114         [ #  # ]:          0 :         if (t == 0) REMOVE();
    1115                 :          0 :         NEXT();
    1116                 :            :       }
    1117                 :            :     }
    1118                 :            : #undef REMOVE
    1119                 :            : #undef NEXT
    1120                 :            :   }
    1121                 :          0 : }
    1122                 :            : 
    1123                 :            : /********************************************************************/
    1124                 :            : /**                                                                **/
    1125                 :            : /**                        HI-RES PLOT                             **/
    1126                 :            : /**                                                                **/
    1127                 :            : /********************************************************************/
    1128                 :            : void
    1129                 :          0 : Printx(dblPointList *f)
    1130                 :            : {
    1131                 :            :   long i;
    1132                 :          0 :   printf("x: [%0.5g,%0.5g], y: [%0.5g,%0.5g]\n",
    1133                 :            :          f->xsml, f->xbig, f->ysml, f->ybig);
    1134         [ #  # ]:          0 :   for (i = 0; i < f->nb; i++) printf("%0.5g ", f->d[i]);
    1135                 :          0 :   printf("\n");
    1136                 :          0 : }
    1137                 :            : 
    1138                 :            : static void
    1139                 :      22236 : Appendx(dblPointList *f, dblPointList *l,double x)
    1140                 :            : {
    1141                 :      22236 :   (l->d)[l->nb++]=x;
    1142         [ +  + ]:      22236 :   if (x < f->xsml) f->xsml = x;
    1143         [ +  + ]:      22236 :   if (x > f->xbig) f->xbig = x;
    1144                 :      22236 : }
    1145                 :            : 
    1146                 :            : static void
    1147                 :     125236 : Appendy(dblPointList *f, dblPointList *l,double y)
    1148                 :            : {
    1149                 :     125236 :   (l->d)[l->nb++]=y;
    1150         [ +  + ]:     125236 :   if (y < f->ysml) f->ysml = y;
    1151         [ +  + ]:     125236 :   if (y > f->ybig) f->ybig = y;
    1152                 :     125236 : }
    1153                 :            : 
    1154                 :            : static void
    1155                 :      30552 : get_xy(long cplx, GEN t, double *x, double *y)
    1156                 :            : {
    1157         [ -  + ]:      30552 :   if (cplx)
    1158                 :            :   {
    1159         [ #  # ]:          0 :     if (typ(t) == t_VEC)
    1160                 :            :     {
    1161         [ #  # ]:          0 :       if (lg(t) != 2) pari_err_DIM("get_xy");
    1162                 :          0 :       t = gel(t,1);
    1163                 :            :     }
    1164                 :          0 :     *x = gtodouble( real_i(t) );
    1165                 :          0 :     *y = gtodouble( imag_i(t) );
    1166                 :            :   }
    1167                 :            :   else
    1168                 :            :   {
    1169 [ +  - ][ -  + ]:      30552 :     if (typ(t) != t_VEC || lg(t) != 3) pari_err_DIM("get_xy");
    1170                 :      30552 :     *x = gtodouble( gel(t,1) );
    1171                 :      30552 :     *y = gtodouble( gel(t,2) );
    1172                 :            :   }
    1173                 :      30552 : }
    1174                 :            : /* t a t_VEC (possibly a scalar if cplx), get next (x,y) coordinate starting
    1175                 :            :  * at index *i [update i] */
    1176                 :            : static void
    1177                 :       6924 : get_xy_from_vec(long cplx, GEN t, long *i, double *x, double *y)
    1178                 :            : {
    1179         [ -  + ]:       6924 :   if (cplx)
    1180                 :            :   {
    1181                 :            :     GEN z;
    1182         [ #  # ]:          0 :     if (typ(t) == t_VEC) z = gel(t,(*i)++); else { z = t; (*i)++; }
    1183                 :          0 :     *x = gtodouble( real_i(z) );
    1184                 :          0 :     *y = gtodouble( imag_i(z) );
    1185                 :            :   }
    1186                 :            :   else
    1187                 :            :   {
    1188                 :       6924 :     *x = gtodouble( gel(t, (*i)++) );
    1189                 :       6924 :     *y = gtodouble( gel(t, (*i)++) );
    1190                 :            :   }
    1191                 :       6924 : }
    1192                 :            : /* X,Y t_VEC, get next (x,y) coordinate starting at index i
    1193                 :            :  * Y ignored if (cplx) */
    1194                 :            : static void
    1195                 :      36772 : get_xy_from_vec2(long cplx, GEN X, GEN Y, long i, double *x, double *y)
    1196                 :            : {
    1197         [ -  + ]:      36772 :   if (cplx)
    1198                 :            :   {
    1199                 :          0 :     GEN z = gel(X,i);
    1200                 :          0 :     *x = gtodouble( real_i(z) );
    1201                 :          0 :     *y = gtodouble( imag_i(z) );
    1202                 :            :   }
    1203                 :            :   else
    1204                 :            :   {
    1205                 :      36772 :     *x = gtodouble( gel(X, i) );
    1206                 :      36772 :     *y = gtodouble( gel(Y, i) );
    1207                 :            :   }
    1208                 :      36772 : }
    1209                 :            : 
    1210                 :            : /* Convert data from GEN to double before we call rectplothrawin. */
    1211                 :            : static dblPointList*
    1212                 :         79 : gtodblList(GEN data, long flags)
    1213                 :            : {
    1214                 :            :   dblPointList *l;
    1215                 :            :   double xsml, xbig, ysml, ybig;
    1216                 :         79 :   long nl=lg(data)-1, lx1, i, j;
    1217                 :         79 :   const long param = (flags & (PLOT_PARAMETRIC|PLOT_COMPLEX));
    1218                 :         79 :   const long cplx = (flags & PLOT_COMPLEX);
    1219                 :            : 
    1220         [ -  + ]:         79 :   if (! is_vec_t(typ(data))) pari_err_TYPE("gtodblList",data);
    1221         [ -  + ]:         79 :   if (!nl) return NULL;
    1222                 :         79 :   lx1 = lg(gel(data,1));
    1223 [ -  + ][ #  # ]:         79 :   if (!param && lx1 == 1) return NULL;
    1224                 :            : 
    1225 [ -  + ][ #  # ]:         79 :   if (nl == 1 && !cplx) pari_err_DIM("gtodblList");
    1226                 :            :   /* Allocate memory, then convert coord. to double */
    1227         [ -  + ]:         79 :   l = (dblPointList*)pari_malloc((cplx? 2*nl: nl)*sizeof(dblPointList));
    1228 [ -  + ][ +  + ]:        158 :   for (i=0; i<nl; i += (cplx? 1: 2))
    1229                 :            :   {
    1230                 :         79 :     dblPointList *LX = l + i, *LY = l + (i+1);
    1231                 :         79 :     GEN x = gel(data,i+1), y;
    1232                 :         79 :     long lx = lg(x);
    1233         [ -  + ]:         79 :     if (!is_vec_t(typ(x))) pari_err_TYPE("gtodblList",x);
    1234         [ -  + ]:         79 :     if (cplx) y = NULL;
    1235                 :            :     else
    1236                 :            :     {
    1237                 :         79 :       y = gel(data,i+2);
    1238         [ -  + ]:         79 :       if (!is_vec_t(typ(y))) pari_err_TYPE("gtodblList",y);
    1239 [ +  - ][ -  + ]:         79 :       if (lg(y) != lx || (!param && lx != lx1)) pari_err_DIM("gtodblList");
                 [ #  # ]
    1240                 :            :     }
    1241                 :            : 
    1242                 :         79 :     lx--;
    1243                 :         79 :     LX->d = (double*)pari_malloc(lx*sizeof(double));
    1244                 :         79 :     LY->d = (double*)pari_malloc(lx*sizeof(double));
    1245         [ +  + ]:      36851 :     for (j=1; j<=lx; j++)
    1246                 :            :     {
    1247                 :            :       double xx, yy;
    1248                 :      36772 :       get_xy_from_vec2(cplx, x,y, j, &xx,&yy);
    1249                 :      36772 :       LX->d[j-1] = xx;
    1250                 :      36772 :       LY->d[j-1] = yy;
    1251                 :            :     }
    1252                 :         79 :     LX->nb = LY->nb = lx;
    1253                 :            :   }
    1254                 :            : 
    1255                 :            :   /* Now compute extremas */
    1256         [ +  - ]:         79 :   if (param)
    1257                 :            :   {
    1258         [ +  - ]:         79 :     l[0].nb = cplx? nl: nl/2;
    1259         [ +  - ]:         79 :     for (i=0; i < l[0].nb; i+=2)
    1260         [ +  - ]:         79 :       if (l[i+1].nb) break;
    1261         [ -  + ]:         79 :     if (i >= l[0].nb) { pari_free(l); return NULL; }
    1262                 :         79 :     xsml = xbig = l[i  ].d[0];
    1263                 :         79 :     ysml = ybig = l[i+1].d[0];
    1264         [ +  + ]:        158 :     for (; i < l[0].nb; i+=2)
    1265                 :            :     {
    1266                 :         79 :       dblPointList *LX = l + i, *LY = l + (i+1);
    1267         [ +  + ]:      36851 :       for (j=0; j < LY->nb; j++)
    1268                 :            :       {
    1269                 :      36772 :         double x = LX->d[j], y = LY->d[j];
    1270 [ -  + ][ +  + ]:      36772 :         if (x < xsml) xsml = x; else if (x > xbig) xbig = x;
    1271 [ -  + ][ +  + ]:      36772 :         if (y < ysml) ysml = y; else if (y > ybig) ybig = y;
    1272                 :            :       }
    1273                 :            :     }
    1274                 :            :   }
    1275                 :            :   else
    1276                 :            :   {
    1277                 :          0 :     l[0].nb = nl-1;
    1278                 :          0 :     xsml = xbig = l[0].d[0];
    1279                 :          0 :     ysml = ybig = l[1].d[0];
    1280         [ #  # ]:          0 :     for (j=0; j < l[1].nb; j++)
    1281                 :            :     {
    1282                 :          0 :       double x = l[0].d[j];
    1283 [ #  # ][ #  # ]:          0 :       if (x < xsml) xsml = x; else if (x > xbig) xbig = x;
    1284                 :            :     }
    1285         [ #  # ]:          0 :     for (i=1; i <= l[0].nb; i++)
    1286         [ #  # ]:          0 :       for (j=0; j < l[i].nb; j++)
    1287                 :            :       {
    1288                 :          0 :         double y = l[i].d[j];
    1289 [ #  # ][ #  # ]:          0 :         if (y < ysml) ysml = y; else if (y > ybig) ybig = y;
    1290                 :            :       }
    1291                 :            :   }
    1292                 :         79 :   l[0].xsml = xsml; l[0].xbig = xbig;
    1293                 :         79 :   l[0].ysml = ysml; l[0].ybig = ybig; return l;
    1294                 :            : }
    1295                 :            : 
    1296                 :            : /* (x+y)/2 */
    1297                 :            : static GEN
    1298                 :      28152 : rmiddle(GEN x, GEN y) { GEN z = addrr(x,y); shiftr_inplace(z,-1); return z; }
    1299                 :            : 
    1300                 :            : static void
    1301                 :          0 : single_recursion(dblPointList *pl,GEN code,GEN xleft,double yleft,
    1302                 :            :   GEN xright,double yright,long depth)
    1303                 :            : {
    1304                 :            :   GEN xx;
    1305                 :          0 :   pari_sp av = avma;
    1306                 :          0 :   double yy, dy=pl[0].ybig - pl[0].ysml;
    1307                 :            : 
    1308         [ #  # ]:          0 :   if (depth==RECUR_MAXDEPTH) return;
    1309                 :            : 
    1310                 :          0 :   xx = rmiddle(xleft,xright);
    1311                 :          0 :   yy = gtodouble(READ_EXPR(code,xx));
    1312                 :            : 
    1313 [ #  # ][ #  # ]:          0 :   if (dy && fabs(yleft+yright-2*yy)< dy*RECUR_PREC) return;
    1314                 :          0 :   single_recursion(pl,code, xleft,yleft, xx,yy, depth+1);
    1315                 :            : 
    1316                 :          0 :   Appendx(&pl[0],&pl[0],rtodbl(xx));
    1317                 :          0 :   Appendy(&pl[0],&pl[1],yy);
    1318                 :            : 
    1319                 :          0 :   single_recursion(pl,code, xx,yy, xright,yright, depth+1);
    1320                 :          0 :   avma = av;
    1321                 :            : }
    1322                 :            : 
    1323                 :            : static void
    1324                 :      28200 : param_recursion(long cplx, dblPointList *pl,GEN code,GEN tleft,double xleft,
    1325                 :            :   double yleft, GEN tright,double xright,double yright, long depth)
    1326                 :            : {
    1327                 :            :   GEN tt, p1;
    1328                 :      28200 :   pari_sp av=avma;
    1329                 :      28200 :   double xx, dy=pl[0].ybig - pl[0].ysml;
    1330                 :      28200 :   double yy, dx=pl[0].xbig - pl[0].xsml;
    1331                 :            : 
    1332         [ +  + ]:      28200 :   if (depth==RECUR_MAXDEPTH) return;
    1333                 :            : 
    1334                 :      28152 :   tt = rmiddle(tleft,tright);
    1335                 :      28152 :   p1 = READ_EXPR(code,tt);
    1336                 :      28152 :   get_xy(cplx, p1, &xx,&yy);
    1337                 :            : 
    1338 [ +  + ][ +  - ]:      28152 :   if (dx && dy && fabs(xleft+xright-2*xx) < dx*RECUR_PREC
                 [ +  + ]
    1339         [ +  + ]:      21096 :                && fabs(yleft+yright-2*yy) < dy*RECUR_PREC) return;
    1340                 :      12912 :   param_recursion(cplx, pl,code, tleft,xleft,yleft, tt,xx,yy, depth+1);
    1341                 :            : 
    1342                 :      12912 :   Appendx(&pl[0],&pl[0],xx);
    1343                 :      12912 :   Appendy(&pl[0],&pl[1],yy);
    1344                 :            : 
    1345                 :      12912 :   param_recursion(cplx, pl,code, tt,xx,yy, tright,xright,yright, depth+1);
    1346                 :      28200 :   avma = av;
    1347                 :            : }
    1348                 :            : 
    1349                 :            : /* Graph 'code' for parameter values in [a,b], using 'testpoints' sample
    1350                 :            :  * points (0 = use a default value); code is either a t_CLOSURE (from GP:
    1351                 :            :  * ploth, etc.) or a t_POL/t_VEC of two t_POLs from rectsplines. Returns a
    1352                 :            :  * dblPointList of (absolute) coordinates. */
    1353                 :            : static dblPointList *
    1354                 :        190 : rectplothin(GEN a, GEN b, GEN code, long prec, ulong flags, long testpoints)
    1355                 :            : {
    1356                 :        190 :   const double INF = 1./0.;
    1357                 :        190 :   const long param = flags & (PLOT_PARAMETRIC|PLOT_COMPLEX);
    1358                 :        190 :   const long recur = flags & PLOT_RECURSIVE;
    1359                 :        190 :   const long cplx = flags & PLOT_COMPLEX;
    1360                 :            :   GEN t,dx,x;
    1361                 :            :   dblPointList *pl;
    1362                 :        190 :   long tx, i, j, sig, nc, nl, ncoords, nbpoints, non_vec = 0;
    1363                 :        190 :   pari_sp av = avma;
    1364                 :            : 
    1365         [ -  + ]:        190 :   sig = gcmp(b,a); if (!sig) return NULL;
    1366         [ -  + ]:        190 :   if (sig < 0) swap(a, b);
    1367         [ +  + ]:        190 :   if (testpoints)
    1368                 :            :   {
    1369         [ +  + ]:         95 :     if (testpoints < 2)
    1370                 :         16 :       pari_err_DOMAIN("ploth", "#points", "<", gen_2, stoi(testpoints));
    1371                 :            :   }
    1372                 :            :   else
    1373                 :            :   {
    1374         [ -  + ]:         95 :     if (recur) testpoints = 8;
    1375         [ +  + ]:         95 :     else       testpoints = param? 1500: 1000;
    1376                 :            :   }
    1377                 :            :   /* compute F(a) to determine nc = #curves; nl = #coord. lists */
    1378                 :        174 :   x = gtofp(a, prec);
    1379         [ +  - ]:        174 :   if (typ(code) == t_CLOSURE) push_lex(x, code);
    1380                 :        174 :   t = READ_EXPR(code,x); tx = typ(t);
    1381         [ +  + ]:        174 :   if (param)
    1382                 :            :   {
    1383 [ -  + ][ #  # ]:         71 :     if (cplx) nc = nl = (tx == t_VEC)? lg(t)-1: 1;
    1384                 :            :     else
    1385                 :            :     {
    1386         [ -  + ]:         71 :       if (tx != t_VEC)
    1387                 :          0 :         pari_err_TYPE("ploth [not a t_VEC with PLOT_PARAMETRIC]", t);
    1388                 :         71 :       nl = lg(t)-1;
    1389                 :         71 :       nc = nl/2;
    1390         [ -  + ]:         71 :       if (odd(nl))
    1391                 :          0 :         pari_err_TYPE("ploth [parametric ploc with odd # of components]",t);
    1392                 :            :     }
    1393                 :            :   }
    1394                 :            :   else
    1395                 :            :   {
    1396         [ +  + ]:        103 :     if (!is_matvec_t(tx)) { nl = 2; non_vec = 1; }
    1397                 :            :     else
    1398                 :            :     {
    1399         [ -  + ]:         48 :       if (tx != t_VEC) pari_err_TYPE("ploth [not a t_VEC]",t);
    1400                 :         48 :       nl = lg(t);
    1401                 :            :     }
    1402                 :        103 :     nc = nl-1;
    1403                 :            :   }
    1404         [ -  + ]:        174 :   if (!nc) { avma = av; return NULL; }
    1405 [ +  + ][ +  + ]:        174 :   if (recur && nc > 1)
    1406                 :         24 :     pari_err_TYPE("ploth [multi-curves cannot be plot recursively]",t);
    1407                 :            : 
    1408         [ -  + ]:        150 :   ncoords = cplx? 2*nl: nl;
    1409         [ +  + ]:        150 :   nbpoints = recur? testpoints << RECUR_MAXDEPTH: testpoints;
    1410                 :        150 :   pl=(dblPointList*) pari_malloc(ncoords*sizeof(dblPointList));
    1411                 :            :   /* set [xy]sml,[xy]big to default values */
    1412         [ +  + ]:        150 :   if (param)
    1413                 :            :   {
    1414                 :         71 :     pl[0].xsml = INF;
    1415                 :         71 :     pl[0].xbig =-INF;
    1416                 :            :   } else {
    1417                 :         79 :     pl[0].xsml = gtodouble(a);
    1418                 :         79 :     pl[0].xbig = gtodouble(b);
    1419                 :            :   }
    1420                 :        150 :   pl[0].ysml = INF;
    1421                 :        150 :   pl[0].ybig =-INF;
    1422         [ +  + ]:        474 :   for (i = 0; i < ncoords; i++)
    1423                 :            :   {
    1424                 :        324 :     pl[i].d = (double*)pari_malloc((nbpoints+1)*sizeof(double));
    1425                 :        324 :     pl[i].nb=0;
    1426                 :            :   }
    1427                 :        150 :   dx = divru(gtofp(gsub(b,a),prec), testpoints-1);
    1428         [ +  + ]:        150 :   if (recur) /* recursive plot */
    1429                 :            :   {
    1430                 :         24 :     double yleft, yright = 0;
    1431         [ +  - ]:         24 :     if (param)
    1432                 :            :     {
    1433                 :         24 :       GEN tleft = cgetr(prec), tright = cgetr(prec);
    1434                 :         24 :       double xleft, xright = 0;
    1435                 :         24 :       pari_sp av2 = avma;
    1436                 :         24 :       affgr(a,tleft);
    1437                 :         24 :       t = READ_EXPR(code,tleft);
    1438                 :         24 :       get_xy(cplx,t, &xleft,&yleft);
    1439         [ +  + ]:       2400 :       for (i=0; i<testpoints-1; i++, avma = av2)
    1440                 :            :       {
    1441         [ +  + ]:       2376 :         if (i) { affrr(tright,tleft); xleft = xright; yleft = yright; }
    1442                 :       2376 :         addrrz(tleft,dx,tright);
    1443                 :       2376 :         t = READ_EXPR(code,tright);
    1444                 :       2376 :         get_xy(cplx,t, &xright,&yright);
    1445                 :       2376 :         Appendx(&pl[0],&pl[0],xleft);
    1446                 :       2376 :         Appendy(&pl[0],&pl[1],yleft);
    1447                 :       2376 :         param_recursion(cplx, pl,code, tleft,xleft,yleft, tright,xright,yright, 0);
    1448                 :            :       }
    1449                 :         24 :       Appendx(&pl[0],&pl[0],xright);
    1450                 :         24 :       Appendy(&pl[0],&pl[1],yright);
    1451                 :            :     }
    1452                 :            :     else /* single curve */
    1453                 :            :     {
    1454                 :          0 :       GEN xleft = cgetr(prec), xright = cgetr(prec);
    1455                 :          0 :       pari_sp av2 = avma;
    1456                 :          0 :       affgr(a,xleft);
    1457                 :          0 :       yleft = gtodouble(READ_EXPR(code,xleft));
    1458         [ #  # ]:          0 :       for (i=0; i<testpoints-1; i++, avma = av2)
    1459                 :            :       {
    1460                 :          0 :         addrrz(xleft,dx,xright);
    1461                 :          0 :         yright = gtodouble(READ_EXPR(code,xright));
    1462                 :            : 
    1463                 :          0 :         Appendx(&pl[0],&pl[0],rtodbl(xleft));
    1464                 :          0 :         Appendy(&pl[0],&pl[1],yleft);
    1465                 :            : 
    1466                 :          0 :         single_recursion(pl,code,xleft,yleft,xright,yright,0);
    1467                 :          0 :         affrr(xright,xleft); yleft = yright;
    1468                 :            :       }
    1469                 :          0 :       Appendx(&pl[0],&pl[0],rtodbl(xright));
    1470                 :         24 :       Appendy(&pl[0],&pl[1],yright);
    1471                 :            :     }
    1472                 :            :   }
    1473                 :            :   else /* non-recursive plot */
    1474                 :            :   {
    1475                 :        126 :     pari_sp av2 = avma;
    1476         [ +  + ]:        126 :     if (param)
    1477                 :            :     {
    1478         [ +  + ]:       6971 :       for (i=0; i<testpoints; i++, affrr(addrr(x,dx), x), avma = av2)
    1479                 :            :       {
    1480                 :            :         long k, nt;
    1481                 :       6940 :         t = READ_EXPR(code,x);
    1482         [ +  + ]:       6940 :         if (typ(t) != t_VEC)
    1483                 :            :         {
    1484         [ -  + ]:         16 :           if (cplx) nt = 1;
    1485                 :         16 :           else nt = 0; /* trigger error */
    1486                 :            :         }
    1487                 :            :         else
    1488                 :       6924 :           nt = lg(t)-1;
    1489         [ +  + ]:       6940 :         if (nt != nl) pari_err_DIM("rectploth");
    1490                 :       6924 :         k = 0; j = 1;
    1491         [ +  + ]:      13848 :         while (j <= nl)
    1492                 :            :         {
    1493                 :            :           double xx, yy;
    1494                 :       6924 :           get_xy_from_vec(cplx, t, &j, &xx, &yy);
    1495                 :       6924 :           Appendx(&pl[0], &pl[k++], xx);
    1496                 :       6924 :           Appendy(&pl[0], &pl[k++], yy);
    1497                 :            :         }
    1498                 :            :       }
    1499                 :            :     }
    1500         [ +  + ]:         79 :     else if (non_vec)
    1501         [ +  + ]:      55055 :       for (i=0; i<testpoints; i++, affrr(addrr(x,dx), x), avma = av2)
    1502                 :            :       {
    1503                 :      55000 :         t = READ_EXPR(code,x);
    1504                 :      55000 :         pl[0].d[i] = gtodouble(x);
    1505                 :      55000 :         Appendy(&pl[0],&pl[1], gtodouble(t));
    1506                 :            :       }
    1507                 :            :     else /* vector of non-parametric curves */
    1508         [ +  + ]:      24024 :       for (i=0; i<testpoints; i++, affrr(addrr(x,dx), x), avma = av2)
    1509                 :            :       {
    1510                 :      24000 :         t = READ_EXPR(code,x);
    1511 [ +  - ][ -  + ]:      24000 :         if (typ(t) != t_VEC || lg(t) != nl) pari_err_DIM("rectploth");
    1512                 :      24000 :         pl[0].d[i] = gtodouble(x);
    1513         [ +  + ]:      72000 :         for (j=1; j<nl; j++) Appendy(&pl[0],&pl[j], gtodouble(gel(t,j)));
    1514                 :            :       }
    1515                 :            :   }
    1516         [ +  - ]:        134 :   if (typ(code) == t_CLOSURE) pop_lex(1);
    1517                 :        134 :   pl[0].nb = nc; avma = av; return pl;
    1518                 :            : }
    1519                 :            : 
    1520                 :            : /* Uses highlevel plotting functions to implement splines as
    1521                 :            :    a low-level plotting function. */
    1522                 :            : static void
    1523                 :          0 : rectsplines(long ne, double *x, double *y, long lx, long flag)
    1524                 :            : {
    1525                 :            :   long i, j;
    1526                 :          0 :   pari_sp av0 = avma;
    1527                 :          0 :   GEN X = pol_x(0), xa = cgetg(lx+1, t_VEC), ya = cgetg(lx+1, t_VEC);
    1528                 :            :   GEN tas, pol3;
    1529                 :          0 :   long param = flag & PLOT_PARAMETRIC;
    1530                 :            : 
    1531         [ #  # ]:          0 :   if (lx < 4) pari_err(e_MISC, "Too few points (%ld) for spline plot", lx);
    1532         [ #  # ]:          0 :   for (i = 1; i <= lx; i++) {
    1533                 :          0 :     gel(xa,i) = dbltor(x[i-1]);
    1534                 :          0 :     gel(ya,i) = dbltor(y[i-1]);
    1535                 :            :   }
    1536         [ #  # ]:          0 :   if (param) {
    1537                 :          0 :     tas = new_chunk(4);
    1538         [ #  # ]:          0 :     for (j = 1; j <= 4; j++) gel(tas,j-1) = utoipos(j);
    1539                 :          0 :     pol3 = cgetg(3, t_VEC);
    1540                 :            :   }
    1541                 :            :   else
    1542                 :          0 :     tas = pol3 = NULL; /* gcc -Wall */
    1543         [ #  # ]:          0 :   for (i = 0; i <= lx - 4; i++) {
    1544                 :          0 :     pari_sp av = avma;
    1545                 :            : 
    1546                 :          0 :     xa++; ya++;
    1547         [ #  # ]:          0 :     if (param) {
    1548                 :          0 :       gel(pol3,1) = polint_i(tas, xa, X, 4, NULL);
    1549                 :          0 :       gel(pol3,2) = polint_i(tas, ya, X, 4, NULL);
    1550                 :            :     } else {
    1551                 :          0 :       pol3 = polint_i(xa, ya, X, 4, NULL);
    1552                 :          0 :       tas = xa;
    1553                 :            :     }
    1554                 :            :     /* Start with 3 points */
    1555 [ #  # ][ #  # ]:          0 :     rectploth(ne, i==   0 ? gel(tas,0) : gel(tas,1),
    1556                 :          0 :                   i==lx-4 ? gel(tas,3) : gel(tas,2), pol3,
    1557                 :            :                   DEFAULTPREC, PLOT_RECURSIVE | PLOT_NO_RESCALE
    1558                 :          0 :                   | PLOT_NO_FRAME | PLOT_NO_AXE_Y | PLOT_NO_AXE_X | param, 2);
    1559                 :          0 :     avma = av;
    1560                 :            :   }
    1561                 :          0 :   avma = av0;
    1562                 :          0 : }
    1563                 :            : 
    1564                 :            : static void
    1565                 :        426 : set_range(double m, double M, double *sml, double *big)
    1566                 :            : {
    1567         [ -  + ]:        426 :   if (M - m < 1.e-9)
    1568                 :            :   {
    1569         [ #  # ]:          0 :     double d = fabs(m)/10; if (!d) d = 0.1;
    1570                 :          0 :     M += d; m -= d;
    1571                 :            :   }
    1572                 :        426 :   *sml = m; *big = M;
    1573                 :        426 : }
    1574                 :            : /* Plot a dblPointList. Complete with axes, bounding box, etc.
    1575                 :            :  *
    1576                 :            :  * data is an array of structs. Its meaning depends on flags :
    1577                 :            :  *
    1578                 :            :  * + data[0] contains global extremas, the number of curves to plot
    1579                 :            :  *   (data[0].nb) and a list of doubles (first set of x-coordinates).
    1580                 :            :  *
    1581                 :            :  * + data[i].nb (i>0) contains the number of points in the list
    1582                 :            :  *   data[i].d (hopefully, data[2i].nb=data[2i+1].nb when i>0...)
    1583                 :            :  *
    1584                 :            :  * + If flags contain PLOT_PARAMETRIC, the array length should be
    1585                 :            :  *   even, and successive pairs (data[2i].d, data[2i+1].d) represent
    1586                 :            :  *   curves to plot.
    1587                 :            :  *
    1588                 :            :  * + If there is no such flag, the first element is an array with
    1589                 :            :  *   x-coordinates and the following ones contain y-coordinates.
    1590                 :            :  * If grect >= 0, output to this rectwindow. Otherwise draw immediately to
    1591                 :            :  * screen (grect=-1) or to screen (grect=-2), using two drawing rectangles:
    1592                 :            :  * one for labels, another for graphs.*/
    1593                 :            : static GEN
    1594                 :        213 : rectplothrawin(long grect, dblPointList *data, long flags)
    1595                 :            : {
    1596                 :        213 :   const long param = flags & (PLOT_PARAMETRIC|PLOT_COMPLEX);
    1597                 :        213 :   const pari_sp av = avma;
    1598                 :            :   PARI_plot *W;
    1599                 :            :   dblPointList y,x;
    1600                 :            :   double xsml, xbig, ysml, ybig;
    1601                 :            :   long ltype, max_graphcolors;
    1602                 :            :   long i,nc,nbpoints, w[2], wx[2], wy[2];
    1603                 :            : 
    1604         [ -  + ]:        213 :   if (!data) return cgetg(1,t_VEC);
    1605                 :        213 :   x = data[0]; nc = x.nb;
    1606                 :        213 :   set_range(x.xsml, x.xbig, &xsml, &xbig);
    1607                 :        213 :   set_range(x.ysml, x.ybig, &ysml, &ybig);
    1608         [ -  + ]:        213 :   if (grect >= 0) /* output to rectwindow, no labels */
    1609                 :          0 :     W = NULL;
    1610                 :            :   else
    1611                 :            :   {
    1612                 :        213 :     const long srect = NUMRECT-2;
    1613                 :            :     long lm, rm, tm, bm;
    1614                 :            : 
    1615         [ +  + ]:        213 :     if (grect == -1) /* output to screen */
    1616                 :        144 :     { W = &pari_plot; PARI_get_plot(); }
    1617                 :            :     else /* output to file */
    1618                 :         69 :     { W = &pari_psplot; PARI_get_psplot(); }
    1619                 :         69 :     grect = NUMRECT-1;
    1620                 :            :     /* left/right/top/bottom margin */
    1621                 :         69 :     lm = W->fwidth*10;
    1622                 :         69 :     rm = W->hunit-1;
    1623                 :         69 :     tm = W->vunit-1;
    1624                 :         69 :     bm = W->vunit+W->fheight-1;
    1625                 :         69 :     w[0] = srect; wx[0] = 0;  wy[0] = 0;
    1626                 :         69 :     w[1] = grect;   wx[1] = lm; wy[1] = tm;
    1627                 :            :    /* Window (width x height) is given in pixels, correct pixels are 0..n-1,
    1628                 :            :     * whereas rect functions work with windows whose pixel range is [0,n] */
    1629                 :         69 :     initrect(srect, W->width - 1, W->height - 1);
    1630                 :         69 :     rectlinetype(srect,-2); /* Frame */
    1631                 :         69 :     current_color[srect] = DEFAULT_COLOR;
    1632                 :         69 :     initrect(grect, W->width - (lm+rm) - 1, W->height - (tm+bm) - 1);
    1633                 :            :     /* draw labels on srect */
    1634                 :         69 :     put_label(srect, lm, 0, ybig, RoSTdirRIGHT|RoSTdirHGAP|RoSTdirTOP);
    1635                 :         69 :     put_label(srect, lm, W->height-bm, ysml, RoSTdirRIGHT|RoSTdirHGAP|RoSTdirVGAP);
    1636                 :         69 :     put_label(srect, lm, W->height - bm, xsml, RoSTdirLEFT|RoSTdirTOP);
    1637                 :         69 :     put_label(srect, W->width-rm-1, W->height-bm, xbig, RoSTdirRIGHT|RoSTdirTOP);
    1638                 :            :   }
    1639                 :         69 :   RHasGraph(check_rect(grect)) = 1;
    1640                 :            : 
    1641         [ +  - ]:         69 :   if (!(flags & PLOT_NO_RESCALE))
    1642                 :         69 :     rectscale0(grect, xsml, xbig, ysml, ybig);
    1643                 :            : 
    1644         [ +  - ]:         69 :   if (!(flags & PLOT_NO_FRAME))
    1645                 :            :   {
    1646         [ -  + ]:         69 :     int do_double = (flags & PLOT_NODOUBLETICK) ? TICKS_NODOUBLE : 0;
    1647                 :         69 :     PARI_plot *pl = W;
    1648         [ -  + ]:         69 :     if (!pl) { PARI_get_plot(); pl = &pari_plot; }
    1649                 :            : 
    1650                 :         69 :     rectlinetype(grect, -2); /* Frame. */
    1651                 :         69 :     current_color[grect] = DEFAULT_COLOR;
    1652                 :         69 :     rectmove0(grect,xsml,ysml,0);
    1653                 :         69 :     rectbox0(grect,xbig,ybig,0);
    1654         [ +  - ]:         69 :     if (!(flags & PLOT_NO_TICK_X)) {
    1655                 :         69 :       rectticks(pl, grect, xsml, ysml, xbig, ysml, xsml, xbig,
    1656                 :         69 :         TICKS_CLOCKW | do_double);
    1657                 :         69 :       rectticks(pl, grect, xbig, ybig, xsml, ybig, xbig, xsml,
    1658                 :         69 :         TICKS_CLOCKW | do_double);
    1659                 :            :     }
    1660         [ +  - ]:         69 :     if (!(flags & PLOT_NO_TICK_Y)) {
    1661                 :         69 :       rectticks(pl, grect, xbig, ysml, xbig, ybig, ysml, ybig,
    1662                 :         69 :         TICKS_CLOCKW | do_double);
    1663                 :         69 :       rectticks(pl, grect, xsml, ybig, xsml, ysml, ybig, ysml,
    1664                 :         69 :         TICKS_CLOCKW | do_double);
    1665                 :            :     }
    1666                 :            :   }
    1667                 :            : 
    1668 [ +  - ][ +  + ]:         69 :   if (!(flags & PLOT_NO_AXE_Y) && (xsml<=0 && xbig >=0))
                 [ +  - ]
    1669                 :            :   {
    1670                 :         62 :     rectlinetype(grect, -1); /* Axes. */
    1671                 :         62 :     current_color[grect] = AXIS_COLOR;
    1672                 :         62 :     rectmove0(grect,0.0,ysml,0);
    1673                 :         62 :     rectline0(grect,0.0,ybig,0);
    1674                 :            :   }
    1675                 :            : 
    1676 [ +  - ][ +  + ]:         69 :   if (!(flags & PLOT_NO_AXE_X) && (ysml<=0 && ybig >=0))
                 [ +  - ]
    1677                 :            :   {
    1678                 :         62 :     rectlinetype(grect, -1); /* Axes. */
    1679                 :         62 :     current_color[grect] = AXIS_COLOR;
    1680                 :         62 :     rectmove0(grect,xsml,0.0,0);
    1681                 :         62 :     rectline0(grect,xbig,0.0,0);
    1682                 :            :   }
    1683                 :            : 
    1684         [ +  + ]:         69 :   if (param) {
    1685                 :         38 :     i = 0;
    1686                 :         38 :     flags |= PLOT_PARAMETRIC;
    1687                 :         38 :     flags &= (~PLOT_COMPLEX); /* turn COMPLEX to PARAMETRIC*/
    1688                 :         31 :   } else i = 1;
    1689                 :         69 :   max_graphcolors = lg(GP_DATA->graphcolors)-1;
    1690         [ +  + ]:        138 :   for (ltype = 0; ltype < nc; ltype++)
    1691                 :            :   {
    1692                 :         69 :     current_color[grect] = GP_DATA->graphcolors[1+(ltype%max_graphcolors)];
    1693         [ +  + ]:         69 :     if (param) x = data[i++];
    1694                 :            : 
    1695                 :         69 :     y = data[i++]; nbpoints = y.nb;
    1696         [ +  + ]:         69 :     if (flags & (PLOT_POINTS_LINES|PLOT_POINTS)) {
    1697                 :          7 :       rectlinetype(grect, rectpoint_itype + ltype); /* Graphs */
    1698                 :          7 :       rectpointtype(grect,rectpoint_itype + ltype); /* Graphs */
    1699                 :          7 :       rectpoints0(grect,x.d,y.d,nbpoints);
    1700         [ +  - ]:          7 :       if (!(flags & PLOT_POINTS_LINES)) continue;
    1701                 :            :     }
    1702                 :            : 
    1703         [ -  + ]:         62 :     if (flags & PLOT_SPLINES) {
    1704                 :            :       /* rectsplines will call us back with ltype == 0 */
    1705                 :          0 :       int old = rectline_itype;
    1706                 :            : 
    1707                 :          0 :       rectline_itype = rectline_itype + ltype;
    1708                 :          0 :       rectsplines(grect,x.d,y.d,nbpoints,flags);
    1709                 :          0 :       rectline_itype = old;
    1710                 :            :     } else {
    1711                 :         62 :       rectlinetype(grect, rectline_itype + ltype); /* Graphs */
    1712                 :         62 :       rectlines0(grect,x.d,y.d,nbpoints,0);
    1713                 :            :     }
    1714                 :            :   }
    1715         [ +  + ]:        207 :   for (i--; i>=0; i--) pari_free(data[i].d);
    1716                 :         69 :   pari_free(data);
    1717                 :            : 
    1718         [ +  - ]:         69 :   if (W)
    1719                 :            :   {
    1720         [ -  + ]:         69 :     if (W == &pari_plot)
    1721                 :          0 :       rectdraw0(w,wx,wy,2);
    1722                 :            :     else
    1723                 :         69 :       postdraw0(w,wx,wy,2, 0);
    1724                 :         69 :     killrect(w[1]);
    1725                 :         69 :     killrect(w[0]);
    1726                 :            :   }
    1727                 :         69 :   avma = av;
    1728                 :         69 :   retmkvec4(dbltor(xsml), dbltor(xbig), dbltor(ysml), dbltor(ybig));
    1729                 :            : }
    1730                 :            : 
    1731                 :            : /*************************************************************************/
    1732                 :            : /*                                                                       */
    1733                 :            : /*                          HI-RES FUNCTIONS                             */
    1734                 :            : /*                                                                       */
    1735                 :            : /*************************************************************************/
    1736                 :            : 
    1737                 :            : GEN
    1738                 :        190 : rectploth(long ne, GEN a,GEN b,GEN code, long prec,ulong flags,long tpts)
    1739                 :            : {
    1740                 :        190 :   dblPointList *pl = rectplothin(a,b, code, prec, flags, tpts);
    1741                 :        134 :   return rectplothrawin(ne, pl, flags);
    1742                 :            : }
    1743                 :            : 
    1744                 :            : GEN
    1745                 :         79 : rectplothraw(long ne, GEN data, long flags)
    1746                 :            : {
    1747                 :         79 :   dblPointList *pl = gtodblList(data,flags);
    1748                 :         79 :   return rectplothrawin(ne, pl, flags);
    1749                 :            : }
    1750                 :            : 
    1751                 :            : static long
    1752                 :         79 : plothraw_flags(long fl)
    1753                 :            : {
    1754      [ +  +  - ]:         79 :   switch(fl)
    1755                 :            :   {
    1756                 :         31 :     case 0: return PLOT_PARAMETRIC|PLOT_POINTS;
    1757                 :         48 :     case 1: return PLOT_PARAMETRIC;
    1758                 :         79 :     default:return PLOT_PARAMETRIC|fl;
    1759                 :            :   }
    1760                 :            : }
    1761                 :            : static GEN
    1762                 :         79 : plothraw0(long ne, GEN listx, GEN listy, long flags)
    1763                 :            : {
    1764                 :         79 :   pari_sp av = avma;
    1765                 :         79 :   GEN z = rectplothraw(ne, mkvec2(listx,listy), plothraw_flags(flags));
    1766                 :         31 :   return gerepileupto(av, z);
    1767                 :            : }
    1768                 :            : 
    1769                 :            : GEN
    1770                 :         48 : plothraw(GEN listx, GEN listy, long flags)
    1771                 :         48 : { return plothraw0(-1, listx, listy, flags); }
    1772                 :            : 
    1773                 :            : GEN
    1774                 :        152 : ploth(GEN a, GEN b, GEN code, long prec,long flags,long numpoints)
    1775                 :        152 : { return rectploth(-1, a,b,code,prec,flags,numpoints); }
    1776                 :            : GEN
    1777                 :          0 : ploth2(GEN a, GEN b, GEN code, long prec)
    1778                 :          0 : { return rectploth(-1, a,b,code,prec,PLOT_PARAMETRIC,0); }
    1779                 :            : GEN
    1780                 :          0 : plothmult(GEN a, GEN b, GEN code, long prec)
    1781                 :          0 : { return rectploth(-1, a,b,code,prec,0,0); }
    1782                 :            : 
    1783                 :            : GEN
    1784                 :         31 : postplothraw(GEN listx, GEN listy, long flags)
    1785                 :         31 : { return plothraw0(-2, listx, listy, flags); }
    1786                 :            : GEN
    1787                 :         38 : postploth(GEN a, GEN b, GEN code, long prec,long flags, long numpoints)
    1788                 :         38 : { return rectploth(-2, a,b,code,prec, flags,numpoints); }
    1789                 :            : GEN
    1790                 :          0 : postploth2(GEN a, GEN b, GEN code, long prec, long numpoints)
    1791                 :          0 : { return rectploth(-2, a,b,code,prec, PLOT_PARAMETRIC,numpoints); }
    1792                 :            : 
    1793                 :            : GEN
    1794                 :          0 : plothsizes(void) { return plothsizes_flag(0); }
    1795                 :            : GEN
    1796                 :         28 : plothsizes_flag(long flag)
    1797                 :            : {
    1798                 :         28 :   GEN vect = cgetg(1+6,t_VEC);
    1799                 :            : 
    1800                 :         28 :   PARI_get_plot();
    1801                 :          0 :   gel(vect,1) = stoi(pari_plot.width);
    1802                 :          0 :   gel(vect,2) = stoi(pari_plot.height);
    1803         [ #  # ]:          0 :   if (flag) {
    1804                 :          0 :     gel(vect,3) = dbltor(pari_plot.hunit*1.0/pari_plot.width);
    1805                 :          0 :     gel(vect,4) = dbltor(pari_plot.vunit*1.0/pari_plot.height);
    1806                 :          0 :     gel(vect,5) = dbltor(pari_plot.fwidth*1.0/pari_plot.width);
    1807                 :          0 :     gel(vect,6) = dbltor(pari_plot.fheight*1.0/pari_plot.height);
    1808                 :            :   } else {
    1809                 :          0 :     gel(vect,3) = stoi(pari_plot.hunit);
    1810                 :          0 :     gel(vect,4) = stoi(pari_plot.vunit);
    1811                 :          0 :     gel(vect,5) = stoi(pari_plot.fwidth);
    1812                 :          0 :     gel(vect,6) = stoi(pari_plot.fheight);
    1813                 :            :   }
    1814                 :          0 :   return vect;
    1815                 :            : }
    1816                 :            : 
    1817                 :            : void
    1818                 :          0 : plot_count(long *w, long lw, col_counter rcolcnt)
    1819                 :            : {
    1820                 :            :   RectObj *O;
    1821                 :            :   long col, i;
    1822                 :            : 
    1823         [ #  # ]:          0 :   for (col = 1; col < lg(GP_DATA->colormap)-1; col++)
    1824         [ #  # ]:          0 :     for (i = 0; i < ROt_MAX; i++) rcolcnt[col][i] = 0;
    1825         [ #  # ]:          0 :   for (i = 0; i < lw; i++)
    1826                 :            :   {
    1827                 :          0 :     PariRect *e = rectgraph[w[i]];
    1828         [ #  # ]:          0 :     for (O = RHead(e); O; O=RoNext(O))
    1829      [ #  #  # ]:          0 :       switch(RoType(O))
    1830                 :            :       {
    1831                 :          0 :         case ROt_MP : rcolcnt[RoCol(O)][ROt_PT] += RoMPcnt(O);
    1832                 :          0 :                       break;                 /* Multiple Point */
    1833                 :            :         case ROt_PT :                        /* Point */
    1834                 :            :         case ROt_LN :                        /* Line */
    1835                 :            :         case ROt_BX :                        /* Box */
    1836                 :            :         case ROt_ML :                        /* Multiple lines */
    1837                 :          0 :         case ROt_ST : rcolcnt[RoCol(O)][RoType(O)]++;
    1838                 :          0 :                       break;                 /* String */
    1839                 :            :       }
    1840                 :            :   }
    1841                 :          0 : }
    1842                 :            : /*************************************************************************/
    1843                 :            : /*                                                                       */
    1844                 :            : /*                         POSTSCRIPT OUTPUT                             */
    1845                 :            : /*                                                                       */
    1846                 :            : /*************************************************************************/
    1847                 :            : 
    1848                 :            : static void
    1849                 :        199 : PARI_get_psplot(void)
    1850                 :            : {
    1851         [ +  + ]:        230 :   if (pari_psplot.init) return;
    1852                 :         31 :   pari_psplot.init = 1;
    1853                 :            : 
    1854                 :         31 :   pari_psplot.width = 1120 - 60; /* 1400 - 60 for hi-res */
    1855                 :         31 :   pari_psplot.height=  800 - 40; /* 1120 - 60 for hi-res */
    1856                 :         31 :   pari_psplot.fheight= 15;
    1857                 :         31 :   pari_psplot.fwidth = 6;
    1858                 :         31 :   pari_psplot.hunit = 5;
    1859                 :         31 :   pari_psplot.vunit = 5;
    1860                 :            : }
    1861                 :            : 
    1862                 :            : static void
    1863                 :        113 : gendraw(GEN list, long ps, long flag)
    1864                 :            : {
    1865                 :            :   long i,n,ne,*w,*x,*y;
    1866                 :            : 
    1867         [ -  + ]:        113 :   if (typ(list) != t_VEC) pari_err_TYPE("rectdraw",list);
    1868         [ -  + ]:        194 :   n = lg(list)-1; if (!n) return;
    1869         [ -  + ]:        113 :   if (n%3) pari_err_DIM("rectdraw");
    1870                 :        113 :   n = n/3;
    1871                 :        113 :   w = (long*)pari_malloc(n*sizeof(long));
    1872                 :        113 :   x = (long*)pari_malloc(n*sizeof(long));
    1873                 :        113 :   y = (long*)pari_malloc(n*sizeof(long));
    1874         [ -  + ]:        113 :   if (flag) PARI_get_plot();
    1875         [ +  + ]:        226 :   for (i=0; i<n; i++)
    1876                 :            :   {
    1877                 :        113 :     GEN win = gel(list,3*i+1), x0 = gel(list,3*i+2), y0 = gel(list,3*i+3);
    1878                 :            :     long xi, yi;
    1879         [ -  + ]:        113 :     if (typ(win)!=t_INT) pari_err_TYPE("rectdraw",win);
    1880         [ -  + ]:        113 :     if (flag) {
    1881                 :          0 :       xi = DTOL(gtodouble(x0)*(pari_plot.width - 1));
    1882                 :          0 :       yi = DTOL(gtodouble(y0)*(pari_plot.height - 1));
    1883                 :            :     } else {
    1884                 :        113 :       xi = gtos(x0);
    1885                 :        113 :       yi = gtos(y0);
    1886                 :            :     }
    1887                 :        113 :     x[i] = xi;
    1888                 :        113 :     y[i] = yi;
    1889                 :        113 :     ne = itos(win); check_rect(ne);
    1890                 :        113 :     w[i] = ne;
    1891                 :            :   }
    1892         [ +  + ]:        113 :   if (ps) postdraw0(w,x,y,n,flag); else rectdraw0(w,x,y,n);
    1893                 :         81 :   pari_free(x); pari_free(y); pari_free(w);
    1894                 :            : }
    1895                 :            : 
    1896                 :            : void
    1897                 :          0 : postdraw(GEN list) { gendraw(list, 1, 0); }
    1898                 :            : 
    1899                 :            : void
    1900                 :          0 : rectdraw(GEN list) { gendraw(list, 0, 0); }
    1901                 :            : 
    1902                 :            : void
    1903                 :         61 : postdraw_flag(GEN list, long flag) { gendraw(list, 1, flag); }
    1904                 :            : 
    1905                 :            : void
    1906                 :         52 : rectdraw_flag(GEN list, long flag) { gendraw(list, 0, flag); }
    1907                 :            : 
    1908                 :            : static void
    1909                 :      10134 : ps_sc(void *data, long col)
    1910                 :            : {
    1911                 :      10134 :   long l = lg(GP_DATA->colormap)-1;
    1912                 :            :   int r, g, b;
    1913         [ -  + ]:      10134 :   if (col >= l)
    1914                 :            :   {
    1915                 :          0 :     pari_warn(warner,"non-existent color: %ld", col);
    1916                 :          0 :     col = l-1;
    1917                 :            :   }
    1918                 :      10134 :   color_to_rgb(gel(GP_DATA->colormap,col+1), &r, &g, &b);
    1919                 :      10134 :   fprintf((FILE*)data,"%f %f %f setrgbcolor\n", r/255., g/255., b/255.);
    1920                 :      10134 : }
    1921                 :            : 
    1922                 :            : static void
    1923                 :        860 : ps_point(void *data, long x, long y)
    1924                 :            : {
    1925                 :        860 :   fprintf((FILE*)data,"%ld %ld p\n",y,x);
    1926                 :        860 : }
    1927                 :            : 
    1928                 :            : static void
    1929                 :       9629 : ps_line(void *data, long x1, long y1, long x2, long y2)
    1930                 :            : {
    1931                 :       9629 :   fprintf((FILE*)data,"%ld %ld m %ld %ld l\n",y1,x1,y2,x2);
    1932                 :       9629 :   fprintf((FILE*)data,"stroke\n");
    1933                 :       9629 : }
    1934                 :            : 
    1935                 :            : static void
    1936                 :         97 : ps_rect(void *data, long x, long y, long w, long h)
    1937                 :            : {
    1938                 :         97 :   fprintf((FILE*)data,"%ld %ld m %ld %ld l %ld %ld l %ld %ld l closepath\n",y,x, y,x+w, y+h,x+w, y+h,x);
    1939                 :         97 : }
    1940                 :            : 
    1941                 :            : static void
    1942                 :         21 : ps_points(void *data, long nb, struct plot_points *p)
    1943                 :            : {
    1944                 :            :   long i;
    1945         [ +  + ]:        860 :   for (i=0; i<nb; i++) ps_point(data, p[i].x, p[i].y);
    1946                 :         21 : }
    1947                 :            : 
    1948                 :            : static void
    1949                 :         76 : ps_lines(void *data, long nb, struct plot_points *p)
    1950                 :            : {
    1951                 :         76 :   FILE *psfile = (FILE*)data;
    1952                 :            :   long i;
    1953                 :         76 :   fprintf(psfile,"%ld %ld m\n",p[0].y,p[0].x);
    1954         [ +  + ]:      43794 :   for (i=1; i<nb; i++) fprintf(psfile, "%ld %ld l\n", p[i].y, p[i].x);
    1955                 :         76 :   fprintf(psfile,"stroke\n");
    1956                 :         76 : }
    1957                 :            : 
    1958                 :            : static void
    1959                 :        290 : ps_string(void *data, long x, long y, char *s, long length)
    1960                 :            : {
    1961                 :        290 :   FILE *psfile = (FILE*)data;
    1962                 :            :   (void)length;
    1963         [ +  + ]:        290 :   if (strpbrk(s, "(\\)")) {
    1964                 :          7 :     fprintf(psfile,"(");
    1965         [ +  + ]:         42 :     while (*s) {
    1966 [ +  + ][ +  + ]:         35 :       if ( *s=='(' || *s==')' || *s=='\\' ) fputc('\\', psfile);
                 [ -  + ]
    1967                 :         35 :       fputc(*s, psfile);
    1968                 :         35 :       s++;
    1969                 :            :     }
    1970                 :            :   } else
    1971                 :        283 :     fprintf(psfile,"(%s", s);
    1972                 :        290 :   fprintf(psfile,") %ld %ld m 90 rotate show -90 rotate\n", y, x);
    1973                 :        290 : }
    1974                 :            : 
    1975                 :            : void
    1976                 :        130 : psplot_init(struct plot_eng *S, FILE *f, double xscale, double yscale, long fontsize)
    1977                 :            : {
    1978                 :        130 :   PARI_get_psplot();
    1979                 :            :   /* Definitions taken from post terminal of Gnuplot. */
    1980                 :        130 :   fprintf(f, "%%!\n\
    1981                 :            : 50 50 translate\n\
    1982                 :            : /p {moveto 0 2 rlineto 2 0 rlineto 0 -2 rlineto closepath fill} def\n\
    1983                 :            : /l {lineto} def\n\
    1984                 :            : /m {moveto} def\n\
    1985                 :            : /Times-Roman findfont %ld scalefont setfont\n\
    1986                 :            : %g %g scale\n", fontsize, yscale, xscale);
    1987                 :            : 
    1988                 :        130 :   S->sc = &ps_sc;
    1989                 :        130 :   S->pt = &ps_point;
    1990                 :        130 :   S->ln = &ps_line;
    1991                 :        130 :   S->bx = &ps_rect;
    1992                 :        130 :   S->mp = &ps_points;
    1993                 :        130 :   S->ml = &ps_lines;
    1994                 :        130 :   S->st = &ps_string;
    1995                 :        130 :   S->pl = &pari_psplot;
    1996                 :        130 :   S->data = (void*)f;
    1997                 :        130 : }
    1998                 :            : 
    1999                 :            : void
    2000                 :        130 : postdraw0(long *w, long *x, long *y, long lw, long scale)
    2001                 :            : {
    2002                 :            :   struct plot_eng plot;
    2003                 :            :   FILE *psfile;
    2004                 :        130 :   double xscale = 0.65, yscale = 0.65;
    2005                 :        130 :   long fontsize = 16;
    2006                 :            : 
    2007                 :        130 :   psfile = fopen(current_psfile, "a");
    2008         [ -  + ]:        130 :   if (!psfile) pari_err_FILE("postscript file",current_psfile);
    2009         [ -  + ]:        130 :   if (scale) {
    2010                 :            :     double psxscale, psyscale;
    2011                 :          0 :     PARI_get_psplot();
    2012                 :          0 :     PARI_get_plot();
    2013                 :          0 :     psxscale = pari_psplot.width * 1.0/pari_plot.width ;
    2014                 :          0 :     psyscale = pari_psplot.height* 1.0/pari_plot.height;
    2015                 :          0 :     fontsize = (long) (fontsize/psxscale);
    2016                 :          0 :     xscale *= psxscale;
    2017                 :          0 :     yscale *= psyscale;
    2018                 :            :   }
    2019                 :        130 :   psplot_init(&plot, psfile, xscale, yscale, fontsize);
    2020                 :        130 :   gen_rectdraw0(&plot, w, x, y, lw, 1, 1);
    2021                 :        130 :   fprintf(psfile,"stroke showpage\n"); fclose(psfile);
    2022                 :        130 : }
    2023                 :            : 
    2024                 :            : #define RoColT(R) minss(numcolors,RoCol(R))
    2025                 :            : 
    2026                 :            : void
    2027                 :        130 : gen_rectdraw0(struct plot_eng *eng, long *w, long *x, long *y, long lw, double xs, double ys)
    2028                 :            : {
    2029                 :        130 :   void *data = eng->data;
    2030                 :            :   long i, j;
    2031                 :        130 :   long hgapsize = eng->pl->hunit, fheight = eng->pl->fheight;
    2032                 :        130 :   long vgapsize = eng->pl->vunit,  fwidth = eng->pl->fwidth;
    2033                 :        130 :   long numcolors = lg(GP_DATA->colormap)-1;
    2034         [ +  + ]:        329 :   for(i=0; i<lw; i++)
    2035                 :            :   {
    2036                 :        199 :     PariRect *e = rectgraph[w[i]];
    2037                 :            :     RectObj *R;
    2038                 :        199 :     long x0 = x[i], y0 = y[i];
    2039         [ +  + ]:      11397 :     for (R = RHead(e); R; R = RoNext(R))
    2040                 :            :     {
    2041   [ +  +  +  +  :      11198 :       switch(RoType(R))
                +  +  + ]
    2042                 :            :       {
    2043                 :            :       case ROt_PT:
    2044                 :         21 :         eng->sc(data,RoColT(R));
    2045                 :         21 :         eng->pt(data, DTOL((RoPTx(R)+x0)*xs), DTOL((RoPTy(R)+y0)*ys));
    2046                 :         21 :         break;
    2047                 :            :       case ROt_LN:
    2048                 :       9629 :         eng->sc(data,RoColT(R));
    2049                 :       9629 :         eng->ln(data, DTOL((RoLNx1(R)+x0)*xs),
    2050                 :       9629 :                       DTOL((RoLNy1(R)+y0)*ys),
    2051                 :       9629 :                       DTOL((RoLNx2(R)+x0)*xs),
    2052                 :       9629 :                       DTOL((RoLNy2(R)+y0)*ys));
    2053                 :       9629 :         break;
    2054                 :            :       case ROt_BX:
    2055                 :         97 :         eng->sc(data,RoColT(R));
    2056                 :         97 :         eng->bx(data,
    2057                 :         97 :                 DTOL((RoBXx1(R)+x0)*xs),
    2058                 :         97 :                 DTOL((RoBXy1(R)+y0)*ys),
    2059                 :         97 :                 DTOL((RoBXx2(R)-RoBXx1(R))*xs),
    2060                 :         97 :                 DTOL((RoBXy2(R)-RoBXy1(R))*ys));
    2061                 :         97 :         break;
    2062                 :            :       case ROt_MP:
    2063                 :            :         {
    2064                 :         21 :           double *ptx = RoMPxs(R);
    2065                 :         21 :           double *pty = RoMPys(R);
    2066                 :         21 :           long     nb = RoMPcnt(R);
    2067                 :         21 :           struct plot_points *points =
    2068                 :         21 :             (struct plot_points *) pari_malloc(sizeof(*points)*nb);
    2069         [ +  + ]:        860 :           for(j=0;j<nb;j++)
    2070                 :            :           {
    2071                 :        839 :             points[j].x = DTOL((ptx[j]+x0)*xs);
    2072                 :        839 :             points[j].y = DTOL((pty[j]+y0)*ys);
    2073                 :            :           }
    2074                 :         21 :           eng->sc(data,RoColT(R));
    2075                 :         21 :           eng->mp(data, nb, points);
    2076                 :         21 :           pari_free(points);
    2077                 :         21 :           break;
    2078                 :            :         }
    2079                 :            :       case ROt_ML:
    2080                 :            :         {
    2081                 :         76 :           double *ptx = RoMLxs(R);
    2082                 :         76 :           double *pty = RoMLys(R);
    2083                 :         76 :           long     nb = RoMLcnt(R);
    2084                 :         76 :           struct plot_points *points =
    2085                 :         76 :             (struct plot_points *) pari_malloc(sizeof(*points)*nb);
    2086         [ +  + ]:      43870 :           for(j=0;j<nb;j++)
    2087                 :            :           {
    2088                 :      43794 :             points[j].x = DTOL((ptx[j]+x0)*xs);
    2089                 :      43794 :             points[j].y = DTOL((pty[j]+y0)*ys);
    2090                 :            :           }
    2091                 :         76 :           eng->sc(data,RoColT(R));
    2092                 :         76 :           eng->ml(data, nb, points);
    2093                 :         76 :           pari_free(points);
    2094                 :         76 :           break;
    2095                 :            :         }
    2096                 :            :       case ROt_ST:
    2097                 :            :         {
    2098                 :        290 :           long dir = RoSTdir(R);
    2099                 :        290 :           long hjust = dir & RoSTdirHPOS_mask, hgap  = dir & RoSTdirHGAP;
    2100                 :        290 :           long vjust = dir & RoSTdirVPOS_mask, vgap  = dir & RoSTdirVGAP;
    2101                 :        290 :           char *text = RoSTs(R);
    2102                 :        290 :           long l     = RoSTl(R);
    2103                 :            :           long x, y;
    2104 [ +  + ][ +  - ]:        290 :           long shift = (hjust == RoSTdirLEFT ? 0 :
    2105                 :            :               (hjust == RoSTdirRIGHT ? 2 : 1));
    2106         [ +  + ]:        290 :           if (hgap)
    2107         [ +  - ]:        138 :             hgap = (hjust == RoSTdirLEFT) ? hgapsize : -hgapsize;
    2108         [ +  + ]:        290 :           if (vgap)
    2109         [ +  - ]:         69 :             vgap = (vjust == RoSTdirBOTTOM) ? 2*vgapsize : -2*vgapsize;
    2110         [ +  + ]:        290 :           if (vjust != RoSTdirBOTTOM)
    2111         [ +  - ]:        207 :             vgap -= ((vjust == RoSTdirTOP) ? 2 : 1)*(fheight - 1);
    2112                 :        290 :           x = DTOL((RoSTx(R) + x0 + hgap - (l * fwidth * shift)/2)*xs);
    2113                 :        290 :           y = DTOL((RoSTy(R) + y0 - vgap/2)*ys);
    2114                 :        290 :           eng->sc(data,RoColT(R));
    2115                 :        290 :           eng->st(data, x, y, text, l);
    2116                 :        290 :           break;
    2117                 :            :         }
    2118                 :            :       default:
    2119                 :       1064 :         break;
    2120                 :            :       }
    2121                 :            :     }
    2122                 :            :   }
    2123                 :        130 : }
    2124                 :            : 
    2125                 :            : /*************************************************************************/
    2126                 :            : /*                                                                       */
    2127                 :            : /*                           RGB COLORS                                  */
    2128                 :            : /*                                                                       */
    2129                 :            : /*************************************************************************/
    2130                 :            : /* generated from /etc/X11/rgb.txt by the following perl script
    2131                 :            : #!/usr/bin/perl
    2132                 :            : while(<>)
    2133                 :            : {
    2134                 :            :   ($hex, $name) = split(/\t\t/, $_);
    2135                 :            :   $hex =~ s/^ +//; chomp($name); $name =~ s, *,,g;
    2136                 :            :   $hex = sprintf("0x%02x%02x%02x", split(/\s+/, $hex));
    2137                 :            :   $name = lc($name); next if ($done{$name});
    2138                 :            :   $done{$name} = 1;
    2139                 :            :   print "COL(\"$name\", $hex),\n";
    2140                 :            : }
    2141                 :            : */
    2142                 :            : 
    2143                 :            : #define COL(x,y) {(void*)x,(void*)y,0,NULL}
    2144                 :            : static hashentry col_list[] = {
    2145                 :            : COL("", 0x000000),
    2146                 :            : COL("snow", 0xfffafa),
    2147                 :            : COL("ghostwhite", 0xf8f8ff),
    2148                 :            : COL("whitesmoke", 0xf5f5f5),
    2149                 :            : COL("gainsboro", 0xdcdcdc),
    2150                 :            : COL("floralwhite", 0xfffaf0),
    2151                 :            : COL("oldlace", 0xfdf5e6),
    2152                 :            : COL("linen", 0xfaf0e6),
    2153                 :            : COL("antiquewhite", 0xfaebd7),
    2154                 :            : COL("papayawhip", 0xffefd5),
    2155                 :            : COL("blanchedalmond", 0xffebcd),
    2156                 :            : COL("bisque", 0xffe4c4),
    2157                 :            : COL("peachpuff", 0xffdab9),
    2158                 :            : COL("navajowhite", 0xffdead),
    2159                 :            : COL("moccasin", 0xffe4b5),
    2160                 :            : COL("cornsilk", 0xfff8dc),
    2161                 :            : COL("ivory", 0xfffff0),
    2162                 :            : COL("lemonchiffon", 0xfffacd),
    2163                 :            : COL("seashell", 0xfff5ee),
    2164                 :            : COL("honeydew", 0xf0fff0),
    2165                 :            : COL("mintcream", 0xf5fffa),
    2166                 :            : COL("azure", 0xf0ffff),
    2167                 :            : COL("aliceblue", 0xf0f8ff),
    2168                 :            : COL("lavender", 0xe6e6fa),
    2169                 :            : COL("lavenderblush", 0xfff0f5),
    2170                 :            : COL("mistyrose", 0xffe4e1),
    2171                 :            : COL("white", 0xffffff),
    2172                 :            : COL("black", 0x000000),
    2173                 :            : COL("darkslategray", 0x2f4f4f),
    2174                 :            : COL("darkslategrey", 0x2f4f4f),
    2175                 :            : COL("dimgray", 0x696969),
    2176                 :            : COL("dimgrey", 0x696969),
    2177                 :            : COL("slategray", 0x708090),
    2178                 :            : COL("slategrey", 0x708090),
    2179                 :            : COL("lightslategray", 0x778899),
    2180                 :            : COL("lightslategrey", 0x778899),
    2181                 :            : COL("gray", 0xbebebe),
    2182                 :            : COL("grey", 0xbebebe),
    2183                 :            : COL("lightgrey", 0xd3d3d3),
    2184                 :            : COL("lightgray", 0xd3d3d3),
    2185                 :            : COL("midnightblue", 0x191970),
    2186                 :            : COL("navy", 0x000080),
    2187                 :            : COL("navyblue", 0x000080),
    2188                 :            : COL("cornflowerblue", 0x6495ed),
    2189                 :            : COL("darkslateblue", 0x483d8b),
    2190                 :            : COL("slateblue", 0x6a5acd),
    2191                 :            : COL("mediumslateblue", 0x7b68ee),
    2192                 :            : COL("lightslateblue", 0x8470ff),
    2193                 :            : COL("mediumblue", 0x0000cd),
    2194                 :            : COL("royalblue", 0x4169e1),
    2195                 :            : COL("blue", 0x0000ff),
    2196                 :            : COL("dodgerblue", 0x1e90ff),
    2197                 :            : COL("deepskyblue", 0x00bfff),
    2198                 :            : COL("skyblue", 0x87ceeb),
    2199                 :            : COL("lightskyblue", 0x87cefa),
    2200                 :            : COL("steelblue", 0x4682b4),
    2201                 :            : COL("lightsteelblue", 0xb0c4de),
    2202                 :            : COL("lightblue", 0xadd8e6),
    2203                 :            : COL("powderblue", 0xb0e0e6),
    2204                 :            : COL("paleturquoise", 0xafeeee),
    2205                 :            : COL("darkturquoise", 0x00ced1),
    2206                 :            : COL("mediumturquoise", 0x48d1cc),
    2207                 :            : COL("turquoise", 0x40e0d0),
    2208                 :            : COL("cyan", 0x00ffff),
    2209                 :            : COL("lightcyan", 0xe0ffff),
    2210                 :            : COL("cadetblue", 0x5f9ea0),
    2211                 :            : COL("mediumaquamarine", 0x66cdaa),
    2212                 :            : COL("aquamarine", 0x7fffd4),
    2213                 :            : COL("darkgreen", 0x006400),
    2214                 :            : COL("darkolivegreen", 0x556b2f),
    2215                 :            : COL("darkseagreen", 0x8fbc8f),
    2216                 :            : COL("seagreen", 0x2e8b57),
    2217                 :            : COL("mediumseagreen", 0x3cb371),
    2218                 :            : COL("lightseagreen", 0x20b2aa),
    2219                 :            : COL("palegreen", 0x98fb98),
    2220                 :            : COL("springgreen", 0x00ff7f),
    2221                 :            : COL("lawngreen", 0x7cfc00),
    2222                 :            : COL("green", 0x00ff00),
    2223                 :            : COL("chartreuse", 0x7fff00),
    2224                 :            : COL("mediumspringgreen", 0x00fa9a),
    2225                 :            : COL("greenyellow", 0xadff2f),
    2226                 :            : COL("limegreen", 0x32cd32),
    2227                 :            : COL("yellowgreen", 0x9acd32),
    2228                 :            : COL("forestgreen", 0x228b22),
    2229                 :            : COL("olivedrab", 0x6b8e23),
    2230                 :            : COL("darkkhaki", 0xbdb76b),
    2231                 :            : COL("khaki", 0xf0e68c),
    2232                 :            : COL("palegoldenrod", 0xeee8aa),
    2233                 :            : COL("lightgoldenrodyellow", 0xfafad2),
    2234                 :            : COL("lightyellow", 0xffffe0),
    2235                 :            : COL("yellow", 0xffff00),
    2236                 :            : COL("gold", 0xffd700),
    2237                 :            : COL("lightgoldenrod", 0xeedd82),
    2238                 :            : COL("goldenrod", 0xdaa520),
    2239                 :            : COL("darkgoldenrod", 0xb8860b),
    2240                 :            : COL("rosybrown", 0xbc8f8f),
    2241                 :            : COL("indianred", 0xcd5c5c),
    2242                 :            : COL("saddlebrown", 0x8b4513),
    2243                 :            : COL("sienna", 0xa0522d),
    2244                 :            : COL("peru", 0xcd853f),
    2245                 :            : COL("burlywood", 0xdeb887),
    2246                 :            : COL("beige", 0xf5f5dc),
    2247                 :            : COL("wheat", 0xf5deb3),
    2248                 :            : COL("sandybrown", 0xf4a460),
    2249                 :            : COL("tan", 0xd2b48c),
    2250                 :            : COL("chocolate", 0xd2691e),
    2251                 :            : COL("firebrick", 0xb22222),
    2252                 :            : COL("brown", 0xa52a2a),
    2253                 :            : COL("darksalmon", 0xe9967a),
    2254                 :            : COL("salmon", 0xfa8072),
    2255                 :            : COL("lightsalmon", 0xffa07a),
    2256                 :            : COL("orange", 0xffa500),
    2257                 :            : COL("darkorange", 0xff8c00),
    2258                 :            : COL("coral", 0xff7f50),
    2259                 :            : COL("lightcoral", 0xf08080),
    2260                 :            : COL("tomato", 0xff6347),
    2261                 :            : COL("orangered", 0xff4500),
    2262                 :            : COL("red", 0xff0000),
    2263                 :            : COL("hotpink", 0xff69b4),
    2264                 :            : COL("deeppink", 0xff1493),
    2265                 :            : COL("pink", 0xffc0cb),
    2266                 :            : COL("lightpink", 0xffb6c1),
    2267                 :            : COL("palevioletred", 0xdb7093),
    2268                 :            : COL("maroon", 0xb03060),
    2269                 :            : COL("mediumvioletred", 0xc71585),
    2270                 :            : COL("violetred", 0xd02090),
    2271                 :            : COL("magenta", 0xff00ff),
    2272                 :            : COL("violet", 0xee82ee),
    2273                 :            : COL("plum", 0xdda0dd),
    2274                 :            : COL("orchid", 0xda70d6),
    2275                 :            : COL("mediumorchid", 0xba55d3),
    2276                 :            : COL("darkorchid", 0x9932cc),
    2277                 :            : COL("darkviolet", 0x9400d3),
    2278                 :            : COL("blueviolet", 0x8a2be2),
    2279                 :            : COL("purple", 0xa020f0),
    2280                 :            : COL("mediumpurple", 0x9370db),
    2281                 :            : COL("thistle", 0xd8bfd8),
    2282                 :            : COL("snow1", 0xfffafa),
    2283                 :            : COL("snow2", 0xeee9e9),
    2284                 :            : COL("snow3", 0xcdc9c9),
    2285                 :            : COL("snow4", 0x8b8989),
    2286                 :            : COL("seashell1", 0xfff5ee),
    2287                 :            : COL("seashell2", 0xeee5de),
    2288                 :            : COL("seashell3", 0xcdc5bf),
    2289                 :            : COL("seashell4", 0x8b8682),
    2290                 :            : COL("antiquewhite1", 0xffefdb),
    2291                 :            : COL("antiquewhite2", 0xeedfcc),
    2292                 :            : COL("antiquewhite3", 0xcdc0b0),
    2293                 :            : COL("antiquewhite4", 0x8b8378),
    2294                 :            : COL("bisque1", 0xffe4c4),
    2295                 :            : COL("bisque2", 0xeed5b7),
    2296                 :            : COL("bisque3", 0xcdb79e),
    2297                 :            : COL("bisque4", 0x8b7d6b),
    2298                 :            : COL("peachpuff1", 0xffdab9),
    2299                 :            : COL("peachpuff2", 0xeecbad),
    2300                 :            : COL("peachpuff3", 0xcdaf95),
    2301                 :            : COL("peachpuff4", 0x8b7765),
    2302                 :            : COL("navajowhite1", 0xffdead),
    2303                 :            : COL("navajowhite2", 0xeecfa1),
    2304                 :            : COL("navajowhite3", 0xcdb38b),
    2305                 :            : COL("navajowhite4", 0x8b795e),
    2306                 :            : COL("lemonchiffon1", 0xfffacd),
    2307                 :            : COL("lemonchiffon2", 0xeee9bf),
    2308                 :            : COL("lemonchiffon3", 0xcdc9a5),
    2309                 :            : COL("lemonchiffon4", 0x8b8970),
    2310                 :            : COL("cornsilk1", 0xfff8dc),
    2311                 :            : COL("cornsilk2", 0xeee8cd),
    2312                 :            : COL("cornsilk3", 0xcdc8b1),
    2313                 :            : COL("cornsilk4", 0x8b8878),
    2314                 :            : COL("ivory1", 0xfffff0),
    2315                 :            : COL("ivory2", 0xeeeee0),
    2316                 :            : COL("ivory3", 0xcdcdc1),
    2317                 :            : COL("ivory4", 0x8b8b83),
    2318                 :            : COL("honeydew1", 0xf0fff0),
    2319                 :            : COL("honeydew2", 0xe0eee0),
    2320                 :            : COL("honeydew3", 0xc1cdc1),
    2321                 :            : COL("honeydew4", 0x838b83),
    2322                 :            : COL("lavenderblush1", 0xfff0f5),
    2323                 :            : COL("lavenderblush2", 0xeee0e5),
    2324                 :            : COL("lavenderblush3", 0xcdc1c5),
    2325                 :            : COL("lavenderblush4", 0x8b8386),
    2326                 :            : COL("mistyrose1", 0xffe4e1),
    2327                 :            : COL("mistyrose2", 0xeed5d2),
    2328                 :            : COL("mistyrose3", 0xcdb7b5),
    2329                 :            : COL("mistyrose4", 0x8b7d7b),
    2330                 :            : COL("azure1", 0xf0ffff),
    2331                 :            : COL("azure2", 0xe0eeee),
    2332                 :            : COL("azure3", 0xc1cdcd),
    2333                 :            : COL("azure4", 0x838b8b),
    2334                 :            : COL("slateblue1", 0x836fff),
    2335                 :            : COL("slateblue2", 0x7a67ee),
    2336                 :            : COL("slateblue3", 0x6959cd),
    2337                 :            : COL("slateblue4", 0x473c8b),
    2338                 :            : COL("royalblue1", 0x4876ff),
    2339                 :            : COL("royalblue2", 0x436eee),
    2340                 :            : COL("royalblue3", 0x3a5fcd),
    2341                 :            : COL("royalblue4", 0x27408b),
    2342                 :            : COL("blue1", 0x0000ff),
    2343                 :            : COL("blue2", 0x0000ee),
    2344                 :            : COL("blue3", 0x0000cd),
    2345                 :            : COL("blue4", 0x00008b),
    2346                 :            : COL("dodgerblue1", 0x1e90ff),
    2347                 :            : COL("dodgerblue2", 0x1c86ee),
    2348                 :            : COL("dodgerblue3", 0x1874cd),
    2349                 :            : COL("dodgerblue4", 0x104e8b),
    2350                 :            : COL("steelblue1", 0x63b8ff),
    2351                 :            : COL("steelblue2", 0x5cacee),
    2352                 :            : COL("steelblue3", 0x4f94cd),
    2353                 :            : COL("steelblue4", 0x36648b),
    2354                 :            : COL("deepskyblue1", 0x00bfff),
    2355                 :            : COL("deepskyblue2", 0x00b2ee),
    2356                 :            : COL("deepskyblue3", 0x009acd),
    2357                 :            : COL("deepskyblue4", 0x00688b),
    2358                 :            : COL("skyblue1", 0x87ceff),
    2359                 :            : COL("skyblue2", 0x7ec0ee),
    2360                 :            : COL("skyblue3", 0x6ca6cd),
    2361                 :            : COL("skyblue4", 0x4a708b),
    2362                 :            : COL("lightskyblue1", 0xb0e2ff),
    2363                 :            : COL("lightskyblue2", 0xa4d3ee),
    2364                 :            : COL("lightskyblue3", 0x8db6cd),
    2365                 :            : COL("lightskyblue4", 0x607b8b),
    2366                 :            : COL("slategray1", 0xc6e2ff),
    2367                 :            : COL("slategray2", 0xb9d3ee),
    2368                 :            : COL("slategray3", 0x9fb6cd),
    2369                 :            : COL("slategray4", 0x6c7b8b),
    2370                 :            : COL("lightsteelblue1", 0xcae1ff),
    2371                 :            : COL("lightsteelblue2", 0xbcd2ee),
    2372                 :            : COL("lightsteelblue3", 0xa2b5cd),
    2373                 :            : COL("lightsteelblue4", 0x6e7b8b),
    2374                 :            : COL("lightblue1", 0xbfefff),
    2375                 :            : COL("lightblue2", 0xb2dfee),
    2376                 :            : COL("lightblue3", 0x9ac0cd),
    2377                 :            : COL("lightblue4", 0x68838b),
    2378                 :            : COL("lightcyan1", 0xe0ffff),
    2379                 :            : COL("lightcyan2", 0xd1eeee),
    2380                 :            : COL("lightcyan3", 0xb4cdcd),
    2381                 :            : COL("lightcyan4", 0x7a8b8b),
    2382                 :            : COL("paleturquoise1", 0xbbffff),
    2383                 :            : COL("paleturquoise2", 0xaeeeee),
    2384                 :            : COL("paleturquoise3", 0x96cdcd),
    2385                 :            : COL("paleturquoise4", 0x668b8b),
    2386                 :            : COL("cadetblue1", 0x98f5ff),
    2387                 :            : COL("cadetblue2", 0x8ee5ee),
    2388                 :            : COL("cadetblue3", 0x7ac5cd),
    2389                 :            : COL("cadetblue4", 0x53868b),
    2390                 :            : COL("turquoise1", 0x00f5ff),
    2391                 :            : COL("turquoise2", 0x00e5ee),
    2392                 :            : COL("turquoise3", 0x00c5cd),
    2393                 :            : COL("turquoise4", 0x00868b),
    2394                 :            : COL("cyan1", 0x00ffff),
    2395                 :            : COL("cyan2", 0x00eeee),
    2396                 :            : COL("cyan3", 0x00cdcd),
    2397                 :            : COL("cyan4", 0x008b8b),
    2398                 :            : COL("darkslategray1", 0x97ffff),
    2399                 :            : COL("darkslategray2", 0x8deeee),
    2400                 :            : COL("darkslategray3", 0x79cdcd),
    2401                 :            : COL("darkslategray4", 0x528b8b),
    2402                 :            : COL("aquamarine1", 0x7fffd4),
    2403                 :            : COL("aquamarine2", 0x76eec6),
    2404                 :            : COL("aquamarine3", 0x66cdaa),
    2405                 :            : COL("aquamarine4", 0x458b74),
    2406                 :            : COL("darkseagreen1", 0xc1ffc1),
    2407                 :            : COL("darkseagreen2", 0xb4eeb4),
    2408                 :            : COL("darkseagreen3", 0x9bcd9b),
    2409                 :            : COL("darkseagreen4", 0x698b69),
    2410                 :            : COL("seagreen1", 0x54ff9f),
    2411                 :            : COL("seagreen2", 0x4eee94),
    2412                 :            : COL("seagreen3", 0x43cd80),
    2413                 :            : COL("seagreen4", 0x2e8b57),
    2414                 :            : COL("palegreen1", 0x9aff9a),
    2415                 :            : COL("palegreen2", 0x90ee90),
    2416                 :            : COL("palegreen3", 0x7ccd7c),
    2417                 :            : COL("palegreen4", 0x548b54),
    2418                 :            : COL("springgreen1", 0x00ff7f),
    2419                 :            : COL("springgreen2", 0x00ee76),
    2420                 :            : COL("springgreen3", 0x00cd66),
    2421                 :            : COL("springgreen4", 0x008b45),
    2422                 :            : COL("green1", 0x00ff00),
    2423                 :            : COL("green2", 0x00ee00),
    2424                 :            : COL("green3", 0x00cd00),
    2425                 :            : COL("green4", 0x008b00),
    2426                 :            : COL("chartreuse1", 0x7fff00),
    2427                 :            : COL("chartreuse2", 0x76ee00),
    2428                 :            : COL("chartreuse3", 0x66cd00),
    2429                 :            : COL("chartreuse4", 0x458b00),
    2430                 :            : COL("olivedrab1", 0xc0ff3e),
    2431                 :            : COL("olivedrab2", 0xb3ee3a),
    2432                 :            : COL("olivedrab3", 0x9acd32),
    2433                 :            : COL("olivedrab4", 0x698b22),
    2434                 :            : COL("darkolivegreen1", 0xcaff70),
    2435                 :            : COL("darkolivegreen2", 0xbcee68),
    2436                 :            : COL("darkolivegreen3", 0xa2cd5a),
    2437                 :            : COL("darkolivegreen4", 0x6e8b3d),
    2438                 :            : COL("khaki1", 0xfff68f),
    2439                 :            : COL("khaki2", 0xeee685),
    2440                 :            : COL("khaki3", 0xcdc673),
    2441                 :            : COL("khaki4", 0x8b864e),
    2442                 :            : COL("lightgoldenrod1", 0xffec8b),
    2443                 :            : COL("lightgoldenrod2", 0xeedc82),
    2444                 :            : COL("lightgoldenrod3", 0xcdbe70),
    2445                 :            : COL("lightgoldenrod4", 0x8b814c),
    2446                 :            : COL("lightyellow1", 0xffffe0),
    2447                 :            : COL("lightyellow2", 0xeeeed1),
    2448                 :            : COL("lightyellow3", 0xcdcdb4),
    2449                 :            : COL("lightyellow4", 0x8b8b7a),
    2450                 :            : COL("yellow1", 0xffff00),
    2451                 :            : COL("yellow2", 0xeeee00),
    2452                 :            : COL("yellow3", 0xcdcd00),
    2453                 :            : COL("yellow4", 0x8b8b00),
    2454                 :            : COL("gold1", 0xffd700),
    2455                 :            : COL("gold2", 0xeec900),
    2456                 :            : COL("gold3", 0xcdad00),
    2457                 :            : COL("gold4", 0x8b7500),
    2458                 :            : COL("goldenrod1", 0xffc125),
    2459                 :            : COL("goldenrod2", 0xeeb422),
    2460                 :            : COL("goldenrod3", 0xcd9b1d),
    2461                 :            : COL("goldenrod4", 0x8b6914),
    2462                 :            : COL("darkgoldenrod1", 0xffb90f),
    2463                 :            : COL("darkgoldenrod2", 0xeead0e),
    2464                 :            : COL("darkgoldenrod3", 0xcd950c),
    2465                 :            : COL("darkgoldenrod4", 0x8b6508),
    2466                 :            : COL("rosybrown1", 0xffc1c1),
    2467                 :            : COL("rosybrown2", 0xeeb4b4),
    2468                 :            : COL("rosybrown3", 0xcd9b9b),
    2469                 :            : COL("rosybrown4", 0x8b6969),
    2470                 :            : COL("indianred1", 0xff6a6a),
    2471                 :            : COL("indianred2", 0xee6363),
    2472                 :            : COL("indianred3", 0xcd5555),
    2473                 :            : COL("indianred4", 0x8b3a3a),
    2474                 :            : COL("sienna1", 0xff8247),
    2475                 :            : COL("sienna2", 0xee7942),
    2476                 :            : COL("sienna3", 0xcd6839),
    2477                 :            : COL("sienna4", 0x8b4726),
    2478                 :            : COL("burlywood1", 0xffd39b),
    2479                 :            : COL("burlywood2", 0xeec591),
    2480                 :            : COL("burlywood3", 0xcdaa7d),
    2481                 :            : COL("burlywood4", 0x8b7355),
    2482                 :            : COL("wheat1", 0xffe7ba),
    2483                 :            : COL("wheat2", 0xeed8ae),
    2484                 :            : COL("wheat3", 0xcdba96),
    2485                 :            : COL("wheat4", 0x8b7e66),
    2486                 :            : COL("tan1", 0xffa54f),
    2487                 :            : COL("tan2", 0xee9a49),
    2488                 :            : COL("tan3", 0xcd853f),
    2489                 :            : COL("tan4", 0x8b5a2b),
    2490                 :            : COL("chocolate1", 0xff7f24),
    2491                 :            : COL("chocolate2", 0xee7621),
    2492                 :            : COL("chocolate3", 0xcd661d),
    2493                 :            : COL("chocolate4", 0x8b4513),
    2494                 :            : COL("firebrick1", 0xff3030),
    2495                 :            : COL("firebrick2", 0xee2c2c),
    2496                 :            : COL("firebrick3", 0xcd2626),
    2497                 :            : COL("firebrick4", 0x8b1a1a),
    2498                 :            : COL("brown1", 0xff4040),
    2499                 :            : COL("brown2", 0xee3b3b),
    2500                 :            : COL("brown3", 0xcd3333),
    2501                 :            : COL("brown4", 0x8b2323),
    2502                 :            : COL("salmon1", 0xff8c69),
    2503                 :            : COL("salmon2", 0xee8262),
    2504                 :            : COL("salmon3", 0xcd7054),
    2505                 :            : COL("salmon4", 0x8b4c39),
    2506                 :            : COL("lightsalmon1", 0xffa07a),
    2507                 :            : COL("lightsalmon2", 0xee9572),
    2508                 :            : COL("lightsalmon3", 0xcd8162),
    2509                 :            : COL("lightsalmon4", 0x8b5742),
    2510                 :            : COL("orange1", 0xffa500),
    2511                 :            : COL("orange2", 0xee9a00),
    2512                 :            : COL("orange3", 0xcd8500),
    2513                 :            : COL("orange4", 0x8b5a00),
    2514                 :            : COL("darkorange1", 0xff7f00),
    2515                 :            : COL("darkorange2", 0xee7600),
    2516                 :            : COL("darkorange3", 0xcd6600),
    2517                 :            : COL("darkorange4", 0x8b4500),
    2518                 :            : COL("coral1", 0xff7256),
    2519                 :            : COL("coral2", 0xee6a50),
    2520                 :            : COL("coral3", 0xcd5b45),
    2521                 :            : COL("coral4", 0x8b3e2f),
    2522                 :            : COL("tomato1", 0xff6347),
    2523                 :            : COL("tomato2", 0xee5c42),
    2524                 :            : COL("tomato3", 0xcd4f39),
    2525                 :            : COL("tomato4", 0x8b3626),
    2526                 :            : COL("orangered1", 0xff4500),
    2527                 :            : COL("orangered2", 0xee4000),
    2528                 :            : COL("orangered3", 0xcd3700),
    2529                 :            : COL("orangered4", 0x8b2500),
    2530                 :            : COL("red1", 0xff0000),
    2531                 :            : COL("red2", 0xee0000),
    2532                 :            : COL("red3", 0xcd0000),
    2533                 :            : COL("red4", 0x8b0000),
    2534                 :            : COL("debianred", 0xd70751),
    2535                 :            : COL("deeppink1", 0xff1493),
    2536                 :            : COL("deeppink2", 0xee1289),
    2537                 :            : COL("deeppink3", 0xcd1076),
    2538                 :            : COL("deeppink4", 0x8b0a50),
    2539                 :            : COL("hotpink1", 0xff6eb4),
    2540                 :            : COL("hotpink2", 0xee6aa7),
    2541                 :            : COL("hotpink3", 0xcd6090),
    2542                 :            : COL("hotpink4", 0x8b3a62),
    2543                 :            : COL("pink1", 0xffb5c5),
    2544                 :            : COL("pink2", 0xeea9b8),
    2545                 :            : COL("pink3", 0xcd919e),
    2546                 :            : COL("pink4", 0x8b636c),
    2547                 :            : COL("lightpink1", 0xffaeb9),
    2548                 :            : COL("lightpink2", 0xeea2ad),
    2549                 :            : COL("lightpink3", 0xcd8c95),
    2550                 :            : COL("lightpink4", 0x8b5f65),
    2551                 :            : COL("palevioletred1", 0xff82ab),
    2552                 :            : COL("palevioletred2", 0xee799f),
    2553                 :            : COL("palevioletred3", 0xcd6889),
    2554                 :            : COL("palevioletred4", 0x8b475d),
    2555                 :            : COL("maroon1", 0xff34b3),
    2556                 :            : COL("maroon2", 0xee30a7),
    2557                 :            : COL("maroon3", 0xcd2990),
    2558                 :            : COL("maroon4", 0x8b1c62),
    2559                 :            : COL("violetred1", 0xff3e96),
    2560                 :            : COL("violetred2", 0xee3a8c),
    2561                 :            : COL("violetred3", 0xcd3278),
    2562                 :            : COL("violetred4", 0x8b2252),
    2563                 :            : COL("magenta1", 0xff00ff),
    2564                 :            : COL("magenta2", 0xee00ee),
    2565                 :            : COL("magenta3", 0xcd00cd),
    2566                 :            : COL("magenta4", 0x8b008b),
    2567                 :            : COL("orchid1", 0xff83fa),
    2568                 :            : COL("orchid2", 0xee7ae9),
    2569                 :            : COL("orchid3", 0xcd69c9),
    2570                 :            : COL("orchid4", 0x8b4789),
    2571                 :            : COL("plum1", 0xffbbff),
    2572                 :            : COL("plum2", 0xeeaeee),
    2573                 :            : COL("plum3", 0xcd96cd),
    2574                 :            : COL("plum4", 0x8b668b),
    2575                 :            : COL("mediumorchid1", 0xe066ff),
    2576                 :            : COL("mediumorchid2", 0xd15fee),
    2577                 :            : COL("mediumorchid3", 0xb452cd),
    2578                 :            : COL("mediumorchid4", 0x7a378b),
    2579                 :            : COL("darkorchid1", 0xbf3eff),
    2580                 :            : COL("darkorchid2", 0xb23aee),
    2581                 :            : COL("darkorchid3", 0x9a32cd),
    2582                 :            : COL("darkorchid4", 0x68228b),
    2583                 :            : COL("purple1", 0x9b30ff),
    2584                 :            : COL("purple2", 0x912cee),
    2585                 :            : COL("purple3", 0x7d26cd),
    2586                 :            : COL("purple4", 0x551a8b),
    2587                 :            : COL("mediumpurple1", 0xab82ff),
    2588                 :            : COL("mediumpurple2", 0x9f79ee),
    2589                 :            : COL("mediumpurple3", 0x8968cd),
    2590                 :            : COL("mediumpurple4", 0x5d478b),
    2591                 :            : COL("thistle1", 0xffe1ff),
    2592                 :            : COL("thistle2", 0xeed2ee),
    2593                 :            : COL("thistle3", 0xcdb5cd),
    2594                 :            : COL("thistle4", 0x8b7b8b),
    2595                 :            : COL("gray0", 0x000000),
    2596                 :            : COL("grey0", 0x000000),
    2597                 :            : COL("gray1", 0x030303),
    2598                 :            : COL("grey1", 0x030303),
    2599                 :            : COL("gray2", 0x050505),
    2600                 :            : COL("grey2", 0x050505),
    2601                 :            : COL("gray3", 0x080808),
    2602                 :            : COL("grey3", 0x080808),
    2603                 :            : COL("gray4", 0x0a0a0a),
    2604                 :            : COL("grey4", 0x0a0a0a),
    2605                 :            : COL("gray5", 0x0d0d0d),
    2606                 :            : COL("grey5", 0x0d0d0d),
    2607                 :            : COL("gray6", 0x0f0f0f),
    2608                 :            : COL("grey6", 0x0f0f0f),
    2609                 :            : COL("gray7", 0x121212),
    2610                 :            : COL("grey7", 0x121212),
    2611                 :            : COL("gray8", 0x141414),
    2612                 :            : COL("grey8", 0x141414),
    2613                 :            : COL("gray9", 0x171717),
    2614                 :            : COL("grey9", 0x171717),
    2615                 :            : COL("gray10", 0x1a1a1a),
    2616                 :            : COL("grey10", 0x1a1a1a),
    2617                 :            : COL("gray11", 0x1c1c1c),
    2618                 :            : COL("grey11", 0x1c1c1c),
    2619                 :            : COL("gray12", 0x1f1f1f),
    2620                 :            : COL("grey12", 0x1f1f1f),
    2621                 :            : COL("gray13", 0x212121),
    2622                 :            : COL("grey13", 0x212121),
    2623                 :            : COL("gray14", 0x242424),
    2624                 :            : COL("grey14", 0x242424),
    2625                 :            : COL("gray15", 0x262626),
    2626                 :            : COL("grey15", 0x262626),
    2627                 :            : COL("gray16", 0x292929),
    2628                 :            : COL("grey16", 0x292929),
    2629                 :            : COL("gray17", 0x2b2b2b),
    2630                 :            : COL("grey17", 0x2b2b2b),
    2631                 :            : COL("gray18", 0x2e2e2e),
    2632                 :            : COL("grey18", 0x2e2e2e),
    2633                 :            : COL("gray19", 0x303030),
    2634                 :            : COL("grey19", 0x303030),
    2635                 :            : COL("gray20", 0x333333),
    2636                 :            : COL("grey20", 0x333333),
    2637                 :            : COL("gray21", 0x363636),
    2638                 :            : COL("grey21", 0x363636),
    2639                 :            : COL("gray22", 0x383838),
    2640                 :            : COL("grey22", 0x383838),
    2641                 :            : COL("gray23", 0x3b3b3b),
    2642                 :            : COL("grey23", 0x3b3b3b),
    2643                 :            : COL("gray24", 0x3d3d3d),
    2644                 :            : COL("grey24", 0x3d3d3d),
    2645                 :            : COL("gray25", 0x404040),
    2646                 :            : COL("grey25", 0x404040),
    2647                 :            : COL("gray26", 0x424242),
    2648                 :            : COL("grey26", 0x424242),
    2649                 :            : COL("gray27", 0x454545),
    2650                 :            : COL("grey27", 0x454545),
    2651                 :            : COL("gray28", 0x474747),
    2652                 :            : COL("grey28", 0x474747),
    2653                 :            : COL("gray29", 0x4a4a4a),
    2654                 :            : COL("grey29", 0x4a4a4a),
    2655                 :            : COL("gray30", 0x4d4d4d),
    2656                 :            : COL("grey30", 0x4d4d4d),
    2657                 :            : COL("gray31", 0x4f4f4f),
    2658                 :            : COL("grey31", 0x4f4f4f),
    2659                 :            : COL("gray32", 0x525252),
    2660                 :            : COL("grey32", 0x525252),
    2661                 :            : COL("gray33", 0x545454),
    2662                 :            : COL("grey33", 0x545454),
    2663                 :            : COL("gray34", 0x575757),
    2664                 :            : COL("grey34", 0x575757),
    2665                 :            : COL("gray35", 0x595959),
    2666                 :            : COL("grey35", 0x595959),
    2667                 :            : COL("gray36", 0x5c5c5c),
    2668                 :            : COL("grey36", 0x5c5c5c),
    2669                 :            : COL("gray37", 0x5e5e5e),
    2670                 :            : COL("grey37", 0x5e5e5e),
    2671                 :            : COL("gray38", 0x616161),
    2672                 :            : COL("grey38", 0x616161),
    2673                 :            : COL("gray39", 0x636363),
    2674                 :            : COL("grey39", 0x636363),
    2675                 :            : COL("gray40", 0x666666),
    2676                 :            : COL("grey40", 0x666666),
    2677                 :            : COL("gray41", 0x696969),
    2678                 :            : COL("grey41", 0x696969),
    2679                 :            : COL("gray42", 0x6b6b6b),
    2680                 :            : COL("grey42", 0x6b6b6b),
    2681                 :            : COL("gray43", 0x6e6e6e),
    2682                 :            : COL("grey43", 0x6e6e6e),
    2683                 :            : COL("gray44", 0x707070),
    2684                 :            : COL("grey44", 0x707070),
    2685                 :            : COL("gray45", 0x737373),
    2686                 :            : COL("grey45", 0x737373),
    2687                 :            : COL("gray46", 0x757575),
    2688                 :            : COL("grey46", 0x757575),
    2689                 :            : COL("gray47", 0x787878),
    2690                 :            : COL("grey47", 0x787878),
    2691                 :            : COL("gray48", 0x7a7a7a),
    2692                 :            : COL("grey48", 0x7a7a7a),
    2693                 :            : COL("gray49", 0x7d7d7d),
    2694                 :            : COL("grey49", 0x7d7d7d),
    2695                 :            : COL("gray50", 0x7f7f7f),
    2696                 :            : COL("grey50", 0x7f7f7f),
    2697                 :            : COL("gray51", 0x828282),
    2698                 :            : COL("grey51", 0x828282),
    2699                 :            : COL("gray52", 0x858585),
    2700                 :            : COL("grey52", 0x858585),
    2701                 :            : COL("gray53", 0x878787),
    2702                 :            : COL("grey53", 0x878787),
    2703                 :            : COL("gray54", 0x8a8a8a),
    2704                 :            : COL("grey54", 0x8a8a8a),
    2705                 :            : COL("gray55", 0x8c8c8c),
    2706                 :            : COL("grey55", 0x8c8c8c),
    2707                 :            : COL("gray56", 0x8f8f8f),
    2708                 :            : COL("grey56", 0x8f8f8f),
    2709                 :            : COL("gray57", 0x919191),
    2710                 :            : COL("grey57", 0x919191),
    2711                 :            : COL("gray58", 0x949494),
    2712                 :            : COL("grey58", 0x949494),
    2713                 :            : COL("gray59", 0x969696),
    2714                 :            : COL("grey59", 0x969696),
    2715                 :            : COL("gray60", 0x999999),
    2716                 :            : COL("grey60", 0x999999),
    2717                 :            : COL("gray61", 0x9c9c9c),
    2718                 :            : COL("grey61", 0x9c9c9c),
    2719                 :            : COL("gray62", 0x9e9e9e),
    2720                 :            : COL("grey62", 0x9e9e9e),
    2721                 :            : COL("gray63", 0xa1a1a1),
    2722                 :            : COL("grey63", 0xa1a1a1),
    2723                 :            : COL("gray64", 0xa3a3a3),
    2724                 :            : COL("grey64", 0xa3a3a3),
    2725                 :            : COL("gray65", 0xa6a6a6),
    2726                 :            : COL("grey65", 0xa6a6a6),
    2727                 :            : COL("gray66", 0xa8a8a8),
    2728                 :            : COL("grey66", 0xa8a8a8),
    2729                 :            : COL("gray67", 0xababab),
    2730                 :            : COL("grey67", 0xababab),
    2731                 :            : COL("gray68", 0xadadad),
    2732                 :            : COL("grey68", 0xadadad),
    2733                 :            : COL("gray69", 0xb0b0b0),
    2734                 :            : COL("grey69", 0xb0b0b0),
    2735                 :            : COL("gray70", 0xb3b3b3),
    2736                 :            : COL("grey70", 0xb3b3b3),
    2737                 :            : COL("gray71", 0xb5b5b5),
    2738                 :            : COL("grey71", 0xb5b5b5),
    2739                 :            : COL("gray72", 0xb8b8b8),
    2740                 :            : COL("grey72", 0xb8b8b8),
    2741                 :            : COL("gray73", 0xbababa),
    2742                 :            : COL("grey73", 0xbababa),
    2743                 :            : COL("gray74", 0xbdbdbd),
    2744                 :            : COL("grey74", 0xbdbdbd),
    2745                 :            : COL("gray75", 0xbfbfbf),
    2746                 :            : COL("grey75", 0xbfbfbf),
    2747                 :            : COL("gray76", 0xc2c2c2),
    2748                 :            : COL("grey76", 0xc2c2c2),
    2749                 :            : COL("gray77", 0xc4c4c4),
    2750                 :            : COL("grey77", 0xc4c4c4),
    2751                 :            : COL("gray78", 0xc7c7c7),
    2752                 :            : COL("grey78", 0xc7c7c7),
    2753                 :            : COL("gray79", 0xc9c9c9),
    2754                 :            : COL("grey79", 0xc9c9c9),
    2755                 :            : COL("gray80", 0xcccccc),
    2756                 :            : COL("grey80", 0xcccccc),
    2757                 :            : COL("gray81", 0xcfcfcf),
    2758                 :            : COL("grey81", 0xcfcfcf),
    2759                 :            : COL("gray82", 0xd1d1d1),
    2760                 :            : COL("grey82", 0xd1d1d1),
    2761                 :            : COL("gray83", 0xd4d4d4),
    2762                 :            : COL("grey83", 0xd4d4d4),
    2763                 :            : COL("gray84", 0xd6d6d6),
    2764                 :            : COL("grey84", 0xd6d6d6),
    2765                 :            : COL("gray85", 0xd9d9d9),
    2766                 :            : COL("grey85", 0xd9d9d9),
    2767                 :            : COL("gray86", 0xdbdbdb),
    2768                 :            : COL("grey86", 0xdbdbdb),
    2769                 :            : COL("gray87", 0xdedede),
    2770                 :            : COL("grey87", 0xdedede),
    2771                 :            : COL("gray88", 0xe0e0e0),
    2772                 :            : COL("grey88", 0xe0e0e0),
    2773                 :            : COL("gray89", 0xe3e3e3),
    2774                 :            : COL("grey89", 0xe3e3e3),
    2775                 :            : COL("gray90", 0xe5e5e5),
    2776                 :            : COL("grey90", 0xe5e5e5),
    2777                 :            : COL("gray91", 0xe8e8e8),
    2778                 :            : COL("grey91", 0xe8e8e8),
    2779                 :            : COL("gray92", 0xebebeb),
    2780                 :            : COL("grey92", 0xebebeb),
    2781                 :            : COL("gray93", 0xededed),
    2782                 :            : COL("grey93", 0xededed),
    2783                 :            : COL("gray94", 0xf0f0f0),
    2784                 :            : COL("grey94", 0xf0f0f0),
    2785                 :            : COL("gray95", 0xf2f2f2),
    2786                 :            : COL("grey95", 0xf2f2f2),
    2787                 :            : COL("gray96", 0xf5f5f5),
    2788                 :            : COL("grey96", 0xf5f5f5),
    2789                 :            : COL("gray97", 0xf7f7f7),
    2790                 :            : COL("grey97", 0xf7f7f7),
    2791                 :            : COL("gray98", 0xfafafa),
    2792                 :            : COL("grey98", 0xfafafa),
    2793                 :            : COL("gray99", 0xfcfcfc),
    2794                 :            : COL("grey99", 0xfcfcfc),
    2795                 :            : COL("gray100", 0xffffff),
    2796                 :            : COL("grey100", 0xffffff),
    2797                 :            : COL("darkgrey", 0xa9a9a9),
    2798                 :            : COL("darkgray", 0xa9a9a9),
    2799                 :            : COL("darkblue", 0x00008b),
    2800                 :            : COL("darkcyan", 0x008b8b),
    2801                 :            : COL("darkmagenta", 0x8b008b),
    2802                 :            : COL("darkred", 0x8b0000),
    2803                 :            : COL("lightgreen", 0x90ee90),
    2804                 :            : COL(NULL,0) /* sentinel */
    2805                 :            : };
    2806                 :            : #undef COL
    2807                 :            : 
    2808                 :            : static void
    2809                 :      10134 : colorname_to_rgb(const char *s, int *r, int *g, int *b)
    2810                 :            : {
    2811                 :            :   hashentry *ep;
    2812                 :            :   long rgb;
    2813                 :            : 
    2814         [ +  + ]:      10134 :   if (!rgb_colors) rgb_colors = hashstr_import_static(col_list, 1000);
    2815                 :      10134 :   ep = hash_search(rgb_colors, (void*)s);
    2816         [ -  + ]:      10134 :   if (!ep) pari_err(e_MISC, "unknown color %s", s);
    2817                 :      10134 :   rgb = (long)ep->val;
    2818                 :      10134 :   *b = rgb & 0xff; rgb >>= 8;
    2819                 :      10134 :   *g = rgb & 0xff; rgb >>= 8;
    2820                 :      10134 :   *r = rgb;
    2821                 :      10134 : }
    2822                 :            : 
    2823                 :            : void
    2824                 :      10134 : color_to_rgb(GEN c, int *r, int *g, int *b)
    2825                 :            : {
    2826         [ +  - ]:      10134 :   switch(typ(c))
    2827                 :            :   {
    2828                 :            :     case t_STR:
    2829                 :      10134 :       colorname_to_rgb(GSTR(c), r,g,b);
    2830                 :      10134 :       break;
    2831                 :            :     default: /* t_VECSMALL: */
    2832                 :          0 :       *r = c[1]; *g = c[2]; *b = c[3];
    2833                 :          0 :       break;
    2834                 :            :   }
    2835                 :      10134 : }

Generated by: LCOV version 1.9