Logo Search packages:      
Sourcecode: r-base-core-ra version File versions  Download package

colors.c

/*
 *  R : A Computer Language for Statistical Data Analysis
 *  Copyright (C) 1995-2008  Robert Gentleman, Ross Ihaka and the
 *                     R Development Core Team
 *  Copyright (C) 2003       The R Foundation
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, a copy is available at
 *  http://www.r-project.org/Licenses/
 */

/* This should be regarded as part of the graphics engine */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <Defn.h>
#include <Graphics.h>  /* for dpptr */
#include <Colors.h>
#include <R_ext/GraphicsEngine.h>
#include <Rmath.h>


static unsigned int rgb2col(const char *);
static char *RGB2rgb(unsigned int, unsigned int, unsigned int);
static char *RGBA2rgb(unsigned int, unsigned int, unsigned int, unsigned int);
static unsigned int str2col(const char *s, unsigned int bg);

static int R_ColorTableSize;
static unsigned int R_ColorTable[COLOR_TABLE_SIZE];

/* String Comparison Ignoring Case and Squeezing Out Blanks */
static int StrMatch(const char *s, const char *t)
{
    for(;;) {
      if(*s == '\0' && *t == '\0') {
          return 1;
      }
      if(*s == ' ') {
          s++; continue;
      }
      if(*t == ' ') {
          t++; continue;
      }
      if(tolower(*s++) != tolower(*t++))
          return 0;
    }
}

static unsigned int char2col(const char *s)
{
    if (s[0] == '#') return rgb2col(s);
    else return name2col(s);
}

static unsigned int ScaleColor(double x)
{
    if (!R_FINITE(x) || x < 0.0 || x > 1.0)
      error(_("color intensity %g, not in [0,1]"), x);
    return (unsigned int)(255*x + 0.5);
}

static unsigned int CheckColor(int x)
{
    if (x == NA_INTEGER || x < 0 || x > 255)
      error(_("color intensity %d, not in 0:255"), x);
    return (unsigned int)x;
}

static unsigned int ScaleAlpha(double x)
{
    if (!R_FINITE(x) || x < 0.0 || x > 1.0)
      error(_("alpha level %g, not in [0,1]"), x);
    return (unsigned int)(255*x + 0.5);
}

static unsigned int CheckAlpha(int x)
{
    if (x == NA_INTEGER || x < 0 || x > 255)
      error(_("alpha level %d, not in 0:255"), x);
    return (unsigned int)x;
}


SEXP attribute_hidden do_hsv(SEXP call, SEXP op, SEXP args, SEXP env)
{
    SEXP c, h, s, v, gm, a;
    double hh, ss, vv, gg, aa, r=0., g=0., b=0.; /* -Wall */
    int i, max, nh, ns, nv, ng, na;

    checkArity(op, args);

    PROTECT(h = coerceVector(CAR(args),REALSXP)); args = CDR(args);
    PROTECT(s = coerceVector(CAR(args),REALSXP)); args = CDR(args);
    PROTECT(v = coerceVector(CAR(args),REALSXP)); args = CDR(args);
    PROTECT(gm = coerceVector(CAR(args),REALSXP)); args = CDR(args);
    PROTECT(a = coerceVector(CAR(args),REALSXP)); args = CDR(args);

    nh = LENGTH(h);
    ns = LENGTH(s);
    nv = LENGTH(v);
    ng = LENGTH(gm);
    na = LENGTH(a);
    if (nh <= 0 || ns <= 0 || nv <= 0 || ng <= 0 || na <= 0) {
      UNPROTECT(5);
      return(allocVector(STRSXP, 0));
    }
    max = nh;
    if (max < ns) max = ns;
    if (max < nv) max = nv;
    if (max < ng) max = ng;
    if (max < na) max = na;
    PROTECT(c = allocVector(STRSXP, max));
    if(max == 0) return(c);

    for (i = 0; i < max; i++) {
      hh = REAL(h)[i % nh];
      ss = REAL(s)[i % ns];
      vv = REAL(v)[i % nv];
      gg = REAL(gm)[i % ng];
      aa = REAL(a)[i % na];
      if (hh < 0 || hh > 1 || ss < 0 || ss > 1 || vv < 0 || vv > 1 ||
          aa < 0 || aa > 1)
          error(_("invalid hsv color"));
      hsv2rgb(hh, ss, vv, &r, &g, &b);
      r = pow(r, gg);
      g = pow(g, gg);
      b = pow(b, gg);
      SET_STRING_ELT(c, i, mkChar(RGBA2rgb(ScaleColor(r),
                                   ScaleColor(g),
                                   ScaleColor(b),
                                   ScaleAlpha(aa))));
    }
    UNPROTECT(6);
    return c;
}

/* D65 White Point */

#define WHITE_X 95.047
#define WHITE_Y 100.000
#define WHITE_Z 108.883
#define WHITE_u 0.1978398
#define WHITE_v 0.4683363

/* Standard CRT Gamma */

#define GAMMA 2.4

static double gtrans(double u)
{
    if (u > 0.00304)
      return 1.055 * pow(u, (1 / GAMMA)) - 0.055;
    else
      return 12.92 * u;
}

static int FixupColor(int *r, int *g, int *b)
{
    int fix = 0;
    if (*r < 0) { *r = 0; fix = 1; } else if (*r > 255) { *r = 255; fix = 1; }
    if (*g < 0) { *g = 0; fix = 1; } else if (*g > 255) { *g = 255; fix = 1; }
    if (*b < 0) { *b = 0; fix = 1; } else if (*b > 255) { *b = 255; fix = 1; }
    return fix;
}

static void
hcl2rgb(double h, double c, double l, double *R, double *G, double *B)
{
    double L, U, V;
    double u, v;
    double X, Y, Z;

    /* Step 1 : Convert to CIE-LUV */

    h = DEG2RAD * h;
    L = l;
    U = c * cos(h);
    V = c * sin(h);

    /* Step 2 : Convert to CIE-XYZ */

    if (L <= 0 && U == 0 && V == 0) {
      X = 0; Y = 0; Z = 0;
    }
    else {
      Y = WHITE_Y * ((L > 7.999592) ? pow((L + 16)/116, 3) : L / 903.3);
      u = U / (13 * L) + WHITE_u;
      v = V / (13 * L) + WHITE_v;
      X =  9.0 * Y * u / (4 * v);
      Z =  - X / 3 - 5 * Y + 3 * Y / v;
    }

    /* Step 4 : CIE-XYZ to sRGB */

    *R = gtrans(( 3.240479 * X - 1.537150 * Y - 0.498535 * Z) / WHITE_Y);
    *G = gtrans((-0.969256 * X + 1.875992 * Y + 0.041556 * Z) / WHITE_Y);
    *B = gtrans(( 0.055648 * X - 0.204043 * Y + 1.057311 * Z) / WHITE_Y);
}

SEXP attribute_hidden do_hcl(SEXP call, SEXP op, SEXP args, SEXP env)
{
    SEXP h, c, l, a, ans;
    double H, C, L, A, r, g, b;
    int nh, nc, nl, na, max, i;
    int ir, ig, ib;
    int fixup;

    checkArity(op, args);

    PROTECT(h = coerceVector(CAR(args),REALSXP)); args = CDR(args);
    PROTECT(c = coerceVector(CAR(args),REALSXP)); args = CDR(args);
    PROTECT(l = coerceVector(CAR(args),REALSXP)); args = CDR(args);
    PROTECT(a = coerceVector(CAR(args),REALSXP)); args = CDR(args);
    fixup = asLogical(CAR(args));
    nh = LENGTH(h);
    nc = LENGTH(c);
    nl = LENGTH(l);
    na = LENGTH(a);
    if (nh <= 0 || nc <= 0 || nl <= 0 || na <= 0) {
      UNPROTECT(4);
      return(allocVector(STRSXP, 0));
    }
    max = nh;
    if (max < nc) max = nc;
    if (max < nl) max = nl;
    if (max < na) max = na;
    PROTECT(ans = allocVector(STRSXP, max));
    for (i = 0; i < max; i++) {
      H = REAL(h)[i % nh];
      C = REAL(c)[i % nc];
      L = REAL(l)[i % nl];
      A = REAL(a)[i % na];
      if (!R_FINITE(A)) A = 1;
      if (L < 0 || L > WHITE_Y || C < 0 || A < 0 || A > 1)
          error(_("invalid hcl color"));
      hcl2rgb(H, C, L, &r, &g, &b);
      ir = 255 * r + .5;
      ig = 255 * g + .5;
      ib = 255 * b + .5;
      if (FixupColor(&ir, &ig, &ib) && !fixup)
          SET_STRING_ELT(ans, i, NA_STRING);
      else
          SET_STRING_ELT(ans, i, mkChar(RGBA2rgb(ir, ig, ib,
                                ScaleAlpha(A))));
    }
    UNPROTECT(5);
    return ans;
}

