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>
9 #include "align-element.hh"
10 #include "interval.hh"
11 #include "direction.hh"
13 #include "hash-table-iter.hh"
15 struct Align_element_content
{
16 Graphical_element
* elem_l_
;
19 static int compare (Align_element_content
const &h1
,
20 Align_element_content
const &h2
)
22 return h1
.priority_i_
- h2
.priority_i_
;
24 Align_element_content (Graphical_element
*elem_l
, int p
)
29 Align_element_content () {
38 Align_element::add_element (Score_element
*el_l
)
40 int p
= elem_l_arr_
.size ();
41 add_element_priority (el_l
, p
);
45 Align_element::add_element_priority (Score_element
*el
, int p
)
47 assert (! contains_b (el
));
48 Axis_group_element::add_element (el
);
49 priority_i_hash_
[el
] = p
;
54 Align_element::do_substitute_element_pointer (Score_element
*o
,
57 Axis_group_element :: do_substitute_element_pointer (o
,n
);
62 if (priority_i_hash_
.elem_b (o
))
64 priority_i_hash_
[n
] = priority_i_hash_
[o
];
66 Huh? It seems the old pointers are still used. Why?
68 // priority_i_hash_.remove (o);
73 Align_element::do_post_processing()
75 if (axis () == Y_AXIS
)
76 do_side_processing ();
80 Align_element::do_pre_processing ()
82 if (axis () == X_AXIS
)
83 do_side_processing ();
87 Align_element::do_side_processing ()
91 Link_array
<Score_element
> elems
;
92 for (int i
=0; i
< elem_l_arr_
.size(); i
++)
94 Interval y
= elem_l_arr_
[i
]->extent(axis ());
98 Score_element
*e
=dynamic_cast<Score_element
*>(elem_l_arr_
[i
]);
100 // todo: fucks up if item both in Halign & Valign.
101 SCM min_dims
= e
->remove_elt_property (minimum_space_scm_sym
);
102 if (min_dims
!= SCM_BOOL_F
)
104 min_dims
= SCM_CDR (min_dims
);
105 y
.unite (Interval (gh_scm2double (SCM_CAR (min_dims
)),
106 gh_scm2double (SCM_CDR (min_dims
))));
109 SCM extra_dims
= e
->remove_elt_property (extra_space_scm_sym
);
110 if (extra_dims
!= SCM_BOOL_F
)
112 extra_dims
= SCM_CDR (extra_dims
);
113 y
[LEFT
] += gh_scm2double (SCM_CAR (extra_dims
));
114 y
[RIGHT
] += gh_scm2double (SCM_CDR (extra_dims
));
124 for (int i
=0 ; i
< elems
.size(); i
++)
126 Real dy
= - stacking_dir_
* dims
[i
][-stacking_dir_
];
128 dy
+= stacking_dir_
* dims
[i
-1][stacking_dir_
];
132 dy
= (dy
>? threshold_interval_
[SMALLER
] )
133 <? threshold_interval_
[BIGGER
];
136 if (!i
&& align_dir_
== LEFT
)
138 else if (align_dir_
== CENTER
&& elems
[i
] == center_l_
)
141 where_f
+= stacking_dir_
* dy
;
142 elems
[i
]->translate_axis (where_f
, axis ());
146 where_f
+= dims
.top ()[stacking_dir_
];
147 if (align_dir_
== RIGHT
)
149 else if (align_dir_
== CENTER
&& !center_l_
)
150 center_f
= where_f
/ 2;
153 translate_axis ( - center_f
, axis ());
155 dim_cache_
[axis ()]->invalidate ();
158 Align_element::Align_element()
161 threshold_interval_
= Interval (0, Interval::infinity ());
162 stacking_dir_
= DOWN
;
165 priority_i_hash_
.hash_func_
= pointer_hash
;
169 Align_element::axis () const
175 Align_element::set_axis (Axis a
)
182 Align_element::contains_b (Score_element
const *e
) const
184 return elem_l_arr_
.find_l (e
);
188 Align_element::sort_elements ()
190 Array
<Align_element_content
> content
;
191 for (int i
=0; i
< elem_l_arr_
.size(); i
++)
193 Score_element
* e
= dynamic_cast<Score_element
*> (elem_l_arr_
[i
]);
194 assert (priority_i_hash_
.elem_b (e
));
195 int p
= priority_i_hash_
[e
];
196 content
.push (Align_element_content (e
, p
));
198 content
.sort (Align_element_content::compare
);
201 priority_i_hash_
.clear();
203 for (int i
=0; i
< content
.size(); i
++)
205 elem_l_arr_
.push (content
[i
].elem_l_
);
210 Align_element::do_print () const
213 DOUT
<< "contains: ";
214 for (int i
=0 ; i
< elem_l_arr_
.size(); i
++)
215 DOUT
<< classname (elem_l_arr_
[i
]) << ", ";
220 Align_element::get_elt_by_priority (int p
) const
222 for (Hash_table_iter
<Score_element
*, int> i(priority_i_hash_
); i
.ok (); i
++)
231 Align_element::get_priority (Score_element
* e
) const
233 if ( priority_i_hash_
.elem_b (e
))
234 return priority_i_hash_
[e
];
236 return elem_l_arr_
.find_i (e
);