]> git.donarmstrong.com Git - lilypond.git/blob - lily/align-element.cc
patch::: 1.3.9.hwn2
[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--1999 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::do_post_processing()
18 {
19   if (axis () == Y_AXIS)
20     do_side_processing ();
21 }
22
23 void
24 Align_element::do_pre_processing ()
25 {
26   if (axis () == X_AXIS)
27     do_side_processing ();
28 }
29
30 void
31 Align_element::do_side_processing ()
32 {
33   Array<Interval> dims;
34
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++) 
38     {
39       Interval y = all_elts[i]->extent(axis ()) + all_elts[i]->relative_coordinate (this, axis ());
40       if (!y.empty_b())
41         {
42           Score_element *e =dynamic_cast<Score_element*>(all_elts[i]);
43
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)
47             {
48               y.unite (Interval (gh_scm2double (SCM_CAR (min_dims)),
49                                  gh_scm2double (SCM_CDR (min_dims))));
50             }
51           
52           SCM extra_dims = e->remove_elt_property ("extra-space");
53           if (extra_dims != SCM_UNDEFINED)
54             {
55               y[LEFT] += gh_scm2double (SCM_CAR (extra_dims));
56               y[RIGHT] += gh_scm2double (SCM_CDR (extra_dims));
57             }
58
59           elems.push (e);
60           dims.push (y);          
61         }
62     }
63
64   Real where_f=0;
65   Real center_f = 0.0;
66   SCM scenter = get_elt_property ("center-element");
67   Score_element *center_elt = (SMOB_IS_TYPE_B(Score_element,scenter))
68     ? SMOB_TO_TYPE(Score_element,scenter) : 0;
69   
70   for (int i=0 ;  i < elems.size(); i++) 
71     {
72       Real dy = - stacking_dir_ * dims[i][-stacking_dir_];
73       if (i)
74         dy += stacking_dir_ * dims[i-1][stacking_dir_];
75
76       if (i)
77         {
78           dy = (dy >? threshold_interval_[SMALLER] )
79             <? threshold_interval_[BIGGER];
80         }
81
82       if (!i && align_dir_ == LEFT)
83         center_f = where_f;
84       else if (align_dir_ == CENTER && elems[i] == center_elt)
85         center_f = where_f;
86
87       where_f += stacking_dir_ * dy;
88       elems[i]->translate_axis (where_f, axis ());
89     }
90
91   if (dims.size ())
92     where_f += dims.top ()[stacking_dir_];
93   if (align_dir_ == RIGHT)
94     center_f = where_f;
95   else if (align_dir_ == CENTER && !center_elt)
96     center_f = where_f / 2;
97     
98   if (center_f)
99     translate_axis ( - center_f, axis ());
100
101   dim_cache_[axis ()]->invalidate ();
102 }
103
104 Align_element::Align_element()
105 {
106   ordered_b_ = true;
107   threshold_interval_ = Interval (0, Interval::infinity ());
108   stacking_dir_ = DOWN;
109   align_dir_ = CENTER;
110 }
111
112 int
113 Align_element::get_count (Score_element*s)const
114 {
115   SCM e = get_elt_property ("elements");
116   int c =0;
117   while (gh_pair_p (e))
118     {
119       if (gh_car (e) == s->self_scm_)
120         break;
121       c++;
122       e = gh_cdr (e);
123     }
124   return c;
125 }
126
127 Axis
128 Align_element::axis () const
129 {
130   return axes_[0];
131 }
132
133 void
134 Align_element::set_axis (Axis a)
135 {
136   set_axes (a,a);
137 }
138
139
140
141
142
143