SEXP attribute_hidden do_rgb(SEXP call, SEXP op, SEXP args, SEXP env)
{
    SEXP c, r, g, b, a, nam;
    int OP, i, l_max, nr, ng, nb, na;
    Rboolean max_1 = FALSE;
    double mV = 0.0; /* -Wall */

    checkArity(op, args);
    OP = PRIMVAL(op);
    if(OP) {/* op == 1:  rgb256() :*/
      PROTECT(r = coerceVector(CAR(args), INTSXP)); args = CDR(args);
      PROTECT(g = coerceVector(CAR(args), INTSXP)); args = CDR(args);
      PROTECT(b = coerceVector(CAR(args), INTSXP)); args = CDR(args);
      PROTECT(a = coerceVector(CAR(args), INTSXP)); args = CDR(args);
    }
    else {
      PROTECT(r = coerceVector(CAR(args), REALSXP)); args = CDR(args);
      PROTECT(g = coerceVector(CAR(args), REALSXP)); args = CDR(args);
      PROTECT(b = coerceVector(CAR(args), REALSXP)); args = CDR(args);
      PROTECT(a = coerceVector(CAR(args), REALSXP)); args = CDR(args);
      mV = asReal(CAR(args));                    args = CDR(args);
      max_1 = (mV == 1.);
    }

    nr = LENGTH(r); ng = LENGTH(g); nb = LENGTH(b); na = LENGTH(a);
    if (nr <= 0 || ng <= 0 || nb <= 0 || na <= 0) {
      UNPROTECT(4);
      return(allocVector(STRSXP, 0));
    }
    l_max = nr;
    if (l_max < ng) l_max = ng;
    if (l_max < nb) l_max = nb;
    if (l_max < na) l_max = na;

    PROTECT(nam = coerceVector(CAR(args), STRSXP)); args = CDR(args);
    if (length(nam) != 0 && length(nam) != l_max)
      error(_("invalid 'names' vector"));
    PROTECT(c = allocVector(STRSXP, l_max));

#define _R_set_c_RGBA(_R,_G,_B,_A)                    \
    for (i = 0; i < l_max; i++)                       \
      SET_STRING_ELT(c, i, mkChar(RGBA2rgb(_R,_G,_B,_A)))

    if(OP) { /* OP == 1:  rgb256() :*/
      _R_set_c_RGBA(CheckColor(INTEGER(r)[i%nr]),
                  CheckColor(INTEGER(g)[i%ng]),
                  CheckColor(INTEGER(b)[i%nb]),
                  CheckAlpha(INTEGER(a)[i%na]));
    }
    else if(max_1) {
      _R_set_c_RGBA(ScaleColor(REAL(r)[i%nr]),
                  ScaleColor(REAL(g)[i%ng]),
                  ScaleColor(REAL(b)[i%nb]),
                  ScaleAlpha(REAL(a)[i%na]));
    }
    else { /* maxColorVal not in {1, 255} */
      _R_set_c_RGBA(ScaleColor(REAL(r)[i%nr] / mV),
                  ScaleColor(REAL(g)[i%ng] / mV),
                  ScaleColor(REAL(b)[i%nb] / mV),
                  ScaleAlpha(REAL(a)[i%na] / mV));
    }
    if (length(nam) != 0)
      setAttrib(c, R_NamesSymbol, nam);
    UNPROTECT(6);
    return c;
}

SEXP attribute_hidden do_gray(SEXP call, SEXP op, SEXP args, SEXP env)
{
    SEXP lev, ans;
    double level;
    int i, ilevel, nlev;

    checkArity(op, args);

    PROTECT(lev = coerceVector(CAR(args),REALSXP));
    nlev = LENGTH(lev);
    PROTECT(ans = allocVector(STRSXP, nlev));
    for (i = 0; i < nlev; i++) {
      level = REAL(lev)[i];
      if (ISNAN(level) || level < 0 || level > 1)
          error(_("invalid gray level, must be in [0,1]."));
      ilevel = 255 * level + 0.5;
      SET_STRING_ELT(ans, i, mkChar(RGB2rgb(ilevel, ilevel, ilevel)));
    }
    UNPROTECT(2);
    return ans;
}

SEXP attribute_hidden do_col2RGB(SEXP call, SEXP op, SEXP args, SEXP env)
{
/* colorname, "#rrggbb" or "col.number" to (r,g,b) conversion */
    SEXP colors, ans, names, dmns;
    unsigned int col, bg;
    int n, i, i4;
    Rboolean bg_needed = FALSE;

    checkArity(op, args);
    colors = CAR(args);
    if(isString(colors)) PROTECT(colors);
    else {
      PROTECT(colors = coerceVector(colors, INTSXP));
      if (TYPEOF(colors) != INTSXP)
          error(_("invalid '%s' value"), "col");
    }
    n = LENGTH(colors);

    /* First set up the output matrix */
    PROTECT(ans = allocMatrix(INTSXP, 4, n));
    PROTECT(dmns = allocVector(VECSXP, 2));
    PROTECT(names = allocVector(STRSXP, 4));
    SET_STRING_ELT(names, 0, mkChar("red"));
    SET_STRING_ELT(names, 1, mkChar("green"));
    SET_STRING_ELT(names, 2, mkChar("blue"));
    SET_STRING_ELT(names, 3, mkChar("alpha"));
    SET_VECTOR_ELT(dmns, 0, names);
    UNPROTECT(1); /*names*/
    if ((names = getAttrib(colors, R_NamesSymbol)) != R_NilValue)
      SET_VECTOR_ELT(dmns, 1, names);
    setAttrib(ans, R_DimNamesSymbol, dmns);

    /* avoid looking up the background unless we will need it;
       this may avoid opening a new window */

    bg_needed = !isString(colors);
    for (i = 0; !bg_needed && i < n; i++)
      bg_needed = isdigit((int)CHAR(STRING_ELT(colors, i))[0]);
    if (bg_needed)
      bg = dpptr(GEcurrentDevice())->bg;
    else
      bg = R_TRANWHITE;

    if(isString(colors)) {
      for(i = i4 = 0; i < n; i++, i4 += 4) {
          col = str2col(CHAR(STRING_ELT(colors, i)), bg);
          INTEGER(ans)[i4 +0] = R_RED(col);
          INTEGER(ans)[i4 +1] = R_GREEN(col);
          INTEGER(ans)[i4 +2] = R_BLUE(col);
          INTEGER(ans)[i4 +3] = R_ALPHA(col);
      }
    } else {
      for(i = i4 = 0; i < n; i++, i4 += 4) {
          col = INTEGER(colors)[i];
          col =  (col > 0) ? R_ColorTable[(col-1) % R_ColorTableSize] : bg;
          INTEGER(ans)[i4 +0] = R_RED(col);
          INTEGER(ans)[i4 +1] = R_GREEN(col);
          INTEGER(ans)[i4 +2] = R_BLUE(col);
          INTEGER(ans)[i4 +3] = R_ALPHA(col);
      }
    }
    UNPROTECT(3);
    return ans;
}

