c_color.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /* This file is part of the GNU plotutils package. Copyright (C) 1995,
  2. 1996, 1997, 1998, 1999, 2000, 2005, 2008, Free Software Foundation, Inc.
  3. The GNU plotutils package is free software. You may redistribute it
  4. and/or modify it under the terms of the GNU General Public License as
  5. published by the Free Software foundation; either version 2, or (at your
  6. option) any later version.
  7. The GNU plotutils package is distributed in the hope that it will be
  8. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. General Public License for more details.
  11. You should have received a copy of the GNU General Public License along
  12. with the GNU plotutils package; see the file COPYING. If not, write to
  13. the Free Software Foundation, Inc., 51 Franklin St., Fifth Floor,
  14. Boston, MA 02110-1301, USA. */
  15. /* This file contains device-specific color database access routines.
  16. These routines are called by various CGMPlotter methods, before drawing
  17. objects.
  18. The CGM output file will use either 24-bit RGB or 48-bit RGB, depending
  19. on the value of CGM_BINARY_BYTES_PER_COLOR_COMPONENT (set in extern.h;
  20. 1 or 2, respectively). This code assumes that the value is 1 or 2, even
  21. though CGM files allow 3 or 4 as well. To handle the `4' case, we
  22. should rewrite this to use unsigned ints rather than signed ints.
  23. The reason we don't bother with 3 or 4 is that internally, libplot uses
  24. 48-bit color. So 48-bit RGB in the CGM output file is all we need. */
  25. #include "sys-defines.h"
  26. #include "extern.h"
  27. void
  28. _pl_c_set_pen_color(R___(Plotter *_plotter) int cgm_object_type)
  29. {
  30. int red_long, green_long, blue_long;
  31. int red, green, blue;
  32. int byte_count, data_byte_count, data_len;
  33. int fullstrength;
  34. if (_plotter->drawstate->pen_type == 0
  35. && cgm_object_type != CGM_OBJECT_TEXT)
  36. /* don't do anything, pen color will be ignored when writing objects */
  37. return;
  38. /* 48-bit RGB */
  39. red_long = _plotter->drawstate->fgcolor.red;
  40. green_long = _plotter->drawstate->fgcolor.green;
  41. blue_long = _plotter->drawstate->fgcolor.blue;
  42. /* 24-bit or 48-bit RGB (as used in CGMs) */
  43. switch (CGM_BINARY_BYTES_PER_COLOR_COMPONENT)
  44. {
  45. case 1:
  46. /* 24-bit */
  47. red = (((unsigned int)red_long) >> 8) & 0xff;
  48. green = (((unsigned int)green_long) >> 8) & 0xff;
  49. blue = (((unsigned int)blue_long) >> 8) & 0xff;
  50. break;
  51. case 2:
  52. default:
  53. /* 48-bit */
  54. red = red_long;
  55. green = green_long;
  56. blue = blue_long;
  57. break;
  58. }
  59. fullstrength = (1 << (8 * CGM_BINARY_BYTES_PER_COLOR_COMPONENT)) - 1;
  60. if ((red != 0 || green != 0 || blue != 0)
  61. && (red != fullstrength || green != fullstrength || blue != fullstrength))
  62. _plotter->cgm_page_need_color = true;
  63. switch (cgm_object_type)
  64. {
  65. case CGM_OBJECT_OPEN:
  66. if (_plotter->cgm_line_color.red != red
  67. || _plotter->cgm_line_color.green != green
  68. || _plotter->cgm_line_color.blue != blue)
  69. /* emit "LINE_COLOR" command */
  70. {
  71. data_len = 3 * CGM_BINARY_BYTES_PER_COLOR_COMPONENT;
  72. byte_count = data_byte_count = 0;
  73. _cgm_emit_command_header (_plotter->data->page, _plotter->cgm_encoding,
  74. CGM_ATTRIBUTE_ELEMENT, 4,
  75. data_len, &byte_count,
  76. "LINECOLR");
  77. _cgm_emit_color_component (_plotter->data->page, false, _plotter->cgm_encoding,
  78. (unsigned int)red,
  79. data_len, &data_byte_count, &byte_count);
  80. _cgm_emit_color_component (_plotter->data->page, false, _plotter->cgm_encoding,
  81. (unsigned int)green,
  82. data_len, &data_byte_count, &byte_count);
  83. _cgm_emit_color_component (_plotter->data->page, false, _plotter->cgm_encoding,
  84. (unsigned int)blue,
  85. data_len, &data_byte_count, &byte_count);
  86. _cgm_emit_command_terminator (_plotter->data->page, _plotter->cgm_encoding,
  87. &byte_count);
  88. /* update our knowledge of CGM's pen color */
  89. _plotter->cgm_line_color.red = red;
  90. _plotter->cgm_line_color.green = green;
  91. _plotter->cgm_line_color.blue = blue;
  92. }
  93. break;
  94. case CGM_OBJECT_CLOSED:
  95. if (_plotter->cgm_edge_color.red != red
  96. || _plotter->cgm_edge_color.green != green
  97. || _plotter->cgm_edge_color.blue != blue)
  98. /* emit "EDGE_COLOR" command */
  99. {
  100. data_len = 3 * CGM_BINARY_BYTES_PER_COLOR_COMPONENT;
  101. byte_count = data_byte_count = 0;
  102. _cgm_emit_command_header (_plotter->data->page, _plotter->cgm_encoding,
  103. CGM_ATTRIBUTE_ELEMENT, 29,
  104. data_len, &byte_count,
  105. "EDGECOLR");
  106. _cgm_emit_color_component (_plotter->data->page, false, _plotter->cgm_encoding,
  107. (unsigned int)red,
  108. data_len, &data_byte_count, &byte_count);
  109. _cgm_emit_color_component (_plotter->data->page, false, _plotter->cgm_encoding,
  110. (unsigned int)green,
  111. data_len, &data_byte_count, &byte_count);
  112. _cgm_emit_color_component (_plotter->data->page, false, _plotter->cgm_encoding,
  113. (unsigned int)blue,
  114. data_len, &data_byte_count, &byte_count);
  115. _cgm_emit_command_terminator (_plotter->data->page, _plotter->cgm_encoding,
  116. &byte_count);
  117. /* update our knowledge of CGM's edge color */
  118. _plotter->cgm_edge_color.red = red;
  119. _plotter->cgm_edge_color.green = green;
  120. _plotter->cgm_edge_color.blue = blue;
  121. }
  122. break;
  123. case CGM_OBJECT_MARKER:
  124. if (_plotter->cgm_marker_color.red != red
  125. || _plotter->cgm_marker_color.green != green
  126. || _plotter->cgm_marker_color.blue != blue)
  127. /* emit "MARKER COLOR" command */
  128. {
  129. data_len = 3 * CGM_BINARY_BYTES_PER_COLOR_COMPONENT;
  130. byte_count = data_byte_count = 0;
  131. _cgm_emit_command_header (_plotter->data->page, _plotter->cgm_encoding,
  132. CGM_ATTRIBUTE_ELEMENT, 8,
  133. data_len, &byte_count,
  134. "MARKERCOLR");
  135. _cgm_emit_color_component (_plotter->data->page, false, _plotter->cgm_encoding,
  136. (unsigned int)red,
  137. data_len, &data_byte_count, &byte_count);
  138. _cgm_emit_color_component (_plotter->data->page, false, _plotter->cgm_encoding,
  139. (unsigned int)green,
  140. data_len, &data_byte_count, &byte_count);
  141. _cgm_emit_color_component (_plotter->data->page, false, _plotter->cgm_encoding,
  142. (unsigned int)blue,
  143. data_len, &data_byte_count, &byte_count);
  144. _cgm_emit_command_terminator (_plotter->data->page, _plotter->cgm_encoding,
  145. &byte_count);
  146. /* update our knowledge of CGM's marker color */
  147. _plotter->cgm_marker_color.red = red;
  148. _plotter->cgm_marker_color.green = green;
  149. _plotter->cgm_marker_color.blue = blue;
  150. }
  151. break;
  152. case CGM_OBJECT_TEXT:
  153. if (_plotter->cgm_text_color.red != red
  154. || _plotter->cgm_text_color.green != green
  155. || _plotter->cgm_text_color.blue != blue)
  156. /* emit "TEXT COLOR" command */
  157. {
  158. data_len = 3 * CGM_BINARY_BYTES_PER_COLOR_COMPONENT;
  159. byte_count = data_byte_count = 0;
  160. _cgm_emit_command_header (_plotter->data->page, _plotter->cgm_encoding,
  161. CGM_ATTRIBUTE_ELEMENT, 14,
  162. data_len, &byte_count,
  163. "TEXTCOLR");
  164. _cgm_emit_color_component (_plotter->data->page, false, _plotter->cgm_encoding,
  165. (unsigned int)red,
  166. data_len, &data_byte_count, &byte_count);
  167. _cgm_emit_color_component (_plotter->data->page, false, _plotter->cgm_encoding,
  168. (unsigned int)green,
  169. data_len, &data_byte_count, &byte_count);
  170. _cgm_emit_color_component (_plotter->data->page, false, _plotter->cgm_encoding,
  171. (unsigned int)blue,
  172. data_len, &data_byte_count, &byte_count);
  173. _cgm_emit_command_terminator (_plotter->data->page, _plotter->cgm_encoding,
  174. &byte_count);
  175. /* update our knowledge of CGM's text color */
  176. _plotter->cgm_text_color.red = red;
  177. _plotter->cgm_text_color.green = green;
  178. _plotter->cgm_text_color.blue = blue;
  179. }
  180. break;
  181. default:
  182. break;
  183. }
  184. }
  185. void
  186. _pl_c_set_fill_color(R___(Plotter *_plotter) int cgm_object_type)
  187. {
  188. int red_long, green_long, blue_long;
  189. int red, green, blue;
  190. int fullstrength;
  191. int byte_count, data_byte_count, data_len;
  192. if (_plotter->drawstate->fill_type == 0)
  193. /* don't do anything, fill color will be ignored when writing objects */
  194. return;
  195. if (cgm_object_type != CGM_OBJECT_OPEN
  196. && cgm_object_type != CGM_OBJECT_CLOSED)
  197. /* don't do anything; won't be filling */
  198. return;
  199. /* obtain each RGB as a 16-bit quantity (48 bits in all) */
  200. red_long = _plotter->drawstate->fillcolor.red;
  201. green_long = _plotter->drawstate->fillcolor.green;
  202. blue_long = _plotter->drawstate->fillcolor.blue;
  203. /* 24-bit or 48-bit RGB (as used in CGMs) */
  204. switch (CGM_BINARY_BYTES_PER_COLOR_COMPONENT)
  205. {
  206. case 1:
  207. /* 24-bit */
  208. red = (((unsigned int)red_long) >> 8) & 0xff;
  209. green = (((unsigned int)green_long) >> 8) & 0xff;
  210. blue = (((unsigned int)blue_long) >> 8) & 0xff;
  211. break;
  212. case 2:
  213. default:
  214. /* 48-bit */
  215. red = red_long;
  216. green = green_long;
  217. blue = blue_long;
  218. break;
  219. }
  220. fullstrength = (1 << (8 * CGM_BINARY_BYTES_PER_COLOR_COMPONENT)) - 1;
  221. if ((red != 0 || green != 0 || blue != 0)
  222. && (red != fullstrength || green != fullstrength || blue != fullstrength))
  223. _plotter->cgm_page_need_color = true;
  224. if (_plotter->cgm_fillcolor.red != red
  225. || _plotter->cgm_fillcolor.green != green
  226. || _plotter->cgm_fillcolor.blue != blue)
  227. /* emit "FILL COLOR" command */
  228. {
  229. data_len = 3 * CGM_BINARY_BYTES_PER_COLOR_COMPONENT;
  230. byte_count = data_byte_count = 0;
  231. _cgm_emit_command_header (_plotter->data->page, _plotter->cgm_encoding,
  232. CGM_ATTRIBUTE_ELEMENT, 23,
  233. data_len, &byte_count,
  234. "FILLCOLR");
  235. _cgm_emit_color_component (_plotter->data->page, false, _plotter->cgm_encoding,
  236. (unsigned int)red,
  237. data_len, &data_byte_count, &byte_count);
  238. _cgm_emit_color_component (_plotter->data->page, false, _plotter->cgm_encoding,
  239. (unsigned int)green,
  240. data_len, &data_byte_count, &byte_count);
  241. _cgm_emit_color_component (_plotter->data->page, false, _plotter->cgm_encoding,
  242. (unsigned int)blue,
  243. data_len, &data_byte_count, &byte_count);
  244. _cgm_emit_command_terminator (_plotter->data->page, _plotter->cgm_encoding,
  245. &byte_count);
  246. /* update our knowledge of CGM's fill color */
  247. _plotter->cgm_fillcolor.red = red;
  248. _plotter->cgm_fillcolor.green = green;
  249. _plotter->cgm_fillcolor.blue = blue;
  250. }
  251. }
  252. void
  253. _pl_c_set_bg_color(S___(Plotter *_plotter))
  254. {
  255. int red_long, green_long, blue_long;
  256. int red, green, blue;
  257. /* 48-bit RGB */
  258. red_long = _plotter->drawstate->bgcolor.red;
  259. green_long = _plotter->drawstate->bgcolor.green;
  260. blue_long = _plotter->drawstate->bgcolor.blue;
  261. /* 24-bit or 48-bit RGB (as used in CGMs) */
  262. switch (CGM_BINARY_BYTES_PER_COLOR_COMPONENT)
  263. {
  264. case 1:
  265. /* 24-bit */
  266. red = (((unsigned int)red_long) >> 8) & 0xff;
  267. green = (((unsigned int)green_long) >> 8) & 0xff;
  268. blue = (((unsigned int)blue_long) >> 8) & 0xff;
  269. break;
  270. case 2:
  271. default:
  272. /* 48-bit */
  273. red = red_long;
  274. green = green_long;
  275. blue = blue_long;
  276. break;
  277. }
  278. /* update our knowledge of what CGM's background color should be (we'll
  279. use it only when we write the picture header) */
  280. _plotter->cgm_bgcolor.red = red;
  281. _plotter->cgm_bgcolor.green = green;
  282. _plotter->cgm_bgcolor.blue = blue;
  283. /* should the just-computed color be ignored, i.e., did the user really
  284. specify "none" as the background color? */
  285. _plotter->cgm_bgcolor_suppressed = _plotter->drawstate->bgcolor_suppressed;
  286. }