1 /*
2 * $Id: style.c,v 1.2 2007-12-26 04:25:46 dhmunro Exp $
3 * Set/get details of graphics style for style.i functions.
4 */
5 /* Copyright (c) 2005, The Regents of the University of California.
6 * All rights reserved.
7 * This file is part of yorick (http://yorick.sourceforge.net).
8 * Read the accompanying LICENSE file for details.
9 */
10
11 #include "gist.h"
12 #include "hlevel.h"
13 #include "draw.h"
14
15 /* various X headers included by xfancy.h define True and False */
16 #undef True
17 #undef False
18
19 #include "ydata.h"
20 #include "pstdlib.h"
21
22 typedef struct GfakeSystem GfakeSystem;
23 struct GfakeSystem {
24 double viewport[4]; /* [xmin,xmax,ymin,ymax] in NDC coordinates */
25 GaTickStyle ticks; /* tick style for this coordinate system */
26 char *legend; /* e.g.- "System 0" or "System 1", p_malloc */
27 };
28
29 /* If nsys==0, this is a query operation which fills in the input
30 data arrays (if the pointers are non-zero)
31 otherwise, systems is systems[nsys], and the operation is to
32 set the values specified in the data arrays
33 the return value is always the number of coordinate systems;
34 for queries the routine must be called twice, first with systems==0
35 to retrieve the number of systems, then with a large enough systems
36 to hold the returned values */
37 extern int raw_style(long nsys, int *landscape,
38 GfakeSystem *systems, GeLegendBox *legends);
39
40 extern BuiltIn Y_viewport;
41
42 /* write wrapper routine by hand -- someday should let codger do it */
43 extern BuiltIn Y_raw_style;
Y_raw_style(int nArgs)44 void Y_raw_style(int nArgs)
45 {
46 if (nArgs!=4) YError("raw_style takes exactly 4 arguments");
47 PushIntValue(raw_style(yarg_si(3),yarg_i(2,0),*yarg_p(1,0),*yarg_p(0,0)));
48 }
49
raw_style(long nsys,int * landscape,GfakeSystem * systems,GeLegendBox * legends)50 int raw_style(long nsys, int *landscape,
51 GfakeSystem *systems, GeLegendBox *legends)
52 {
53 extern int YCurrentPlotter(void); /* defined in graph.c */
54 int nsy= YCurrentPlotter();
55 Drauing *drawing= (nsy>=0 && nsy<GH_NDEVS)? ghDevices[nsy].drawing : 0;
56 GeSystem *sys= drawing? drawing->systems : 0;
57
58 if (!nsys) {
59 /* query operation */
60 if (!drawing) return 0;
61 if (landscape) *landscape= drawing->landscape;
62 nsy= drawing->nSystems;
63 if (systems && nsy>0) {
64 int i;
65 for (i=0 ; i<nsy ; i++,sys=(GeSystem *)sys->el.next) {
66 if (systems[i].legend) {
67 char *legend= systems[i].legend;
68 systems[i].legend= 0;
69 p_free(legend);
70 }
71 systems[i].legend= p_strcpy(sys->el.legend);
72 systems[i].viewport[0]= sys->trans.viewport.xmin;
73 systems[i].viewport[1]= sys->trans.viewport.xmax;
74 systems[i].viewport[2]= sys->trans.viewport.ymin;
75 systems[i].viewport[3]= sys->trans.viewport.ymax;
76 /* lazy today -- use ANSI struct assignment */
77 systems[i].ticks= sys->ticks;
78 }
79 }
80 if (legends) {
81 /* lazy today -- use ANSI struct assignment */
82 legends[0]= drawing->legends[0];
83 legends[1]= drawing->legends[1];
84 }
85 return nsy;
86
87 } else {
88 /* set new style operation */
89 int i;
90 extern void GdKillSystems(void); /* defined in draw.c */
91 GpBox vp;
92
93 if (!landscape || !systems || !legends)
94 YError("missing data in Y_raw_style call");
95
96 /* don't clobber the current display list(s) unless the
97 number of coordinate systems has changed */
98 nsy= drawing? drawing->nSystems : 0;
99 if (nsy != nsys) GdKillSystems();
100
101 for (i=0 ; i<nsys ; i++) {
102 gistD.hidden= 0;
103 gistD.legend= systems[i].legend;
104 vp.xmin= systems[i].viewport[0];
105 vp.xmax= systems[i].viewport[1];
106 vp.ymin= systems[i].viewport[2];
107 vp.ymax= systems[i].viewport[3];
108 if (nsy==nsys) {
109 GdSetSystem(i+1);
110 /* don't bother with the legend */
111 gistD.trans.viewport.xmin= vp.xmin;
112 gistD.trans.viewport.xmax= vp.xmax;
113 gistD.trans.viewport.ymin= vp.ymin;
114 gistD.trans.viewport.ymax= vp.ymax;
115 /* lazy today -- use ANSI struct assignment */
116 gistD.ticks= systems[i].ticks;
117 GdSetPort();
118 } else if (GdNewSystem(&vp, &systems[i].ticks)<0) {
119 gistD.legend= 0;
120 YError("GdNewSystem failed in Y_raw_style");
121 }
122 gistD.legend= 0;
123 }
124 if (nsys && nsy==nsys) GdSetSystem(1);
125
126 for (i=0 ; i<2 ; i++)
127 GdLegendBox(i, legends[i].x, legends[i].y,
128 legends[i].dx, legends[i].dy,
129 &legends[i].textStyle, legends[i].nchars,
130 legends[i].nlines, legends[i].nwrap);
131
132 GdLandscape(*landscape);
133
134 return (int)nsys;
135 }
136 }
137
Y_viewport(int nArgs)138 void Y_viewport(int nArgs)
139 {
140 Array *array=
141 PushDataBlock(NewArray(&doubleStruct,
142 NewDimension(4L, 1L, (Dimension *)0)));
143 double *port= array->value.d;
144 array->type.dims->references--;
145 port[0]= gistD.trans.viewport.xmin;
146 port[1]= gistD.trans.viewport.xmax;
147 port[2]= gistD.trans.viewport.ymin;
148 port[3]= gistD.trans.viewport.ymax;
149 }
150