SEXP attribute_hidden do_RGB2hsv(SEXP call, SEXP op, SEXP args, SEXP env)
{
/* (r,g,b) -> (h,s,v) conversion */
    SEXP rgb, dd, ans, names, dmns;
    int n, i, i3;

    checkArity(op, args);

    PROTECT(rgb = coerceVector(CAR(args),REALSXP)); args = CDR(args);
    if(!isMatrix(rgb))
      error(_("rgb is not a matrix (internally)"));
    dd = getAttrib(rgb, R_DimSymbol);
    if(INTEGER(dd)[0] != 3)
      error(_("rgb must have 3 rows (internally)"));
    n = INTEGER(dd)[1];

    PROTECT(ans = allocMatrix(REALSXP, 3, n));
    PROTECT(dmns = allocVector(VECSXP, 2));
    /* row names: */
    PROTECT(names = allocVector(STRSXP, 3));
    SET_STRING_ELT(names, 0, mkChar("h"));
    SET_STRING_ELT(names, 1, mkChar("s"));
    SET_STRING_ELT(names, 2, mkChar("v"));
    SET_VECTOR_ELT(dmns, 0, names);
    /* column names if input has: */
    if ((dd = getAttrib(rgb, R_DimNamesSymbol)) != R_NilValue &&
      (names = VECTOR_ELT(dd, 1)) != R_NilValue)
      SET_VECTOR_ELT(dmns, 1, names);
    setAttrib(ans, R_DimNamesSymbol, dmns);
    UNPROTECT(2);/* names, dmns */

    for(i = i3 = 0; i < n; i++, i3 += 3) {
      rgb2hsv(REAL(rgb)[i3+ 0],  REAL(rgb)[i3+ 1],  REAL(rgb)[i3+ 2],
            &REAL(ans)[i3+ 0], &REAL(ans)[i3+ 1], &REAL(ans)[i3 +2]);
    }
    UNPROTECT(2);
    return ans;
}

/* From here on down moved from graphics.c in 2.7.0 *//* Colour Code */

/* hsv2rgb -- HSV to RGB conversion  */
/* Based on HSV_TO_RGB from Foley and Van Dam First Ed. Page 616 */
/* See Alvy Ray Smith, Color Gamut Transform Pairs, SIGGRAPH '78 */

static char HexDigits[] = "0123456789ABCDEF";

/* rgb2hsv and hsv2rgb are in Utils.h ! */
void hsv2rgb(double h, double s, double v, double *r, double *g, double *b)
{
    double f, p, q, t;
    int i;

    f = modf(h * 6.0, &t);
    i = ((int) t) % 6;

    p = v * (1 - s);
    q = v * (1 - s * f);
    t = v * (1 - (s * (1 - f)));
    switch (i) {
    case 0: *r = v;           *g = t;           *b = p;     break;
    case 1: *r = q;           *g = v;           *b = p;     break;
    case 2: *r = p;           *g = v;           *b = t;     break;
    case 3: *r = p;           *g = q;           *b = v; break;
    case 4: *r = t;           *g = p;           *b = v; break;
    case 5: *r = v;           *g = p;           *b = q;     break;
    default:
      error(_("bad hsv to rgb color conversion"));
    }
}

/* rgb2hsv() -- the reverse (same reference as above)
 *    this implementation is adapted from code by Nicholas Lewin-Koh.
 */
void rgb2hsv(double r, double g, double b,
           double *h, double *s, double *v)
    /* all (r,g,b, h,s,v) values in [0,1] */
{
    double min, max, delta;
    Rboolean r_max = TRUE, b_max = FALSE;
    /* Compute  min(r,g,b) and max(r,g,b) and remember where max is: */
    min = max = r;
    if(min > g) { /* g < r */
      if(b < g)
          min = b;/* &  max = r */
      else { /* g <= b, g < r */
          min = g;
          if(b > r) { max = b; b_max = TRUE; r_max = FALSE; }
          /* else : g <= b <=r */
      }
    } else { /* r <= g */
      if(b > g) {
          max = b; b_max = TRUE; r_max = FALSE; /* &  min = r */
      } else { /* b,r <= g */
          max = g; r_max = FALSE; /* &  min = r */
          if(b < r) min = b; /* else : r <= b <= g */
      }
    }

    *v = max;
    if( max == 0 || (delta = max - min) == 0) {
      /*   r = g = b : "gray" : s = h = 0 */
      *s = *h = 0;
      return;
    }
    /* else : */
    *s = delta / max;

    if(r_max)
      *h =     ( g - b ) / delta; /* between yellow & magenta */
    else if(b_max)
      *h = 4 + ( r - g ) / delta; /* between magenta & cyan */
    else /* g == max */
      *h = 2 + ( b - r ) / delta; /* between cyan & yellow*/

    *h /= 6;
    if(*h < 0)
      *h += 1.;
    return;
}


/*
 *  Color Specification
 *
 *  Colors are stored internally in integers.  Each integer is
 *  broken into four bytes.    The three least significant bytes
 *  are used to contain levels of red, green and blue.      These
 *  levels are integers in the range [0,255].
 *
 *  Externally, colors are specified either:
 *
 *    a) by name, using a large table of color names,
 *
 *    b) by RGB values using a string of the form "#rrggbb"
 *     where rr, gg and bb are hex integers giving the level
 *     of red green and blue,
 *
 *    c) as an index into a user setable palette of colors.
 *
 */

/* Default Color Palette */
/* Paul Murrell 05/06/02 (2002, probably)
 * Changed "white" to "grey" in the default palette
 * in response to user suggestion
 */

attribute_hidden
const char *DefaultPalette[] = {
    "black",
    "red",
    "green3",
    "blue",
    "cyan",
    "magenta",
    "yellow",
    "grey",
    NULL
};

/* The Table of Known Color Names */
/* Adapted from the X11 RGB database */
/* Note: the color "white" is moved */
/* to the top of the database to avoid */
/* its being known as "gray100" */

00583 typedef
struct colorDataBaseEntry {
      char *name; /* X11 Color Name */
      char *rgb;  /* #RRGGBB String */
      unsigned int code;  /* Internal R Color Code */
} ColorDataBaseEntry;

static int ColorDataBaseSize;

