do_graph.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <grass/gis.h>
  4. #include <grass/colors.h>
  5. #include <grass/raster.h>
  6. #include <grass/display.h>
  7. #include <grass/symbol.h>
  8. #include <grass/glocale.h>
  9. #include "options.h"
  10. #include "local_proto.h"
  11. #define CHUNK 128
  12. static int coors_allocated = 0;
  13. static double *xarray;
  14. static double *yarray;
  15. static float xincr;
  16. static float yincr;
  17. static double rotation; /* degrees counter-clockwise from east */
  18. static RGBA_Color last_color;
  19. static double t, b, l, r;
  20. static double cur_x, cur_y;
  21. int set_graph_stuff(void)
  22. {
  23. D_get_dst(&t, &b, &l, &r);
  24. if (mapunits) {
  25. xincr = (r - l) / 100.;
  26. if (xincr < 0.0)
  27. xincr = -xincr; /* mod: shapiro 13 jun 1991 */
  28. yincr = (b - t) / 100.;
  29. if (yincr < 0.0)
  30. yincr = -yincr; /* mod: shapiro 13 jun 1991 */
  31. }
  32. else
  33. xincr = yincr = 1;
  34. rotation = 0.0; /* init */
  35. return 0;
  36. }
  37. int set_text_size(void)
  38. {
  39. if (hsize >= 0. && vsize >= 0. && hsize <= 100. && vsize <= 100.) {
  40. D_text_size(hsize * xincr, vsize * yincr);
  41. G_debug(3, "text size initialized to [%.1f,%.1f]",
  42. hsize * xincr, vsize * yincr);
  43. }
  44. return (0);
  45. }
  46. int do_draw(const char *str)
  47. {
  48. float xper, yper;
  49. if (2 != sscanf(str, "%*s %f %f", &xper, &yper)) {
  50. G_warning(_("Problem parsing coordinates [%s]"), str);
  51. return (-1);
  52. }
  53. D_line_abs(cur_x, cur_y, xper, yper);
  54. cur_x = xper;
  55. cur_y = yper;
  56. return (0);
  57. }
  58. int do_move(const char *str)
  59. {
  60. float xper, yper;
  61. if (2 != sscanf(str, "%*s %f %f", &xper, &yper)) {
  62. G_warning(_("Problem parsing coordinates [%s]"), str);
  63. return (-1);
  64. }
  65. D_pos_abs(xper, yper);
  66. cur_x = xper;
  67. cur_y = yper;
  68. return (0);
  69. }
  70. int do_color(const char *str)
  71. {
  72. char in_color[64];
  73. int R, G, B, color = 0;
  74. if (1 != sscanf(str, "%*s %s", in_color)) {
  75. G_warning(_("Unable to read color"));
  76. return (-1);
  77. }
  78. /* Parse and select color */
  79. color = G_str_to_color(in_color, &R, &G, &B);
  80. if (color == 0) {
  81. G_warning(_("[%s]: No such color"), in_color);
  82. /* store for backup */
  83. last_color.a = RGBA_COLOR_NONE;
  84. return (-1);
  85. }
  86. if (color == 1) {
  87. D_RGB_color(R, G, B);
  88. /* store for backup */
  89. set_last_color(R, G, B, RGBA_COLOR_OPAQUE);
  90. }
  91. if (color == 2) { /* color == 'none' */
  92. R = D_translate_color(DEFAULT_BG_COLOR);
  93. D_use_color(R);
  94. /* store for backup */
  95. set_last_color(0, 0, 0, RGBA_COLOR_NONE);
  96. }
  97. return (0);
  98. }
  99. int do_linewidth(const char *str)
  100. {
  101. double width;
  102. if (1 != sscanf(str, "%*s %lf", &width)) {
  103. G_warning(_("Problem parsing command [%s]"), str);
  104. return (-1);
  105. }
  106. D_line_width(width);
  107. G_debug(3, "line width set to %.1f", width);
  108. return (0);
  109. }
  110. int do_poly(char *buff, FILE * infile)
  111. {
  112. int num;
  113. char origcmd[64];
  114. float xper, yper;
  115. int to_return;
  116. sscanf(buff, "%s", origcmd);
  117. num = 0;
  118. for (;;) {
  119. if ((to_return = G_getl2(buff, 128, infile)) != 1)
  120. break;
  121. if (2 != sscanf(buff, "%f %f", &xper, &yper)) {
  122. if ('#' == buff[0]) {
  123. G_debug(3, " skipping comment line [%s]", buff);
  124. continue;
  125. }
  126. G_debug(3, "coordinate pair not found. ending polygon. [%s]",
  127. buff);
  128. break;
  129. }
  130. check_alloc(num + 1);
  131. xarray[num] = xper;
  132. yarray[num] = yper;
  133. num++;
  134. }
  135. if (num) {
  136. /* this check is here so you can use the "polyline" command
  137. to make an unfilled polygon */
  138. if (!strcmp(origcmd, "polygon"))
  139. D_polygon_abs(xarray, yarray, num);
  140. else
  141. D_polyline_abs(xarray, yarray, num);
  142. }
  143. return (to_return);
  144. }
  145. int do_size(const char *str)
  146. {
  147. float xper, yper;
  148. int ret;
  149. ret = sscanf(str, "%*s %f %f", &xper, &yper);
  150. if (ret != 2 && ret != 1) {
  151. G_warning(_("Problem parsing command [%s]"), str);
  152. return (-1);
  153. }
  154. /* if only one size is given assume same value in both axes */
  155. if (ret == 1)
  156. yper = xper;
  157. if (xper < 0. || yper < 0. || xper > 100. || yper > 100.)
  158. return (-1);
  159. D_text_size(xper * xincr, yper * yincr);
  160. G_debug(3, "text size set to [%.1f,%.1f]",
  161. xper * xincr, yper * yincr);
  162. return (0);
  163. }
  164. int do_rotate(const char *str)
  165. {
  166. if (1 != sscanf(str, "%*s %lf", &rotation)) {
  167. G_warning(_("Problem parsing command [%s]"), str);
  168. return (-1);
  169. }
  170. D_text_rotation(rotation);
  171. G_debug(3, "rotation set to %.1f degrees", rotation);
  172. return (0);
  173. }
  174. int do_text(const char *str)
  175. {
  176. const char *ptr = str;
  177. /* skip to beginning of actual text */
  178. for (; *ptr != ' '; ptr++)
  179. ;
  180. for (; *ptr == ' '; ptr++)
  181. ;
  182. D_text(ptr);
  183. return 0;
  184. }
  185. int check_alloc(int num)
  186. {
  187. int to_alloc;
  188. if (num < coors_allocated)
  189. return 0;
  190. to_alloc = coors_allocated;
  191. if (num >= to_alloc)
  192. to_alloc = num + CHUNK;
  193. xarray = G_realloc(xarray, to_alloc * sizeof(double));
  194. yarray = G_realloc(yarray, to_alloc * sizeof(double));
  195. coors_allocated = to_alloc;
  196. return 0;
  197. }
  198. int do_icon(const char *str)
  199. {
  200. double xper, yper;
  201. char type;
  202. double size;
  203. double ix, iy;
  204. if (4 != sscanf(str, "%*s %c %lf %lf %lf", &type, &size, &xper, &yper)) {
  205. G_warning(_("Problem parsing command [%s]"), str);
  206. return (-1);
  207. }
  208. ix = xper;
  209. iy = yper;
  210. size *= yincr;
  211. D_begin();
  212. switch (type & 0x7F) {
  213. case 'o':
  214. D_move_abs(ix - size, iy - size);
  215. D_cont_abs(ix - size, iy + size);
  216. D_cont_abs(ix + size, iy + size);
  217. D_cont_abs(ix + size, iy - size);
  218. D_cont_abs(ix - size, iy - size);
  219. break;
  220. case 'x':
  221. D_move_abs(ix - size, iy - size);
  222. D_cont_abs(ix + size, iy + size);
  223. D_move_abs(ix - size, iy + size);
  224. D_cont_abs(ix + size, iy - size);
  225. break;
  226. case '+':
  227. default:
  228. D_move_abs(ix, iy - size);
  229. D_cont_abs(ix, iy + size);
  230. D_move_abs(ix - size, iy);
  231. D_cont_abs(ix + size, iy);
  232. break;
  233. }
  234. D_end();
  235. D_stroke();
  236. return (0);
  237. }
  238. int do_symbol(const char *str)
  239. {
  240. double xper, yper;
  241. double size;
  242. double ix, iy;
  243. char *symb_name;
  244. SYMBOL *Symb;
  245. char *line_color_str, *fill_color_str;
  246. RGBA_Color *line_color, *fill_color;
  247. int R, G, B, ret;
  248. line_color = G_malloc(sizeof(RGBA_Color));
  249. fill_color = G_malloc(sizeof(RGBA_Color));
  250. symb_name = G_malloc(strlen(str) + 1); /* well, it won't be any bigger than this */
  251. line_color_str = G_malloc(strlen(str) + 1);
  252. fill_color_str = G_malloc(strlen(str) + 1);
  253. G_debug(3, "do_symbol() [%s]", str);
  254. /* set default colors so colors are optional */
  255. strcpy(line_color_str, DEFAULT_FG_COLOR);
  256. strcpy(fill_color_str, "grey");
  257. if (sscanf
  258. (str, "%*s %s %lf %lf %lf %s %s", symb_name, &size, &xper, &yper,
  259. line_color_str, fill_color_str) < 4) {
  260. G_warning(_("Problem parsing command [%s]"), str);
  261. return (-1);
  262. }
  263. ix = xper;
  264. iy = yper;
  265. size *= yincr;
  266. /* parse line color */
  267. ret = G_str_to_color(line_color_str, &R, &G, &B);
  268. line_color->r = (unsigned char)R;
  269. line_color->g = (unsigned char)G;
  270. line_color->b = (unsigned char)B;
  271. if (ret == 1) {
  272. /* here alpha is only used as an on/off switch, otherwise unused by the display drivers */
  273. line_color->a = RGBA_COLOR_OPAQUE;
  274. }
  275. else if (ret == 2)
  276. line_color->a = RGBA_COLOR_NONE;
  277. else {
  278. G_warning(_("[%s]: No such color"), line_color_str);
  279. return (-1);
  280. }
  281. /* parse fill color */
  282. ret = G_str_to_color(fill_color_str, &R, &G, &B);
  283. fill_color->r = (unsigned char)R;
  284. fill_color->g = (unsigned char)G;
  285. fill_color->b = (unsigned char)B;
  286. if (ret == 1)
  287. fill_color->a = RGBA_COLOR_OPAQUE;
  288. else if (ret == 2)
  289. fill_color->a = RGBA_COLOR_NONE;
  290. else {
  291. G_warning(_("[%s]: No such color"), fill_color_str);
  292. return (-1);
  293. }
  294. Symb = S_read(symb_name);
  295. if (Symb == NULL) {
  296. G_warning(_("Cannot read symbol, cannot display points"));
  297. return (-1);
  298. }
  299. else
  300. S_stroke(Symb, size, rotation, 0);
  301. D_symbol(Symb, ix, iy, line_color, fill_color);
  302. /* restore previous d.graph draw color */
  303. if (last_color.a == RGBA_COLOR_OPAQUE)
  304. D_RGB_color(last_color.r, last_color.g, last_color.b);
  305. else if (last_color.a == RGBA_COLOR_NONE)
  306. D_use_color(D_parse_color(DEFAULT_BG_COLOR, 0));
  307. else /* unset or bad */
  308. D_RGB_color(line_color->r, line_color->g, line_color->b);
  309. G_free(symb_name);
  310. G_free(line_color_str);
  311. G_free(fill_color_str);
  312. G_free(line_color);
  313. G_free(fill_color);
  314. return (0);
  315. }
  316. /* RGBA are 0-255; alpha is only used as an on/off switch. maybe test a<127<a ? */
  317. void set_last_color(int R, int G, int B, int alpha)
  318. {
  319. if (alpha == RGBA_COLOR_OPAQUE) {
  320. last_color.r = (unsigned char)R;
  321. last_color.g = (unsigned char)G;
  322. last_color.b = (unsigned char)B;
  323. last_color.a = RGBA_COLOR_OPAQUE;
  324. }
  325. else if (alpha == RGBA_COLOR_NONE) {
  326. last_color.a = RGBA_COLOR_NONE;
  327. }
  328. else
  329. last_color.a = RGBA_COLOR_NONE;
  330. }