2 break-align-item.cc -- implement Break_align_item
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 #include <libc-extension.hh>
11 #include "side-position-interface.hh"
13 #include "dimension-cache.hh"
14 #include "lily-guile.hh"
15 #include "break-align-item.hh"
16 #include "dimensions.hh"
17 #include "paper-score.hh"
18 #include "paper-def.hh"
19 #include "paper-column.hh"
20 #include "group-interface.hh"
21 #include "align-interface.hh"
23 GLUE_SCORE_ELEMENT(Break_align_item
,before_line_breaking
);
25 Break_align_item::member_before_line_breaking ()
27 if (break_status_dir() == LEFT
)
29 set_elt_property ("self-alignment-X", gh_int2scm (RIGHT
));
33 add_offset_callback (Align_interface::center_on_element
, X_AXIS
);
38 Real interline
= paper_l ()->get_var ("interline");
39 Link_array
<Score_element
> elems
;
40 Link_array
<Score_element
> all_elems
41 = Pointer_group_interface__extract_elements (this, (Score_element
*)0,
44 for (int i
=0; i
< all_elems
.size(); i
++)
46 Interval y
= all_elems
[i
]->extent(X_AXIS
);
48 elems
.push (dynamic_cast<Score_element
*> (all_elems
[i
]));
54 SCM symbol_list
= SCM_EOL
;
56 SCM current_origin
= ly_symbol2scm ("none");
57 for (int i
=0; i
<= elems
.size (); i
++)
59 Score_element
*next_elt
= i
< elems
.size ()
67 next_origin
= next_elt
->get_elt_property ("break-align-symbol");
69 (next_origin
== SCM_UNDEFINED
)
70 ? ly_symbol2scm ("none")
74 next_origin
= ly_symbol2scm ("begin-of-note");
76 SCM e
= scm_assoc (scm_listify (current_origin
,
79 scm_eval (ly_symbol2scm ("space-alist")));
84 extra_space
= gh_cdr (e
);
88 warning (_f ("unknown spacing pair `%s', `%s'",
89 ly_symbol2string (current_origin
),
90 ly_symbol2string (next_origin
)));
91 extra_space
= scm_listify (ly_symbol2scm ("minimum-space"), gh_double2scm (0.0), SCM_UNDEFINED
);
94 SCM symbol
= gh_car (extra_space
);
95 Real spc
= gh_scm2double (gh_cadr(extra_space
));
99 symbol_list
= gh_cons (symbol
, symbol_list
);
100 current_origin
= next_origin
;
104 // skip the first sym.
105 symbol_list
= gh_cdr (scm_reverse (symbol_list
));
106 for (int i
=0; i
<elems
.size()-1; i
++)
108 String sym_str
= ly_symbol2string (gh_car (symbol_list
));
109 elems
[i
]->set_elt_property (sym_str
,
110 scm_cons (gh_double2scm (0),
111 gh_double2scm (dists
[i
+1])));
113 symbol_list
= gh_cdr (symbol_list
);
118 SCM first_pair
= elems
[0]->get_elt_property ("minimum-space");
119 if (gh_pair_p (first_pair
))
120 first_pair
= first_pair
;
122 first_pair
= gh_cons (gh_double2scm (0.0), gh_double2scm (0.0));
124 scm_set_car_x (first_pair
, gh_double2scm (-dists
[0]));
125 elems
[0]->set_elt_property ("minimum-space", first_pair
);
129 Force callbacks for alignment to be called
131 Real unused
= elems
[0]->relative_coordinate (this, X_AXIS
);
132 Real pre_space
= elems
[0]->relative_coordinate (column_l (), X_AXIS
);
134 Real xl
= elems
[0]->extent (X_AXIS
)[LEFT
];
138 programming_error ("Infinity reached. ");
140 Real xr
= elems
.top ()->extent (X_AXIS
)[RIGHT
];
141 Real spring_len
= elems
.top ()->relative_coordinate (column_l (), X_AXIS
);
145 programming_error ("Infinity reached.");
147 Real stretch_distance
=0.;
149 if (gh_car (symbol_list
) == ly_symbol2scm ("extra-space"))
151 spring_len
+= dists
.top ();
152 stretch_distance
= dists
.top ();
154 else if (gh_car (symbol_list
) == ly_symbol2scm ("minimum-space"))
156 spring_len
= spring_len
>? dists
.top ();
157 stretch_distance
= spring_len
;
161 Hint the spacing engine how much space to put in.
163 The pairs are in the format of an interval (ie. CAR < CDR).
165 column_l ()->set_elt_property ("extra-space",
166 scm_cons (gh_double2scm (pre_space
),
167 gh_double2scm (spring_len
)));
169 column_l ()->set_elt_property ("stretch-distance",
170 gh_cons (gh_double2scm (-dists
[0]),
171 gh_double2scm (stretch_distance
)));
174 return SCM_UNDEFINED
;
177 Break_align_item::Break_align_item (SCM s
)
180 set_elt_property ("stacking-dir" , gh_int2scm (RIGHT
));
182 Align_interface (this).set_interface ();
183 Align_interface (this).set_axis (X_AXIS
);
185 add_offset_callback (Side_position_interface::aligned_on_self
, X_AXIS
);