color_str.c 3.5 KB

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