static ColorDataBaseEntry ColorDataBase[] = {
    /* name       rgb         code -- filled in by InitColors() */
    {"white",           "#FFFFFF",  0},
    {"aliceblue", "#F0F8FF",  0},
    {"antiquewhite",    "#FAEBD7",  0},
    {"antiquewhite1",   "#FFEFDB",  0},
    {"antiquewhite2",   "#EEDFCC",  0},
    {"antiquewhite3",   "#CDC0B0",  0},
    {"antiquewhite4",   "#8B8378",  0},
    {"aquamarine",      "#7FFFD4",  0},
    {"aquamarine1",     "#7FFFD4",  0},
    {"aquamarine2",     "#76EEC6",  0},
    {"aquamarine3",     "#66CDAA",  0},
    {"aquamarine4",     "#458B74",  0},
    {"azure",           "#F0FFFF",  0},
    {"azure1",          "#F0FFFF",  0},
    {"azure2",          "#E0EEEE",  0},
    {"azure3",          "#C1CDCD",  0},
    {"azure4",          "#838B8B",  0},
    {"beige",           "#F5F5DC",  0},
    {"bisque",          "#FFE4C4",  0},
    {"bisque1",         "#FFE4C4",  0},
    {"bisque2",         "#EED5B7",  0},
    {"bisque3",         "#CDB79E",  0},
    {"bisque4",         "#8B7D6B",  0},
    {"black",           "#000000",  0},
    {"blanchedalmond",  "#FFEBCD",  0},
    {"blue",            "#0000FF",  0},
    {"blue1",           "#0000FF",  0},
    {"blue2",           "#0000EE",  0},
    {"blue3",           "#0000CD",  0},
    {"blue4",           "#00008B",  0},
    {"blueviolet",      "#8A2BE2",  0},
    {"brown",           "#A52A2A",  0},
    {"brown1",          "#FF4040",  0},
    {"brown2",          "#EE3B3B",  0},
    {"brown3",          "#CD3333",  0},
    {"brown4",          "#8B2323",  0},
    {"burlywood", "#DEB887",  0},
    {"burlywood1",      "#FFD39B",  0},
    {"burlywood2",      "#EEC591",  0},
    {"burlywood3",      "#CDAA7D",  0},
    {"burlywood4",      "#8B7355",  0},
    {"cadetblue", "#5F9EA0",  0},
    {"cadetblue1",      "#98F5FF",  0},
    {"cadetblue2",      "#8EE5EE",  0},
    {"cadetblue3",      "#7AC5CD",  0},
    {"cadetblue4",      "#53868B",  0},
    {"chartreuse",      "#7FFF00",  0},
    {"chartreuse1",     "#7FFF00",  0},
    {"chartreuse2",     "#76EE00",  0},
    {"chartreuse3",     "#66CD00",  0},
    {"chartreuse4",     "#458B00",  0},
    {"chocolate", "#D2691E",  0},
    {"chocolate1",      "#FF7F24",  0},
    {"chocolate2",      "#EE7621",  0},
    {"chocolate3",      "#CD661D",  0},
    {"chocolate4",      "#8B4513",  0},
    {"coral",           "#FF7F50",  0},
    {"coral1",          "#FF7256",  0},
    {"coral2",          "#EE6A50",  0},
    {"coral3",          "#CD5B45",  0},
    {"coral4",          "#8B3E2F",  0},
    {"cornflowerblue",  "#6495ED",  0},
    {"cornsilk",  "#FFF8DC",  0},
    {"cornsilk1", "#FFF8DC",  0},
    {"cornsilk2", "#EEE8CD",  0},
    {"cornsilk3", "#CDC8B1",  0},
    {"cornsilk4", "#8B8878",  0},
    {"cyan",            "#00FFFF",  0},
    {"cyan1",           "#00FFFF",  0},
    {"cyan2",           "#00EEEE",  0},
    {"cyan3",           "#00CDCD",  0},
    {"cyan4",           "#008B8B",  0},
    {"darkblue",  "#00008B",  0},
    {"darkcyan",  "#008B8B",  0},
    {"darkgoldenrod",   "#B8860B",  0},
    {"darkgoldenrod1",  "#FFB90F",  0},
    {"darkgoldenrod2",  "#EEAD0E",  0},
    {"darkgoldenrod3",  "#CD950C",  0},
    {"darkgoldenrod4",  "#8B6508",  0},
    {"darkgray",  "#A9A9A9",  0},
    {"darkgreen", "#006400",  0},
    {"darkgrey",  "#A9A9A9",  0},
    {"darkkhaki", "#BDB76B",  0},
    {"darkmagenta",     "#8B008B",  0},
    {"darkolivegreen",  "#556B2F",  0},
    {"darkolivegreen1", "#CAFF70",  0},
    {"darkolivegreen2", "#BCEE68",  0},
    {"darkolivegreen3", "#A2CD5A",  0},
    {"darkolivegreen4", "#6E8B3D",  0},
    {"darkorange",      "#FF8C00",  0},
    {"darkorange1",     "#FF7F00",  0},
    {"darkorange2",     "#EE7600",  0},
    {"darkorange3",     "#CD6600",  0},
    {"darkorange4",     "#8B4500",  0},
    {"darkorchid",      "#9932CC",  0},
    {"darkorchid1",     "#BF3EFF",  0},
    {"darkorchid2",     "#B23AEE",  0},
    {"darkorchid3",     "#9A32CD",  0},
    {"darkorchid4",     "#68228B",  0},
    {"darkred",         "#8B0000",  0},
    {"darksalmon",      "#E9967A",  0},
    {"darkseagreen",    "#8FBC8F",  0},
    {"darkseagreen1",   "#C1FFC1",  0},
    {"darkseagreen2",   "#B4EEB4",  0},
    {"darkseagreen3",   "#9BCD9B",  0},
    {"darkseagreen4",   "#698B69",  0},
    {"darkslateblue",   "#483D8B",  0},
    {"darkslategray",   "#2F4F4F",  0},
    {"darkslategray1",  "#97FFFF",  0},
    {"darkslategray2",  "#8DEEEE",  0},
    {"darkslategray3",  "#79CDCD",  0},
    {"darkslategray4",  "#528B8B",  0},
    {"darkslategrey",   "#2F4F4F",  0},
    {"darkturquoise",   "#00CED1",  0},
    {"darkviolet",      "#9400D3",  0},
    {"deeppink",  "#FF1493",  0},
    {"deeppink1", "#FF1493",  0},
    {"deeppink2", "#EE1289",  0},
    {"deeppink3", "#CD1076",  0},
    {"deeppink4", "#8B0A50",  0},
    {"deepskyblue",     "#00BFFF",  0},
    {"deepskyblue1",    "#00BFFF",  0},
    {"deepskyblue2",    "#00B2EE",  0},
    {"deepskyblue3",    "#009ACD",  0},
    {"deepskyblue4",    "#00688B",  0},
    {"dimgray",         "#696969",  0},
    {"dimgrey",         "#696969",  0},
    {"dodgerblue",      "#1E90FF",  0},
    {"dodgerblue1",     "#1E90FF",  0},
    {"dodgerblue2",     "#1C86EE",  0},
    {"dodgerblue3",     "#1874CD",  0},
    {"dodgerblue4",     "#104E8B",  0},
    {"firebrick", "#B22222",  0},
    {"firebrick1",      "#FF3030",  0},
    {"firebrick2",      "#EE2C2C",  0},
    {"firebrick3",      "#CD2626",  0},
    {"firebrick4",      "#8B1A1A",  0},
    {"floralwhite",     "#FFFAF0",  0},
    {"forestgreen",     "#228B22",  0},
    {"gainsboro", "#DCDCDC",  0},
    {"ghostwhite",      "#F8F8FF",  0},
    {"gold",            "#FFD700",  0},
    {"gold1",           "#FFD700",  0},
    {"gold2",           "#EEC900",  0},
    {"gold3",           "#CDAD00",  0},
    {"gold4",           "#8B7500",  0},
    {"goldenrod", "#DAA520",  0},
    {"goldenrod1",      "#FFC125",  0},
    {"goldenrod2",      "#EEB422",  0},
    {"goldenrod3",      "#CD9B1D",  0},
    {"goldenrod4",      "#8B6914",  0},
    {"gray",            "#BEBEBE",  0},
    {"gray0",           "#000000",  0},
    {"gray1",           "#030303",  0},
    {"gray2",           "#050505",  0},
    {"gray3",           "#080808",  0},
    {"gray4",           "#0A0A0A",  0},
    {"gray5",           "#0D0D0D",  0},
    {"gray6",           "#0F0F0F",  0},
    {"gray7",           "#121212",  0},
    {"gray8",           "#141414",  0},
    {"gray9",           "#171717",  0},
    {"gray10",          "#1A1A1A",  0},
    {"gray11",          "#1C1C1C",  0},
    {"gray12",          "#1F1F1F",  0},
    {"gray13",          "#212121",  0},
    {"gray14",          "#242424",  0},
    {"gray15",          "#262626",  0},
    {"gray16",          "#292929",  0},
    {"gray17",          "#2B2B2B",  0},
    {"gray18",          "#2E2E2E",  0},
    {"gray19",          "#303030",  0},
    {"gray20",          "#333333",  0},
    {"gray21",          "#363636",  0},
    {"gray22",          "#383838",  0},
    {"gray23",          "#3B3B3B",  0},
    {"gray24",          "#3D3D3D",  0},
    {"gray25",          "#404040",  0},
    {"gray26",          "#424242",  0},
    {"gray27",          "#454545",  0},
    {"gray28",          "#474747",  0},
    {"gray29",          "#4A4A4A",  0},
    {"gray30",          "#4D4D4D",  0},
    {"gray31",          "#4F4F4F",  0},
    {"gray32",          "#525252",  0},
    {"gray33",          "#545454",  0},
    {"gray34",          "#575757",  0},
    {"gray35",          "#595959",  0},
    {"gray36",          "#5C5C5C",  0},
    {"gray37",          "#5E5E5E",  0},
    {"gray38",          "#616161",  0},
    {"gray39",          "#636363",  0},
    {"gray40",          "#666666",  0},
    {"gray41",          "#696969",  0},
    {"gray42",          "#6B6B6B",  0},
    {"gray43",          "#6E6E6E",  0},
    {"gray44",          "#707070",  0},
    {"gray45",          "#737373",  0},
    {"gray46",          "#757575",  0},
    {"gray47",          "#787878",  0},
    {"gray48",          "#7A7A7A",  0},
    {"gray49",          "#7D7D7D",  0},
    {"gray50",          "#7F7F7F",  0},
    {"gray51",          "#828282",  0},
    {"gray52",          "#858585",  0},
    {"gray53",          "#878787",  0},
    {"gray54",          "#8A8A8A",  0},
    {"gray55",          "#8C8C8C",  0},
    {"gray56",          "#8F8F8F",  0},
    {"gray57",          "#919191",  0},
    {"gray58",          "#949494",  0},
    {"gray59",          "#969696",  0},
    {"gray60",          "#999999",  0},
    {"gray61",          "#9C9C9C",  0},
    {"gray62",          "#9E9E9E",  0},
    {"gray63",          "#A1A1A1",  0},
    {"gray64",          "#A3A3A3",  0},
    {"gray65",          "#A6A6A6",  0},
    {"gray66",          "#A8A8A8",  0},
    {"gray67",          "#ABABAB",  0},
    {"gray68",          "#ADADAD",  0},
    {"gray69",          "#B0B0B0",  0},
    {"gray70",          "#B3B3B3",  0},
    {"gray71",          "#B5B5B5",  0},
    {"gray72",          "#B8B8B8",  0},
    {"gray73",          "#BABABA",  0},
    {"gray74",          "#BDBDBD",  0},
    {"gray75",          "#BFBFBF",  0},
    {"gray76",          "#C2C2C2",  0},
    {"gray77",          "#C4C4C4",  0},
    {"gray78",          "#C7C7C7",  0},
    {"gray79",          "#C9C9C9",  0},
    {"gray80",          "#CCCCCC",  0},
    {"gray81",          "#CFCFCF",  0},
    {"gray82",          "#D1D1D1",  0},
    {"gray83",          "#D4D4D4",  0},
    {"gray84",          "#D6D6D6",  0},
    {"gray85",          "#D9D9D9",  0},
    {"gray86",          "#DBDBDB",  0},
    {"gray87",          "#DEDEDE",  0},
    {"gray88",          "#E0E0E0",  0},
    {"gray89",          "#E3E3E3",  0},
    {"gray90",          "#E5E5E5",  0},
    {"gray91",          "#E8E8E8",  0},
    {"gray92",          "#EBEBEB",  0},
    {"gray93",          "#EDEDED",  0},
    {"gray94",          "#F0F0F0",  0},
    {"gray95",          "#F2F2F2",  0},
    {"gray96",          "#F5F5F5",  0},
    {"gray97",          "#F7F7F7",  0},
    {"gray98",          "#FAFAFA",  0},
    {"gray99",          "#FCFCFC",  0},
    {"gray100",         "#FFFFFF",  0},
    {"green",           "#00FF00",  0},
    {"green1",          "#00FF00",  0},
    {"green2",          "#00EE00",  0},
    {"green3",          "#00CD00",  0},
    {"green4",          "#008B00",  0},
    {"greenyellow",     "#ADFF2F",  0},
    {"grey",            "#BEBEBE",  0},
    {"grey0",           "#000000",  0},
    {"grey1",           "#030303",  0},
    {"grey2",           "#050505",  0},
    {"grey3",           "#080808",  0},
    {"grey4",           "#0A0A0A",  0},
    {"grey5",           "#0D0D0D",  0},
    {"grey6",           "#0F0F0F",  0},
    {"grey7",           "#121212",  0},
    {"grey8",           "#141414",  0},
    {"grey9",           "#171717",  0},
    {"grey10",          "#1A1A1A",  0},
    {"grey11",          "#1C1C1C",  0},
    {"grey12",          "#1F1F1F",  0},
    {"grey13",          "#212121",  0},
    {"grey14",          "#242424",  0},
    {"grey15",          "#262626",  0},
    {"grey16",          "#292929",  0},
    {"grey17",          "#2B2B2B",  0},
    {"grey18",          "#2E2E2E",  0},
    {"grey19",          "#303030",  0},
    {"grey20",          "#333333",  0},
    {"grey21",          "#363636",  0},
    {"grey22",          "#383838",  0},
    {"grey23",          "#3B3B3B",  0},
    {"grey24",          "#3D3D3D",  0},
    {"grey25",          "#404040",  0},
    {"grey26",          "#424242",  0},
    {"grey27",          "#454545",  0},
    {"grey28",          "#474747",  0},
    {"grey29",          "#4A4A4A",  0},
    {"grey30",          "#4D4D4D",  0},
    {"grey31",          "#4F4F4F",  0},
    {"grey32",          "#525252",  0},
    {"grey33",          "#545454",  0},
    {"grey34",          "#575757",  0},
    {"grey35",          "#595959",  0},
    {"grey36",          "#5C5C5C",  0},
    {"grey37",          "#5E5E5E",  0},
    {"grey38",          "#616161",  0},
    {"grey39",          "#636363",  0},
    {"grey40",          "#666666",  0},
    {"grey41",          "#696969",  0},
    {"grey42",          "#6B6B6B",  0},
    {"grey43",          "#6E6E6E",  0},
    {"grey44",          "#707070",  0},
    {"grey45",          "#737373",  0},
    {"grey46",          "#757575",  0},
    {"grey47",          "#787878",  0},
    {"grey48",          "#7A7A7A",  0},
    {"grey49",          "#7D7D7D",  0},
    {"grey50",          "#7F7F7F",  0},
    {"grey51",          "#828282",  0},
    {"grey52",          "#858585",  0},
    {"grey53",          "#878787",  0},
    {"grey54",          "#8A8A8A",  0},
    {"grey55",          "#8C8C8C",  0},
    {"grey56",          "#8F8F8F",  0},
    {"grey57",          "#919191",  0},
    {"grey58",          "#949494",  0},
    {"grey59",          "#969696",  0},
    {"grey60",          "#999999",  0},
    {"grey61",          "#9C9C9C",  0},
    {"grey62",          "#9E9E9E",  0},
    {"grey63",          "#A1A1A1",  0},
    {"grey64",          "#A3A3A3",  0},
    {"grey65",          "#A6A6A6",  0},
    {"grey66",          "#A8A8A8",  0},
    {"grey67",          "#ABABAB",  0},
    {"grey68",          "#ADADAD",  0},
    {"grey69",          "#B0B0B0",  0},
    {"grey70",          "#B3B3B3",  0},
    {"grey71",          "#B5B5B5",  0},
    {"grey72",          "#B8B8B8",  0},
    {"grey73",          "#BABABA",  0},
    {"grey74",          "#BDBDBD",  0},
    {"grey75",          "#BFBFBF",  0},
    {"grey76",          "#C2C2C2",  0},
    {"grey77",          "#C4C4C4",  0},
    {"grey78",          "#C7C7C7",  0},
    {"grey79",          "#C9C9C9",  0},
    {"grey80",          "#CCCCCC",  0},
    {"grey81",          "#CFCFCF",  0},
    {"grey82",          "#D1D1D1",  0},
    {"grey83",          "#D4D4D4",  0},
    {"grey84",          "#D6D6D6",  0},
    {"grey85",          "#D9D9D9",  0},
    {"grey86",          "#DBDBDB",  0},
    {"grey87",          "#DEDEDE",  0},
    {"grey88",          "#E0E0E0",  0},
    {"grey89",          "#E3E3E3",  0},
    {"grey90",          "#E5E5E5",  0},
    {"grey91",          "#E8E8E8",  0},
    {"grey92",          "#EBEBEB",  0},
    {"grey93",          "#EDEDED",  0},
    {"grey94",          "#F0F0F0",  0},
    {"grey95",          "#F2F2F2",  0},
    {"grey96",          "#F5F5F5",  0},
    {"grey97",          "#F7F7F7",  0},
    {"grey98",          "#FAFAFA",  0},
    {"grey99",          "#FCFCFC",  0},
    {"grey100",         "#FFFFFF",  0},
    {"honeydew",  "#F0FFF0",  0},
    {"honeydew1", "#F0FFF0",  0},
    {"honeydew2", "#E0EEE0",  0},
    {"honeydew3", "#C1CDC1",  0},
    {"honeydew4", "#838B83",  0},
    {"hotpink",         "#FF69B4",  0},
    {"hotpink1",  "#FF6EB4",  0},
    {"hotpink2",  "#EE6AA7",  0},
    {"hotpink3",  "#CD6090",  0},
    {"hotpink4",  "#8B3A62",  0},
    {"indianred", "#CD5C5C",  0},
    {"indianred1",      "#FF6A6A",  0},
    {"indianred2",      "#EE6363",  0},
    {"indianred3",      "#CD5555",  0},
    {"indianred4",      "#8B3A3A",  0},
    {"ivory",           "#FFFFF0",  0},
    {"ivory1",          "#FFFFF0",  0},
    {"ivory2",          "#EEEEE0",  0},
    {"ivory3",          "#CDCDC1",  0},
    {"ivory4",          "#8B8B83",  0},
    {"khaki",           "#F0E68C",  0},
    {"khaki1",          "#FFF68F",  0},
    {"khaki2",          "#EEE685",  0},
    {"khaki3",          "#CDC673",  0},
    {"khaki4",          "#8B864E",  0},
    {"lavender",  "#E6E6FA",  0},
    {"lavenderblush",   "#FFF0F5",  0},
    {"lavenderblush1",  "#FFF0F5",  0},
    {"lavenderblush2",  "#EEE0E5",  0},
    {"lavenderblush3",  "#CDC1C5",  0},
    {"lavenderblush4",  "#8B8386",  0},
    {"lawngreen", "#7CFC00",  0},
    {"lemonchiffon",    "#FFFACD",  0},
    {"lemonchiffon1",   "#FFFACD",  0},
    {"lemonchiffon2",   "#EEE9BF",  0},
    {"lemonchiffon3",   "#CDC9A5",  0},
    {"lemonchiffon4",   "#8B8970",  0},
    {"lightblue", "#ADD8E6",  0},
    {"lightblue1",      "#BFEFFF",  0},
    {"lightblue2",      "#B2DFEE",  0},
    {"lightblue3",      "#9AC0CD",  0},
    {"lightblue4",      "#68838B",  0},
    {"lightcoral",      "#F08080",  0},
    {"lightcyan", "#E0FFFF",  0},
    {"lightcyan1",      "#E0FFFF",  0},
    {"lightcyan2",      "#D1EEEE",  0},
    {"lightcyan3",      "#B4CDCD",  0},
    {"lightcyan4",      "#7A8B8B",  0},
    {"lightgoldenrod",  "#EEDD82",  0},
    {"lightgoldenrod1", "#FFEC8B",  0},
    {"lightgoldenrod2", "#EEDC82",  0},
    {"lightgoldenrod3", "#CDBE70",  0},
    {"lightgoldenrod4", "#8B814C",  0},
    {"lightgoldenrodyellow","#FAFAD2",    0},
    {"lightgray", "#D3D3D3",  0},
    {"lightgreen",      "#90EE90",  0},
    {"lightgrey", "#D3D3D3",  0},
    {"lightpink", "#FFB6C1",  0},
    {"lightpink1",      "#FFAEB9",  0},
    {"lightpink2",      "#EEA2AD",  0},
    {"lightpink3",      "#CD8C95",  0},
    {"lightpink4",      "#8B5F65",  0},
    {"lightsalmon",     "#FFA07A",  0},
    {"lightsalmon1",    "#FFA07A",  0},
    {"lightsalmon2",    "#EE9572",  0},
    {"lightsalmon3",    "#CD8162",  0},
    {"lightsalmon4",    "#8B5742",  0},
    {"lightseagreen",   "#20B2AA",  0},
    {"lightskyblue",    "#87CEFA",  0},
    {"lightskyblue1",   "#B0E2FF",  0},
    {"lightskyblue2",   "#A4D3EE",  0},
    {"lightskyblue3",   "#8DB6CD",  0},
    {"lightskyblue4",   "#607B8B",  0},
    {"lightslateblue",  "#8470FF",  0},
    {"lightslategray",  "#778899",  0},
    {"lightslategrey",  "#778899",  0},
    {"lightsteelblue",  "#B0C4DE",  0},
    {"lightsteelblue1", "#CAE1FF",  0},
    {"lightsteelblue2", "#BCD2EE",  0},
    {"lightsteelblue3", "#A2B5CD",  0},
    {"lightsteelblue4", "#6E7B8B",  0},
    {"lightyellow",     "#FFFFE0",  0},
    {"lightyellow1",    "#FFFFE0",  0},
    {"lightyellow2",    "#EEEED1",  0},
    {"lightyellow3",    "#CDCDB4",  0},
    {"lightyellow4",    "#8B8B7A",  0},
    {"limegreen", "#32CD32",  0},
    {"linen",           "#FAF0E6",  0},
    {"magenta",         "#FF00FF",  0},
    {"magenta1",  "#FF00FF",  0},
    {"magenta2",  "#EE00EE",  0},
    {"magenta3",  "#CD00CD",  0},
    {"magenta4",  "#8B008B",  0},
    {"maroon",          "#B03060",  0},
    {"maroon1",         "#FF34B3",  0},
    {"maroon2",         "#EE30A7",  0},
    {"maroon3",         "#CD2990",  0},
    {"maroon4",         "#8B1C62",  0},
    {"mediumaquamarine","#66CDAA",  0},
    {"mediumblue",      "#0000CD",  0},
    {"mediumorchid",    "#BA55D3",  0},
    {"mediumorchid1",   "#E066FF",  0},
    {"mediumorchid2",   "#D15FEE",  0},
    {"mediumorchid3",   "#B452CD",  0},
    {"mediumorchid4",   "#7A378B",  0},
    {"mediumpurple",    "#9370DB",  0},
    {"mediumpurple1",   "#AB82FF",  0},
    {"mediumpurple2",   "#9F79EE",  0},
    {"mediumpurple3",   "#8968CD",  0},
    {"mediumpurple4",   "#5D478B",  0},
    {"mediumseagreen",  "#3CB371",  0},
    {"mediumslateblue", "#7B68EE",  0},
    {"mediumspringgreen","#00FA9A", 0},
    {"mediumturquoise", "#48D1CC",  0},
    {"mediumvioletred", "#C71585",  0},
    {"midnightblue",    "#191970",  0},
    {"mintcream", "#F5FFFA",  0},
    {"mistyrose", "#FFE4E1",  0},
    {"mistyrose1",      "#FFE4E1",  0},
    {"mistyrose2",      "#EED5D2",  0},
    {"mistyrose3",      "#CDB7B5",  0},
    {"mistyrose4",      "#8B7D7B",  0},
    {"moccasin",  "#FFE4B5",  0},
    {"navajowhite",     "#FFDEAD",  0},
    {"navajowhite1",    "#FFDEAD",  0},
    {"navajowhite2",    "#EECFA1",  0},
    {"navajowhite3",    "#CDB38B",  0},
    {"navajowhite4",    "#8B795E",  0},
    {"navy",            "#000080",  0},
    {"navyblue",  "#000080",  0},
    {"oldlace",         "#FDF5E6",  0},
    {"olivedrab", "#6B8E23",  0},
    {"olivedrab1",      "#C0FF3E",  0},
    {"olivedrab2",      "#B3EE3A",  0},
    {"olivedrab3",      "#9ACD32",  0},
    {"olivedrab4",      "#698B22",  0},
    {"orange",          "#FFA500",  0},
    {"orange1",         "#FFA500",  0},
    {"orange2",         "#EE9A00",  0},
    {"orange3",         "#CD8500",  0},
    {"orange4",         "#8B5A00",  0},
    {"orangered", "#FF4500",  0},
    {"orangered1",      "#FF4500",  0},
    {"orangered2",      "#EE4000",  0},
    {"orangered3",      "#CD3700",  0},
    {"orangered4",      "#8B2500",  0},
    {"orchid",          "#DA70D6",  0},
    {"orchid1",         "#FF83FA",  0},
    {"orchid2",         "#EE7AE9",  0},
    {"orchid3",         "#CD69C9",  0},
    {"orchid4",         "#8B4789",  0},
    {"palegoldenrod",   "#EEE8AA",  0},
    {"palegreen", "#98FB98",  0},
    {"palegreen1",      "#9AFF9A",  0},
    {"palegreen2",      "#90EE90",  0},
    {"palegreen3",      "#7CCD7C",  0},
    {"palegreen4",      "#548B54",  0},
    {"paleturquoise",   "#AFEEEE",  0},
    {"paleturquoise1",  "#BBFFFF",  0},
    {"paleturquoise2",  "#AEEEEE",  0},
    {"paleturquoise3",  "#96CDCD",  0},
    {"paleturquoise4",  "#668B8B",  0},
    {"palevioletred",   "#DB7093",  0},
    {"palevioletred1",  "#FF82AB",  0},
    {"palevioletred2",  "#EE799F",  0},
    {"palevioletred3",  "#CD6889",  0},
    {"palevioletred4",  "#8B475D",  0},
    {"papayawhip",      "#FFEFD5",  0},
    {"peachpuff", "#FFDAB9",  0},
    {"peachpuff1",      "#FFDAB9",  0},
    {"peachpuff2",      "#EECBAD",  0},
    {"peachpuff3",      "#CDAF95",  0},
    {"peachpuff4",      "#8B7765",  0},
    {"peru",            "#CD853F",  0},
    {"pink",            "#FFC0CB",  0},
    {"pink1",           "#FFB5C5",  0},
    {"pink2",           "#EEA9B8",  0},
    {"pink3",           "#CD919E",  0},
    {"pink4",           "#8B636C",  0},
    {"plum",            "#DDA0DD",  0},
    {"plum1",           "#FFBBFF",  0},
    {"plum2",           "#EEAEEE",  0},
    {"plum3",           "#CD96CD",  0},
    {"plum4",           "#8B668B",  0},
    {"powderblue",      "#B0E0E6",  0},
    {"purple",          "#A020F0",  0},
    {"purple1",         "#9B30FF",  0},
    {"purple2",         "#912CEE",  0},
    {"purple3",         "#7D26CD",  0},
    {"purple4",         "#551A8B",  0},
    {"red",       "#FF0000",  0},
    {"red1",            "#FF0000",  0},
    {"red2",            "#EE0000",  0},
    {"red3",            "#CD0000",  0},
    {"red4",            "#8B0000",  0},
    {"rosybrown", "#BC8F8F",  0},
    {"rosybrown1",      "#FFC1C1",  0},
    {"rosybrown2",      "#EEB4B4",  0},
    {"rosybrown3",      "#CD9B9B",  0},
    {"rosybrown4",      "#8B6969",  0},
    {"royalblue", "#4169E1",  0},
    {"royalblue1",      "#4876FF",  0},
    {"royalblue2",      "#436EEE",  0},
    {"royalblue3",      "#3A5FCD",  0},
    {"royalblue4",      "#27408B",  0},
    {"saddlebrown",     "#8B4513",  0},
    {"salmon",          "#FA8072",  0},
    {"salmon1",         "#FF8C69",  0},
    {"salmon2",         "#EE8262",  0},
    {"salmon3",         "#CD7054",  0},
    {"salmon4",         "#8B4C39",  0},
    {"sandybrown",      "#F4A460",  0},
    {"seagreen",  "#2E8B57",  0},
    {"seagreen1", "#54FF9F",  0},
    {"seagreen2", "#4EEE94",  0},
    {"seagreen3", "#43CD80",  0},
    {"seagreen4", "#2E8B57",  0},
    {"seashell",  "#FFF5EE",  0},
    {"seashell1", "#FFF5EE",  0},
    {"seashell2", "#EEE5DE",  0},
    {"seashell3", "#CDC5BF",  0},
    {"seashell4", "#8B8682",  0},
    {"sienna",          "#A0522D",  0},
    {"sienna1",         "#FF8247",  0},
    {"sienna2",         "#EE7942",  0},
    {"sienna3",         "#CD6839",  0},
    {"sienna4",         "#8B4726",  0},
    {"skyblue",         "#87CEEB",  0},
    {"skyblue1",  "#87CEFF",  0},
    {"skyblue2",  "#7EC0EE",  0},
    {"skyblue3",  "#6CA6CD",  0},
    {"skyblue4",  "#4A708B",  0},
    {"slateblue", "#6A5ACD",  0},
    {"slateblue1",      "#836FFF",  0},
    {"slateblue2",      "#7A67EE",  0},
    {"slateblue3",      "#6959CD",  0},
    {"slateblue4",      "#473C8B",  0},
    {"slategray", "#708090",  0},
    {"slategray1",      "#C6E2FF",  0},
    {"slategray2",      "#B9D3EE",  0},
    {"slategray3",      "#9FB6CD",  0},
    {"slategray4",      "#6C7B8B",  0},
    {"slategrey", "#708090",  0},
    {"snow",            "#FFFAFA",  0},
    {"snow1",           "#FFFAFA",  0},
    {"snow2",           "#EEE9E9",  0},
    {"snow3",           "#CDC9C9",  0},
    {"snow4",           "#8B8989",  0},
    {"springgreen",     "#00FF7F",  0},
    {"springgreen1",    "#00FF7F",  0},
    {"springgreen2",    "#00EE76",  0},
    {"springgreen3",    "#00CD66",  0},
    {"springgreen4",    "#008B45",  0},
    {"steelblue", "#4682B4",  0},
    {"steelblue1",      "#63B8FF",  0},
    {"steelblue2",      "#5CACEE",  0},
    {"steelblue3",      "#4F94CD",  0},
    {"steelblue4",      "#36648B",  0},
    {"tan",       "#D2B48C",  0},
    {"tan1",            "#FFA54F",  0},
    {"tan2",            "#EE9A49",  0},
    {"tan3",            "#CD853F",  0},
    {"tan4",            "#8B5A2B",  0},
    {"thistle",         "#D8BFD8",  0},
    {"thistle1",  "#FFE1FF",  0},
    {"thistle2",  "#EED2EE",  0},
    {"thistle3",  "#CDB5CD",  0},
    {"thistle4",  "#8B7B8B",  0},
    {"tomato",          "#FF6347",  0},
    {"tomato1",         "#FF6347",  0},
    {"tomato2",         "#EE5C42",  0},
    {"tomato3",         "#CD4F39",  0},
    {"tomato4",         "#8B3626",  0},
    {"turquoise", "#40E0D0",  0},
    {"turquoise1",      "#00F5FF",  0},
    {"turquoise2",      "#00E5EE",  0},
    {"turquoise3",      "#00C5CD",  0},
    {"turquoise4",      "#00868B",  0},
    {"violet",          "#EE82EE",  0},
    {"violetred", "#D02090",  0},
    {"violetred1",      "#FF3E96",  0},
    {"violetred2",      "#EE3A8C",  0},
    {"violetred3",      "#CD3278",  0},
    {"violetred4",      "#8B2252",  0},
    {"wheat",           "#F5DEB3",  0},
    {"wheat1",          "#FFE7BA",  0},
    {"wheat2",          "#EED8AE",  0},
    {"wheat3",          "#CDBA96",  0},
    {"wheat4",          "#8B7E66",  0},
    {"whitesmoke",      "#F5F5F5",  0},
    {"yellow",          "#FFFF00",  0},
    {"yellow1",         "#FFFF00",  0},
    {"yellow2",         "#EEEE00",  0},
    {"yellow3",         "#CDCD00",  0},
    {"yellow4",         "#8B8B00",  0},
    {"yellowgreen",     "#9ACD32",  0},
    {NULL,        NULL,       0}
};


