PageRenderTime 80ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/ATF2/control-software/epics-3.14.10/extensions/src/edm/pvFactory/SciPlot.c

http://atf2flightsim.googlecode.com/
C | 2143 lines | 1831 code | 234 blank | 78 comment | 238 complexity | 90323d5e806635f00d9f428b1389fdbf MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-2.0, IPL-1.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. /*----------------------------------------------------------------------------
  2. * SciPlot A generalized plotting widget
  3. *
  4. * Copyright (c) 1996 Robert W. McMullen
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Library General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Library General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Library General Public
  17. * License along with this library; if not, write to the Free
  18. * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. *
  20. *
  21. * Author: Rob McMullen <rwmcm@mail.ae.utexas.edu>
  22. * http://www.ae.utexas.edu/~rwmcm
  23. *
  24. * Modifications (KUK): Double-buffering, seperate Text color
  25. */
  26. #include <X11/IntrinsicP.h>
  27. #include <X11/StringDefs.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include "SciPlotP.h"
  31. #define offset(field) XtOffsetOf(SciPlotRec, plot.field)
  32. static XtResource resources[] =
  33. {
  34. {XtNchartType, XtCMargin, XtRInt, sizeof(int),
  35. offset(ChartType), XtRImmediate, (XtPointer) XtCARTESIAN},
  36. {XtNdegrees, XtCBoolean, XtRBoolean, sizeof(Boolean),
  37. offset(Degrees), XtRImmediate, (XtPointer) True},
  38. {XtNdrawMajor, XtCBoolean, XtRBoolean, sizeof(Boolean),
  39. offset(DrawMajor), XtRImmediate, (XtPointer) True},
  40. {XtNdrawMajorTics, XtCBoolean, XtRBoolean, sizeof(Boolean),
  41. offset(DrawMajorTics), XtRImmediate, (XtPointer) True},
  42. {XtNdrawMinor, XtCBoolean, XtRBoolean, sizeof(Boolean),
  43. offset(DrawMinor), XtRImmediate, (XtPointer) True},
  44. {XtNdrawMinorTics, XtCBoolean, XtRBoolean, sizeof(Boolean),
  45. offset(DrawMinorTics), XtRImmediate, (XtPointer) True},
  46. {XtNmonochrome, XtCBoolean, XtRBoolean, sizeof(Boolean),
  47. offset(Monochrome), XtRImmediate, (XtPointer) False},
  48. {XtNshowLegend, XtCBoolean, XtRBoolean, sizeof(Boolean),
  49. offset(ShowLegend), XtRImmediate, (XtPointer) True},
  50. {XtNshowTitle, XtCBoolean, XtRBoolean, sizeof(Boolean),
  51. offset(ShowTitle), XtRImmediate, (XtPointer) True},
  52. {XtNshowXLabel, XtCBoolean, XtRBoolean, sizeof(Boolean),
  53. offset(ShowXLabel), XtRImmediate, (XtPointer) True},
  54. {XtNshowYLabel, XtCBoolean, XtRBoolean, sizeof(Boolean),
  55. offset(ShowYLabel), XtRImmediate, (XtPointer) True},
  56. {XtNxLabel, XtCString, XtRString, sizeof(String),
  57. offset(TransientXLabel), XtRString, "X Axis"},
  58. {XtNyLabel, XtCString, XtRString, sizeof(String),
  59. offset(TransientYLabel), XtRString, "Y Axis"},
  60. {XtNplotTitle, XtCString, XtRString, sizeof(String),
  61. offset(TransientPlotTitle), XtRString, "Plot"},
  62. {XtNmargin, XtCMargin, XtRInt, sizeof(int),
  63. offset(Margin), XtRImmediate, (XtPointer) 5},
  64. {XtNtitleMargin, XtCMargin, XtRInt, sizeof(int),
  65. offset(TitleMargin), XtRImmediate, (XtPointer) 16},
  66. {XtNlegendLineSize, XtCMargin, XtRInt, sizeof(int),
  67. offset(LegendLineSize), XtRImmediate, (XtPointer) 16},
  68. {XtNdefaultMarkerSize, XtCMargin, XtRInt, sizeof(int),
  69. offset(DefaultMarkerSize), XtRImmediate, (XtPointer) 3},
  70. {XtNlegendMargin, XtCMargin, XtRInt, sizeof(int),
  71. offset(LegendMargin), XtRImmediate, (XtPointer) 3},
  72. {XtNlegendThroughPlot, XtCBoolean, XtRBoolean, sizeof(Boolean),
  73. offset(LegendThroughPlot), XtRImmediate, (XtPointer) False},
  74. {XtNtitleFont, XtCMargin, XtRInt, sizeof(int),
  75. offset(TitleFont), XtRImmediate, (XtPointer) (XtFONT_HELVETICA | 24)},
  76. {XtNlabelFont, XtCMargin, XtRInt, sizeof(int),
  77. offset(LabelFont), XtRImmediate, (XtPointer) (XtFONT_TIMES | 18)},
  78. {XtNaxisFont, XtCMargin, XtRInt, sizeof(int),
  79. offset(AxisFont), XtRImmediate, (XtPointer) (XtFONT_TIMES | 10)},
  80. {XtNxAutoScale, XtCBoolean, XtRBoolean, sizeof(Boolean),
  81. offset(XAutoScale), XtRImmediate, (XtPointer) True},
  82. {XtNyAutoScale, XtCBoolean, XtRBoolean, sizeof(Boolean),
  83. offset(YAutoScale), XtRImmediate, (XtPointer) True},
  84. {XtNxAxisNumbers, XtCBoolean, XtRBoolean, sizeof(Boolean),
  85. offset(XAxisNumbers), XtRImmediate, (XtPointer) True},
  86. {XtNyAxisNumbers, XtCBoolean, XtRBoolean, sizeof(Boolean),
  87. offset(YAxisNumbers), XtRImmediate, (XtPointer) True},
  88. {XtNxLog, XtCBoolean, XtRBoolean, sizeof(Boolean),
  89. offset(XLog), XtRImmediate, (XtPointer) False},
  90. {XtNyLog, XtCBoolean, XtRBoolean, sizeof(Boolean),
  91. offset(YLog), XtRImmediate, (XtPointer) False},
  92. {XtNxOrigin, XtCBoolean, XtRBoolean, sizeof(Boolean),
  93. offset(XOrigin), XtRImmediate, (XtPointer) False},
  94. {XtNyOrigin, XtCBoolean, XtRBoolean, sizeof(Boolean),
  95. offset(YOrigin), XtRImmediate, (XtPointer) False},
  96. {XtNyNumbersHorizontal, XtCBoolean, XtRBoolean, sizeof(Boolean),
  97. offset(YNumHorz), XtRImmediate, (XtPointer) True},
  98. };
  99. static SciPlotFontDesc font_desc_table[] =
  100. {
  101. {XtFONT_TIMES, "Times", "times", False, True},
  102. {XtFONT_COURIER, "Courier", "courier", True, False},
  103. {XtFONT_HELVETICA, "Helvetica", "helvetica", True, False},
  104. {XtFONT_LUCIDA, "Lucida", "lucidabright", False, False},
  105. {XtFONT_LUCIDASANS, "LucidaSans", "lucida", False, False},
  106. {XtFONT_NCSCHOOLBOOK, "NewCenturySchlbk",
  107. "new century schoolbook", False, True},
  108. {-1, NULL, NULL, False, False},
  109. };
  110. /*
  111. * Private function declarations
  112. */
  113. static void Redisplay();
  114. static void Resize();
  115. static Boolean SetValues();
  116. static void GetValuesHook();
  117. static void Initialize();
  118. static void Realize();
  119. static void Destroy();
  120. static void ComputeAll();
  121. static void ComputeAllDimensions();
  122. static void DrawAll();
  123. static void ItemDrawAll();
  124. static void ItemDraw();
  125. static void EraseAll();
  126. static void FontInit();
  127. static int ColorStore(SciPlotWidget w, Pixel color);
  128. static int FontStore();
  129. static int FontnumReplace();
  130. SciPlotClassRec sciplotClassRec =
  131. {
  132. {
  133. /* core_class fields */
  134. #ifdef MOTIF
  135. /* superclass */ (WidgetClass) & xmPrimitiveClassRec,
  136. #else
  137. /* superclass */ (WidgetClass) & widgetClassRec,
  138. #endif
  139. /* class_name */ "SciPlot",
  140. /* widget_size */ sizeof(SciPlotRec),
  141. /* class_initialize */ NULL,
  142. /* class_part_initialize */ NULL,
  143. /* class_inited */ False,
  144. /* initialize */ Initialize,
  145. /* initialize_hook */ NULL,
  146. /* realize */ Realize,
  147. /* actions */ NULL,
  148. /* num_actions */ 0,
  149. /* resources */ resources,
  150. /* num_resources */ XtNumber(resources),
  151. /* xrm_class */ NULLQUARK,
  152. /* compress_motion */ True,
  153. /* compress_exposure */ XtExposeCompressMultiple,
  154. /* compress_enterleave */ True,
  155. /* visible_interest */ True,
  156. /* destroy */ Destroy,
  157. /* resize */ Resize,
  158. /* expose */ Redisplay,
  159. /* set_values */ SetValues,
  160. /* set_values_hook */ NULL,
  161. /* set_values_almost */ XtInheritSetValuesAlmost,
  162. /* get_values_hook */ GetValuesHook,
  163. /* accept_focus */ NULL,
  164. /* version */ XtVersion,
  165. /* callback_private */ NULL,
  166. /* tm_table */ NULL,
  167. /* query_geometry */ NULL,
  168. /* display_accelerator */ XtInheritDisplayAccelerator,
  169. /* extension */ NULL
  170. },
  171. #ifdef MOTIF
  172. {
  173. /* primitive_class fields */
  174. /* border_highlight */ (XtWidgetProc) _XtInherit,
  175. /* border_unhighligh */ (XtWidgetProc) _XtInherit,
  176. /* translations */ XtInheritTranslations,
  177. /* arm_and_activate */ (XtActionProc)_XtInherit,
  178. /* syn_resources */ NULL,
  179. /* num_syn_resources */ 0,
  180. /* extension */ NULL
  181. },
  182. #endif
  183. {
  184. /* plot_class fields */
  185. /* dummy */ 0
  186. /* (some stupid compilers barf on empty structures) */
  187. }
  188. };
  189. WidgetClass sciplotWidgetClass = (WidgetClass) & sciplotClassRec;
  190. static void
  191. Initialize(Widget treq, Widget tnew, ArgList args, Cardinal *num)
  192. {
  193. SciPlotWidget new;
  194. new = (SciPlotWidget) tnew;
  195. new->plot.plotlist = NULL;
  196. new->plot.alloc_plotlist = 0;
  197. new->plot.num_plotlist = 0;
  198. new->plot.alloc_drawlist = NUMPLOTITEMALLOC;
  199. new->plot.drawlist = (SciPlotItem *) XtCalloc(new->plot.alloc_drawlist,
  200. sizeof(SciPlotItem));
  201. new->plot.num_drawlist = 0;
  202. new->plot.cmap = DefaultColormap(XtDisplay(new),
  203. DefaultScreen(XtDisplay(new)));
  204. new->plot.xlabel = (char *) XtMalloc(strlen(new->plot.TransientXLabel) + 1);
  205. strcpy(new->plot.xlabel, new->plot.TransientXLabel);
  206. new->plot.ylabel = (char *) XtMalloc(strlen(new->plot.TransientYLabel) + 1);
  207. strcpy(new->plot.ylabel, new->plot.TransientYLabel);
  208. new->plot.plotTitle = (char *) XtMalloc(strlen(new->plot.TransientPlotTitle) + 1);
  209. strcpy(new->plot.plotTitle, new->plot.TransientPlotTitle);
  210. new->plot.TransientXLabel=NULL;
  211. new->plot.TransientYLabel=NULL;
  212. new->plot.TransientPlotTitle=NULL;
  213. new->plot.colors = NULL;
  214. new->plot.num_colors = 0;
  215. new->plot.fonts = NULL;
  216. new->plot.num_fonts = 0;
  217. new->plot.update = FALSE;
  218. new->plot.UserMin.x = new->plot.UserMin.y = 0.0;
  219. new->plot.UserMax.x = new->plot.UserMax.y = 10.0;
  220. new->plot.titleFont = FontStore(new, new->plot.TitleFont);
  221. new->plot.labelFont = FontStore(new, new->plot.LabelFont);
  222. new->plot.axisFont = FontStore(new, new->plot.AxisFont);
  223. }
  224. static void
  225. GCInitialize(SciPlotWidget new)
  226. {
  227. XGCValues values;
  228. XtGCMask mask;
  229. long colorsave;
  230. values.line_style = LineSolid;
  231. values.line_width = 0;
  232. values.fill_style = FillSolid;
  233. values.background = WhitePixelOfScreen(XtScreen(new));
  234. values.background = new->core.background_pixel;
  235. new->plot.BackgroundColor = ColorStore(new, values.background);
  236. #ifdef MOTIF
  237. new->core.background_pixel = values.background;
  238. #endif
  239. values.foreground = colorsave = BlackPixelOfScreen(XtScreen(new));
  240. new->plot.TextColor = ColorStore(new, values.foreground);
  241. new->plot.ForegroundColor = ColorStore(new, values.foreground);
  242. mask = GCLineStyle | GCLineWidth | GCFillStyle | GCForeground | GCBackground;
  243. #ifdef DOUBLE_BUF
  244. new->plot.screenGC = XCreateGC(XtDisplay(new), XtWindow(new),
  245. mask, &values);
  246. new->plot.double_buf =
  247. XCreatePixmap(XtDisplay(new),
  248. XtWindow(new),
  249. new->core.width,
  250. new->core.height,
  251. DefaultDepth(XtDisplay(new),
  252. DefaultScreen(XtDisplay(new))));
  253. new->plot.defaultGC = XCreateGC(XtDisplay(new), new->plot.double_buf,
  254. mask, &values);
  255. values.foreground = colorsave;
  256. values.line_style = LineOnOffDash;
  257. new->plot.dashGC = XCreateGC(XtDisplay(new), new->plot.double_buf,
  258. mask, &values);
  259. #else
  260. new->plot.defaultGC = XCreateGC(XtDisplay(new), XtWindow(new),
  261. mask, &values);
  262. values.foreground = colorsave;
  263. values.line_style = LineOnOffDash;
  264. new->plot.dashGC = XCreateGC(XtDisplay(new),XtWindow(new), mask, &values);
  265. #endif
  266. }
  267. static void
  268. Realize(Widget aw, XtValueMask * value_mask, XSetWindowAttributes * attributes)
  269. {
  270. SciPlotWidget w = (SciPlotWidget) aw;
  271. #define superclass (&widgetClassRec)
  272. (*superclass->core_class.realize) (aw, value_mask, attributes);
  273. #undef superclass
  274. GCInitialize(w);
  275. }
  276. static void
  277. Destroy(SciPlotWidget w)
  278. {
  279. int i;
  280. SciPlotFont *pf;
  281. SciPlotList *p;
  282. EraseAll(w);
  283. XFreeGC(XtDisplay(w), w->plot.defaultGC);
  284. w->plot.defaultGC = 0;
  285. #ifdef DOUBLE_BUF
  286. XFreeGC(XtDisplay(w), w->plot.screenGC);
  287. XFreePixmap(XtDisplay(w), w->plot.double_buf);
  288. w->plot.screenGC = 0;
  289. w->plot.double_buf = 0;
  290. #endif
  291. XFreeGC(XtDisplay(w), w->plot.dashGC);
  292. XtFree((char *) w->plot.xlabel);
  293. XtFree((char *) w->plot.ylabel);
  294. XtFree((char *) w->plot.plotTitle);
  295. for (i = 0; i < w->plot.num_fonts; i++) {
  296. pf = &w->plot.fonts[i];
  297. XFreeFont(XtDisplay((Widget) w), pf->font);
  298. }
  299. XtFree((char *) w->plot.fonts);
  300. XtFree((char *) w->plot.colors);
  301. for (i = 0; i < w->plot.alloc_plotlist; i++) {
  302. p = w->plot.plotlist + i;
  303. if (p->allocated > 0)
  304. XtFree((char *) p->data);
  305. if (p->legend)
  306. XtFree(p->legend);
  307. }
  308. if (w->plot.alloc_plotlist > 0)
  309. XtFree((char *) w->plot.plotlist);
  310. XtFree((char *) w->plot.drawlist);
  311. }
  312. static Boolean
  313. SetValues(SciPlotWidget current, SciPlotWidget request, SciPlotWidget new,
  314. ArgList args, Cardinal nargs)
  315. {
  316. Boolean redisplay = FALSE;
  317. if (current->plot.XLog != new->plot.XLog)
  318. redisplay = TRUE;
  319. else if (current->plot.YLog != new->plot.YLog)
  320. redisplay = TRUE;
  321. else if (current->plot.XOrigin != new->plot.XOrigin)
  322. redisplay = TRUE;
  323. else if (current->plot.YOrigin != new->plot.YOrigin)
  324. redisplay = TRUE;
  325. else if (current->plot.XAxisNumbers != new->plot.XAxisNumbers)
  326. redisplay = TRUE;
  327. else if (current->plot.YAxisNumbers != new->plot.YAxisNumbers)
  328. redisplay = TRUE;
  329. else if (current->plot.DrawMajor != new->plot.DrawMajor)
  330. redisplay = TRUE;
  331. else if (current->plot.DrawMajorTics != new->plot.DrawMajorTics)
  332. redisplay = TRUE;
  333. else if (current->plot.DrawMinor != new->plot.DrawMinor)
  334. redisplay = TRUE;
  335. else if (current->plot.DrawMinorTics != new->plot.DrawMinorTics)
  336. redisplay = TRUE;
  337. else if (current->plot.ChartType != new->plot.ChartType)
  338. redisplay = TRUE;
  339. else if (current->plot.Degrees != new->plot.Degrees)
  340. redisplay = TRUE;
  341. else if (current->plot.ShowLegend != new->plot.ShowLegend)
  342. redisplay = TRUE;
  343. else if (current->plot.ShowTitle != new->plot.ShowTitle)
  344. redisplay = TRUE;
  345. else if (current->plot.ShowXLabel != new->plot.ShowXLabel)
  346. redisplay = TRUE;
  347. else if (current->plot.ShowYLabel != new->plot.ShowYLabel)
  348. redisplay = TRUE;
  349. else if (current->plot.ShowTitle != new->plot.ShowTitle)
  350. redisplay = TRUE;
  351. else if (current->plot.Monochrome != new->plot.Monochrome)
  352. redisplay = TRUE;
  353. if (new->plot.TransientXLabel) {
  354. if (current->plot.TransientXLabel != new->plot.TransientXLabel ||
  355. strcmp(new->plot.TransientXLabel,current->plot.xlabel)!=0) {
  356. redisplay = TRUE;
  357. XtFree(current->plot.xlabel);
  358. new->plot.xlabel = (char *) XtMalloc(strlen(new->plot.TransientXLabel) + 1);
  359. strcpy(new->plot.xlabel, new->plot.TransientXLabel);
  360. new->plot.TransientXLabel=NULL;
  361. }
  362. }
  363. if (new->plot.TransientYLabel) {
  364. if (current->plot.TransientYLabel != new->plot.TransientYLabel ||
  365. strcmp(new->plot.TransientYLabel,current->plot.ylabel)!=0) {
  366. redisplay = TRUE;
  367. XtFree(current->plot.ylabel);
  368. new->plot.ylabel = (char *) XtMalloc(strlen(new->plot.TransientYLabel) + 1);
  369. strcpy(new->plot.ylabel, new->plot.TransientYLabel);
  370. new->plot.TransientYLabel=NULL;
  371. }
  372. }
  373. if (new->plot.TransientPlotTitle) {
  374. if (current->plot.TransientPlotTitle != new->plot.TransientPlotTitle ||
  375. strcmp(new->plot.TransientPlotTitle,current->plot.plotTitle)!=0) {
  376. redisplay = TRUE;
  377. XtFree(current->plot.plotTitle);
  378. new->plot.plotTitle = (char *) XtMalloc(strlen(new->plot.TransientPlotTitle) + 1);
  379. strcpy(new->plot.plotTitle, new->plot.TransientPlotTitle);
  380. new->plot.TransientPlotTitle=NULL;
  381. }
  382. }
  383. if (current->plot.AxisFont != new->plot.AxisFont) {
  384. redisplay = TRUE;
  385. FontnumReplace(new, new->plot.axisFont, new->plot.AxisFont);
  386. }
  387. if (current->plot.TitleFont != new->plot.TitleFont) {
  388. redisplay = TRUE;
  389. FontnumReplace(new, new->plot.titleFont, new->plot.TitleFont);
  390. }
  391. if (current->plot.LabelFont != new->plot.LabelFont) {
  392. redisplay = TRUE;
  393. FontnumReplace(new, new->plot.labelFont, new->plot.LabelFont);
  394. }
  395. new->plot.update = redisplay;
  396. return redisplay;
  397. }
  398. static void
  399. GetValuesHook(SciPlotWidget w, ArgList args, Cardinal *num_args)
  400. {
  401. int i;
  402. char **loc;
  403. for (i=0; i<*num_args; i++) {
  404. loc=(char **)args[i].value;
  405. if (strcmp(args[i].name,XtNplotTitle)==0)
  406. *loc=w->plot.plotTitle;
  407. else if (strcmp(args[i].name,XtNxLabel)==0)
  408. *loc=w->plot.xlabel;
  409. else if (strcmp(args[i].name,XtNyLabel)==0)
  410. *loc=w->plot.ylabel;
  411. }
  412. }
  413. static void
  414. Redisplay(SciPlotWidget w)
  415. {
  416. if (!XtIsRealized((Widget)w))
  417. return;
  418. if (w->plot.update) {
  419. Resize(w);
  420. w->plot.update = FALSE;
  421. }
  422. else {
  423. ItemDrawAll(w);
  424. }
  425. }
  426. static void
  427. Resize(SciPlotWidget w)
  428. {
  429. if (!XtIsRealized((Widget)w))
  430. return;
  431. EraseAll(w);
  432. ComputeAll(w);
  433. DrawAll(w);
  434. }
  435. /*
  436. * Private SciPlot utility functions
  437. */
  438. static int ColorStore(SciPlotWidget w, Pixel color)
  439. {
  440. w->plot.num_colors++;
  441. w->plot.colors = (Pixel *) XtRealloc((char *) w->plot.colors,
  442. sizeof(Pixel) * w->plot.num_colors);
  443. w->plot.colors[w->plot.num_colors - 1] = color;
  444. return w->plot.num_colors - 1;
  445. }
  446. static void
  447. FontnumStore (SciPlotWidget w, int fontnum, int flag)
  448. {
  449. SciPlotFont *pf;
  450. int fontflag, sizeflag, attrflag;
  451. pf = &w->plot.fonts[fontnum];
  452. fontflag = flag & XtFONT_NAME_MASK;
  453. sizeflag = flag & XtFONT_SIZE_MASK;
  454. attrflag = flag & XtFONT_ATTRIBUTE_MASK;
  455. switch (fontflag) {
  456. case XtFONT_TIMES:
  457. case XtFONT_COURIER:
  458. case XtFONT_HELVETICA:
  459. case XtFONT_LUCIDA:
  460. case XtFONT_LUCIDASANS:
  461. case XtFONT_NCSCHOOLBOOK:
  462. break;
  463. default:
  464. fontflag = XtFONT_NAME_DEFAULT;
  465. break;
  466. }
  467. if (sizeflag < 1)
  468. sizeflag = XtFONT_SIZE_DEFAULT;
  469. switch (attrflag) {
  470. case XtFONT_BOLD:
  471. case XtFONT_ITALIC:
  472. case XtFONT_BOLD_ITALIC:
  473. break;
  474. default:
  475. attrflag = XtFONT_ATTRIBUTE_DEFAULT;
  476. break;
  477. }
  478. pf->id = flag;
  479. FontInit(w, pf);
  480. }
  481. static int
  482. FontnumReplace (SciPlotWidget w, int fontnum, int flag)
  483. {
  484. SciPlotFont *pf;
  485. pf = &w->plot.fonts[fontnum];
  486. XFreeFont(XtDisplay(w), pf->font);
  487. FontnumStore(w, fontnum, flag);
  488. return fontnum;
  489. }
  490. static int
  491. FontStore (SciPlotWidget w, int flag)
  492. {
  493. int fontnum;
  494. w->plot.num_fonts++;
  495. w->plot.fonts = (SciPlotFont *) XtRealloc((char *) w->plot.fonts,
  496. sizeof(SciPlotFont) * w->plot.num_fonts);
  497. fontnum = w->plot.num_fonts - 1;
  498. FontnumStore(w, fontnum, flag);
  499. return fontnum;
  500. }
  501. static SciPlotFontDesc *
  502. FontDescLookup (int flag)
  503. {
  504. SciPlotFontDesc *pfd;
  505. pfd = font_desc_table;
  506. while (pfd->flag >= 0) {
  507. #ifdef DEBUG_SCIPLOT
  508. printf("checking if %d == %d (font %s)\n",
  509. flag & XtFONT_NAME_MASK, pfd->flag, pfd->PostScript);
  510. #endif
  511. if ((flag & XtFONT_NAME_MASK) == pfd->flag)
  512. return pfd;
  513. pfd++;
  514. }
  515. return NULL;
  516. }
  517. static void
  518. FontnumPostScriptString (SciPlotWidget w, int fontnum, char *str)
  519. {
  520. char temp[128];
  521. int flag, bold, italic;
  522. SciPlotFontDesc *pfd;
  523. flag = w->plot.fonts[fontnum].id;
  524. pfd = FontDescLookup(flag);
  525. if (pfd) {
  526. strcpy(temp, pfd->PostScript);
  527. bold = False;
  528. italic = False;
  529. if (flag & XtFONT_BOLD) {
  530. bold = True;
  531. strcat(temp, "-Bold");
  532. }
  533. if (flag & XtFONT_ITALIC) {
  534. italic = True;
  535. if (!bold)
  536. strcat(temp, "-");
  537. if (pfd->PSUsesOblique)
  538. strcat(temp, "Oblique");
  539. else
  540. strcat(temp, "Italic");
  541. }
  542. if (!bold && !italic && pfd->PSUsesRoman) {
  543. strcat(temp, "-Roman");
  544. }
  545. sprintf(str, "/%s findfont %d scalefont",
  546. temp,
  547. (flag & XtFONT_SIZE_MASK));
  548. }
  549. else
  550. sprintf(str, "/Courier findfond 10 scalefont");
  551. }
  552. static void
  553. FontX11String (int flag, char *str)
  554. {
  555. SciPlotFontDesc *pfd;
  556. pfd = FontDescLookup(flag);
  557. if (pfd) {
  558. sprintf(str, "-*-%s-%s-%s-*-*-%d-*-*-*-*-*-*-*",
  559. pfd->X11,
  560. (flag & XtFONT_BOLD ? "bold" : "medium"),
  561. (flag & XtFONT_ITALIC ? (pfd->PSUsesOblique ? "o" : "i") : "r"),
  562. (flag & XtFONT_SIZE_MASK));
  563. }
  564. else
  565. sprintf(str, "fixed");
  566. #ifdef DEBUG_SCIPLOT
  567. printf("font string=%s\n", str);
  568. #endif
  569. }
  570. static void
  571. FontInit (SciPlotWidget w, SciPlotFont *pf)
  572. {
  573. char str[256], **list;
  574. int num;
  575. FontX11String(pf->id, str);
  576. list = XListFonts(XtDisplay(w), str, 100, &num);
  577. #ifdef DEBUG_SCIPLOT
  578. if (1) {
  579. int i;
  580. i = 0;
  581. while (i < num) {
  582. printf("Found font: %s\n", list[i]);
  583. i++;
  584. }
  585. }
  586. #endif
  587. if (num <= 0) {
  588. pf->id &= ~XtFONT_ATTRIBUTE_MASK;
  589. pf->id |= XtFONT_ATTRIBUTE_DEFAULT;
  590. FontX11String(pf->id, str);
  591. list = XListFonts(XtDisplay(w), str, 100, &num);
  592. #ifdef DEBUG_SCIPLOT
  593. if (1) {
  594. int i;
  595. i = 0;
  596. while (i < num) {
  597. printf("Attr reset: found: %s\n", list[i]);
  598. i++;
  599. }
  600. }
  601. #endif
  602. }
  603. if (num <= 0) {
  604. pf->id &= ~XtFONT_NAME_MASK;
  605. pf->id |= XtFONT_NAME_DEFAULT;
  606. FontX11String(pf->id, str);
  607. list = XListFonts(XtDisplay(w), str, 100, &num);
  608. #ifdef DEBUG_SCIPLOT
  609. if (1) {
  610. int i;
  611. i = 0;
  612. while (i < num) {
  613. printf("Name reset: found: %s\n", list[i]);
  614. i++;
  615. }
  616. }
  617. #endif
  618. }
  619. if (num <= 0) {
  620. pf->id &= ~XtFONT_SIZE_MASK;
  621. pf->id |= XtFONT_SIZE_DEFAULT;
  622. FontX11String(pf->id, str);
  623. list = XListFonts(XtDisplay(w), str, 100, &num);
  624. #ifdef DEBUG_SCIPLOT
  625. if (1) {
  626. int i;
  627. i = 0;
  628. while (i < num) {
  629. printf("Size reset: found: %s\n", list[i]);
  630. i++;
  631. }
  632. }
  633. #endif
  634. }
  635. if (num <= 0)
  636. strcpy(str, "fixed");
  637. else
  638. XFreeFontNames(list);
  639. pf->font = XLoadQueryFont(XtDisplay(w), str);
  640. }
  641. static XFontStruct *
  642. FontFromFontnum (SciPlotWidget w, int fontnum)
  643. {
  644. XFontStruct *f;
  645. if (fontnum >= w->plot.num_fonts)
  646. fontnum = 0;
  647. f = w->plot.fonts[fontnum].font;
  648. return f;
  649. }
  650. static real
  651. FontHeight(XFontStruct *f)
  652. {
  653. return (real) (f->max_bounds.ascent + f->max_bounds.descent);
  654. }
  655. static real
  656. FontnumHeight(SciPlotWidget w, int fontnum)
  657. {
  658. XFontStruct *f;
  659. f = FontFromFontnum(w, fontnum);
  660. return FontHeight(f);
  661. }
  662. static real
  663. FontDescent(XFontStruct *f)
  664. {
  665. return (real) (f->max_bounds.descent);
  666. }
  667. static real
  668. FontnumDescent(SciPlotWidget w, int fontnum)
  669. {
  670. XFontStruct *f;
  671. f = FontFromFontnum(w, fontnum);
  672. return FontDescent(f);
  673. }
  674. static real
  675. FontAscent(XFontStruct *f)
  676. {
  677. return (real) (f->max_bounds.ascent);
  678. }
  679. static real
  680. FontnumAscent(SciPlotWidget w, int fontnum)
  681. {
  682. XFontStruct *f;
  683. f = FontFromFontnum(w, fontnum);
  684. return FontAscent(f);
  685. }
  686. static real
  687. FontTextWidth(XFontStruct *f, char *c)
  688. {
  689. return (real) XTextWidth(f, c, strlen(c));
  690. }
  691. static real
  692. FontnumTextWidth(SciPlotWidget w, int fontnum, char *c)
  693. {
  694. XFontStruct *f;
  695. f = FontFromFontnum(w, fontnum);
  696. return FontTextWidth(f, c);
  697. }
  698. /*
  699. * Private List functions
  700. */
  701. static int
  702. _ListNew (SciPlotWidget w)
  703. {
  704. int index;
  705. SciPlotList *p;
  706. Boolean found;
  707. /* First check to see if there is any free space in the index */
  708. found = FALSE;
  709. for (index = 0; index < w->plot.num_plotlist; index++) {
  710. p = w->plot.plotlist + index;
  711. if (!p->used) {
  712. found = TRUE;
  713. break;
  714. }
  715. }
  716. /* If no space is found, increase the size of the index */
  717. if (!found) {
  718. w->plot.num_plotlist++;
  719. if (w->plot.alloc_plotlist == 0) {
  720. w->plot.alloc_plotlist = NUMPLOTLINEALLOC;
  721. w->plot.plotlist = (SciPlotList *) XtCalloc(w->plot.alloc_plotlist, sizeof(SciPlotList));
  722. if (!w->plot.plotlist) {
  723. printf("Can't calloc memory for SciPlotList\n");
  724. exit(1);
  725. }
  726. w->plot.alloc_plotlist = NUMPLOTLINEALLOC;
  727. }
  728. else if (w->plot.num_plotlist > w->plot.alloc_plotlist) {
  729. w->plot.alloc_plotlist += NUMPLOTLINEALLOC;
  730. w->plot.plotlist = (SciPlotList *) XtRealloc((char *) w->plot.plotlist,
  731. w->plot.alloc_plotlist * sizeof(SciPlotList));
  732. if (!w->plot.plotlist) {
  733. printf("Can't realloc memory for SciPlotList\n");
  734. exit(1);
  735. }
  736. }
  737. index = w->plot.num_plotlist - 1;
  738. p = w->plot.plotlist + index;
  739. }
  740. p->LineStyle = p->LineColor = p->PointStyle = p->PointColor = 0;
  741. p->number = p->allocated = 0;
  742. p->data = NULL;
  743. p->legend = NULL;
  744. p->draw = p->used = TRUE;
  745. p->markersize = (real) w->plot.DefaultMarkerSize;
  746. return index;
  747. }
  748. static void
  749. _ListDelete (SciPlotList *p)
  750. {
  751. p->draw = p->used = FALSE;
  752. p->number = p->allocated = 0;
  753. if (p->data)
  754. XtFree((char *) p->data);
  755. p->data = NULL;
  756. if (p->legend)
  757. XtFree((char *) p->legend);
  758. p->legend = NULL;
  759. }
  760. static SciPlotList *
  761. _ListFind (SciPlotWidget w, int id)
  762. {
  763. SciPlotList *p;
  764. if ((id >= 0) && (id < w->plot.num_plotlist)) {
  765. p = w->plot.plotlist + id;
  766. if (p->used)
  767. return p;
  768. }
  769. return NULL;
  770. }
  771. static void
  772. _ListSetStyle (SciPlotList *p, int pcolor, int pstyle, int lcolor, int lstyle)
  773. {
  774. /* Note! Do checks in here later on... */
  775. if (lstyle >= 0)
  776. p->LineStyle = lstyle;
  777. if (lcolor >= 0)
  778. p->LineColor = lcolor;
  779. if (pstyle >= 0)
  780. p->PointStyle = pstyle;
  781. if (pcolor >= 0)
  782. p->PointColor = pcolor;
  783. }
  784. static void
  785. _ListSetLegend (SciPlotList *p, char *legend)
  786. {
  787. /* Note! Do checks in here later on... */
  788. p->legend = (char *) XtMalloc(strlen(legend) + 1);
  789. strcpy(p->legend, legend);
  790. }
  791. static void
  792. _ListAllocData (SciPlotList *p, int num)
  793. {
  794. if (p->data) {
  795. XtFree((char *) p->data);
  796. p->allocated = 0;
  797. }
  798. p->allocated = num + NUMPLOTDATAEXTRA;
  799. p->data = (realpair *) XtCalloc(p->allocated, sizeof(realpair));
  800. if (!p->data) {
  801. p->number = p->allocated = 0;
  802. }
  803. }
  804. static void
  805. _ListReallocData (SciPlotList *p, int more)
  806. {
  807. if (!p->data) {
  808. _ListAllocData(p, more);
  809. }
  810. else if (p->number + more > p->allocated) {
  811. p->allocated += more + NUMPLOTDATAEXTRA;
  812. p->data = (realpair *) XtRealloc((char *) p->data, p->allocated * sizeof(realpair));
  813. if (!p->data) {
  814. p->number = p->allocated = 0;
  815. }
  816. }
  817. }
  818. static void
  819. _ListAddReal (SciPlotList *p, int num, real *xlist, real *ylist)
  820. {
  821. int i;
  822. _ListReallocData(p, num);
  823. if (p->data) {
  824. for (i = 0; i < num; i++) {
  825. p->data[i + p->number].x = xlist[i];
  826. p->data[i + p->number].y = ylist[i];
  827. }
  828. p->number += num;
  829. }
  830. }
  831. static void
  832. _ListAddFloat (SciPlotList *p, int num, float *xlist, float *ylist)
  833. {
  834. int i;
  835. _ListReallocData(p, num);
  836. if (p->data) {
  837. for (i = 0; i < num; i++) {
  838. p->data[i + p->number].x = xlist[i];
  839. p->data[i + p->number].y = ylist[i];
  840. }
  841. p->number += num;
  842. }
  843. }
  844. static void
  845. _ListAddDouble (SciPlotList *p, int num, double *xlist, double *ylist)
  846. {
  847. int i;
  848. _ListReallocData(p, num);
  849. if (p->data) {
  850. for (i = 0; i < num; i++) {
  851. p->data[i + p->number].x = xlist[i];
  852. p->data[i + p->number].y = ylist[i];
  853. }
  854. p->number += num;
  855. }
  856. }
  857. static void
  858. _ListSetReal(SciPlotList *p, int num, real *xlist, real *ylist)
  859. {
  860. if ((!p->data) || (p->allocated < num))
  861. _ListAllocData(p, num);
  862. p->number = 0;
  863. _ListAddReal(p, num, xlist, ylist);
  864. }
  865. static void
  866. _ListSetFloat (SciPlotList *p, int num, float *xlist, float *ylist)
  867. {
  868. if ((!p->data) || (p->allocated < num))
  869. _ListAllocData(p, num);
  870. p->number = 0;
  871. _ListAddFloat(p, num, xlist, ylist);
  872. }
  873. static void
  874. _ListSetDouble (SciPlotList *p, int num, double *xlist, double *ylist)
  875. {
  876. if ((!p->data) || (p->allocated < num))
  877. _ListAllocData(p, num);
  878. p->number = 0;
  879. _ListAddDouble(p, num, xlist, ylist);
  880. }
  881. /*
  882. * Private SciPlot functions
  883. */
  884. /*
  885. * The following vertical text drawing routine uses the "Fill Stippled" idea
  886. * found in xvertext-5.0, by Alan Richardson (mppa3@syma.sussex.ac.uk).
  887. *
  888. * The following code is my interpretation of his idea, including some
  889. * hacked together excerpts from his source. The credit for the clever bits
  890. * belongs to him.
  891. *
  892. * To be complete, portions of the subroutine XDrawVString are
  893. * Copyright (c) 1993 Alan Richardson (mppa3@syma.sussex.ac.uk)
  894. */
  895. static void
  896. XDrawVString (Display *display, Drawable win, GC gc, int x, int y, char *str, int len, XFontStruct *f)
  897. {
  898. XImage *before, *after;
  899. char *dest, *source;
  900. int xloop, yloop, xdest, ydest;
  901. Pixmap pix, rotpix;
  902. int width, height;
  903. GC drawGC;
  904. width = (int) FontTextWidth(f, str);
  905. height = (int) FontHeight(f);
  906. pix = XCreatePixmap(display, win, width, height, 1);
  907. rotpix = XCreatePixmap(display, win, height, width, 1);
  908. drawGC = XCreateGC(display, pix, 0L, NULL);
  909. XSetBackground(display, drawGC, 0);
  910. XSetFont(display, drawGC, f->fid);
  911. XSetForeground(display, drawGC, 0);
  912. XFillRectangle(display, pix, drawGC, 0, 0, width, height);
  913. XFillRectangle(display, rotpix, drawGC, 0, 0, height, width);
  914. XSetForeground(display, drawGC, 1);
  915. XDrawImageString(display, pix, drawGC, 0, (int) FontAscent(f),
  916. str, strlen(str));
  917. source = (char *) XtCalloc((((width + 7) / 8) * height), 1);
  918. before = XCreateImage(display, DefaultVisual(display, DefaultScreen(display)),
  919. 1, XYPixmap, 0, source, width, height, 8, 0);
  920. before->byte_order = before->bitmap_bit_order = MSBFirst;
  921. XGetSubImage(display, pix, 0, 0, width, height, 1L, XYPixmap, before, 0, 0);
  922. source = (char *) XtCalloc((((height + 7) / 8) * width), 1);
  923. after = XCreateImage(display, DefaultVisual(display, DefaultScreen(display)),
  924. 1, XYPixmap, 0, source, height, width, 8, 0);
  925. after->byte_order = after->bitmap_bit_order = MSBFirst;
  926. for (yloop = 0; yloop < height; yloop++) {
  927. for (xloop = 0; xloop < width; xloop++) {
  928. source = before->data + (xloop / 8) +
  929. (yloop * before->bytes_per_line);
  930. if (*source & (128 >> (xloop % 8))) {
  931. dest = after->data + (yloop / 8) +
  932. ((width - 1 - xloop) * after->bytes_per_line);
  933. *dest |= (128 >> (yloop % 8));
  934. }
  935. }
  936. }
  937. #ifdef DEBUG_SCIPLOT_VTEXT
  938. if (1) {
  939. char sourcebit;
  940. for (yloop = 0; yloop < before->height; yloop++) {
  941. for (xloop = 0; xloop < before->width; xloop++) {
  942. source = before->data + (xloop / 8) +
  943. (yloop * before->bytes_per_line);
  944. sourcebit = *source & (128 >> (xloop % 8));
  945. if (sourcebit)
  946. putchar('X');
  947. else
  948. putchar('.');
  949. }
  950. putchar('\n');
  951. }
  952. for (yloop = 0; yloop < after->height; yloop++) {
  953. for (xloop = 0; xloop < after->width; xloop++) {
  954. source = after->data + (xloop / 8) +
  955. (yloop * after->bytes_per_line);
  956. sourcebit = *source & (128 >> (xloop % 8));
  957. if (sourcebit)
  958. putchar('X');
  959. else
  960. putchar('.');
  961. }
  962. putchar('\n');
  963. }
  964. }
  965. #endif
  966. xdest = x - (int) FontAscent(f);
  967. if (xdest < 0)
  968. xdest = 0;
  969. ydest = y - width;
  970. XPutImage(display, rotpix, drawGC, after, 0, 0, 0, 0,
  971. after->width, after->height);
  972. XSetFillStyle(display, gc, FillStippled);
  973. XSetStipple(display, gc, rotpix);
  974. XSetTSOrigin(display, gc, xdest, ydest);
  975. XFillRectangle(display, win, gc, xdest, ydest, after->width, after->height);
  976. XSetFillStyle(display, gc, FillSolid);
  977. XFreeGC(display, drawGC);
  978. XDestroyImage(before);
  979. XDestroyImage(after);
  980. XFreePixmap(display, pix);
  981. XFreePixmap(display, rotpix);
  982. /* Note that it appears that there is a memory leak here, but XDestroyImage
  983. * frees the image data that is XtCalloc'ed
  984. */
  985. }
  986. static char dots[] =
  987. {2, 1, 1};
  988. static char widedots[] =
  989. {2, 1, 4};
  990. static GC
  991. ItemGetGC (SciPlotWidget w, SciPlotItem *item)
  992. {
  993. GC gc;
  994. short color;
  995. switch (item->kind.any.style) {
  996. case XtLINE_SOLID:
  997. gc = w->plot.defaultGC;
  998. break;
  999. case XtLINE_DOTTED:
  1000. XSetDashes(XtDisplay(w), w->plot.dashGC, 0, &dots[1],
  1001. (int) dots[0]);
  1002. gc = w->plot.dashGC;
  1003. break;
  1004. case XtLINE_WIDEDOT:
  1005. XSetDashes(XtDisplay(w), w->plot.dashGC, 0, &widedots[1],
  1006. (int) widedots[0]);
  1007. gc = w->plot.dashGC;
  1008. break;
  1009. default:
  1010. return NULL;
  1011. break;
  1012. }
  1013. if (w->plot.Monochrome)
  1014. if (item->kind.any.color > 0)
  1015. color = w->plot.ForegroundColor;
  1016. else
  1017. color = w->plot.BackgroundColor;
  1018. else if (item->kind.any.color >= w->plot.num_colors)
  1019. color = w->plot.ForegroundColor;
  1020. else if (item->kind.any.color <= 0)
  1021. color = w->plot.BackgroundColor;
  1022. else
  1023. color = item->kind.any.color;
  1024. XSetForeground(XtDisplay(w), gc, w->plot.colors[color]);
  1025. return gc;
  1026. }
  1027. static GC
  1028. ItemGetFontGC (SciPlotWidget w, SciPlotItem *item)
  1029. {
  1030. GC gc;
  1031. short color, fontnum;
  1032. gc = w->plot.dashGC;
  1033. if (w->plot.Monochrome)
  1034. if (item->kind.any.color > 0)
  1035. color = w->plot.TextColor;
  1036. else
  1037. color = w->plot.BackgroundColor;
  1038. else if (item->kind.any.color >= w->plot.num_colors)
  1039. color = w->plot.TextColor;
  1040. else if (item->kind.any.color <= 0)
  1041. color = w->plot.BackgroundColor;
  1042. else
  1043. color = item->kind.any.color;
  1044. XSetForeground(XtDisplay(w), gc, w->plot.colors[color]);
  1045. if (item->kind.text.font >= w->plot.num_fonts)
  1046. fontnum = 0;
  1047. else
  1048. fontnum = item->kind.text.font;
  1049. /*
  1050. * fontnum==0 hack: 0 is supposed to be the default font, but the program
  1051. * can't seem to get the default font ID from the GC for some reason. So,
  1052. * use a different GC where the default font still exists.
  1053. */
  1054. XSetFont(XtDisplay(w), gc, w->plot.fonts[fontnum].font->fid);
  1055. return gc;
  1056. }
  1057. static void
  1058. ItemDraw (SciPlotWidget w, SciPlotItem *item)
  1059. {
  1060. XPoint point[8];
  1061. XSegment seg;
  1062. XRectangle rect;
  1063. int i;
  1064. GC gc;
  1065. Drawable win;
  1066. if (!XtIsRealized((Widget) w))
  1067. return;
  1068. #ifdef DOUBLE_BUF
  1069. win = w->plot.double_buf;
  1070. #else
  1071. win = XtWindow(w);
  1072. #endif
  1073. if ((item->type > SciPlotStartTextTypes) && (item->type < SciPlotEndTextTypes))
  1074. gc = ItemGetFontGC(w, item);
  1075. else
  1076. gc = ItemGetGC(w, item);
  1077. if (!gc)
  1078. return;
  1079. switch (item->type) {
  1080. case SciPlotLine:
  1081. seg.x1 = (short) item->kind.line.x1;
  1082. seg.y1 = (short) item->kind.line.y1;
  1083. seg.x2 = (short) item->kind.line.x2;
  1084. seg.y2 = (short) item->kind.line.y2;
  1085. XDrawSegments(XtDisplay(w), win, gc,
  1086. &seg, 1);
  1087. break;
  1088. case SciPlotRect:
  1089. XDrawRectangle(XtDisplay(w), win, gc,
  1090. (int) (item->kind.rect.x),
  1091. (int) (item->kind.rect.y),
  1092. (unsigned int) (item->kind.rect.w),
  1093. (unsigned int) (item->kind.rect.h));
  1094. break;
  1095. case SciPlotFRect:
  1096. XFillRectangle(XtDisplay(w), win, gc,
  1097. (int) (item->kind.rect.x),
  1098. (int) (item->kind.rect.y),
  1099. (unsigned int) (item->kind.rect.w),
  1100. (unsigned int) (item->kind.rect.h));
  1101. XDrawRectangle(XtDisplay(w), win, gc,
  1102. (int) (item->kind.rect.x),
  1103. (int) (item->kind.rect.y),
  1104. (unsigned int) (item->kind.rect.w),
  1105. (unsigned int) (item->kind.rect.h));
  1106. break;
  1107. case SciPlotPoly:
  1108. i = 0;
  1109. while (i < item->kind.poly.count) {
  1110. point[i].x = (int) item->kind.poly.x[i];
  1111. point[i].y = (int) item->kind.poly.y[i];
  1112. i++;
  1113. }
  1114. point[i].x = (int) item->kind.poly.x[0];
  1115. point[i].y = (int) item->kind.poly.y[0];
  1116. XDrawLines(XtDisplay(w), win, gc,
  1117. point, i + 1, CoordModeOrigin);
  1118. break;
  1119. case SciPlotFPoly:
  1120. i = 0;
  1121. while (i < item->kind.poly.count) {
  1122. point[i].x = (int) item->kind.poly.x[i];
  1123. point[i].y = (int) item->kind.poly.y[i];
  1124. i++;
  1125. }
  1126. point[i].x = (int) item->kind.poly.x[0];
  1127. point[i].y = (int) item->kind.poly.y[0];
  1128. XFillPolygon(XtDisplay(w), win, gc,
  1129. point, i + 1, Complex, CoordModeOrigin);
  1130. XDrawLines(XtDisplay(w), win, gc,
  1131. point, i + 1, CoordModeOrigin);
  1132. break;
  1133. case SciPlotCircle:
  1134. XDrawArc(XtDisplay(w), win, gc,
  1135. (int) (item->kind.circ.x - item->kind.circ.r),
  1136. (int) (item->kind.circ.y - item->kind.circ.r),
  1137. (unsigned int) (item->kind.circ.r * 2),
  1138. (unsigned int) (item->kind.circ.r * 2),
  1139. 0 * 64, 360 * 64);
  1140. break;
  1141. case SciPlotFCircle:
  1142. XFillArc(XtDisplay(w), win, gc,
  1143. (int) (item->kind.circ.x - item->kind.circ.r),
  1144. (int) (item->kind.circ.y - item->kind.circ.r),
  1145. (unsigned int) (item->kind.circ.r * 2),
  1146. (unsigned int) (item->kind.circ.r * 2),
  1147. 0 * 64, 360 * 64);
  1148. break;
  1149. case SciPlotText:
  1150. XDrawString(XtDisplay(w), win, gc,
  1151. (int) (item->kind.text.x), (int) (item->kind.text.y),
  1152. item->kind.text.text,
  1153. (int) item->kind.text.length);
  1154. break;
  1155. case SciPlotVText:
  1156. XDrawVString(XtDisplay(w), win, gc,
  1157. (int) (item->kind.text.x), (int) (item->kind.text.y),
  1158. item->kind.text.text,
  1159. (int) item->kind.text.length,
  1160. FontFromFontnum(w, item->kind.text.font));
  1161. break;
  1162. case SciPlotClipRegion:
  1163. rect.x = (short) item->kind.line.x1;
  1164. rect.y = (short) item->kind.line.y1;
  1165. rect.width = (short) item->kind.line.x2;
  1166. rect.height = (short) item->kind.line.y2;
  1167. XSetClipRectangles(XtDisplay(w), w->plot.dashGC, 0, 0, &rect, 1, Unsorted);
  1168. XSetClipRectangles(XtDisplay(w), w->plot.defaultGC, 0, 0, &rect, 1, Unsorted);
  1169. break;
  1170. case SciPlotClipClear:
  1171. XSetClipMask(XtDisplay(w), w->plot.dashGC, None);
  1172. XSetClipMask(XtDisplay(w), w->plot.defaultGC, None);
  1173. break;
  1174. default:
  1175. break;
  1176. }
  1177. }
  1178. static void
  1179. ItemDrawAll (SciPlotWidget w)
  1180. {
  1181. SciPlotItem *item;
  1182. int i;
  1183. if (!XtIsRealized((Widget) w))
  1184. return;
  1185. item = w->plot.drawlist;
  1186. i = 0;
  1187. while (i < w->plot.num_drawlist) {
  1188. ItemDraw(w, item);
  1189. i++;
  1190. item++;
  1191. }
  1192. }
  1193. /*
  1194. * PostScript (r) functions ------------------------------------------------
  1195. *
  1196. */
  1197. typedef struct {
  1198. char *command;
  1199. char *prolog;
  1200. } PScommands;
  1201. static PScommands psc[] =
  1202. {
  1203. {"ma", "moveto"},
  1204. {"da", "lineto stroke newpath"},
  1205. {"la", "lineto"},
  1206. {"poly", "closepath stroke newpath"},
  1207. {"fpoly", "closepath fill newpath"},
  1208. {"box", "1 index 0 rlineto 0 exch rlineto neg 0 rlineto closepath stroke newpath"},
  1209. {"fbox", "1 index 0 rlineto 0 exch rlineto neg 0 rlineto closepath fill newpath"},
  1210. {"clipbox", "gsave 1 index 0 rlineto 0 exch rlineto neg 0 rlineto closepath clip newpath"},
  1211. {"unclip", "grestore newpath"},
  1212. {"cr", "0 360 arc stroke newpath"},
  1213. {"fcr", "0 360 arc fill newpath"},
  1214. {"vma", "gsave moveto 90 rotate"},
  1215. {"norm", "grestore"},
  1216. {"solid", "[] 0 setdash"},
  1217. {"dot", "[.25 2] 0 setdash"},
  1218. {"widedot", "[.25 8] 0 setdash"},
  1219. {"rgb", "setrgbcolor"},
  1220. {NULL, NULL}
  1221. };
  1222. enum PSenums {
  1223. PSmoveto, PSlineto,
  1224. PSpolyline, PSendpoly, PSendfill,
  1225. PSbox, PSfbox,
  1226. PSclipbox, PSunclip,
  1227. PScircle, PSfcircle,
  1228. PSvmoveto, PSnormal,
  1229. PSsolid, PSdot, PSwidedot,
  1230. PSrgb
  1231. };
  1232. static void
  1233. ItemPSDrawAll (SciPlotWidget w, FILE *fd, double yflip, Boolean usecolor)
  1234. {
  1235. int i, loopcount;
  1236. SciPlotItem *item;
  1237. XcmsColor currentcolor;
  1238. int previousfont, previousline, currentfont, currentline, previouscolor;
  1239. item = w->plot.drawlist;
  1240. loopcount = 0;
  1241. previousfont = 0;
  1242. previouscolor = -1;
  1243. previousline = XtLINE_SOLID;
  1244. while (loopcount < w->plot.num_drawlist) {
  1245. /* 2 switch blocks: 1st sets up defaults, 2nd actually draws things. */
  1246. currentline = previousline;
  1247. currentfont = previousfont;
  1248. switch (item->type) {
  1249. case SciPlotLine:
  1250. case SciPlotCircle:
  1251. currentline = item->kind.any.style;
  1252. break;
  1253. default:
  1254. break;
  1255. }
  1256. if (currentline != XtLINE_NONE) {
  1257. if (currentline != previousline) {
  1258. switch (item->kind.any.style) {
  1259. case XtLINE_SOLID:
  1260. fprintf(fd, "%s ", psc[PSsolid].command);
  1261. break;
  1262. case XtLINE_DOTTED:
  1263. fprintf(fd, "%s ", psc[PSdot].command);
  1264. break;
  1265. case XtLINE_WIDEDOT:
  1266. fprintf(fd, "%s ", psc[PSwidedot].command);
  1267. break;
  1268. }
  1269. previousline = currentline;
  1270. }
  1271. if (usecolor && item->kind.any.color != previouscolor) {
  1272. /* Get Pixel index */
  1273. currentcolor.pixel = w->plot.colors[item->kind.any.color];
  1274. /* Get RGBi components [0.0,1.0] */
  1275. XcmsQueryColor( XtDisplay(w), w->plot.cmap, &currentcolor,
  1276. XcmsRGBiFormat );
  1277. /* output PostScript command */
  1278. fprintf(fd, "%f %f %f %s ", currentcolor.spec.RGBi.red,
  1279. currentcolor.spec.RGBi.green, currentcolor.spec.RGBi.blue,
  1280. psc[PSrgb].command);
  1281. previouscolor=item->kind.any.color;
  1282. }
  1283. switch (item->type) {
  1284. case SciPlotLine:
  1285. fprintf(fd, "%.2f %.2f %s %.2f %.2f %s\n",
  1286. item->kind.line.x1, yflip - item->kind.line.y1,
  1287. psc[PSmoveto].command,
  1288. item->kind.line.x2, yflip - item->kind.line.y2,
  1289. psc[PSlineto].command);
  1290. break;
  1291. case SciPlotRect:
  1292. fprintf(fd, "%.2f %.2f %s %.2f %.2f %s\n",
  1293. item->kind.rect.x,
  1294. yflip - item->kind.rect.y - (item->kind.rect.h - 1.0),
  1295. psc[PSmoveto].command,
  1296. item->kind.rect.w - 1.0, item->kind.rect.h - 1.0,
  1297. psc[PSbox].command);
  1298. break;
  1299. case SciPlotFRect:
  1300. fprintf(fd, "%.2f %.2f %s %.2f %.2f %s\n",
  1301. item->kind.rect.x,
  1302. yflip - item->kind.rect.y - (item->kind.rect.h - 1.0),
  1303. psc[PSmoveto].command,
  1304. item->kind.rect.w - 1.0, item->kind.rect.h - 1.0,
  1305. psc[PSfbox].command);
  1306. break;
  1307. case SciPlotPoly:
  1308. fprintf(fd, "%.2f %.2f %s ",
  1309. item->kind.poly.x[0], yflip - item->kind.poly.y[0],
  1310. psc[PSmoveto].command);
  1311. for (i = 1; i < item->kind.poly.count; i++) {
  1312. fprintf(fd, "%.2f %.2f %s ",
  1313. item->kind.poly.x[i],
  1314. yflip - item->kind.poly.y[i],
  1315. psc[PSpolyline].command);
  1316. }
  1317. fprintf(fd, "%s\n", psc[PSendpoly].command);
  1318. break;
  1319. case SciPlotFPoly:
  1320. fprintf(fd, "%.2f %.2f %s ",
  1321. item->kind.poly.x[0], yflip - item->kind.poly.y[0],
  1322. psc[PSmoveto].command);
  1323. for (i = 1; i < item->kind.poly.count; i++) {
  1324. fprintf(fd, "%.2f %.2f %s ",
  1325. item->kind.poly.x[i],
  1326. yflip - item->kind.poly.y[i],
  1327. psc[PSpolyline].command);
  1328. }
  1329. fprintf(fd, "%s\n", psc[PSendfill].command);
  1330. break;
  1331. case SciPlotCircle:
  1332. fprintf(fd, "%.2f %.2f %.2f %s\n",
  1333. item->kind.circ.x, yflip - item->kind.circ.y,
  1334. item->kind.circ.r,
  1335. psc[PScircle].command);
  1336. break;
  1337. case SciPlotFCircle:
  1338. fprintf(fd, "%.2f %.2f %.2f %s\n",
  1339. item->kind.circ.x, yflip - item->kind.circ.y,
  1340. item->kind.circ.r,
  1341. psc[PSfcircle].command);
  1342. break;
  1343. case SciPlotText:
  1344. fprintf(fd, "font-%d %.2f %.2f %s (%s) show\n",
  1345. item->kind.text.font,
  1346. item->kind.text.x, yflip - item->kind.text.y,
  1347. psc[PSmoveto].command,
  1348. item->kind.text.text);
  1349. break;
  1350. case SciPlotVText:
  1351. fprintf(fd, "font-%d %.2f %.2f %s (%s) show %s\n",
  1352. item->kind.text.font,
  1353. item->kind.text.x, yflip - item->kind.text.y,
  1354. psc[PSvmoveto].command,
  1355. item->kind.text.text,
  1356. psc[PSnormal].command);
  1357. break;
  1358. case SciPlotClipRegion:
  1359. fprintf(fd, "%.2f %.2f %s %.2f %.2f %s\n",
  1360. item->kind.line.x1,
  1361. yflip - item->kind.line.y1 - item->kind.line.y2,
  1362. psc[PSmoveto].command,
  1363. item->kind.line.x2, item->kind.line.y2,
  1364. psc[PSclipbox].command);
  1365. break;
  1366. case SciPlotClipClear:
  1367. fprintf(fd, "%s\n", psc[PSunclip].command);
  1368. break;
  1369. default:
  1370. break;
  1371. }
  1372. }
  1373. loopcount++;
  1374. item++;
  1375. }
  1376. }
  1377. Boolean
  1378. SciPlotPSCreateFancy (SciPlotWidget w, char *filename, int drawborder, char *titles, Boolean usecolor)
  1379. {
  1380. FILE *fd;
  1381. float scale, xoff, yoff, xmax, ymax, yflip, aspect, border, titlefontsize;
  1382. int i;
  1383. PScommands *p;
  1384. char fontname[128];
  1385. if (!(fd = fopen(filename, "w"))) {
  1386. XtWarning("SciPlotPSCreate: Unable to open postscript file.");
  1387. return False;
  1388. }
  1389. DrawAll(w);
  1390. aspect = (float) w->core.width / (float) w->core.height;
  1391. border = 36.0;
  1392. if (aspect > (612.0 / 792.0)) {
  1393. scale = (612.0 - (2 * border)) / (float) w->core.width;
  1394. xoff = border;
  1395. yoff = (792.0 - (2 * border) - scale * (float) w->core.height) / 2.0;
  1396. xmax = xoff + scale * (float) w->core.width;
  1397. ymax = yoff + scale * (float) w->core.height;
  1398. }
  1399. else {
  1400. scale = (792.0 - (2 * border)) / (float) w->core.height;
  1401. yoff = border;
  1402. xoff = (612.0 - (2 * border) - scale * (float) w->core.width) / 2.0;
  1403. xmax = xoff + s

Large files files are truncated, but you can click here to view the full file