do_labels.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /* Function: do_labels
  2. **
  3. ** This function is a much modified version of the p.map function of
  4. ** the same name.
  5. **
  6. ** Author: Paul W. Carlson March 1992
  7. */
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <grass/colors.h>
  11. #include <grass/raster.h>
  12. #include <grass/glocale.h>
  13. #include "clr.h"
  14. #include "labels.h"
  15. #include "local_proto.h"
  16. #define FIELD(x) strcmp(x,field)==0
  17. #define LEFT 0
  18. #define RIGHT 1
  19. #define LOWER 0
  20. #define UPPER 1
  21. #define CENTER 2
  22. int do_labels(int other)
  23. {
  24. FILE *fd;
  25. int i;
  26. int font_override = 0;
  27. if (!labels.count && labels.other == NULL)
  28. return 0;
  29. /* default is Helvetica font */
  30. set_font_name("Helvetica");
  31. if (!other) {
  32. for (i = 0; i < labels.count; i++) {
  33. fd = G_fopen_old("paint/labels", labels.name[i],
  34. labels.mapset[i]);
  35. if (fd == NULL) {
  36. G_warning(_("Can't open label file <%s> in mapset <%s>"),
  37. labels.name[i], labels.mapset[i]);
  38. }
  39. else {
  40. G_message(_("Reading labels file <%s in %s> ..."),
  41. labels.name[i], labels.mapset[i]);
  42. if (labels.font[i] != NULL) {
  43. set_font_name(labels.font[i]);
  44. font_override = 1;
  45. }
  46. set_font_size(10);
  47. do_label(fd, font_override);
  48. fclose(fd);
  49. font_override = 0;
  50. }
  51. }
  52. }
  53. if (other && labels.other) {
  54. fd = fopen(labels.other, "r");
  55. if (fd == NULL)
  56. G_warning(_("Can't open temporary label file <%s>"),
  57. labels.other);
  58. else {
  59. G_message(_("Reading text file ..."));
  60. do_label(fd, font_override);
  61. fclose(fd);
  62. }
  63. }
  64. return 0;
  65. }
  66. int do_label(FILE * fd, int font_override)
  67. {
  68. double east, north, dtmp, x, y;
  69. float size, rotate, margin;
  70. int xoffset, yoffset, xref, yref;
  71. PSCOLOR background, border, color, hcolor;
  72. int r, g, b;
  73. int ret;
  74. double width, hwidth;
  75. int opaque, fontsize, multi_text, x_int, y_int;
  76. int itmp;
  77. char field[1024];
  78. char value[1024];
  79. char ch, buf[1024];
  80. double atof();
  81. int X_just_offset, Y_just_offset;
  82. /* initialize */
  83. north = PS.w.north;
  84. east = PS.w.west;
  85. opaque = 0;
  86. xoffset = 0;
  87. yoffset = 0;
  88. width = 1.;
  89. set_color(&color, 0, 0, 0); /* black */
  90. set_color(&background, 255, 255, 255); /* white */
  91. set_color(&border, 0, 0, 0); /* black */
  92. unset_color(&hcolor);
  93. hwidth = 0.;
  94. xref = CENTER;
  95. yref = CENTER;
  96. rotate = 0., size = 0.;
  97. fontsize = 0;
  98. X_just_offset = Y_just_offset = 0;
  99. /* read the labels file */
  100. while (fgets(buf, sizeof buf, fd)) {
  101. *value = 0;
  102. *field = 0;
  103. if (sscanf(buf, "%[^:]:%[^\n]", field, value) < 1)
  104. continue;
  105. if (FIELD("text")) { /* appears last in the labels file */
  106. G_strip(value);
  107. /* get reference coordinates */
  108. /*
  109. x = XCONV(east);
  110. y = YCONV(north);
  111. */
  112. G_plot_where_xy(east, north, &x_int, &y_int);
  113. /* justification based padding */
  114. if (xref == LEFT)
  115. X_just_offset = 35;
  116. if (xref == RIGHT)
  117. X_just_offset = -35;
  118. if (xref == CENTER)
  119. X_just_offset = 0;
  120. if (yref == UPPER)
  121. Y_just_offset = 35;
  122. if (yref == LOWER)
  123. Y_just_offset = -35;
  124. if (yref == CENTER)
  125. Y_just_offset = 0;
  126. /* adjust padding for given rotation */
  127. if (rotate != 0.0)
  128. G_rotate_around_point_int(0, 0, &X_just_offset,
  129. &Y_just_offset, -1 * rotate);
  130. /* apply padding */
  131. x_int += X_just_offset;
  132. y_int -= Y_just_offset;
  133. x = (double)x_int / 10.;
  134. y = (double)y_int / 10.;
  135. x += xoffset;
  136. y += yoffset;
  137. /* set font size if given in map units and not given by fontsize */
  138. if (fontsize && size > 0)
  139. G_warning(_("Text labels: 'fontsize' given so ignoring 'size'"));
  140. if (!fontsize)
  141. fontsize = size * PS.ns_to_y;
  142. /* fall back if no size of any kind is defined */
  143. if (fontsize == 0)
  144. fontsize = 10;
  145. /*
  146. if (fontsize < 10) fontsize = 10;
  147. if (fontsize > 50) fontsize = 50;
  148. */
  149. set_font_size(fontsize);
  150. /* set margin to 20% of font size */
  151. if (opaque || !color_none(&border)) {
  152. margin = 0.2 * (double)fontsize + 0.5;
  153. /*if (margin < 2) margin = 2; *//* commented because
  154. too big box was created for little font; RB March 2000 */
  155. if (!color_none(&hcolor))
  156. margin += hwidth;
  157. }
  158. else
  159. margin = 0;
  160. fprintf(PS.fp, "/mg %.2f def\n", margin);
  161. /* construct path for box */
  162. multi_text = multi_lines(value);
  163. if (multi_text) {
  164. /* multiple lines - text is in PostScript array "ta" */
  165. multi_text_box_path(x, y, xref, yref, value, fontsize,
  166. rotate);
  167. }
  168. else {
  169. /* single line - text is left on stack */
  170. text_box_path(x, y, xref, yref, value, rotate);
  171. }
  172. if (opaque && !color_none(&background)) {
  173. /* fill the box */
  174. set_ps_color(&background);
  175. fprintf(PS.fp, "F ");
  176. opaque = 0;
  177. }
  178. if (!color_none(&border)) {
  179. /* draw the border */
  180. set_line_width(width); /* added by RB, ? add bwidth option */
  181. set_ps_color(&border);
  182. fprintf(PS.fp, "D ");
  183. unset_color(&border);
  184. }
  185. /* draw the text */
  186. if (!color_none(&hcolor)) {
  187. set_ps_color(&hcolor);
  188. set_line_width(width + 2 * hwidth);
  189. if (multi_text)
  190. fprintf(PS.fp, "DMH ");
  191. else
  192. fprintf(PS.fp, "HC ");
  193. }
  194. set_ps_color(&color);
  195. if (multi_text)
  196. fprintf(PS.fp, "DMT ");
  197. else
  198. fprintf(PS.fp, "TIB ");
  199. /* done; clear the decks for the next round */
  200. unset_color(&hcolor);
  201. hwidth = 0.;
  202. width = 1.;
  203. fontsize = 0;
  204. rotate = 0.;
  205. continue;
  206. }
  207. if (FIELD("color")) {
  208. ret = G_str_to_color(value, &r, &g, &b);
  209. if (ret == 1)
  210. set_color(&color, r, g, b);
  211. else
  212. set_color(&color, 0, 0, 0); /* black */
  213. continue;
  214. }
  215. if (FIELD("hcolor")) {
  216. ret = G_str_to_color(value, &r, &g, &b);
  217. if (ret == 1)
  218. set_color(&hcolor, r, g, b);
  219. else if (ret == 2)
  220. unset_color(&hcolor);
  221. continue;
  222. }
  223. if (FIELD("xoffset")) {
  224. xoffset = atoi(value);
  225. continue;
  226. }
  227. if (FIELD("yoffset")) {
  228. yoffset = atoi(value);
  229. continue;
  230. }
  231. if (FIELD("ref")) {
  232. if (!scan_ref(value, &xref, &yref)) {
  233. yref = CENTER;
  234. xref = CENTER;
  235. }
  236. continue;
  237. }
  238. if (FIELD("background")) {
  239. /*
  240. if(strncmp(value, "none", 4)==0) opaque = 0;
  241. */
  242. ret = G_str_to_color(value, &r, &g, &b);
  243. if (ret == 1)
  244. set_color(&background, r, g, b);
  245. else if (ret == 2)
  246. unset_color(&background);
  247. continue;
  248. }
  249. if (FIELD("border")) {
  250. ret = G_str_to_color(value, &r, &g, &b);
  251. if (ret == 1)
  252. set_color(&border, r, g, b);
  253. else if (ret == 2)
  254. unset_color(&border);
  255. continue;
  256. }
  257. if (FIELD("opaque")) {
  258. G_strip(value);
  259. opaque = (strcmp(value, "no") != 0);
  260. continue;
  261. }
  262. if (FIELD("width")) {
  263. ch = ' ';
  264. sscanf(value, "%lf%c", &width, &ch);
  265. if (ch == 'i')
  266. width = width * 72.0;
  267. if (width < 0.)
  268. width = 1.;
  269. if (width > 25.)
  270. width = 25.;
  271. continue;
  272. }
  273. if (FIELD("hwidth")) {
  274. ch = ' ';
  275. sscanf(value, "%lf%c", &hwidth, &ch);
  276. if (ch == 'i')
  277. hwidth = hwidth * 72.0;
  278. if (hwidth < 0.)
  279. hwidth = 0.;
  280. if (hwidth > 5.)
  281. hwidth = 5.;
  282. continue;
  283. }
  284. if (FIELD("size")) {
  285. if (scan_resolution(value, &dtmp))
  286. size = dtmp;
  287. continue;
  288. }
  289. if (FIELD("fontsize")) {
  290. if (sscanf(value, "%d", &itmp) == 1 && itmp > 0)
  291. fontsize = itmp;
  292. continue;
  293. }
  294. if (FIELD("north")) {
  295. if (scan_northing(value, &dtmp))
  296. north = dtmp;
  297. continue;
  298. }
  299. if (FIELD("east")) {
  300. if (scan_easting(value, &dtmp))
  301. east = dtmp;
  302. continue;
  303. }
  304. if (FIELD("font")) {
  305. G_strip(value);
  306. if (!font_override)
  307. set_font_name(value);
  308. continue;
  309. }
  310. if (FIELD("rotate")) {
  311. if (scan_northing(value, &dtmp))
  312. rotate = dtmp;
  313. continue;
  314. }
  315. }
  316. /*fclose (fd); *//* commented because fd is closed after
  317. do_label call; RB March 2000 */
  318. return 0;
  319. }