static void setpalette(const char **palette)
{
    int i;
    for (i = 0; (i < COLOR_TABLE_SIZE) && palette[i]; i++)
      R_ColorTable[i] = name2col(palette[i]);
    R_ColorTableSize = i;
}

SEXP attribute_hidden do_palette(SEXP call, SEXP op, SEXP args, SEXP rho)
{
    SEXP val, ans;
    unsigned int color[COLOR_TABLE_SIZE];
    int i, n;
    checkArity(op,args);
    /* Record the current palette */
    PROTECT(ans = allocVector(STRSXP, R_ColorTableSize));
    for (i = 0; i < R_ColorTableSize; i++)
      SET_STRING_ELT(ans, i, mkChar(col2name(R_ColorTable[i])));
    val = CAR(args);
    if (!isString(val)) error(_("invalid argument type"));
    if ((n=length(val)) == 1) {
      if (StrMatch("default", CHAR(STRING_ELT(val, 0)))) /* ASCII */
          setpalette(DefaultPalette);
      else error(_("unknown palette (need >= 2 colors)"));
    }
    else if (n > 1) {
      if (n > COLOR_TABLE_SIZE)
           error(_("maximum number of colors exceeded"));
      for (i = 0; i < n; i++)
          color[i] = char2col(CHAR(STRING_ELT(val, i)));
      for (i = 0; i < n; i++)
          R_ColorTable[i] = color[i];
      R_ColorTableSize = n;
    }
    UNPROTECT(1);
    return ans;
}

