]> git.donarmstrong.com Git - lilypond.git/blob - lily/align-element.cc
c75902783b546eabf421fc36630cb62d60ba288f
[lilypond.git] / lily / align-element.cc
1 /*
2   align-elem.cc -- implement Align_elem
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 "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"
15
16 void
17 Align_element::after_line_breaking()
18 {
19   if (axis () == Y_AXIS)
20     do_side_processing ();
21 }
22
23 void
24 Align_element::before_line_breaking ()
25 {
26   if (axis () == X_AXIS)
27     do_side_processing ();
28 }
29
30 void
31 Align_element::do_side_processing ()
32 {
33   SCM d = get_elt_property ("stacking-dir");
34   Direction stacking_dir = gh_number_p(d) ? to_dir (d) : CENTER;
35   if (!stacking_dir)
36     stacking_dir = DOWN;
37
38   
39   Array<Interval> dims;
40
41   Link_array<Score_element> elems;
42   Link_array<Score_element> all_elts (elem_l_arr ());
43   for (int i=0; i < all_elts.size(); i++) 
44     {
45       Interval y = all_elts[i]->extent(axis ()) + all_elts[i]->relative_coordinate (this, axis ());
46       if (!y.empty_b())
47         {
48           Score_element *e =dynamic_cast<Score_element*>(all_elts[i]);
49
50           // todo: fucks up if item both in Halign & Valign. 
51           SCM min_dims = e->remove_elt_property ("minimum-space");
52           if (gh_pair_p (min_dims) &&
53               gh_number_p (gh_car (min_dims))
54               && gh_number_p (gh_cdr (min_dims)))
55             {
56               y.unite (Interval (gh_scm2double (gh_car  (min_dims)),
57                                  gh_scm2double (gh_cdr (min_dims))));
58             }
59           
60           SCM extra_dims = e->remove_elt_property ("extra-space");
61           if (gh_pair_p (extra_dims) &&
62               gh_number_p (gh_car (extra_dims))
63               && gh_number_p (gh_cdr (extra_dims)))
64             {
65               y[LEFT] += gh_scm2double (gh_car  (extra_dims));
66               y[RIGHT] += gh_scm2double (gh_cdr (extra_dims));
67             }
68
69           elems.push (e);
70           dims.push (y);          
71         }
72     }
73
74   Real where_f=0;
75   for (int i=0 ;  i < elems.size(); i++) 
76     {
77       Real dy = - stacking_dir * dims[i][-stacking_dir];
78       if (i)
79         dy += stacking_dir * dims[i-1][stacking_dir];
80
81       if (i)
82         {
83           dy = (dy >? threshold_interval_[SMALLER] )
84             <? threshold_interval_[BIGGER];
85         }
86
87
88       where_f += stacking_dir * dy;
89       elems[i]->translate_axis (where_f, axis ());
90     }
91 }
92
93 Align_element::Align_element()
94 {
95   threshold_interval_ = Interval (0, Interval::infinity ());
96 }
97
98 int
99 Align_element::get_count (Score_element*s)const
100 {
101   SCM e = get_elt_property ("elements");
102   int c =0;
103   while (gh_pair_p (e))
104     {
105       if (gh_car (e) == s->self_scm_)
106         break;
107       c++;
108       e = gh_cdr (e);
109     }
110   return c;
111 }
112
113 Axis
114 Align_element::axis () const
115 {
116   return axes_[0];
117 }
118
119 void
120 Align_element::set_axis (Axis a)
121 {
122   set_axes (a,a);
123 }
124
125
126
127
128
129