2 staff-column.cc -- implement Staff_column
4 source file of the GNU LilyPond music typesetter
6 (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
12 #include "time-description.hh"
13 #include "score-column.hh"
14 #include "staff-column.hh"
15 #include "command-request.hh"
16 #include "musical-request.hh"
17 #include "interval.hh"
21 #include "request-column.hh"
22 #include "grouping.hh"
25 Staff_column::OK() const
33 Staff_column::when() const
35 return req_col_l_
->when();
39 Staff_column::add_reqs(Array
<Request
*> req_l_arr
)
41 for (int i
=0; i
< req_l_arr
.size(); i
++) {
42 Request
* j
= req_l_arr
[i
];
44 Command_req
* c_l
= j
->command();
46 timing_req_l_arr_
.push(j
->command()->timing());
48 if (c_l
->groupchange())
49 creationreq_l_arr_
.push(c_l
);
50 else if (!c_l
->barcheck() && !c_l
->partial() &&
51 !c_l
->measuregrouping())
56 Musical_req
*m
= j
->musical();
58 req_col_l_
->musical_column_l_
->add_duration(m
->rhythmic()->duration());
68 Staff_column::Staff_column()
76 Staff_column::~Staff_column()
81 Staff_column::set_req_col(Request_column
*col_l
)
87 Staff_column::setup_one_request(Request
* j
)
89 if (j
->command()) // ugh
90 commandreq_l_arr_
.push(j
);
91 else if (j
->musical())
92 musicalreq_l_arr_
.push(j
);
96 Staff_column::typeset_musical_item(Item
*i
)
99 Score_column
* scorecolumn_l
= req_col_l_
->musical_column_l_
;
100 scorecolumn_l
->pcol_l_
->pscore_l_
->typeset_item(i
, scorecolumn_l
->pcol_l_
);
104 align items in #item_l_arr#,
106 @return the width of the items after aligning.
109 align_items(Array
<Item
*> item_l_arr
)
112 for (int i
=0; i
< item_l_arr
.size(); i
++) {
113 Interval item_width
= item_l_arr
[i
]->width();
114 if (item_width
.empty_b()) {
115 item_width
= Interval(0,0);
117 Real dx
=wid
.right
- item_width
.left
;
119 item_l_arr
[i
]->translate(Offset(dx
,0));
120 wid
.unite(item_width
);
126 translate_items(Real x
, Array
<Item
*> item_l_arr
)
128 for (int i
=0; i
< item_l_arr
.size(); i
++)
129 item_l_arr
[i
]->translate(Offset(x
, 0));
133 Write a "horizontal align" item, which aligns the pres, nobreaks, posts, etc.
137 Staff_column::typeset_breakable_items(Array
<Item
*> &pre_p_arr
,
138 Array
<Item
*> &nobreak_p_arr
,
139 Array
<Item
*> &post_p_arr
)
141 Score_column
* scol_l
= req_col_l_
->command_column_l_
;
142 PCol
* c
= scol_l
->pcol_l_
;
143 PScore
*ps_l
=scol_l
->pcol_l_
->pscore_l_
;
145 if (!c
->breakable_b()) {
146 for (int i
=0; i
< pre_p_arr
.size(); i
++) {
147 pre_p_arr
[i
]->unlink();
150 pre_p_arr
.set_size(0);
151 for (int i
=0; i
< post_p_arr
.size(); i
++) {
152 post_p_arr
[i
]->unlink();
153 delete post_p_arr
[i
];
155 post_p_arr
.set_size(0);
159 for (int i
=0; i
< pre_p_arr
.size(); i
++) {
160 ps_l
->typeset_item(pre_p_arr
[i
], c
,0);
162 for (int i
=0; i
< nobreak_p_arr
.size(); i
++) {
163 ps_l
->typeset_item(nobreak_p_arr
[i
], c
, 1);
165 for (int i
=0; i
< post_p_arr
.size(); i
++) {
166 ps_l
->typeset_item(post_p_arr
[i
], c
, 2);
169 Interval pre_wid
= align_items(pre_p_arr
);
170 translate_items( -pre_wid
.right
, pre_p_arr
);
171 align_items(nobreak_p_arr
);
172 Interval post_wid
=align_items(post_p_arr
);
173 translate_items (-post_wid
.left
, post_p_arr
);
175 pre_p_arr
.set_size(0);
176 post_p_arr
.set_size(0);
177 nobreak_p_arr
.set_size(0);
181 Staff_column::command_column_l()
183 return req_col_l_
->command_column_l_
;
187 Staff_column::musical_column_l()
189 return req_col_l_
->musical_column_l_
;
193 Staff_column::update_time(Time_description
&time_
,
194 Rhythmic_grouping
*default_grouping
)
196 // first all meter changes
197 for (int i
=0; i
< timing_req_l_arr_
.size(); i
++) {
198 Timing_req
* tr_l
= timing_req_l_arr_
[i
];
199 if (tr_l
->meterchange()) {
200 int b_i
=tr_l
->meterchange()->beats_i_
;
201 int o_i
= tr_l
->meterchange()->one_beat_i_
;
202 if (! time_
.allow_meter_change_b() )
203 tr_l
->warning("Meter change not allowed here");
205 time_
.set_meter(b_i
, o_i
);
206 if (default_grouping
)
208 Rhythmic_grouping(MInterval(0,Moment(b_i
, o_i
)), b_i
);
214 for (int i
=0; i
< timing_req_l_arr_
.size(); i
++) {
215 Timing_req
* tr_l
= timing_req_l_arr_
[i
];
216 if (tr_l
->partial()) {
217 Moment m
= tr_l
->partial()->duration_
;
218 String error
= time_
.try_set_partial_str(m
);
220 tr_l
->warning(error
);
223 } else if (tr_l
->barcheck() && time_
.whole_in_measure_
) {
224 tr_l
->warning( "Barcheck failed");
226 time_
.whole_in_measure_
= 0; // resync
227 time_
.error_b_
= true;
228 } else if (tr_l
->cadenza()) {
229 time_
.set_cadenza(tr_l
->cadenza()->on_b_
);
230 } else if (tr_l
->measuregrouping()) {
231 if (default_grouping
)
232 *default_grouping
= parse_grouping(
233 tr_l
->measuregrouping()->beat_i_arr_
,
234 tr_l
->measuregrouping()->elt_length_arr_
);