SEXP attribute_hidden do_colors(SEXP call, SEXP op, SEXP args, SEXP rho)
{
    SEXP ans;
    int n;

    for (n = 0; ColorDataBase[n].name != NULL; n++) ;
    PROTECT(ans = allocVector(STRSXP, n));
    for (n = 0; ColorDataBase[n].name != NULL; n++)
      SET_STRING_ELT(ans, n, mkChar(ColorDataBase[n].name));
    UNPROTECT(1);
    return ans;
}

/* Hex Digit to Integer Conversion */

static unsigned int hexdigit(int digit)
{
    if('0' <= digit && digit <= '9') return digit - '0';
    if('A' <= digit && digit <= 'F') return 10 + digit - 'A';
    if('a' <= digit && digit <= 'f') return 10 + digit - 'a';
    /*else */ error(_("invalid hex digit in 'color' or 'lty'"));
    return digit; /* never occurs (-Wall) */
}

#ifdef UNUSED
/* Integer to Hex Digit */

static unsigned int digithex(int digit)
{
    return HexDigits[abs(digit) % 16];
}
#endif

/* #RRGGBB[AA] String to Internal Color Code */
static unsigned int rgb2col(const char *rgb)
{
    unsigned int r=0, g=0, b=0, a=0; /* -Wall */
    if(rgb[0] != '#')
      error(_("invalid RGB specification"));
    switch (strlen(rgb)) {
    case 9:
      a = 16 * hexdigit(rgb[7]) + hexdigit(rgb[8]);
    case 7:
      r = 16 * hexdigit(rgb[1]) + hexdigit(rgb[2]);
      g = 16 * hexdigit(rgb[3]) + hexdigit(rgb[4]);
      b = 16 * hexdigit(rgb[5]) + hexdigit(rgb[6]);
      break;
    default:
      error(_("invalid RGB specification"));
    }
    if (strlen(rgb) == 7)
      return R_RGB(r, g, b);
    else
      return R_RGBA(r, g, b, a);
}

