]> git.donarmstrong.com Git - lilypond.git/blob - lily/molecule.cc
45fa78b7ec5a5a019fd9a87d263e799beaf12ecc
[lilypond.git] / lily / molecule.cc
1 /*
2   molecule.cc -- implement Molecule
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
8 #include <math.h>
9
10 #include "interval.hh"
11 #include "string.hh"
12 #include "molecule.hh"
13 #include "atom.hh"
14 #include "debug.hh"
15 #include "killing-cons.tcc"
16
17
18 Box
19 Molecule::extent() const
20 {
21   return dim_;
22 }
23
24 Interval
25 Molecule::extent(Axis a) const
26 {
27   return dim_[a];
28 }
29
30 void
31 Molecule::translate (Offset o)
32 {
33   if (isinf (o.length ()))
34     {
35       programming_error ("Translating infinitely. Ignore.");
36       return;
37     }
38     
39   for (SCM ptr = gh_cdr (atom_list_);  ptr != SCM_EOL; ptr = gh_cdr(ptr))
40     {
41       unsmob_atom (gh_car (ptr))->off_ += o;
42     }
43   if (!empty_b ())
44     dim_.translate (o);
45 }
46
47 void
48 Molecule::translate_axis (Real x,Axis a)
49 {
50   if (isinf (x))
51     {
52       programming_error ("Translating infinitely. Ignore.");
53       return;
54     }
55   for (SCM ptr = gh_cdr (atom_list_);  ptr != SCM_EOL; ptr = gh_cdr(ptr))
56     {
57       unsmob_atom (gh_car (ptr))->off_[a] += x;
58     }
59
60   if (!dim_[a].empty_b ())
61     dim_[a] += x;
62 }
63
64 void
65 Molecule::add_molecule (Molecule const &m)
66 {
67   for (SCM ptr = gh_cdr (m.atom_list_);  ptr != SCM_EOL; ptr = gh_cdr(ptr))
68     {
69       Atom *a = new Atom (*unsmob_atom (gh_car (ptr)));
70       add_atom (a->self_scm_);
71     }
72   dim_.unite (m.dim_);
73 }
74
75 void
76 Molecule::add_atom (SCM atomsmob)
77 {
78   gh_set_cdr_x (atom_list_,
79                 gh_cons  (atomsmob, gh_cdr (atom_list_)));
80
81   scm_unprotect_object (atomsmob);
82 }
83
84 void
85 Molecule::operator=(Molecule const & src)
86 {
87   if (&src == this)
88     return;
89
90   atom_list_ = gh_cons (SCM_EOL,SCM_EOL);
91   dim_= src.dim_;
92   add_molecule (src);
93 }
94
95 void
96 Molecule::set_empty (bool e)
97 {
98   if (e)
99     {
100       dim_[X_AXIS].set_empty ();
101       dim_[Y_AXIS].set_empty ();
102     }
103   else
104     {
105       dim_[X_AXIS] = Interval(0,0);
106       dim_[Y_AXIS] = Interval (0,0);
107     }
108 }
109
110 void
111 Molecule::print () const
112 {
113 #ifndef NPRINT
114   for (SCM ptr = gh_cdr (atom_list_);  ptr != SCM_EOL; ptr = gh_cdr(ptr))
115     gh_display (gh_car (ptr));
116 #endif
117 }
118
119 Molecule::Molecule (Molecule const &s)
120 {
121   atom_list_ = gh_cons (SCM_EOL, SCM_EOL);
122   set_empty (true);
123   add_molecule (s);
124 }
125
126 Molecule::~Molecule ()
127 {
128 }
129
130
131 void
132 Molecule::align_to (Axis a, Direction d)
133 {
134   if (d == CENTER)
135     {
136       Interval i (extent (a));
137       translate_axis (-i.center (), a);
138     }
139   else
140     {
141       translate_axis (-extent (a)[d], a);
142     }
143 }
144
145 Molecule::Molecule ()
146 {
147   dim_[X_AXIS].set_empty ();
148   dim_[Y_AXIS].set_empty ();
149   atom_list_ = gh_cons (SCM_EOL, SCM_EOL);
150 }
151
152
153 void
154 Molecule::add_at_edge (Axis a, Direction d, Molecule const &m, Real padding)
155 {
156   Real my_extent= empty_b () ? 0.0 : dim_[a][d];
157   Interval i (m.extent ()[a]);
158   if (i.empty_b ())
159     programming_error ("Molecule::add_at_edge: adding empty molecule.");
160   
161   Real his_extent = i[-d];
162   Real offset = my_extent -  his_extent;
163   Molecule toadd (m);
164   toadd.translate_axis (offset + d * padding, a);
165   add_molecule (toadd);
166 }
167
168 bool
169 Molecule::empty_b () const
170 {
171   return gh_cdr (atom_list_) == SCM_EOL;
172 }