g_mark.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  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. /* This file contains the marker method, which is a GNU extension to
  16. libplot. It plots an object: a marker, of specified size, at a
  17. specified location. This marker may be one of a list of standard
  18. symbols, or a single character in the current font.
  19. The `size' argument is expressed in terms of user coordinates. If the
  20. marker is a character, it is the font size (i.e., the em size of the
  21. font). If the marker is a symbol, the maximum dimension of the symbol
  22. will be a fixed fraction of `size'. */
  23. /* This is a generic version. Currently, it is overridden only by Metafile
  24. and CGM Plotters. */
  25. #include "sys-defines.h"
  26. #include "extern.h"
  27. /* The maximum dimension of most markers, e.g. the diameter of the circle
  28. marker (marker #4). Expressed as a fraction of the `size' argument. */
  29. #define MAXIMUM_MARKER_DIMENSION (5.0/8.0)
  30. /* Line width used while drawing marker symbols. Expressed as a fraction
  31. of the `size' argument. */
  32. #define LINE_SCALE (0.05 * MAXIMUM_MARKER_DIMENSION)
  33. /* The diameter of a `dot' (marker #1), as a fraction of the maximum marker
  34. dimension (see above). This applies only if the Plotter has a physical
  35. display, i.e. the PAGESIZE parameter is meaningful for it, or if the
  36. Plotter has a virtual display that uses real coordinates. Currently,
  37. none of our Plotters falls into the 2nd category.
  38. If the Plotter falls into neither of these two categories, we assume
  39. that fpoint() draws a single pixel, or something like it, and we use
  40. fpoint() to draw marker #1. E.g., we do so on Tektronix, GIF, PNM, X,
  41. and X Drawable displays. For them, RELATIVE_DOT_SIZE is ignored. */
  42. #define RELATIVE_DOT_SIZE 0.15
  43. /* Argument for filltype(), when we draw the half-filled marker symbols.
  44. (This isn't exactly half, but it looks better than half.) */
  45. #define NOMINAL_HALF 0xa000
  46. int
  47. _API_fmarker (R___(Plotter *_plotter) double x, double y, int type, double size)
  48. {
  49. bool drawn;
  50. char label_buf[2];
  51. double x_dev, y_dev, delta_x_dev, delta_y_dev;
  52. double delta_x_user = 0.0, delta_y_user = 0.0;
  53. if (!_plotter->data->open)
  54. {
  55. _plotter->error (R___(_plotter)
  56. "fmarker: invalid operation");
  57. return -1;
  58. }
  59. _API_endpath (S___(_plotter)); /* flush path if any */
  60. /* update our notion of position */
  61. _plotter->drawstate->pos.x = x;
  62. _plotter->drawstate->pos.y = y;
  63. if (_plotter->drawstate->pen_type == 0)
  64. /* no pen to draw with, so do nothing */
  65. return 0;
  66. /* attempt to draw marker in a Plotter-specific way */
  67. drawn = _plotter->paint_marker (R___(_plotter) type, size);
  68. if (drawn)
  69. return 0;
  70. /* Plotter couldn't do it, so draw the marker in a generic way, by
  71. constructing it from other libplot primitives. */
  72. if (type < 0) /* silently return if marker type < 0 */
  73. return 0;
  74. type %= 256; /* compute marker type mod 256 */
  75. /* begin by saving drawing attributes we may change */
  76. _API_savestate (S___(_plotter));
  77. if (_plotter->data->display_coors_type != (int)DISP_DEVICE_COORS_REAL)
  78. /* move temporarily to nearest point with integer device coordinates,
  79. so that marker will be symmetrically positioned */
  80. {
  81. x_dev = XD(x, y);
  82. y_dev = YD(x, y);
  83. delta_x_dev = IROUND(x_dev) - x_dev;
  84. delta_y_dev = IROUND(y_dev) - y_dev;
  85. delta_x_user = XUV(delta_x_dev, delta_y_dev);
  86. delta_y_user = YUV(delta_x_dev, delta_y_dev);
  87. _plotter->drawstate->pos.x += delta_x_user;
  88. _plotter->drawstate->pos.y += delta_y_user;
  89. }
  90. if (type > 31)
  91. /* plot a single character, in current font */
  92. {
  93. _API_pentype (R___(_plotter) 1);
  94. _API_ffontsize (R___(_plotter) size);
  95. _API_textangle (R___(_plotter) 0);
  96. label_buf[0] = (char)type;
  97. label_buf[1] = '\0';
  98. _API_alabel (R___(_plotter) 'c', 'c', label_buf);
  99. }
  100. else
  101. /* plot a handcrafted marker symbol */
  102. {
  103. _API_pentype (R___(_plotter) 1);
  104. _API_linemod (R___(_plotter) "solid");
  105. _API_capmod (R___(_plotter) "butt");
  106. _API_joinmod (R___(_plotter) "miter");
  107. _API_flinewidth (R___(_plotter) LINE_SCALE * size);
  108. _API_fillcolor (R___(_plotter)
  109. _plotter->drawstate->fgcolor.red,
  110. _plotter->drawstate->fgcolor.green,
  111. _plotter->drawstate->fgcolor.blue);
  112. /* beautification kludge: if display is a bitmap device using libxmi
  113. or a compatible scan-conversion scheme, and line thickness is one
  114. pixel or less, but not zero, then change it to zero thickess
  115. (which will be interpreted as specifying a Bresenham line). */
  116. if ((_plotter->data->display_coors_type ==
  117. (int)DISP_DEVICE_COORS_INTEGER_LIBXMI)
  118. && _plotter->drawstate->quantized_device_line_width == 1)
  119. _API_flinewidth (R___(_plotter) 0.0);
  120. size *= (0.5 * MAXIMUM_MARKER_DIMENSION);
  121. switch (type)
  122. /* N.B. 5-pointed star should be added some day */
  123. {
  124. case (int)M_NONE: /* no-op */
  125. default:
  126. break;
  127. case (int)M_DOT: /* dot, GKS 1 */
  128. if (_plotter->data->display_model_type == (int)DISP_MODEL_PHYSICAL
  129. ||
  130. _plotter->data->display_coors_type ==(int)DISP_DEVICE_COORS_REAL)
  131. {
  132. _API_filltype (R___(_plotter) 1);
  133. _API_fcirclerel (R___(_plotter) 0.0, 0.0,
  134. RELATIVE_DOT_SIZE * size);
  135. }
  136. else /* see comment above */
  137. _API_fpointrel (R___(_plotter) 0.0, 0.0);
  138. break;
  139. case (int)M_PLUS: /* plus, GKS 2 */
  140. _API_fmoverel (R___(_plotter) -size, 0.0);
  141. _API_fcontrel (R___(_plotter) 2 * size, 0.0);
  142. _API_fmoverel (R___(_plotter) -size, -size);
  143. _API_fcontrel (R___(_plotter) 0.0, 2 * size);
  144. _API_fmoverel (R___(_plotter) 0.0, -size);
  145. break;
  146. case (int)M_ASTERISK: /* asterisk, GKS 3 */
  147. {
  148. double vert = 0.5 * size;
  149. double hori = 0.5 * M_SQRT3 * size;
  150. _API_fmoverel (R___(_plotter) 0.0, -size);
  151. _API_fcontrel (R___(_plotter) 0.0, 2 * size);
  152. _API_fmoverel (R___(_plotter) 0.0, -size);
  153. _API_fcontrel (R___(_plotter) hori, vert);
  154. _API_fmoverel (R___(_plotter) -hori, -vert);
  155. _API_fcontrel (R___(_plotter) -hori, -vert);
  156. _API_fmoverel (R___(_plotter) hori, vert);
  157. _API_fcontrel (R___(_plotter) hori, -vert);
  158. _API_fmoverel (R___(_plotter) -hori, vert);
  159. _API_fcontrel (R___(_plotter) -hori, vert);
  160. _API_fmoverel (R___(_plotter) hori, -vert);
  161. }
  162. break;
  163. case (int)M_CIRCLE: /* circle, GKS 4 */
  164. _API_filltype (R___(_plotter) 0);
  165. _API_fcirclerel (R___(_plotter) 0.0, 0.0, size);
  166. break;
  167. case (int)M_CROSS: /* cross, GKS 5 */
  168. _API_fmoverel (R___(_plotter) -size, -size);
  169. _API_fcontrel (R___(_plotter) 2 * size, 2 * size);
  170. _API_fmoverel (R___(_plotter) 0.0, - 2 * size);
  171. _API_fcontrel (R___(_plotter) -2 * size, 2 * size);
  172. _API_fmoverel (R___(_plotter) size, -size);
  173. break;
  174. case (int)M_STAR: /* star */
  175. _API_fmoverel (R___(_plotter) -size, 0.0);
  176. _API_fcontrel (R___(_plotter) 2 * size, 0.0);
  177. _API_fmoverel (R___(_plotter) -size, -size);
  178. _API_fcontrel (R___(_plotter) 0.0, 2 * size);
  179. _API_fmoverel (R___(_plotter) 0.0, -size);
  180. _API_fcontrel (R___(_plotter) size, size);
  181. _API_fmoverel (R___(_plotter) -size, -size);
  182. _API_fcontrel (R___(_plotter) size, -size);
  183. _API_fmoverel (R___(_plotter) -size, size);
  184. _API_fcontrel (R___(_plotter) -size, size);
  185. _API_fmoverel (R___(_plotter) size, -size);
  186. _API_fcontrel (R___(_plotter) -size, -size);
  187. _API_fmoverel (R___(_plotter) size, size);
  188. break;
  189. case (int)M_SQUARE: /* square */
  190. _API_filltype (R___(_plotter) 0);
  191. _API_fboxrel (R___(_plotter) -size, -size, size, size);
  192. _API_fmoverel (R___(_plotter) -size, -size);
  193. break;
  194. case (int)M_DIAMOND: /* diamond */
  195. _API_filltype (R___(_plotter) 0);
  196. _API_fmoverel (R___(_plotter) size, 0.0);
  197. _API_fcontrel (R___(_plotter) -size, size);
  198. _API_fcontrel (R___(_plotter) -size, -size);
  199. _API_fcontrel (R___(_plotter) size, -size);
  200. _API_fcontrel (R___(_plotter) size, size);
  201. _API_fmoverel (R___(_plotter) -size, 0.0);
  202. break;
  203. case (int)M_TRIANGLE: /* triangle */
  204. {
  205. double halfwidth = 0.5 * M_SQRT3 * size;
  206. _API_filltype (R___(_plotter) 0);
  207. _API_fmoverel (R___(_plotter) 0.0, size);
  208. _API_fcontrel (R___(_plotter) halfwidth, -1.5 * size);
  209. _API_fcontrel (R___(_plotter) -2 * halfwidth, 0.0);
  210. _API_fcontrel (R___(_plotter) halfwidth, 1.5 * size);
  211. _API_fmoverel (R___(_plotter) 0.0, -size);
  212. }
  213. break;
  214. case (int)M_INVERTED_TRIANGLE: /* triangle, vertex down */
  215. {
  216. double halfwidth = 0.5 * M_SQRT3 * size;
  217. _API_filltype (R___(_plotter) 0);
  218. _API_fmoverel (R___(_plotter) 0.0, -size);
  219. _API_fcontrel (R___(_plotter) halfwidth, 1.5 * size);
  220. _API_fcontrel (R___(_plotter) -2 * halfwidth, 0.0);
  221. _API_fcontrel (R___(_plotter) halfwidth, -1.5 * size);
  222. _API_fmoverel (R___(_plotter) 0.0, size);
  223. }
  224. break;
  225. case (int)M_FILLED_SQUARE: /* filled square */
  226. _API_filltype (R___(_plotter) 1);
  227. _API_fboxrel (R___(_plotter) -size, -size, size, size);
  228. _API_fmoverel (R___(_plotter) -size, -size);
  229. break;
  230. case (int)M_FILLED_DIAMOND: /* filled diamond */
  231. _API_filltype (R___(_plotter) 1);
  232. _API_fmoverel (R___(_plotter) 0.0, -size);
  233. _API_fcontrel (R___(_plotter) size, size);
  234. _API_fcontrel (R___(_plotter) -size, size);
  235. _API_fcontrel (R___(_plotter) -size, -size);
  236. _API_fcontrel (R___(_plotter) size, -size);
  237. _API_fmoverel (R___(_plotter) 0.0, size);
  238. break;
  239. case (int)M_FILLED_TRIANGLE: /* filled triangle */
  240. {
  241. double halfwidth = 0.5 * M_SQRT3 * size;
  242. _API_filltype (R___(_plotter) 1);
  243. _API_fmoverel (R___(_plotter) 0.0, size);
  244. _API_fcontrel (R___(_plotter) halfwidth, -1.5 * size);
  245. _API_fcontrel (R___(_plotter) -2 * halfwidth, 0.0);
  246. _API_fcontrel (R___(_plotter) halfwidth, 1.5 * size);
  247. _API_fmoverel (R___(_plotter) 0.0, -size);
  248. }
  249. break;
  250. case (int)M_FILLED_INVERTED_TRIANGLE: /* filled triangle, vertex down*/
  251. {
  252. double halfwidth = 0.5 * M_SQRT3 * size;
  253. _API_filltype (R___(_plotter) 1);
  254. _API_fmoverel (R___(_plotter) 0.0, -size);
  255. _API_fcontrel (R___(_plotter) halfwidth, 1.5 * size);
  256. _API_fcontrel (R___(_plotter) -2 * halfwidth, 0.0);
  257. _API_fcontrel (R___(_plotter) halfwidth, -1.5 * size);
  258. _API_fmoverel (R___(_plotter) 0.0, size);
  259. }
  260. break;
  261. case (int)M_FILLED_CIRCLE: /* filled circle */
  262. _API_filltype (R___(_plotter) 1);
  263. _API_fcirclerel (R___(_plotter) 0.0, 0.0, size);
  264. break;
  265. case (int)M_STARBURST: /* starburst */
  266. _API_fmoverel (R___(_plotter) -0.5 * size, 0.0);
  267. _API_fcontrel (R___(_plotter) -0.5 * size, 0.0);
  268. _API_fmoverel (R___(_plotter) 0.0, -size);
  269. _API_fcontrel (R___(_plotter) 0.5 * size, 0.5 * size);
  270. _API_fmoverel (R___(_plotter) 0.5 * size, 0.0);
  271. _API_fcontrel (R___(_plotter) 0.0, -0.5 * size);
  272. _API_fmoverel (R___(_plotter) size, 0.0);
  273. _API_fcontrel (R___(_plotter) -0.5 * size, 0.5 * size);
  274. _API_fmoverel (R___(_plotter) 0.0, 0.5 * size);
  275. _API_fcontrel (R___(_plotter) 0.5 * size, 0.0);
  276. _API_fmoverel (R___(_plotter) 0.0, size);
  277. _API_fcontrel (R___(_plotter) -0.5 * size, -0.5 * size);
  278. _API_fmoverel (R___(_plotter) -0.5 * size, 0.0);
  279. _API_fcontrel (R___(_plotter) 0.0, 0.5 * size);
  280. _API_fmoverel (R___(_plotter) -size, 0.0);
  281. _API_fcontrel (R___(_plotter) 0.5 * size, -0.5 * size);
  282. _API_fmoverel (R___(_plotter) 0.5 * size, -0.5 * size);
  283. break;
  284. case (int)M_FANCY_PLUS: /* ornate plus */
  285. _API_fmoverel (R___(_plotter) -size, 0.0);
  286. _API_fcontrel (R___(_plotter) 2 * size, 0.0);
  287. _API_fmoverel (R___(_plotter) -size, -size);
  288. _API_fcontrel (R___(_plotter) 0.0, 2 * size);
  289. _API_fmoverel (R___(_plotter) 0.5 * size, 0.0);
  290. _API_fcontrel (R___(_plotter) -size, 0.0);
  291. _API_fmoverel (R___(_plotter) -0.5 * size, -0.5 * size);
  292. _API_fcontrel (R___(_plotter) 0.0, -size);
  293. _API_fmoverel (R___(_plotter) 0.5 * size, -0.5 * size);
  294. _API_fcontrel (R___(_plotter) size, 0.0);
  295. _API_fmoverel (R___(_plotter) 0.5 * size, 0.5 * size);
  296. _API_fcontrel (R___(_plotter) 0.0, size);
  297. _API_fmoverel (R___(_plotter) -size, 0.0);
  298. break;
  299. case (int)M_FANCY_CROSS: /* ornate cross */
  300. _API_fmoverel (R___(_plotter) -size, -size);
  301. _API_fcontrel (R___(_plotter) 2 * size, 2 * size);
  302. _API_fmoverel (R___(_plotter) 0.0, -2 * size);
  303. _API_fcontrel (R___(_plotter) -2 * size, 2 * size);
  304. _API_fmoverel (R___(_plotter) 2 * size, -0.5 * size);
  305. _API_fcontrel (R___(_plotter) -0.5 * size, 0.5 * size);
  306. _API_fmoverel (R___(_plotter) -size, 0.0);
  307. _API_fcontrel (R___(_plotter) -0.5 * size, -0.5 * size);
  308. _API_fmoverel (R___(_plotter) 0.0, -size);
  309. _API_fcontrel (R___(_plotter) 0.5 * size, -0.5 * size);
  310. _API_fmoverel (R___(_plotter) size, 0.0);
  311. _API_fcontrel (R___(_plotter) 0.5 * size, 0.5 * size);
  312. _API_fmoverel (R___(_plotter) -size, 0.5 * size);
  313. break;
  314. case (int)M_FANCY_SQUARE: /* ornate square */
  315. _API_filltype (R___(_plotter) 0);
  316. _API_fboxrel (R___(_plotter) -0.5 * size, -0.5 * size, 0.5 * size, 0.5 * size);
  317. _API_fmoverel (R___(_plotter) 0.5 * size, 0.5 * size);
  318. _API_fcontrel (R___(_plotter) 0.5 * size, 0.5 * size);
  319. _API_fmoverel (R___(_plotter) -1.5 * size, -1.5 * size);
  320. _API_fcontrel (R___(_plotter) -0.5 * size, -0.5 * size);
  321. _API_fmoverel (R___(_plotter) 1.5 * size, 0.5 * size);
  322. _API_fcontrel (R___(_plotter) 0.5 * size, -0.5 * size);
  323. _API_fmoverel (R___(_plotter) -1.5 * size, 1.5 * size);
  324. _API_fcontrel (R___(_plotter) -0.5 * size, 0.5 * size);
  325. _API_fmoverel (R___(_plotter) 1.5 * size, -1.5 * size);
  326. break;
  327. case (int)M_FANCY_DIAMOND: /* diamond */
  328. _API_filltype (R___(_plotter) 0);
  329. _API_fmoverel (R___(_plotter) 0.5 * size, 0.0);
  330. _API_fcontrel (R___(_plotter) -0.5 * size, 0.5 * size);
  331. _API_fcontrel (R___(_plotter) -0.5 * size, -0.5 * size);
  332. _API_fcontrel (R___(_plotter) 0.5 * size, -0.5 * size);
  333. _API_fcontrel (R___(_plotter) 0.5 * size, 0.5 * size);
  334. _API_endpath (S___(_plotter));
  335. _API_fcontrel (R___(_plotter) 0.5 * size, 0.0);
  336. _API_fmoverel (R___(_plotter) -size, 0.5 * size);
  337. _API_fcontrel (R___(_plotter) 0.0, 0.5 * size);
  338. _API_fmoverel (R___(_plotter) -0.5 * size, -size);
  339. _API_fcontrel (R___(_plotter) -0.5 * size, 0.0);
  340. _API_fmoverel (R___(_plotter) size, -0.5 * size);
  341. _API_fcontrel (R___(_plotter) 0.0, -0.5 * size);
  342. _API_fmoverel (R___(_plotter) 0.0, size);
  343. break;
  344. case (int)M_FILLED_FANCY_SQUARE: /* filled ornate square */
  345. _API_filltype (R___(_plotter) 1);
  346. _API_fboxrel (R___(_plotter) -0.5 * size, -0.5 * size, 0.5 * size, 0.5 * size);
  347. _API_fmoverel (R___(_plotter) 0.5 * size, 0.5 * size);
  348. _API_fcontrel (R___(_plotter) 0.5 * size, 0.5 * size);
  349. _API_fmoverel (R___(_plotter) -1.5 * size, -1.5 * size);
  350. _API_fcontrel (R___(_plotter) -0.5 * size, -0.5 * size);
  351. _API_fmoverel (R___(_plotter) 1.5 * size, 0.5 * size);
  352. _API_fcontrel (R___(_plotter) 0.5 * size, -0.5 * size);
  353. _API_fmoverel (R___(_plotter) -1.5 * size, 1.5 * size);
  354. _API_fcontrel (R___(_plotter) -0.5 * size, 0.5 * size);
  355. _API_fmoverel (R___(_plotter) 1.5 * size, -1.5 * size);
  356. break;
  357. case (int)M_FILLED_FANCY_DIAMOND: /* filled ornate diamond */
  358. _API_filltype (R___(_plotter) 1);
  359. _API_fmoverel (R___(_plotter) 0.5 * size, 0.0);
  360. _API_fcontrel (R___(_plotter) -0.5 * size, 0.5 * size);
  361. _API_fcontrel (R___(_plotter) -0.5 * size, -0.5 * size);
  362. _API_fcontrel (R___(_plotter) 0.5 * size, -0.5 * size);
  363. _API_fcontrel (R___(_plotter) 0.5 * size, 0.5 * size);
  364. _API_endpath (S___(_plotter));
  365. _API_fcontrel (R___(_plotter) 0.5 * size, 0.0);
  366. _API_fmoverel (R___(_plotter) -size, 0.5 * size);
  367. _API_fcontrel (R___(_plotter) 0.0, 0.5 * size);
  368. _API_fmoverel (R___(_plotter) -0.5 * size, -size);
  369. _API_fcontrel (R___(_plotter) -0.5 * size, 0.0);
  370. _API_fmoverel (R___(_plotter) size, -0.5 * size);
  371. _API_fcontrel (R___(_plotter) 0.0, -0.5 * size);
  372. _API_fmoverel (R___(_plotter) 0.0, size);
  373. break;
  374. case (int)M_HALF_FILLED_SQUARE: /* half_filled square */
  375. _API_filltype (R___(_plotter) NOMINAL_HALF);
  376. _API_fboxrel (R___(_plotter) -size, -size, size, size);
  377. _API_fmoverel (R___(_plotter) -size, -size);
  378. break;
  379. case (int)M_HALF_FILLED_DIAMOND: /* half_filled diamond */
  380. _API_filltype (R___(_plotter) NOMINAL_HALF);
  381. _API_fmoverel (R___(_plotter) 0.0, -size);
  382. _API_fcontrel (R___(_plotter) size, size);
  383. _API_fcontrel (R___(_plotter) -size, size);
  384. _API_fcontrel (R___(_plotter) -size, -size);
  385. _API_fcontrel (R___(_plotter) size, -size);
  386. _API_fmoverel (R___(_plotter) 0.0, size);
  387. break;
  388. case (int)M_HALF_FILLED_TRIANGLE: /* half_filled triangle */
  389. {
  390. double halfwidth = 0.5 * M_SQRT3 * size;
  391. _API_filltype (R___(_plotter) NOMINAL_HALF);
  392. _API_fmoverel (R___(_plotter) 0.0, size);
  393. _API_fcontrel (R___(_plotter) halfwidth, -1.5 * size);
  394. _API_fcontrel (R___(_plotter) -2 * halfwidth, 0.0);
  395. _API_fcontrel (R___(_plotter) halfwidth, 1.5 * size);
  396. _API_fmoverel (R___(_plotter) 0.0, -size);
  397. }
  398. break;
  399. case (int)M_HALF_FILLED_INVERTED_TRIANGLE: /* half_filled triangle, vertex down */
  400. {
  401. double halfwidth = 0.5 * M_SQRT3 * size;
  402. _API_filltype (R___(_plotter) NOMINAL_HALF);
  403. _API_fmoverel (R___(_plotter) 0.0, -size);
  404. _API_fcontrel (R___(_plotter) halfwidth, 1.5 * size);
  405. _API_fcontrel (R___(_plotter) -2 * halfwidth, 0.0);
  406. _API_fcontrel (R___(_plotter) halfwidth, -1.5 * size);
  407. _API_fmoverel (R___(_plotter) 0.0, size);
  408. }
  409. break;
  410. case (int)M_HALF_FILLED_CIRCLE: /* half_filled circle */
  411. _API_filltype (R___(_plotter) NOMINAL_HALF);
  412. _API_fcirclerel (R___(_plotter) 0.0, 0.0, size);
  413. break;
  414. case (int)M_HALF_FILLED_FANCY_SQUARE: /* half-filled ornate square */
  415. _API_filltype (R___(_plotter) NOMINAL_HALF);
  416. _API_fboxrel (R___(_plotter) -0.5 * size, -0.5 * size, 0.5 * size, 0.5 * size);
  417. _API_fmoverel (R___(_plotter) 0.5 * size, 0.5 * size);
  418. _API_fcontrel (R___(_plotter) 0.5 * size, 0.5 * size);
  419. _API_fmoverel (R___(_plotter) -1.5 * size, -1.5 * size);
  420. _API_fcontrel (R___(_plotter) -0.5 * size, -0.5 * size);
  421. _API_fmoverel (R___(_plotter) 1.5 * size, 0.5 * size);
  422. _API_fcontrel (R___(_plotter) 0.5 * size, -0.5 * size);
  423. _API_fmoverel (R___(_plotter) -1.5 * size, 1.5 * size);
  424. _API_fcontrel (R___(_plotter) -0.5 * size, 0.5 * size);
  425. _API_fmoverel (R___(_plotter) 1.5 * size, -1.5 * size);
  426. break;
  427. case (int)M_HALF_FILLED_FANCY_DIAMOND: /* half-filled ornate diamond */
  428. _API_filltype (R___(_plotter) NOMINAL_HALF);
  429. _API_fmoverel (R___(_plotter) 0.5 * size, 0.0);
  430. _API_fcontrel (R___(_plotter) -0.5 * size, 0.5 * size);
  431. _API_fcontrel (R___(_plotter) -0.5 * size, -0.5 * size);
  432. _API_fcontrel (R___(_plotter) 0.5 * size, -0.5 * size);
  433. _API_fcontrel (R___(_plotter) 0.5 * size, 0.5 * size);
  434. _API_endpath (S___(_plotter));
  435. _API_fcontrel (R___(_plotter) 0.5 * size, 0.0);
  436. _API_fmoverel (R___(_plotter) -size, 0.5 * size);
  437. _API_fcontrel (R___(_plotter) 0.0, 0.5 * size);
  438. _API_fmoverel (R___(_plotter) -0.5 * size, -size);
  439. _API_fcontrel (R___(_plotter) -0.5 * size, 0.0);
  440. _API_fmoverel (R___(_plotter) size, -0.5 * size);
  441. _API_fcontrel (R___(_plotter) 0.0, -0.5 * size);
  442. _API_fmoverel (R___(_plotter) 0.0, size);
  443. break;
  444. case (int)M_OCTAGON: /* octagon */
  445. _API_filltype (R___(_plotter) 0);
  446. _API_fmoverel (R___(_plotter) -size, 0.5 * size);
  447. _API_fcontrel (R___(_plotter) 0.0, -size);
  448. _API_fcontrel (R___(_plotter) 0.5 * size, -0.5 * size);
  449. _API_fcontrel (R___(_plotter) size, 0.0);
  450. _API_fcontrel (R___(_plotter) 0.5 * size, 0.5 * size);
  451. _API_fcontrel (R___(_plotter) 0.0, size);
  452. _API_fcontrel (R___(_plotter) -0.5 * size, 0.5 * size);
  453. _API_fcontrel (R___(_plotter) -size, 0.0);
  454. _API_fcontrel (R___(_plotter) -0.5 * size, -0.5 * size);
  455. _API_fmoverel (R___(_plotter) size, -0.5 * size);
  456. break;
  457. case (int)M_FILLED_OCTAGON: /* filled octagon */
  458. _API_filltype (R___(_plotter) 1);
  459. _API_fmoverel (R___(_plotter) -size, 0.5 * size);
  460. _API_fcontrel (R___(_plotter) 0.0, -size);
  461. _API_fcontrel (R___(_plotter) 0.5 * size, -0.5 * size);
  462. _API_fcontrel (R___(_plotter) size, 0.0);
  463. _API_fcontrel (R___(_plotter) 0.5 * size, 0.5 * size);
  464. _API_fcontrel (R___(_plotter) 0.0, size);
  465. _API_fcontrel (R___(_plotter) -0.5 * size, 0.5 * size);
  466. _API_fcontrel (R___(_plotter) -size, 0.0);
  467. _API_fcontrel (R___(_plotter) -0.5 * size, -0.5 * size);
  468. _API_fmoverel (R___(_plotter) size, -0.5 * size);
  469. break;
  470. }
  471. }
  472. if (_plotter->data->display_coors_type != (int)DISP_DEVICE_COORS_REAL)
  473. /* undo the small repositioning (see above) */
  474. {
  475. _plotter->drawstate->pos.x -= delta_x_user;
  476. _plotter->drawstate->pos.y -= delta_y_user;
  477. }
  478. /* restore the original values of all drawing attributes */
  479. _API_restorestate (S___(_plotter));
  480. return 0;
  481. }
  482. /* The paint_marker method, which is an internal function that is called
  483. when the marker() method is invoked. It plots an object: a marker of a
  484. specified type, at a specified size, at the current location.
  485. If this returns `false', marker() will construct the marker from other
  486. libplot primitives, in a generic way. */
  487. /* Nearly all Plotters use this version, which does nothing but returns
  488. `false'. */
  489. bool
  490. _pl_g_paint_marker (R___(Plotter *_plotter) int type, double size)
  491. {
  492. return false;
  493. }