/* External Color Name to Internal Color Code */

unsigned int attribute_hidden name2col(const char *nm)
{
    int i;
    if(strcmp(nm, "NA") == 0 || strcmp(nm, "transparent") == 0)
      /*
       * Paul 01/07/04 (2004-07-01?)
       *
       * Used to be set to NA_INTEGER.
       *
       * Now set to fully transparent white.
       *
       * In some cases, fully transparent gets caught by
       * the graphics engine and no drawing occurs, but
       * in other cases, transparent colours are passed to devices.
       *
       * All devices should respond to fully transparent by
       * not drawing.
       */
      return R_TRANWHITE;
    for(i = 0; ColorDataBase[i].name ; i++) {
      if(StrMatch(ColorDataBase[i].name, nm))
          return ColorDataBase[i].code;
    }
    error(_("invalid color name '%s'"), nm);
    return 0;           /* never occurs but avoid compiler warnings */
}

static unsigned int number2col(const char *nm, unsigned int bg)
{
    int indx;
    char *ptr;
    indx = strtod(nm, &ptr);
    if(*ptr) error(_("invalid color specification '%s'"), nm);
    if(indx == 0) return bg;
    else return R_ColorTable[(indx-1) % R_ColorTableSize];
}


static char ColBuf[10];

static
char *RGB2rgb(unsigned int r, unsigned int g, unsigned int b)
{
    ColBuf[0] = '#';
    ColBuf[1] = HexDigits[(r >> 4) & 15];
    ColBuf[2] = HexDigits[r & 15];
    ColBuf[3] = HexDigits[(g >> 4) & 15];
    ColBuf[4] = HexDigits[g & 15];
    ColBuf[5] = HexDigits[(b >> 4) & 15];
    ColBuf[6] = HexDigits[b & 15];
    ColBuf[7] = '\0';
    return &ColBuf[0];
}

