NEURON
grglyph.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 // hoc level Glyph implementation for graphing
3 #include <stdio.h>
4 #include "classreg.h"
5 #include "oc2iv.h"
6 #if HAVE_IV
7 #include "ivoc.h"
8 #include <InterViews/printer.h>
9 #include <InterViews/image.h>
10 #include "grglyph.h"
11 #include "idraw.h"
12 
13 extern Image* gif_image(const char*);
14 #else
15 #include <InterViews/resource.h>
16 class GrGlyph: public Resource {
17  public:
18  GrGlyph(Object*);
19  virtual ~GrGlyph();
20  Object** temp_objvar();
21 
22  private:
24 };
25 #endif // HAVE_IV
26 
27 #include "gui-redirect.h"
28 
29 double gr_addglyph(void* v) {
30  TRY_GUI_REDIRECT_ACTUAL_DOUBLE("Graph.addglyph", v);
31 #if HAVE_IV
32  if (hoc_usegui) {
33  Graph* g = (Graph*) v;
34  Object* obj = *hoc_objgetarg(1);
35  check_obj_type(obj, "Glyph");
36  GrGlyph* gl = (GrGlyph*) (obj->u.this_pointer);
37  Coord x = *getarg(2);
38  Coord y = *getarg(3);
39  Coord sx = ifarg(4) ? *getarg(4) : 1.;
40  Coord sy = ifarg(5) ? *getarg(5) : 1.;
41  Coord rot = ifarg(6) ? *getarg(6) : 0.;
42  int fix = ifarg(7) ? int(chkarg(7, 0, 2)) : 0;
43  GrGlyphItem* ggi = new GrGlyphItem(gl, sx, sy, rot);
44  switch (fix) {
45  case 0:
46  g->append(ggi);
47  break;
48  case 1:
49  g->append_fixed(ggi);
50  break;
51  case 2:
52  g->append_viewfixed(ggi);
53  break;
54  }
55  g->move(g->count() - 1, x, y);
56  }
57 #endif
58  return 0.;
59 }
60 
61 static Object** g_new_path(void* v) {
62  TRY_GUI_REDIRECT_ACTUAL_OBJ("Glyph.path", v);
63  GrGlyph* g = (GrGlyph*) v;
64 #if HAVE_IV
65  if (hoc_usegui) {
66  g->new_path();
67  }
68 #endif
69  return g->temp_objvar();
70 }
71 
72 static Object** g_move_to(void* v) {
73  TRY_GUI_REDIRECT_ACTUAL_OBJ("Glyph.m", v);
74  GrGlyph* g = (GrGlyph*) v;
75 #if HAVE_IV
76  if (hoc_usegui) {
77  g->move_to(*getarg(1), *getarg(2));
78  }
79 #endif
80  return g->temp_objvar();
81 }
82 
83 static Object** g_line_to(void* v) {
84  TRY_GUI_REDIRECT_ACTUAL_OBJ("Glyph.l", v);
85  GrGlyph* g = (GrGlyph*) v;
86 #if HAVE_IV
87  if (hoc_usegui) {
88  g->line_to(*getarg(1), *getarg(2));
89  }
90 #endif
91  return g->temp_objvar();
92 }
93 
94 static Object** g_control_point(void* v) {
95  TRY_GUI_REDIRECT_ACTUAL_OBJ("Glyph.cpt", v);
96  GrGlyph* g = (GrGlyph*) v;
97 #if HAVE_IV
98  if (hoc_usegui) {
99  g->control_point(*getarg(1), *getarg(2));
100  }
101 #endif
102  return g->temp_objvar();
103 }
104 
105 static Object** g_curve_to(void* v) {
106  TRY_GUI_REDIRECT_ACTUAL_OBJ("Glyph.curve", v);
107  GrGlyph* g = (GrGlyph*) v;
108 #if HAVE_IV
109  if (hoc_usegui) {
110  g->curve_to(*getarg(1), *getarg(2), *getarg(3), *getarg(4), *getarg(5), *getarg(6));
111  }
112 #endif
113  return g->temp_objvar();
114 }
115 
116 static Object** g_stroke(void* v) {
117  TRY_GUI_REDIRECT_ACTUAL_OBJ("Glyph.s", v);
118  GrGlyph* g = (GrGlyph*) v;
119 #if HAVE_IV
120  if (hoc_usegui) {
121  int ci = ifarg(1) ? int(chkarg(1, 0, 10000)) : 1;
122  int bi = ifarg(2) ? int(chkarg(2, 0, 10000)) : 0;
123  g->stroke(ci, bi);
124  }
125 #endif
126  return g->temp_objvar();
127 }
128 
129 static Object** g_close_path(void* v) {
130  TRY_GUI_REDIRECT_ACTUAL_OBJ("Glyph.close", v);
131  GrGlyph* g = (GrGlyph*) v;
132 #if HAVE_IV
133  if (hoc_usegui) {
134  g->close_path();
135  }
136 #endif
137  return g->temp_objvar();
138 }
139 
140 static Object** g_fill(void* v) {
141  TRY_GUI_REDIRECT_ACTUAL_OBJ("Glyph.fill", v);
142  GrGlyph* g = (GrGlyph*) v;
143 #if HAVE_IV
144  if (hoc_usegui) {
145  int ci = ifarg(1) ? int(chkarg(1, 0, 10000)) : 1;
146  g->fill(ci);
147  }
148 #endif
149  return g->temp_objvar();
150 }
151 
152 static Object** g_erase(void* v) {
153  TRY_GUI_REDIRECT_ACTUAL_OBJ("Glyph.erase", v);
154  GrGlyph* g = (GrGlyph*) v;
155 #if HAVE_IV
156  if (hoc_usegui) {
157  g->erase();
158  }
159 #endif
160  return g->temp_objvar();
161 }
162 
163 static Object** g_circle(void* v) {
164  TRY_GUI_REDIRECT_ACTUAL_OBJ("Glyph.circle", v);
165  GrGlyph* g = (GrGlyph*) v;
166 #if HAVE_IV
167  if (hoc_usegui) {
168  g->circle(*getarg(1), *getarg(2), *getarg(3));
169  }
170 #endif
171  return g->temp_objvar();
172 }
173 
174 static Object** g_gif(void* v) {
175  TRY_GUI_REDIRECT_ACTUAL_OBJ("Glyph.gif", v);
176  GrGlyph* g = (GrGlyph*) v;
177 #if HAVE_IV
178  if (hoc_usegui) {
179  g->gif(gargstr(1));
180  }
181 #endif
182  return g->temp_objvar();
183 }
184 
185 static Symbol* sggl_;
186 
188  {"m", g_move_to},
189  {"l", g_line_to},
190  {"s", g_stroke},
191  {"close", g_close_path},
192  {"fill", g_fill},
193  {"curve", g_curve_to},
194  {"cpt", g_control_point},
195  {"erase", g_erase},
196  {"gif", g_gif},
197  {"circle", g_circle},
198  {nullptr, nullptr}};
199 
200 static void* cons(Object* o) {
201  TRY_GUI_REDIRECT_OBJ("Glyph", NULL);
202  GrGlyph* g = new GrGlyph(o);
203  g->ref();
204  return g;
205 }
206 
207 static void destruct(void* v) {
208  TRY_GUI_REDIRECT_NO_RETURN("~Glyph", v);
209  GrGlyph* g = (GrGlyph*) v;
210  g->unref();
211 }
212 
213 void GrGlyph_reg() {
214  class2oc("Glyph", cons, destruct, nullptr, objmembers, nullptr);
215  sggl_ = hoc_lookup("Glyph");
216 }
217 
219  obj_ = o;
220 #if HAVE_IV
221  if (hoc_usegui) {
222  type_ = new DataVec(10);
223  x_ = new DataVec(10);
224  y_ = new DataVec(10);
225  type_->ref();
226  x_->ref();
227  y_->ref();
228  gif_ = NULL;
229  }
230 #endif
231 }
232 
234 #if HAVE_IV
235  if (hoc_usegui) {
236  type_->unref();
237  x_->unref();
238  y_->unref();
240  }
241 #endif
242 }
243 
245  GrGlyph* gg = (GrGlyph*) this;
246  Object** po;
247  po = hoc_temp_objptr(gg->obj_);
248  return po;
249 }
250 
251 #if HAVE_IV
252 
253 GrGlyphItem::GrGlyphItem(Glyph* g, float sx, float sy, float angle)
254  : GraphItem(g) {
255  t_.scale(sx, sy);
256  t_.rotate(angle);
257 }
259 
260 void GrGlyphItem::allocate(Canvas* c, const Allocation& a, Extension& e) {
261  e.set(c, a);
262 }
263 
264 void GrGlyphItem::draw(Canvas* c, const Allocation& a) const {
265  c->push_transform();
266  Transformer t = t_;
267  t.translate(a.x(), a.y());
268  c->transform(t);
269  IfIdraw(pict(t));
270  // float m1, m2, m3,m4,m5,m6;
271  // t.matrix(m1,m2,m3,m4,m5,m6);
272  // printf("transformer %g %g %g %g %g %g\n", m1,m2,m3,m4,m5,m6);
273  body()->draw(c, a);
274  c->pop_transform();
275  IfIdraw(end());
276 }
277 
278 void GrGlyphItem::print(Printer* c, const Allocation& a) const {
279  draw(c, a);
280 }
281 
282 void GrGlyph::gif(const char* file) {
283  gif_ = gif_image(file);
284 }
285 void GrGlyph::new_path() {
286  type_->add(1);
287 }
288 void GrGlyph::move_to(Coord x, Coord y) {
289  type_->add(2);
290  x_->add(x);
291  y_->add(y);
292 }
293 void GrGlyph::line_to(Coord x, Coord y) {
294  type_->add(3);
295  x_->add(x);
296  y_->add(y);
297 }
298 void GrGlyph::curve_to(Coord x, Coord y, Coord x1, Coord y1, Coord x2, Coord y2) {
299  type_->add(4);
300  x_->add(x);
301  y_->add(y);
302  x_->add(x1);
303  y_->add(y1);
304  x_->add(x2);
305  y_->add(y2);
306 }
307 void GrGlyph::close_path() {
308  type_->add(5);
309 }
310 void GrGlyph::circle(Coord x, Coord y, Coord r) {
311  const Coord p0 = 1.00000000 * r;
312  const Coord p1 = 0.89657547 * r; // cos 30 * sqrt(1 + tan 15 * tan 15)
313  const Coord p2 = 0.70710678 * r; // cos 45
314  const Coord p3 = 0.51763809 * r; // cos 60 * sqrt(1 + tan 15 * tan 15)
315  const Coord p4 = 0.26794919 * r; // tan 15
316  new_path();
317  move_to(x + p0, y);
318  curve_to(x + p2, y + p2, x + p0, y + p4, x + p1, y + p3);
319  curve_to(x, y + p0, x + p3, y + p1, x + p4, y + p0);
320  curve_to(x - p2, y + p2, x - p4, y + p0, x - p3, y + p1);
321  curve_to(x - p0, y, x - p1, y + p3, x - p0, y + p4);
322  curve_to(x - p2, y - p2, x - p0, y - p4, x - p1, y - p3);
323  curve_to(x, y - p0, x - p3, y - p1, x - p4, y - p0);
324  curve_to(x + p2, y - p2, x + p4, y - p0, x + p3, y - p1);
325  curve_to(x + p0, y, x + p1, y - p3, x + p0, y - p4);
326  close_path();
327 }
328 
329 void GrGlyph::stroke(int ci, int bi) {
330  type_->add(6);
331  type_->add(ci);
332  type_->add(bi);
333 }
334 void GrGlyph::fill(int ci) {
335  type_->add(7);
336  type_->add(ci);
337 }
339  type_->add(8);
340  x_->add(x);
341  y_->add(y);
342 }
343 void GrGlyph::erase() {
344  type_->erase();
345  x_->erase();
346  y_->erase();
347  if (gif_) {
348  gif_->unref();
349  gif_ = NULL;
350  }
351 }
352 
353 void GrGlyph::draw(Canvas* c, const Allocation& a) const {
354  int i, j;
355  Coord x, y;
356  if (gif_) {
357  gif_->draw(c, a);
358  }
359  for (i = 0, j = 0; i < type_->count(); ++i) {
360  switch (int(type_->get_val(i))) {
361  case 1:
362  c->new_path();
363  IfIdraw(new_path());
364  break;
365  case 2:
366  x = x_->get_val(j);
367  y = y_->get_val(j);
368  ++j;
369  c->move_to(x, y);
370  IfIdraw(move_to(x, y));
371  break;
372  case 3:
373  x = x_->get_val(j);
374  y = y_->get_val(j);
375  ++j;
376  c->line_to(x, y);
377  IfIdraw(line_to(x, y));
378  break;
379  case 4:
380  x = x_->get_val(j);
381  y = y_->get_val(j);
382  c->curve_to(x,
383  y,
384  x_->get_val(j + 1),
385  y_->get_val(j + 1),
386  x_->get_val(j + 2),
387  y_->get_val(j + 2));
388  IfIdraw(curve_to(x,
389  y,
390  x_->get_val(j + 1),
391  y_->get_val(j + 1),
392  x_->get_val(j + 2),
393  y_->get_val(j + 2)));
394  j += 3;
395  break;
396  case 5:
397  c->close_path();
398  IfIdraw(close_path());
399  break;
400  case 6:
401  x = type_->get_val(++i);
402  y = type_->get_val(++i);
403  c->stroke(colors->color(int(x)), brushes->brush(int(y)));
404  IfIdraw(stroke(c, colors->color(int(x)), brushes->brush(int(y))));
405  break;
406  case 7:
407  x = type_->get_val(++i);
408  c->fill(colors->color(int(x)));
409  IfIdraw(fill(c, colors->color(int(x))));
410  break;
411  case 8:
412  x = x_->get_val(j);
413  y = y_->get_val(j);
414  ++j;
415  c->transformer().transform(x, y);
416  // printf("x=%g y=%g\n", x, y);
417  c->push_transform();
418  Transformer t;
419  c->transformer(t);
420  c->rect(x - 2, y - 2, x + 2, y + 2, colors->color(1), brushes->brush(0));
421  c->pop_transform();
422  break;
423  }
424  }
425 }
426 
427 void GrGlyph::request(Requisition& r) const {
428  Coord min, max, natural;
429  min = x_->min();
430  max = x_->max();
431  natural = max - min;
432  r.x_requirement().natural(natural);
433  if (natural > 0) {
434  r.x_requirement().alignment(-min / natural);
435  }
436 
437  min = y_->min();
438  max = y_->max();
439  natural = max - min;
440  r.y_requirement().natural(natural);
441  if (natural > 0) {
442  r.y_requirement().alignment(-min / natural);
443  }
444 
445  if (gif_) {
446  gif_->request(r);
447  }
448 }
449 
450 #endif
#define Image
Definition: _defines.h:148
#define Transformer
Definition: _defines.h:313
#define Canvas
Definition: _defines.h:63
#define Coord
Definition: _defines.h:17
#define Printer
Definition: _defines.h:209
#define Glyph
Definition: _defines.h:130
Coord x() const
Definition: geometry.h:286
Coord y() const
Definition: geometry.h:287
const Brush * brush(int) const
const Color * color(int) const
Definition: graph.h:196
void add(float)
float get_val(int i) const
Definition: graph.h:210
float min() const
float max() const
void erase()
int count() const
Definition: graph.h:206
void set(Canvas *, const Allocation &)
virtual void draw(Canvas *, const Allocation &) const
DataVec * y_
Definition: grglyph.h:46
void fill(int color)
virtual ~GrGlyph()
Definition: grglyph.cpp:233
void line_to(Coord, Coord)
void move_to(Coord, Coord)
Object * obj_
Definition: grglyph.cpp:23
void circle(Coord x, Coord y, Coord r)
void new_path()
void erase()
Glyph * gif_
Definition: grglyph.h:48
DataVec * x_
Definition: grglyph.h:45
void stroke(int color, int brush)
virtual void request(Requisition &) const
GrGlyph(Object *)
Definition: grglyph.cpp:218
void close_path()
void control_point(Coord, Coord)
DataVec * type_
Definition: grglyph.h:44
Object ** temp_objvar()
Definition: grglyph.cpp:244
void gif(const char *)
void curve_to(Coord, Coord, Coord, Coord, Coord, Coord)
virtual void allocate(Canvas *, const Allocation &, Extension &)
virtual ~GrGlyphItem()
virtual void draw(Canvas *, const Allocation &) const
Transformer t_
Definition: grglyph.h:18
GrGlyphItem(Glyph *g, float scalex, float scaley, float rot)
virtual void print(Printer *, const Allocation &) const
Definition: graph.h:54
void alignment(float)
Definition: geometry.h:237
void natural(Coord)
Definition: geometry.h:231
const Requirement & x_requirement() const
Definition: geometry.h:245
const Requirement & y_requirement() const
Definition: geometry.h:246
virtual void ref() const
Definition: resource.cpp:42
virtual void unref() const
Definition: resource.cpp:47
void move(GlyphIndex, Coord x, Coord y)
virtual void append_viewfixed(Glyph *)
virtual void append(Glyph *)
virtual GlyphIndex count() const
virtual void append_fixed(Glyph *)
void class2oc(const char *, ctor_f *cons, dtor_f *destruct, Member_func *, Member_ret_obj_func *, Member_ret_str_func *)
Definition: hoc_oop.cpp:1631
char * gargstr(int narg)
Definition: code2.cpp:227
#define v
Definition: md1redef.h:11
#define i
Definition: md1redef.h:19
double chkarg(int, double low, double high)
Definition: code2.cpp:626
BrushPalette * brushes
ColorPalette * colors
static Object ** g_erase(void *v)
Definition: grglyph.cpp:152
static Object ** g_stroke(void *v)
Definition: grglyph.cpp:116
Member_ret_obj_func objmembers[]
Definition: grglyph.cpp:187
static Object ** g_move_to(void *v)
Definition: grglyph.cpp:72
static Object ** g_gif(void *v)
Definition: grglyph.cpp:174
static void destruct(void *v)
Definition: grglyph.cpp:207
static Object ** g_fill(void *v)
Definition: grglyph.cpp:140
double gr_addglyph(void *v)
Definition: grglyph.cpp:29
static Object ** g_circle(void *v)
Definition: grglyph.cpp:163
static Symbol * sggl_
Definition: grglyph.cpp:185
static Object ** g_curve_to(void *v)
Definition: grglyph.cpp:105
static void * cons(Object *o)
Definition: grglyph.cpp:200
static Object ** g_control_point(void *v)
Definition: grglyph.cpp:94
void GrGlyph_reg()
Definition: grglyph.cpp:213
static Object ** g_new_path(void *v)
Definition: grglyph.cpp:61
static Object ** g_line_to(void *v)
Definition: grglyph.cpp:83
static Object ** g_close_path(void *v)
Definition: grglyph.cpp:129
void check_obj_type(Object *obj, const char *type_name)
Definition: hoc_oop.cpp:2098
Symbol * hoc_lookup(const char *)
Definition: symbol.cpp:59
#define TRY_GUI_REDIRECT_ACTUAL_DOUBLE(name, obj)
Definition: gui-redirect.h:55
#define TRY_GUI_REDIRECT_NO_RETURN(name, obj)
Definition: gui-redirect.h:40
#define TRY_GUI_REDIRECT_OBJ(name, obj)
Definition: gui-redirect.h:10
#define TRY_GUI_REDIRECT_ACTUAL_OBJ(name, obj)
Definition: gui-redirect.h:73
static int c
Definition: hoc.cpp:169
int hoc_usegui
Definition: hoc.cpp:121
#define getarg
Definition: hocdec.h:17
Object ** hoc_objgetarg(int)
Definition: code.cpp:1614
#define IfIdraw(arg)
Definition: idraw.h:102
size_t j
int ifarg(int)
Definition: code.cpp:1607
#define NULL
Definition: spdefs.h:105
Object ** hoc_temp_objptr(Object *)
Definition: code.cpp:151
Definition: hocdec.h:173
void * this_pointer
Definition: hocdec.h:178
union Object::@47 u
Definition: model.h:47