r_raster.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. /*!
  2. \file lib/display/r_raster.c
  3. \brief Display Library - Raster graphics subroutines
  4. (C) 2001-2015 by the GRASS Development Team
  5. This program is free software under the GNU General Public License
  6. (>=v2). Read the file COPYING that comes with GRASS for details.
  7. \author Original author CERL
  8. \author Monitors support by Martin Landa <landa.martin gmail.com>
  9. */
  10. #include <grass/config.h>
  11. #include <errno.h>
  12. #include <signal.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <unistd.h>
  17. #include <grass/gis.h>
  18. #include <grass/glocale.h>
  19. #include <grass/display.h>
  20. #include <grass/spawn.h>
  21. #include "driver.h"
  22. extern const struct driver *PNG_Driver(void);
  23. extern const struct driver *PS_Driver(void);
  24. extern const struct driver *HTML_Driver(void);
  25. #ifdef USE_CAIRO
  26. extern const struct driver *Cairo_Driver(void);
  27. #endif
  28. static struct {
  29. double t, b, l, r;
  30. } screen, frame;
  31. static void init(void)
  32. {
  33. const char *fenc = getenv("GRASS_ENCODING");
  34. const char *font = getenv("GRASS_FONT");
  35. const char *line_width = getenv("GRASS_RENDER_LINE_WIDTH");
  36. const char *text_size = getenv("GRASS_RENDER_TEXT_SIZE");
  37. const char *frame_str = getenv("GRASS_RENDER_FRAME");
  38. D_font(font ? font : "romans");
  39. if (fenc)
  40. D_encoding(fenc);
  41. if (line_width)
  42. COM_Line_width(atof(line_width));
  43. if (text_size) {
  44. double s = atof(text_size);
  45. D_text_size(s, s);
  46. }
  47. D_text_rotation(0);
  48. COM_Get_window(&screen.t, &screen.b, &screen.l, &screen.r);
  49. if (frame_str) {
  50. sscanf(frame_str, "%lf,%lf,%lf,%lf", &frame.t, &frame.b, &frame.l, &frame.r);
  51. COM_Set_window(frame.t, frame.b, frame.l, frame.r);
  52. }
  53. else
  54. frame = screen;
  55. }
  56. /*!
  57. \brief Open display driver
  58. Default display driver is Cairo, if not available PNG is used.
  59. \return 0 on success
  60. */
  61. int D_open_driver(void)
  62. {
  63. const char *p, *c, *m;
  64. const struct driver *drv;
  65. G_debug(1, "D_open_driver():");
  66. p = getenv("GRASS_RENDER_IMMEDIATE");
  67. c = getenv("GRASS_RENDER_COMMAND");
  68. m = G_getenv_nofatal("MONITOR");
  69. if (!p && (m || c)) {
  70. char *cmd;
  71. char progname[GPATH_MAX];
  72. cmd = G_recreate_command();
  73. if (c && m) {
  74. G_warning(_("Both %s and %s are defined. "
  75. "%s will be ignored."),
  76. "GRASS_RENDER_COMMAND", "MONITOR",
  77. "MONITOR");
  78. m = NULL;
  79. }
  80. if (c)
  81. sprintf(progname, "%s", c);
  82. else { /* monitors managed by d.mon -> call default renderer */
  83. char element[GPATH_MAX];
  84. G_temp_element(element);
  85. strcat(element, "/");
  86. strcat(element, "MONITORS");
  87. strcat(element, "/");
  88. strcat(element, m);
  89. G_file_name(progname, element, "render.py", G_mapset());
  90. }
  91. G_debug(1, "rendering redirected to %s", progname);
  92. /* assuming Python script here (could be extended in the future) */
  93. G_spawn_ex(getenv("GRASS_PYTHON"), getenv("GRASS_PYTHON"), progname,
  94. cmd, NULL);
  95. G_free(cmd);
  96. /* force exiting GRASS command, leave rendering on
  97. * GRASS_RENDER_COMMAND program */
  98. exit(0);
  99. }
  100. if (!p)
  101. G_fatal_error(_("Neither %s (managed by d.mon command) nor %s "
  102. "(used for direct rendering) defined"),
  103. "MONITOR", "GRASS_RENDER_IMMEDIATE");
  104. if (p && G_strcasecmp(p, "default") == 0)
  105. p = NULL;
  106. drv =
  107. (p && G_strcasecmp(p, "png") == 0) ? PNG_Driver() :
  108. (p && G_strcasecmp(p, "ps") == 0) ? PS_Driver() :
  109. (p && G_strcasecmp(p, "html") == 0) ? HTML_Driver() :
  110. #ifdef USE_CAIRO
  111. (p && G_strcasecmp(p, "cairo") == 0) ? Cairo_Driver() :
  112. Cairo_Driver();
  113. #else
  114. PNG_Driver();
  115. #endif
  116. if (p && G_strcasecmp(drv->name, p) != 0)
  117. G_warning(_("Unknown display driver <%s>"), p);
  118. G_verbose_message(_("Using display driver <%s>..."), drv->name);
  119. LIB_init(drv);
  120. init();
  121. return 0;
  122. }
  123. /*!
  124. \brief Close display driver
  125. If GRASS_NOTIFY is defined, run notifier.
  126. */
  127. void D_close_driver(void)
  128. {
  129. const char *cmd = getenv("GRASS_NOTIFY");
  130. COM_Graph_close();
  131. if (cmd)
  132. system(cmd);
  133. }
  134. /*!
  135. \brief Append command to the cmd file (unused)
  136. \todo To be removed
  137. */
  138. int D_save_command(const char *cmd)
  139. {
  140. return 0;
  141. }
  142. /*!
  143. \brief Erase display (internal use only)
  144. */
  145. void D__erase(void)
  146. {
  147. COM_Erase();
  148. }
  149. /*!
  150. \brief Set text size (width and height)
  151. \param width text pixel width
  152. \param height text pixel height
  153. */
  154. void D_text_size(double width, double height)
  155. {
  156. COM_Text_size(width, height);
  157. }
  158. /*!
  159. \brief Set text rotation
  160. \param rotation value
  161. */
  162. void D_text_rotation(double rotation)
  163. {
  164. COM_Text_rotation(rotation);
  165. }
  166. /*!
  167. \brief Draw text
  168. Writes <em>text</em> in the current color and font, at the current text
  169. width and height, starting at the current screen location.
  170. \param text text to be drawn
  171. */
  172. void D_text(const char *text)
  173. {
  174. COM_Text(text);
  175. }
  176. /*!
  177. \brief Choose font
  178. Set current font to <em>font name</em>.
  179. \param name font name
  180. */
  181. void D_font(const char *name)
  182. {
  183. COM_Set_font(name);
  184. }
  185. /*!
  186. \brief Set encoding
  187. \param name encoding name
  188. */
  189. void D_encoding(const char *name)
  190. {
  191. COM_Set_encoding(name);
  192. }
  193. /*!
  194. \brief Get font list
  195. \param[out] list list of font names
  196. \param[out] number of items in the list
  197. */
  198. void D_font_list(char ***list, int *count)
  199. {
  200. COM_Font_list(list, count);
  201. }
  202. /*!
  203. \brief Get font info
  204. \param[out] list list of font info
  205. \param[out] number of items in the list
  206. */
  207. void D_font_info(char ***list, int *count)
  208. {
  209. COM_Font_info(list, count);
  210. }
  211. /*!
  212. * \brief get graphical clipping window
  213. *
  214. * Queries the graphical clipping window (origin is top right)
  215. *
  216. * \param[out] t top edge of clip window
  217. * \param[out] b bottom edge of clip window
  218. * \param[out] l left edge of clip window
  219. * \param[out] r right edge of clip window
  220. * \return ~
  221. */
  222. void D_get_clip_window(double *t, double *b, double *l, double *r)
  223. {
  224. COM_Get_window(t, b, l, r);
  225. }
  226. /*!
  227. * \brief set graphical clipping window
  228. *
  229. * Sets the graphical clipping window to the specified rectangle
  230. * (origin is top right)
  231. *
  232. * \param t top edge of clip window
  233. * \param b bottom edge of clip window
  234. * \param l left edge of clip window
  235. * \param r right edge of clip window
  236. * \return ~
  237. */
  238. void D_set_clip_window(double t, double b, double l, double r)
  239. {
  240. if (t < frame.t) t = frame.t;
  241. if (b > frame.b) b = frame.b;
  242. if (l < frame.l) l = frame.l;
  243. if (r > frame.r) r = frame.r;
  244. COM_Set_window(t, b, l, r);
  245. }
  246. /*!
  247. * \brief get graphical window (frame)
  248. *
  249. * Queries the graphical frame (origin is top right)
  250. *
  251. * \param[out] t top edge of frame
  252. * \param[out] b bottom edge of frame
  253. * \param[out] l left edge of frame
  254. * \param[out] r right edge of frame
  255. * \return ~
  256. */
  257. void D_get_frame(double *t, double *b, double *l, double *r)
  258. {
  259. *t = frame.t;
  260. *b = frame.b;
  261. *l = frame.l;
  262. *r = frame.r;
  263. }
  264. /*!
  265. * \brief get screen bounds
  266. *
  267. * Queries the screen bounds (origin is top right)
  268. *
  269. * \param[out] t top edge of screen
  270. * \param[out] b bottom edge of screen
  271. * \param[out] l left edge of screen
  272. * \param[out] r right edge of screen
  273. * \return ~
  274. */
  275. void D_get_screen(double *t, double *b, double *l, double *r)
  276. {
  277. *t = screen.t;
  278. *b = screen.b;
  279. *l = screen.l;
  280. *r = screen.r;
  281. }
  282. /*!
  283. * \brief set graphical clipping window to map window
  284. *
  285. * Sets the graphical clipping window to the pixel window that corresponds
  286. * to the current database region.
  287. *
  288. * \param ~
  289. * \return ~
  290. */
  291. void D_set_clip_window_to_map_window(void)
  292. {
  293. D_set_clip_window(
  294. D_get_d_north(), D_get_d_south(),
  295. D_get_d_west(), D_get_d_east());
  296. }
  297. /*!
  298. * \brief set clipping window to screen window
  299. *
  300. * Sets the clipping window to the pixel window that corresponds to the
  301. * full screen window. Off screen rendering is still clipped.
  302. *
  303. * \param ~
  304. * \return ~
  305. */
  306. void D_set_clip_window_to_screen_window(void)
  307. {
  308. COM_Set_window(frame.t, frame.b, frame.l, frame.r);
  309. }