do_graph.c 8.5 KB

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