m_attribs.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. /* This file is part of the GNU plotutils package. Copyright (C) 1995,
  2. 1996, 1997, 1998, 1999, 2000, 2005, 2008, Free Software Foundation, Inc.
  3. The GNU plotutils package is free software. You may redistribute it
  4. and/or modify it under the terms of the GNU General Public License as
  5. published by the Free Software foundation; either version 2, or (at your
  6. option) any later version.
  7. The GNU plotutils package is distributed in the hope that it will be
  8. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. General Public License for more details.
  11. You should have received a copy of the GNU General Public License along
  12. with the GNU plotutils package; see the file COPYING. If not, write to
  13. the Free Software Foundation, Inc., 51 Franklin St., Fifth Floor,
  14. Boston, MA 02110-1301, USA. */
  15. #include "sys-defines.h"
  16. #include "extern.h"
  17. /* ARGS: mask = attributes to be updated */
  18. void
  19. _pl_m_set_attributes (R___(Plotter *_plotter) unsigned int mask)
  20. {
  21. if (mask & PL_ATTR_POSITION)
  22. {
  23. if (_plotter->meta_pos.x != _plotter->drawstate->pos.x
  24. || _plotter->meta_pos.y != _plotter->drawstate->pos.y)
  25. {
  26. _pl_m_emit_op_code (R___(_plotter) O_FMOVE);
  27. _pl_m_emit_float (R___(_plotter) _plotter->drawstate->pos.x);
  28. _pl_m_emit_float (R___(_plotter) _plotter->drawstate->pos.y);
  29. _pl_m_emit_terminator (S___(_plotter));
  30. _plotter->meta_pos = _plotter->drawstate->pos;
  31. }
  32. }
  33. if (mask & PL_ATTR_TRANSFORMATION_MATRIX)
  34. {
  35. bool need_change = false;
  36. int i;
  37. for (i = 0; i < 6; i++)
  38. {
  39. if (_plotter->meta_m_user_to_ndc[i]
  40. != _plotter->drawstate->transform.m_user_to_ndc[i])
  41. {
  42. need_change = true;
  43. break;
  44. }
  45. }
  46. if (need_change)
  47. {
  48. _pl_m_emit_op_code (R___(_plotter) O_FSETMATRIX);
  49. for (i = 0; i < 6; i++)
  50. {
  51. _pl_m_emit_float (R___(_plotter) _plotter->drawstate->transform.m_user_to_ndc[i]);
  52. _plotter->meta_m_user_to_ndc[i] =
  53. _plotter->drawstate->transform.m_user_to_ndc[i];
  54. }
  55. _pl_m_emit_terminator (S___(_plotter));
  56. }
  57. }
  58. if (mask & PL_ATTR_PEN_COLOR)
  59. {
  60. if (_plotter->meta_fgcolor.red != _plotter->drawstate->fgcolor.red
  61. || _plotter->meta_fgcolor.green != _plotter->drawstate->fgcolor.green
  62. || _plotter->meta_fgcolor.blue != _plotter->drawstate->fgcolor.blue)
  63. {
  64. _pl_m_emit_op_code (R___(_plotter) O_PENCOLOR);
  65. _pl_m_emit_integer (R___(_plotter) _plotter->drawstate->fgcolor.red);
  66. _pl_m_emit_integer (R___(_plotter) _plotter->drawstate->fgcolor.green);
  67. _pl_m_emit_integer (R___(_plotter) _plotter->drawstate->fgcolor.blue);
  68. _pl_m_emit_terminator (S___(_plotter));
  69. _plotter->meta_fgcolor = _plotter->drawstate->fgcolor;
  70. }
  71. }
  72. if (mask & PL_ATTR_FILL_COLOR)
  73. {
  74. if (_plotter->meta_fillcolor_base.red != _plotter->drawstate->fillcolor_base.red
  75. || _plotter->meta_fillcolor_base.green != _plotter->drawstate->fillcolor_base.green
  76. || _plotter->meta_fillcolor_base.blue != _plotter->drawstate->fillcolor_base.blue)
  77. {
  78. _pl_m_emit_op_code (R___(_plotter) O_FILLCOLOR);
  79. _pl_m_emit_integer (R___(_plotter) _plotter->drawstate->fillcolor_base.red);
  80. _pl_m_emit_integer (R___(_plotter) _plotter->drawstate->fillcolor_base.green);
  81. _pl_m_emit_integer (R___(_plotter) _plotter->drawstate->fillcolor_base.blue);
  82. _pl_m_emit_terminator (S___(_plotter));
  83. _plotter->meta_fillcolor_base = _plotter->drawstate->fillcolor_base;
  84. }
  85. }
  86. if (mask & PL_ATTR_BG_COLOR)
  87. {
  88. if (_plotter->meta_bgcolor.red != _plotter->drawstate->bgcolor.red
  89. || _plotter->meta_bgcolor.green != _plotter->drawstate->bgcolor.green
  90. || _plotter->meta_bgcolor.blue != _plotter->drawstate->bgcolor.blue)
  91. {
  92. _pl_m_emit_op_code (R___(_plotter) O_BGCOLOR);
  93. _pl_m_emit_integer (R___(_plotter) _plotter->drawstate->bgcolor.red);
  94. _pl_m_emit_integer (R___(_plotter) _plotter->drawstate->bgcolor.green);
  95. _pl_m_emit_integer (R___(_plotter) _plotter->drawstate->bgcolor.blue);
  96. _pl_m_emit_terminator (S___(_plotter));
  97. _plotter->meta_bgcolor = _plotter->drawstate->bgcolor;
  98. }
  99. }
  100. if (mask & PL_ATTR_PEN_TYPE)
  101. {
  102. if (_plotter->meta_pen_type != _plotter->drawstate->pen_type)
  103. {
  104. _pl_m_emit_op_code (R___(_plotter) O_PENTYPE);
  105. _pl_m_emit_integer (R___(_plotter) _plotter->drawstate->pen_type);
  106. _pl_m_emit_terminator (S___(_plotter));
  107. _plotter->meta_pen_type = _plotter->drawstate->pen_type;
  108. }
  109. }
  110. if (mask & PL_ATTR_FILL_TYPE)
  111. {
  112. if (_plotter->meta_fill_type != _plotter->drawstate->fill_type)
  113. {
  114. _pl_m_emit_op_code (R___(_plotter) O_FILLTYPE);
  115. _pl_m_emit_integer (R___(_plotter) _plotter->drawstate->fill_type);
  116. _pl_m_emit_terminator (S___(_plotter));
  117. _plotter->meta_fill_type = _plotter->drawstate->fill_type;
  118. }
  119. }
  120. if (mask & PL_ATTR_LINE_STYLE)
  121. {
  122. if (_plotter->drawstate->dash_array_in_effect)
  123. /* desired line style specified by a dashing pattern */
  124. {
  125. bool array_ok = true, offset_ok = true;
  126. int i;
  127. if (_plotter->meta_dash_array_in_effect == false
  128. || (_plotter->meta_dash_array_len !=
  129. _plotter->drawstate->dash_array_len))
  130. array_ok = false;
  131. else
  132. {
  133. for (i = 0; i < _plotter->meta_dash_array_len; i++)
  134. {
  135. if (_plotter->meta_dash_array[i] !=
  136. _plotter->drawstate->dash_array[i])
  137. {
  138. array_ok = false;
  139. break;
  140. }
  141. }
  142. }
  143. if (_plotter->meta_dash_offset != _plotter->drawstate->dash_offset)
  144. offset_ok = false;
  145. if (array_ok == false || offset_ok == false)
  146. {
  147. _pl_m_emit_op_code (R___(_plotter) O_FLINEDASH);
  148. _pl_m_emit_integer (R___(_plotter)
  149. _plotter->drawstate->dash_array_len);
  150. for (i = 0; i < _plotter->drawstate->dash_array_len; i++)
  151. _pl_m_emit_float (R___(_plotter)
  152. _plotter->drawstate->dash_array[i]);
  153. _pl_m_emit_float (R___(_plotter) _plotter->drawstate->dash_offset);
  154. _pl_m_emit_terminator (S___(_plotter));
  155. if (array_ok == false)
  156. {
  157. double *new_dash_array;
  158. if (_plotter->meta_dash_array != (const double *)NULL)
  159. free ((double *)_plotter->meta_dash_array);
  160. new_dash_array = (double *)_pl_xmalloc (_plotter->drawstate->dash_array_len * sizeof (double));
  161. for (i = 0; i < _plotter->drawstate->dash_array_len; i++)
  162. new_dash_array[i] = _plotter->drawstate->dash_array[i];
  163. _plotter->meta_dash_array = new_dash_array;
  164. _plotter->meta_dash_array_len =
  165. _plotter->drawstate->dash_array_len;
  166. }
  167. if (offset_ok == false)
  168. _plotter->meta_dash_offset = _plotter->drawstate->dash_offset;
  169. _plotter->meta_dash_array_in_effect = true;
  170. }
  171. }
  172. else
  173. /* desired line style is a builtin line mode */
  174. {
  175. if (_plotter->drawstate->points_are_connected == false)
  176. /* select special "disconnected" line mode */
  177. {
  178. if (_plotter->meta_dash_array_in_effect
  179. || _plotter->meta_points_are_connected)
  180. {
  181. _pl_m_emit_op_code (R___(_plotter) O_LINEMOD);
  182. _pl_m_emit_string (R___(_plotter) "disconnected");
  183. _pl_m_emit_terminator (S___(_plotter));
  184. _plotter->meta_points_are_connected = false;
  185. _plotter->meta_line_type = PL_L_SOLID;
  186. }
  187. }
  188. else
  189. /* select a normal line mode */
  190. {
  191. if (_plotter->meta_dash_array_in_effect
  192. || _plotter->meta_points_are_connected == false
  193. || (_plotter->meta_line_type !=
  194. _plotter->drawstate->line_type))
  195. {
  196. const char *line_mode;
  197. _pl_m_emit_op_code (R___(_plotter) O_LINEMOD);
  198. switch (_plotter->drawstate->line_type)
  199. {
  200. case PL_L_SOLID:
  201. default:
  202. line_mode = "solid";
  203. break;
  204. case PL_L_DOTTED:
  205. line_mode = "dotted";
  206. break;
  207. case PL_L_DOTDASHED:
  208. line_mode = "dotdashed";
  209. break;
  210. case PL_L_SHORTDASHED:
  211. line_mode = "shortdashed";
  212. break;
  213. case PL_L_LONGDASHED:
  214. line_mode = "longdashed";
  215. break;
  216. case PL_L_DOTDOTDASHED:
  217. line_mode = "dotdotdashed";
  218. break;
  219. case PL_L_DOTDOTDOTDASHED:
  220. line_mode = "dotdotdotdashed";
  221. break;
  222. }
  223. _pl_m_emit_string (R___(_plotter) line_mode);
  224. _pl_m_emit_terminator (S___(_plotter));
  225. _plotter->meta_points_are_connected = true;
  226. _plotter->meta_line_type = _plotter->drawstate->line_type;
  227. }
  228. }
  229. /* discard current dash array if any, since we've selected a
  230. builtin line mode rather than a user-specified dashing mode */
  231. _plotter->meta_dash_array_in_effect = false;
  232. if (_plotter->meta_dash_array != (const double *)NULL)
  233. {
  234. free ((double *)_plotter->meta_dash_array);
  235. _plotter->meta_dash_array = (const double *)NULL;
  236. }
  237. }
  238. }
  239. if (mask & PL_ATTR_LINE_WIDTH)
  240. {
  241. if ((_plotter->meta_line_width_is_default == false
  242. && _plotter->drawstate->line_width_is_default == false
  243. && _plotter->meta_line_width != _plotter->drawstate->line_width)
  244. ||
  245. (_plotter->meta_line_width_is_default !=
  246. _plotter->drawstate->line_width_is_default))
  247. {
  248. _pl_m_emit_op_code (R___(_plotter) O_FLINEWIDTH);
  249. if (_plotter->drawstate->line_width_is_default)
  250. /* switch to default by emitting negative line width */
  251. _pl_m_emit_float (R___(_plotter) -1.0);
  252. else
  253. _pl_m_emit_float (R___(_plotter) _plotter->drawstate->line_width);
  254. _pl_m_emit_terminator (S___(_plotter));
  255. _plotter->meta_line_width = _plotter->drawstate->line_width;
  256. _plotter->meta_line_width_is_default =
  257. _plotter->drawstate->line_width_is_default;
  258. }
  259. }
  260. if (mask & PL_ATTR_ORIENTATION)
  261. {
  262. if (_plotter->meta_orientation != _plotter->drawstate->orientation)
  263. {
  264. _pl_m_emit_op_code (R___(_plotter) O_ORIENTATION);
  265. _pl_m_emit_integer (R___(_plotter) _plotter->drawstate->orientation);
  266. _pl_m_emit_terminator (S___(_plotter));
  267. _plotter->meta_orientation = _plotter->drawstate->orientation;
  268. }
  269. }
  270. if (mask & PL_ATTR_MITER_LIMIT)
  271. {
  272. if (_plotter->meta_miter_limit != _plotter->drawstate->miter_limit)
  273. {
  274. _pl_m_emit_op_code (R___(_plotter) O_FMITERLIMIT);
  275. _pl_m_emit_float (R___(_plotter) _plotter->drawstate->miter_limit);
  276. _pl_m_emit_terminator (S___(_plotter));
  277. _plotter->meta_miter_limit = _plotter->drawstate->miter_limit;
  278. }
  279. }
  280. if (mask & PL_ATTR_FILL_RULE)
  281. {
  282. if (_plotter->meta_fill_rule_type != _plotter->drawstate->fill_rule_type)
  283. {
  284. const char *fill_mode;
  285. _pl_m_emit_op_code (R___(_plotter) O_FILLMOD);
  286. switch (_plotter->drawstate->fill_rule_type)
  287. {
  288. case PL_FILL_ODD_WINDING:
  289. default:
  290. fill_mode = "even-odd";
  291. break;
  292. case PL_FILL_NONZERO_WINDING:
  293. fill_mode = "nonzero-winding";
  294. break;
  295. }
  296. _pl_m_emit_string (R___(_plotter) fill_mode);
  297. _pl_m_emit_terminator (S___(_plotter));
  298. _plotter->meta_fill_rule_type = _plotter->drawstate->fill_rule_type;
  299. }
  300. }
  301. if (mask & PL_ATTR_JOIN_STYLE)
  302. {
  303. if (_plotter->meta_join_type != _plotter->drawstate->join_type)
  304. {
  305. const char *join_mode;
  306. _pl_m_emit_op_code (R___(_plotter) O_JOINMOD);
  307. switch (_plotter->drawstate->join_type)
  308. {
  309. case PL_JOIN_MITER:
  310. default:
  311. join_mode = "miter";
  312. break;
  313. case PL_JOIN_ROUND:
  314. join_mode = "round";
  315. break;
  316. case PL_JOIN_BEVEL:
  317. join_mode = "bevel";
  318. break;
  319. case PL_JOIN_TRIANGULAR:
  320. join_mode = "triangular";
  321. break;
  322. }
  323. _pl_m_emit_string (R___(_plotter) join_mode);
  324. _pl_m_emit_terminator (S___(_plotter));
  325. _plotter->meta_join_type = _plotter->drawstate->join_type;
  326. }
  327. }
  328. if (mask & PL_ATTR_CAP_STYLE)
  329. {
  330. if (_plotter->meta_cap_type != _plotter->drawstate->cap_type)
  331. {
  332. const char *cap_mode;
  333. _pl_m_emit_op_code (R___(_plotter) O_CAPMOD);
  334. switch (_plotter->drawstate->cap_type)
  335. {
  336. case PL_CAP_BUTT:
  337. default:
  338. cap_mode = "butt";
  339. break;
  340. case PL_CAP_ROUND:
  341. cap_mode = "round";
  342. break;
  343. case PL_CAP_PROJECT:
  344. cap_mode = "project";
  345. break;
  346. case PL_CAP_TRIANGULAR:
  347. cap_mode = "triangular";
  348. break;
  349. }
  350. _pl_m_emit_string (R___(_plotter) cap_mode);
  351. _pl_m_emit_terminator (S___(_plotter));
  352. _plotter->meta_cap_type = _plotter->drawstate->cap_type;
  353. }
  354. }
  355. if (mask & PL_ATTR_FONT_NAME)
  356. {
  357. const char *font_name = _plotter->drawstate->font_name;
  358. if (_plotter->meta_font_name == (const char *)NULL
  359. || strcasecmp (_plotter->meta_font_name, font_name) != 0)
  360. {
  361. char *copied_font_name;
  362. copied_font_name = (char *)_pl_xmalloc (strlen (font_name) + 1);
  363. strcpy (copied_font_name, font_name);
  364. _pl_m_emit_op_code (R___(_plotter) O_FONTNAME);
  365. _pl_m_emit_string (R___(_plotter) copied_font_name);
  366. _pl_m_emit_terminator (S___(_plotter));
  367. if (_plotter->meta_font_name != (const char *)NULL)
  368. free ((char *)_plotter->meta_font_name);
  369. _plotter->meta_font_name = copied_font_name;
  370. }
  371. }
  372. if (mask & PL_ATTR_FONT_SIZE)
  373. {
  374. if ((_plotter->meta_font_size_is_default == false
  375. && _plotter->drawstate->font_size_is_default == false
  376. && _plotter->meta_font_size != _plotter->drawstate->font_size)
  377. ||
  378. (_plotter->meta_font_size_is_default !=
  379. _plotter->drawstate->font_size_is_default))
  380. {
  381. _pl_m_emit_op_code (R___(_plotter) O_FFONTSIZE);
  382. if (_plotter->drawstate->font_size_is_default)
  383. /* switch to default by emitting negative font size */
  384. _pl_m_emit_float (R___(_plotter) -1.0);
  385. else
  386. _pl_m_emit_float (R___(_plotter) _plotter->drawstate->font_size);
  387. _pl_m_emit_terminator (S___(_plotter));
  388. _plotter->meta_font_size = _plotter->drawstate->font_size;
  389. _plotter->meta_font_size_is_default =
  390. _plotter->drawstate->font_size_is_default;
  391. }
  392. }
  393. if (mask & PL_ATTR_TEXT_ANGLE)
  394. {
  395. if (_plotter->meta_text_rotation != _plotter->drawstate->text_rotation)
  396. {
  397. _pl_m_emit_op_code (R___(_plotter) O_FTEXTANGLE);
  398. _pl_m_emit_float (R___(_plotter) _plotter->drawstate->text_rotation);
  399. _pl_m_emit_terminator (S___(_plotter));
  400. _plotter->meta_text_rotation = _plotter->drawstate->text_rotation;
  401. }
  402. }
  403. }