draw.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /* draw.c:
  2. *
  3. * With do_bg=1 compute position of all legend graphic item and draw only background.
  4. * Eith do_bg=0 compute position of all legend graphic item and draw all.
  5. *
  6. * Copyright (C) 2016 by Adam Laza, GSoC 2016, and the GRASS Development Team*
  7. * This program is free software under the GPL (>=v2)
  8. * Read the COPYING file that comes with GRASS for details.
  9. */
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <math.h>
  13. #include <grass/display.h>
  14. #include <grass/glocale.h>
  15. #include <grass/colors.h>
  16. #include "local_proto.h"
  17. void draw(char *file_name, double LL, double LT, char *title, int cols, int bgcolor,
  18. int bcolor, int bg_width, int do_bg, char* tit_font, int tit_size, char *sub_font,
  19. int sub_size, char *font, int fontsize, int fontcolor, int symb_size, char *sep)
  20. {
  21. double db, dt, dl, dr;
  22. double bb, bt, bl, br;
  23. double x0, y0;
  24. double offs_y, row_ind, offs_x;
  25. double x, y;
  26. FILE *file_in;
  27. char buf[BUFFSIZE];
  28. int got_new;
  29. SYMBOL *Symb;
  30. char *symb_name, *line_color_str, *fill_color_str, *label, *type_str, *color_type;
  31. double size, line_width;
  32. double row_w, text_h, title_h, title_w;
  33. RGBA_Color *line_color, *fill_color;
  34. int ret, R, G, B;
  35. char *part, *sub_delim;
  36. double maxlblw, sym_lbl_space;
  37. double symb_h, symb_w, def_symb_h, def_symb_w;
  38. int item_count, item;
  39. double it_per_col;
  40. double margin, bg_h, bg_w;
  41. char **tokens;
  42. D_get_src(&dt, &db, &dl, &dr);
  43. x0 = dl + (int)((dr - dl) * LL / 100.);
  44. y0 = dt + (int)((db - dt) * (100 - LT) / 100.);
  45. /* Draw title */
  46. title_h = 0;
  47. if (strlen(title) > 0) {
  48. D_font(tit_font);
  49. D_text_size(tit_size, tit_size);
  50. D_get_text_box(title, &bb, &bt, &bl, &br);
  51. margin = 10;
  52. title_h = bb - bt + margin;
  53. title_w = br - bl;
  54. if (! do_bg) {
  55. x = x0;
  56. y = y0 + title_h;
  57. D_pos_abs(x, y);
  58. D_use_color(fontcolor);
  59. D_text(title);
  60. }
  61. }
  62. file_in = fopen(file_name, "r");
  63. sub_delim = G_malloc(GNAME_MAX);
  64. snprintf(sub_delim, sizeof(GNAME_MAX), "%s%s%s%s%s%s", sep, sep, sep, sep, sep, sep);
  65. if (!file_in)
  66. G_fatal_error(_("Unable to open input file <%s>"), file_name);
  67. /* Get number of legend row(item) and the biggest symbol*/
  68. item_count = 0;
  69. def_symb_w = symb_size;
  70. got_new = G_getl2(buf, sizeof(buf), file_in);
  71. G_strip(buf);
  72. while (got_new) {
  73. if (strstr(buf, sub_delim) == NULL) {
  74. /* Get the maximum symbol size */
  75. tokens = G_tokenize(buf, sep);
  76. symb_name = G_store(tokens[1]);
  77. size = atof(tokens[2]);
  78. type_str = G_store(tokens[7]);
  79. G_free_tokens(tokens);
  80. /* Symbol */
  81. if (((strcmp(type_str,"point") != 0) && (strcmp(type_str, "centroid") != 0)) || size < 0) {
  82. size = symb_size;
  83. }
  84. Symb = S_read(symb_name);
  85. if (Symb == NULL)
  86. G_warning(_("Cannot read symbol"));
  87. else
  88. S_stroke(Symb, size, 0, 0);
  89. symb_w = size;
  90. if (symb_w > def_symb_w)
  91. def_symb_w = symb_w;
  92. }
  93. item_count++;
  94. got_new = G_getl2(buf, sizeof(buf), file_in);
  95. G_strip(buf);
  96. }
  97. rewind(file_in);
  98. it_per_col = ceil(item_count / (cols * 1.0));
  99. bg_h = 0;
  100. maxlblw = 0;
  101. offs_y = title_h;
  102. sym_lbl_space = 10;
  103. def_symb_h = symb_size;
  104. item = 0;
  105. offs_x = 0;
  106. margin = 10;
  107. got_new = G_getl2(buf, sizeof(buf), file_in);
  108. G_strip(buf);
  109. while (got_new) {
  110. if (item < it_per_col){
  111. row_ind = 5;
  112. item++;
  113. }
  114. else {
  115. if (bg_h < offs_y)
  116. bg_h = offs_y + def_symb_h/2.;
  117. offs_x += maxlblw + margin;
  118. offs_y = title_h + row_ind;
  119. maxlblw = 0;
  120. item = 1;
  121. row_ind = 0;
  122. }
  123. if (strstr(buf, sub_delim) != NULL) {
  124. /* Group subtitle */
  125. label = G_malloc(GNAME_MAX);
  126. part = strtok(buf, sep);
  127. label = G_store(part);
  128. D_text_size(sub_size, sub_size);
  129. D_font(sub_font);
  130. D_get_text_box(label, &bb, &bt, &bl, &br);
  131. text_h = bb - bt;
  132. row_w = br - bl;
  133. offs_y += text_h + row_ind;
  134. if (bg_h < offs_y)
  135. bg_h = offs_y + def_symb_h/2.;
  136. if (row_w > maxlblw)
  137. maxlblw = row_w;
  138. if (! do_bg) {
  139. x = x0 + offs_x;
  140. y = y0 + offs_y;
  141. D_pos_abs(x, y);
  142. D_use_color(fontcolor);
  143. D_text(label);
  144. }
  145. }
  146. else {
  147. /* Map layers */
  148. line_color = G_malloc(sizeof(RGBA_Color));
  149. fill_color = G_malloc(sizeof(RGBA_Color));
  150. tokens = G_tokenize(buf, sep);
  151. label = G_store(tokens[0]);
  152. symb_name = G_store(tokens[1]);
  153. size = atof(tokens[2]);
  154. color_type = G_store(tokens[3]);
  155. line_color_str = G_store(tokens[4]);
  156. fill_color_str = G_store(tokens[5]);
  157. line_width = atof(tokens[6]);
  158. type_str = G_store(tokens[7]);
  159. G_free_tokens(tokens);
  160. /* Symbol */
  161. if (((strcmp(type_str,"point") != 0) && (strcmp(type_str, "centroid") != 0)) || size < 0) {
  162. size = symb_size;
  163. }
  164. Symb = S_read(symb_name);
  165. if (Symb == NULL)
  166. G_warning(_("Cannot read symbol"));
  167. else
  168. S_stroke(Symb, size, 0, 0);
  169. /* parse line color */
  170. ret = G_str_to_color(line_color_str, &R, &G, &B);
  171. line_color->r = (unsigned char)R;
  172. line_color->g = (unsigned char)G;
  173. line_color->b = (unsigned char)B;
  174. if (ret == 1)
  175. /* here alpha is only used as an on/off switch, otherwise unused by the display drivers */
  176. line_color->a = RGBA_COLOR_OPAQUE;
  177. else if (ret == 2)
  178. line_color->a = RGBA_COLOR_NONE;
  179. else
  180. G_warning(_("[%s]: No such color"), line_color_str);
  181. /* parse fill color */
  182. ret = G_str_to_color(fill_color_str, &R, &G, &B);
  183. fill_color->r = (unsigned char)R;
  184. fill_color->g = (unsigned char)G;
  185. fill_color->b = (unsigned char)B;
  186. if (ret == 1)
  187. fill_color->a = RGBA_COLOR_OPAQUE;
  188. else if (ret == 2)
  189. fill_color->a = RGBA_COLOR_NONE;
  190. else
  191. G_warning(_("[%s]: No such color"), fill_color_str);
  192. /* Label */
  193. D_text_size(fontsize, fontsize);
  194. D_font(font);
  195. D_get_text_box(label, &bb, &bt, &bl, &br);
  196. symb_h = size;
  197. if (symb_h < def_symb_h)
  198. symb_h = def_symb_h;
  199. text_h = bb - bt;
  200. row_w = def_symb_w + sym_lbl_space + br - bl;
  201. if (symb_h >= text_h)
  202. offs_y += symb_h + row_ind;
  203. else
  204. offs_y += text_h + row_ind;
  205. if (bg_h <= offs_y)
  206. bg_h = offs_y + symb_h/2.;
  207. if (row_w > maxlblw)
  208. maxlblw = row_w;
  209. if (! do_bg) {
  210. S_stroke(Symb, size, 0, 0);
  211. x = x0 + offs_x + def_symb_w/2.;
  212. y = y0 + offs_y - symb_h/2;
  213. D_line_width(line_width);
  214. /* lf - line, fill (as in d.vect)*/
  215. if (strcmp(color_type, "lf") == 0)
  216. D_symbol(Symb, x, y, line_color, fill_color);
  217. /* ps - primary, secondary (as in d.vect.thematic) */
  218. else if (strcmp(color_type, "ps") == 0)
  219. D_symbol2(Symb, x, y, line_color, fill_color);
  220. else {
  221. G_warning(_("Invalid value for color type in legend file. "
  222. "Use one of 'lf' or 'ps'."));
  223. D_symbol(Symb, x, y, line_color, fill_color);
  224. }
  225. x = x0 + offs_x + def_symb_w + sym_lbl_space;
  226. y = y0 + offs_y - symb_h/2. + text_h/2.;
  227. D_pos_abs(x, y);
  228. D_use_color(fontcolor);
  229. D_text(label);
  230. }
  231. }
  232. got_new = G_getl2(buf, sizeof(buf), file_in);
  233. G_strip(buf);
  234. }
  235. fclose(file_in);
  236. /* Draw background */
  237. if (do_bg) {
  238. double x0bg, y0bg, x1bg, y1bg;
  239. if (title_w > offs_x + maxlblw)
  240. bg_w = title_w;
  241. else
  242. bg_w = offs_x + maxlblw;
  243. x0bg = x0 - margin;
  244. y0bg = y0;
  245. x1bg = x0 + bg_w + margin;
  246. y1bg = y0 + bg_h;
  247. if (bgcolor) {
  248. D_use_color(bgcolor);
  249. D_box_abs(x0bg, y0bg, x1bg, y1bg);
  250. }
  251. D_use_color(bcolor);
  252. D_line_width(bg_width);
  253. D_begin();
  254. D_move_abs(x0bg, y0bg);
  255. D_cont_abs(x0bg, y1bg);
  256. D_cont_abs(x1bg, y1bg);
  257. D_cont_abs(x1bg, y0bg);
  258. D_close();
  259. D_end();
  260. D_stroke();
  261. }
  262. D_save_command(G_recreate_command());
  263. }