static
char *RGBA2rgb(unsigned int r, unsigned int g, unsigned int b, unsigned int a)
{
    ColBuf[0] = '#';
    ColBuf[1] = HexDigits[(r >> 4) & 15];
    ColBuf[2] = HexDigits[r & 15];
    ColBuf[3] = HexDigits[(g >> 4) & 15];
    ColBuf[4] = HexDigits[g & 15];
    ColBuf[5] = HexDigits[(b >> 4) & 15];
    ColBuf[6] = HexDigits[b & 15];
    ColBuf[7] = HexDigits[(a >> 4) & 15];
    ColBuf[8] = HexDigits[a & 15];
    ColBuf[9] = '\0';
    return &ColBuf[0];
}


/* Internal to External Color Representation */
/* Search the color name database first */
/* If this fails, create an #RRGGBB string */

/* used in grid */
const char *col2name(unsigned int col)
{
    int i;

    if(R_OPAQUE(col)) {
      for(i=0 ; ColorDataBase[i].name ; i++) {
          if(col == ColorDataBase[i].code)
            return ColorDataBase[i].name;
      }
      ColBuf[0] = '#';
      ColBuf[1] = HexDigits[(col >>  4) & 15];
      ColBuf[2] = HexDigits[(col        ) & 15];
      ColBuf[3] = HexDigits[(col >> 12) & 15];
      ColBuf[4] = HexDigits[(col >>  8) & 15];
      ColBuf[5] = HexDigits[(col >> 20) & 15];
      ColBuf[6] = HexDigits[(col >> 16) & 15];
      ColBuf[7] = '\0';
      return &ColBuf[0];
    } else if (R_TRANSPARENT(col)) {
      return "transparent";
    } else {
      ColBuf[0] = '#';
      ColBuf[1] = HexDigits[(col >>  4) & 15];
      ColBuf[2] = HexDigits[(col    ) & 15];
      ColBuf[3] = HexDigits[(col >> 12) & 15];
      ColBuf[4] = HexDigits[(col >>  8) & 15];
      ColBuf[5] = HexDigits[(col >> 20) & 15];
      ColBuf[6] = HexDigits[(col >> 16) & 15];
      ColBuf[7] = HexDigits[(col >> 28) & 15];
      ColBuf[8] = HexDigits[(col >> 24) & 15];
      ColBuf[9] = '\0';
      return &ColBuf[0];
    }
}

static unsigned int str2col(const char *s, unsigned int bg)
{
    if(s[0] == '#') return rgb2col(s);
    /* This seems rather strange,
       and made this depend on base graphics.
       Looks like it was an artefact of conversion in col2rgb().
    */
    else if(isdigit((int)s[0])) return number2col(s, bg);
    else return name2col(s);
}

/* used in grDevices, public */
unsigned int R_GE_str2col(const char *s)
{
    return str2col(s, R_TRANWHITE);
}

/* Convert a sexp element to an R color desc */
/* We Assume that Checks Have Been Done */

/* used in grid/src/gpar.c */
unsigned int RGBpar3(SEXP x, int i, unsigned int bg)
{
    int indx;
    switch(TYPEOF(x))
    {
    case STRSXP:
      return str2col(CHAR(STRING_ELT(x, i)), bg);
    case LGLSXP:
      indx = LOGICAL(x)[i];
      if (indx == NA_LOGICAL) return R_TRANWHITE;
      break;
    case INTSXP:
      indx = INTEGER(x)[i];
      if (indx == NA_INTEGER) return R_TRANWHITE;
      break;
    case REALSXP:
      if(!R_FINITE(REAL(x)[i])) return R_TRANWHITE;
      indx = REAL(x)[i];
      break;
         default:
         warning(_("supplied color is not numeric nor character"));
         return bg;
    }
    if (indx <= 0) return bg;
    else return R_ColorTable[(indx-1) % R_ColorTableSize];
}

unsigned int RGBpar(SEXP x, int i)
{
    return RGBpar3(x, i, R_TRANWHITE);
}


/*
 * Is element i of a colour object NA (or NULL)?
 */
Rboolean attribute_hidden isNAcol(SEXP col, int index, int ncol)
{
    Rboolean result = TRUE; /* -Wall */

    if (isNull(col))
      result = TRUE;
    else {
      if (isLogical(col))
          result = LOGICAL(col)[index % ncol] == NA_LOGICAL;
      else if (isString(col))
          result = strcmp(CHAR(STRING_ELT(col, index % ncol)), "NA") == 0;
      else if (isInteger(col))
          result = INTEGER(col)[index % ncol] == NA_INTEGER;
      else if (isReal(col))
          result = !R_FINITE(REAL(col)[index % ncol]);
      else
          error(_("Invalid color specification"));
    }
    return result;
}

/* Initialize the Color Databases */

void attribute_hidden InitColors(void)
{
    int i;

    /* Initialize the Color Database */
    for(i = 0 ; ColorDataBase[i].name ; i++)
      ColorDataBase[i].code = rgb2col(ColorDataBase[i].rgb);
    ColorDataBaseSize = i;

    /* Install Default Palette */
    for(i = 0 ; DefaultPalette[i] ; i++)
      R_ColorTable[i] = name2col(DefaultPalette[i]);
    R_ColorTableSize = i;
}

Generated by  Doxygen 1.6.0   Back to index