]> git.donarmstrong.com Git - lilypond.git/blob - lily/molecule.cc
release: 1.3.56
[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
9 #include <math.h>
10
11 #include "font-metric.hh"
12 #include "dimensions.hh"
13 #include "interval.hh"
14 #include "string.hh"
15 #include "molecule.hh"
16 #include "debug.hh"
17 #include "killing-cons.tcc"
18
19 Interval
20 Molecule::extent(Axis a) const
21 {
22   return dim_[a];
23 }
24
25 Molecule::Molecule (Box b, SCM func)
26 {
27   expr_ = func;
28   dim_ = b;
29 }
30
31 Molecule::Molecule()
32 {
33   expr_ = SCM_EOL;
34   set_empty (true);
35 }
36
37 void
38 Molecule::translate (Offset o)
39 {
40   Axis a = X_AXIS;
41   while (a < NO_AXES)
42     {
43       if (abs(o[a]) > 30 CM
44           || isinf (o[a]) || isnan (o[a]))
45         {
46           programming_error ("Improbable offset for translation: setting to zero");
47           o[a] =  0.0;
48         }
49       incr (a);
50     }
51
52   expr_ = gh_list (ly_symbol2scm ("translate-molecule"),
53                    ly_offset2scm (o),
54                    expr_, SCM_UNDEFINED);
55   if (!empty_b ())
56     dim_.translate (o);
57 }
58   
59
60 void
61 Molecule::translate_axis (Real x,Axis a)
62 {
63   Offset o(0,0);
64   o[a] = x;
65   translate (o);
66 }  
67
68
69
70 void
71 Molecule::add_molecule (Molecule const &m)
72 {
73   expr_ = gh_list (ly_symbol2scm ("combine-molecule"),
74                    m.expr_,
75                    expr_, SCM_UNDEFINED);
76   dim_.unite (m.dim_);
77 }
78
79 void
80 Molecule::set_empty (bool e)
81 {
82   if (e)
83     {
84       dim_[X_AXIS].set_empty ();
85       dim_[Y_AXIS].set_empty ();
86     }
87   else
88     {
89       dim_[X_AXIS] = Interval(0,0);
90       dim_[Y_AXIS] = Interval (0,0);
91     }
92 }
93
94
95 void
96 Molecule::align_to (Axis a, Direction d)
97 {
98   Interval i (extent (a));
99   Real r =  (d == CENTER) ? i.center () : i[d];
100   translate_axis (-r, a);
101 }
102
103 void
104 Molecule::add_at_edge (Axis a, Direction d, Molecule const &m, Real padding)
105 {
106   Real my_extent= empty_b () ? 0.0 : dim_[a][d];
107   Interval i (m.extent (a));
108   if (i.empty_b ())
109     programming_error ("Molecule::add_at_edge: adding empty molecule.");
110   
111   Real his_extent = i[-d];
112   Real offset = my_extent -  his_extent;
113   Molecule toadd (m);
114   toadd.translate_axis (offset + d * padding, a);
115   add_molecule (toadd);
116 }
117
118 bool
119 Molecule::empty_b () const
120 {
121   return expr_ == SCM_EOL;
122 }
123
124 SCM
125 fontify_atom(Font_metric * met, SCM f)
126 {
127   return  gh_list (ly_symbol2scm ("fontify"),
128                    ly_quote_scm (met->description ()), f, SCM_UNDEFINED);
129 }
130
131 SCM
132 Molecule::get_expr () const
133 {
134   return expr_;
135 }
136
137 Molecule
138 create_molecule (SCM scm_mol)
139 {
140   if (!gh_pair_p (scm_mol))
141     return Molecule ();
142
143   SCM exp = gh_car (scm_mol);
144   scm_mol = gh_cdr (scm_mol);
145   Box b ;
146   if (gh_pair_p (scm_mol))
147     {
148       Interval i1 = ly_scm2interval (gh_car (scm_mol));
149       Interval i2 = ly_scm2interval (gh_cdr (scm_mol));  
150       b = Box (i1,i2);
151     }
152   return Molecule (b, exp);
153 }
154
155 SCM
156 Molecule::create_scheme () const
157 {
158   return gh_cons (expr_,
159                   gh_cons (ly_interval2scm (dim_[X_AXIS]),
160                            ly_interval2scm (dim_[Y_AXIS])));
161 }