| 1 | /*!
|
|---|
| 2 | \file lib/gis/color_str.c
|
|---|
| 3 |
|
|---|
| 4 | \brief GIS library - color management, named color to RGB triplet
|
|---|
| 5 |
|
|---|
| 6 | (C) 2001-2016 by the GRASS Development Team
|
|---|
| 7 |
|
|---|
| 8 | This program is free software under the
|
|---|
| 9 | GNU General Public License (>=v2).
|
|---|
| 10 | Read the file COPYING that comes with GRASS
|
|---|
| 11 | for details.
|
|---|
| 12 |
|
|---|
| 13 | \author Original author CERL
|
|---|
| 14 | */
|
|---|
| 15 |
|
|---|
| 16 | #include <string.h>
|
|---|
| 17 |
|
|---|
| 18 | #include <grass/gis.h>
|
|---|
| 19 | #include <grass/colors.h>
|
|---|
| 20 |
|
|---|
| 21 | /* The order in this table is important! It will be indexed by color number */
|
|---|
| 22 | static const struct color_rgb standard_colors_rgb[] = {
|
|---|
| 23 | {0, 0, 0}, /* This is a dummy value to make lookup easier */
|
|---|
| 24 | {0, 0, 0}, /* BLACK */
|
|---|
| 25 | {255, 0, 0}, /* RED */
|
|---|
| 26 | {0, 255, 0}, /* GREEN */
|
|---|
| 27 | {0, 0, 255}, /* BLUE */
|
|---|
| 28 | {255, 255, 0}, /* YELLOW */
|
|---|
| 29 | {0, 255, 255}, /* CYAN */
|
|---|
| 30 | {255, 0, 255}, /* MAGENTA */
|
|---|
| 31 | {255, 255, 255}, /* WHITE */
|
|---|
| 32 | {128, 128, 128}, /* GRAY */
|
|---|
| 33 | {255, 128, 0}, /* ORANGE */
|
|---|
| 34 | {100, 128, 255}, /* AQUA */
|
|---|
| 35 | {0, 128, 255}, /* INDIGO */
|
|---|
| 36 | {128, 0, 255}, /* VIOLET */
|
|---|
| 37 | {180, 77, 25} /* BROWN */
|
|---|
| 38 | };
|
|---|
| 39 |
|
|---|
| 40 | /* The order in this table has no meaning. */
|
|---|
| 41 | static const struct color_name standard_color_names[] = {
|
|---|
| 42 | {"black", BLACK},
|
|---|
| 43 | {"red", RED},
|
|---|
| 44 | {"green", GREEN},
|
|---|
| 45 | {"blue", BLUE},
|
|---|
| 46 | {"yellow", YELLOW},
|
|---|
| 47 | {"cyan", CYAN},
|
|---|
| 48 | {"magenta", MAGENTA},
|
|---|
| 49 | {"white", WHITE},
|
|---|
| 50 | {"grey", GREY},
|
|---|
| 51 | {"gray", GRAY},
|
|---|
| 52 | {"orange", ORANGE},
|
|---|
| 53 | {"aqua", AQUA},
|
|---|
| 54 | {"indigo", INDIGO},
|
|---|
| 55 | {"violet", VIOLET},
|
|---|
| 56 | {"purple", PURPLE},
|
|---|
| 57 | {"brown", BROWN}
|
|---|
| 58 | };
|
|---|
| 59 |
|
|---|
| 60 | /*!
|
|---|
| 61 | \brief Get number of named colors (RGB triplets)
|
|---|
| 62 |
|
|---|
| 63 | \return number of colors
|
|---|
| 64 | */
|
|---|
| 65 | int G_num_standard_colors(void)
|
|---|
| 66 | {
|
|---|
| 67 | return sizeof(standard_colors_rgb) / sizeof(standard_colors_rgb[0]);
|
|---|
| 68 | }
|
|---|
| 69 |
|
|---|
| 70 | /*!
|
|---|
| 71 | \brief Get RGB triplet of given color
|
|---|
| 72 |
|
|---|
| 73 | \param n color index
|
|---|
| 74 | */
|
|---|
| 75 | struct color_rgb G_standard_color_rgb(int n)
|
|---|
| 76 | {
|
|---|
| 77 | return standard_colors_rgb[n];
|
|---|
| 78 | }
|
|---|
| 79 |
|
|---|
| 80 | /*!
|
|---|
| 81 | \brief Get number of named colors (color names)
|
|---|
| 82 |
|
|---|
| 83 | \return number of colors
|
|---|
| 84 | */
|
|---|
| 85 | int G_num_standard_color_names(void)
|
|---|
| 86 | {
|
|---|
| 87 | return sizeof(standard_color_names) / sizeof(standard_color_names[0]);
|
|---|
| 88 | }
|
|---|
| 89 |
|
|---|
| 90 | /*!
|
|---|
| 91 | \brief Get color name
|
|---|
| 92 |
|
|---|
| 93 | \param n color index
|
|---|
| 94 | */
|
|---|
| 95 | const struct color_name *G_standard_color_name(int n)
|
|---|
| 96 | {
|
|---|
| 97 | return &standard_color_names[n];
|
|---|
| 98 | }
|
|---|
| 99 |
|
|---|
| 100 | /*!
|
|---|
| 101 | \brief Parse color string and set red,green,blue
|
|---|
| 102 |
|
|---|
| 103 | \param str color string
|
|---|
| 104 | \param[out] red red value
|
|---|
| 105 | \param[out] grn green value
|
|---|
| 106 | \param[out] blu blue value
|
|---|
| 107 |
|
|---|
| 108 | \return 1 OK
|
|---|
| 109 | \return 2 NONE
|
|---|
| 110 | \return 0 on error
|
|---|
| 111 | */
|
|---|
| 112 | int G_str_to_color(const char *str, int *red, int *grn, int *blu)
|
|---|
| 113 | {
|
|---|
| 114 | char buf[100];
|
|---|
| 115 | int num_names = G_num_standard_color_names();
|
|---|
| 116 | int i;
|
|---|
| 117 |
|
|---|
| 118 | strcpy(buf, str);
|
|---|
| 119 | G_chop(buf);
|
|---|
| 120 |
|
|---|
| 121 | G_debug(3, "G_str_to_color(): str = '%s'", buf);
|
|---|
| 122 |
|
|---|
| 123 | if (G_strcasecmp(buf, "NONE") == 0)
|
|---|
| 124 | return 2;
|
|---|
| 125 |
|
|---|
| 126 | if (sscanf(buf, "%d%*[,:; ]%d%*[,:; ]%d", red, grn, blu) == 3) {
|
|---|
| 127 | if (*red < 0 || *red > 255 ||
|
|---|
| 128 | *grn < 0 || *grn > 255 || *blu < 0 || *blu > 255)
|
|---|
| 129 | return 0;
|
|---|
| 130 |
|
|---|
| 131 | return 1;
|
|---|
| 132 | }
|
|---|
| 133 |
|
|---|
| 134 | int hex;
|
|---|
| 135 |
|
|---|
| 136 | if (sscanf(buf, "#%x", &hex) == 1) {
|
|---|
| 137 | *red = (hex >> 16) & 0xFF;
|
|---|
| 138 | *grn = (hex >> 8) & 0xFF;
|
|---|
| 139 | *blu = hex & 0xFF;
|
|---|
| 140 | if (*red < 0 || *red > 255 ||
|
|---|
| 141 | *grn < 0 || *grn > 255 || *blu < 0 || *blu > 255)
|
|---|
| 142 | return 0;
|
|---|
| 143 |
|
|---|
| 144 | return 1;
|
|---|
| 145 | }
|
|---|
| 146 |
|
|---|
| 147 | /* Look for this color in the standard (preallocated) colors */
|
|---|
| 148 | for (i = 0; i < num_names; i++) {
|
|---|
| 149 | const struct color_name *name = &standard_color_names[i];
|
|---|
| 150 |
|
|---|
| 151 | if (G_strcasecmp(buf, name->name) == 0) {
|
|---|
| 152 | struct color_rgb rgb = standard_colors_rgb[name->number];
|
|---|
| 153 |
|
|---|
| 154 | *red = (int)rgb.r;
|
|---|
| 155 | *grn = (int)rgb.g;
|
|---|
| 156 | *blu = (int)rgb.b;
|
|---|
| 157 |
|
|---|
| 158 | return 1;
|
|---|
| 159 | }
|
|---|
| 160 | }
|
|---|
| 161 |
|
|---|
| 162 | return 0;
|
|---|
| 163 | }
|
|---|