lilypond-1.3.11
[lilypond.git] / lily / align-element.cc
blob5f4080015c39040d4b9a1b3f2f90e4e2c3c47244
1 /*
2 align-elem.cc -- implement Align_elem
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7 */
9 #include "align-element.hh"
10 #include "interval.hh"
11 #include "direction.hh"
12 #include "debug.hh"
13 #include "hash-table-iter.hh"
14 #include "dimension-cache.hh"
16 void
17 Align_element::do_post_processing()
19 if (axis () == Y_AXIS)
20 do_side_processing ();
23 void
24 Align_element::do_pre_processing ()
26 if (axis () == X_AXIS)
27 do_side_processing ();
30 void
31 Align_element::do_side_processing ()
33 Array<Interval> dims;
35 Link_array<Score_element> elems;
36 Link_array<Score_element> all_elts (elem_l_arr ());
37 for (int i=0; i < elem_l_arr ().size(); i++)
39 Interval y = all_elts[i]->extent(axis ()) + all_elts[i]->relative_coordinate (this, axis ());
40 if (!y.empty_b())
42 Score_element *e =dynamic_cast<Score_element*>(all_elts[i]);
44 // todo: fucks up if item both in Halign & Valign.
45 SCM min_dims = e->remove_elt_property ("minimum-space");
46 if (min_dims != SCM_UNDEFINED)
48 y.unite (Interval (gh_scm2double (SCM_CAR (min_dims)),
49 gh_scm2double (SCM_CDR (min_dims))));
52 SCM extra_dims = e->remove_elt_property ("extra-space");
53 if (extra_dims != SCM_UNDEFINED)
55 y[LEFT] += gh_scm2double (SCM_CAR (extra_dims));
56 y[RIGHT] += gh_scm2double (SCM_CDR (extra_dims));
59 elems.push (e);
60 dims.push (y);
64 Real where_f=0;
65 Real center_f = 0.0;
66 SCM scenter = get_elt_property ("center-element");
67 Score_element *center_elt = unsmob_element (scenter);
69 for (int i=0 ; i < elems.size(); i++)
71 Real dy = - stacking_dir_ * dims[i][-stacking_dir_];
72 if (i)
73 dy += stacking_dir_ * dims[i-1][stacking_dir_];
75 if (i)
77 dy = (dy >? threshold_interval_[SMALLER] )
78 <? threshold_interval_[BIGGER];
81 if (!i && align_dir_ == LEFT)
82 center_f = where_f;
83 else if (align_dir_ == CENTER && elems[i] == center_elt)
84 center_f = where_f;
86 where_f += stacking_dir_ * dy;
87 elems[i]->translate_axis (where_f, axis ());
90 if (dims.size ())
91 where_f += dims.top ()[stacking_dir_];
92 if (align_dir_ == RIGHT)
93 center_f = where_f;
94 else if (align_dir_ == CENTER && !center_elt)
95 center_f = where_f / 2;
97 if (center_f)
98 translate_axis ( - center_f, axis ());
101 // dim_cache_[axis ()]->invalidate ();
105 Align_element::Align_element()
107 threshold_interval_ = Interval (0, Interval::infinity ());
108 stacking_dir_ = DOWN;
109 align_dir_ = CENTER;
113 Align_element::get_count (Score_element*s)const
115 SCM e = get_elt_property ("elements");
116 int c =0;
117 while (gh_pair_p (e))
119 if (gh_car (e) == s->self_scm_)
120 break;
121 c++;
122 e = gh_cdr (e);
124 return c;
127 Axis
128 Align_element::axis () const
130 return axes_[0];
133 void
134 Align_element::set_axis (Axis a)
136 set_axes (a,a);