lilypond-1.3.15
[lilypond.git] / lily / molecule.cc
blob710ee8b397298b6bad669b8c3510bb9c8ad46578
1 /*
2 molecule.cc -- implement Molecule
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
9 #include "interval.hh"
10 #include "string.hh"
11 #include "molecule.hh"
12 #include "atom.hh"
13 #include "debug.hh"
15 #include "killing-cons.tcc"
17 #ifdef ATOM_SMOB
18 #define MOL_EOL SCM_EOL
19 #define NEXT_CELL(a) gh_cdr(a)
20 #define CELLTYPE SCM
21 #define UNBOX_ATOM(a) Atom::atom_l (a)
22 #define BOX_ATOM(a) a->make_smob ()
23 #define NEWCELL(a,b) gh_cons (a,b)
24 #define UNBOX_PTR(a) gh_car (a)
25 #else
26 #define MOL_EOL 0
27 #define NEXT_CELL(a) ptr->next_
28 #define CELLTYPE Cons<Atom>*
29 #define UNBOX_ATOM(a) a
30 #define UNBOX_PTR(a) a->car_
31 #define BOX_ATOM(a) a
32 #define NEWCELL(a,b) new Killing_cons<Atom>(a,b)
33 #endif
35 Box
36 Molecule::extent() const
38 return dim_;
41 Interval
42 Molecule::extent(Axis a) const
44 return dim_[a];
47 void
48 Molecule::translate (Offset o)
50 for (CELLTYPE ptr = atom_list_; ptr != MOL_EOL; ptr = NEXT_CELL(ptr))
52 UNBOX_ATOM(UNBOX_PTR(ptr))->off_ += o;
54 if (!empty_b ())
55 dim_.translate (o);
58 void
59 Molecule::translate_axis (Real x,Axis a)
61 for (CELLTYPE ptr = atom_list_; ptr != MOL_EOL; ptr = NEXT_CELL(ptr))
62 UNBOX_ATOM (UNBOX_PTR(ptr))->off_[a] += x;
64 if (!dim_[a].empty_b ())
65 dim_[a] += x;
68 void
69 Molecule::add_molecule (Molecule const &m)
71 for (CELLTYPE ptr = m.atom_list_; ptr != MOL_EOL; ptr = NEXT_CELL(ptr))
72 add_atom(UNBOX_ATOM (UNBOX_PTR(ptr)));
74 dim_.unite (m.dim_);
77 void
78 Molecule::add_atom (Atom const *al)
80 Atom *a = new Atom(*al);
82 atom_list_ = NEWCELL(BOX_ATOM(a), atom_list_);
85 void
86 Molecule::operator=(Molecule const & src)
88 if (&src == this) return;
90 #ifndef ATOM_SMOB
91 delete atom_list_;
92 #endif
94 atom_list_ = MOL_EOL;
95 dim_= src.dim_;
96 add_molecule (src);
99 void
100 Molecule::set_empty (bool e)
102 if (e)
104 dim_[X_AXIS].set_empty ();
105 dim_[Y_AXIS].set_empty ();
107 else
109 dim_[X_AXIS] = Interval(0,0);
110 dim_[Y_AXIS] = Interval (0,0);
114 Molecule::Molecule (Molecule const &s)
116 atom_list_ = MOL_EOL;
117 set_empty (true);
118 add_molecule (s);
121 Molecule::~Molecule ()
123 #ifndef ATOM_SMOB
124 delete atom_list_;
125 #endif
128 void
129 Molecule::print() const
131 #ifndef NPRINT
132 if (! flower_dstream)
133 return;
134 DEBUG_OUT << "dim:";
135 for (Axis i=X_AXIS; i < NO_AXES; incr (i))
136 DEBUG_OUT << axis_name_str (i) << " = " << dim_[i].str ();
137 #endif
140 void
141 Molecule::align_to (Axis a, Direction d)
143 if (d == CENTER)
145 Interval i (extent (a));
146 translate_axis (-i.center (), a);
148 else
150 translate_axis (-extent (a)[d], a);
154 Molecule::Molecule ()
156 dim_[X_AXIS].set_empty ();
157 dim_[Y_AXIS].set_empty ();
158 atom_list_ = MOL_EOL;
162 void
163 Molecule::add_at_edge (Axis a, Direction d, Molecule const &m, Real padding)
165 Real my_extent= empty_b () ? 0.0 : dim_[a][d];
166 Interval i (m.extent ()[a]);
167 if (i.empty_b ())
168 programming_error ("Molecule::add_at_edge: adding empty molecule.");
170 Real his_extent = i[-d];
171 Real offset = my_extent - his_extent;
172 Molecule toadd (m);
173 toadd.translate_axis (offset + d * padding, a);
174 add_molecule (toadd);
177 bool
178 Molecule::empty_b () const
180 return atom_list_ == MOL_EOL;