2 p-score.cc -- implement Paper_score
4 source file of the GNU LilyPond music typesetter
6 (c) 1996, 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
13 #include "paper-def.hh"
14 #include "line-of-score.hh"
19 #include "word-wrap.hh"
20 #include "gourlay-breaking.hh"
21 #include "paper-stream.hh"
22 #include "paper-outputter.hh"
23 #include "file-results.hh"
26 Paper_score::Paper_score ()
30 Line_of_score
* line_p
= new Line_of_score
;
31 typeset_unbroken_spanner (line_p
);
36 Paper_score::Paper_score (Paper_score
const &s
)
42 Paper_score::~Paper_score ()
44 for (int i
=span_p_arr_
.size (); --i
>=0 ; )
45 delete span_p_arr_
[i
];
46 for (int i
=elem_p_arr_
.size (); --i
>=0 ; )
47 delete elem_p_arr_
[i
];
51 Paper_score::typeset_element (Score_element
* elem_p
)
53 elem_p_arr_
.push (elem_p
);
54 elem_p
->pscore_l_
= this;
57 SCM p
= elem_p
->remove_elt_property (break_helper_only_scm_sym
);
59 break_helpers_arr_
.push (elem_p
);
64 Paper_score::typeset_unbroken_spanner (Spanner
*span_p
)
66 span_p_arr_
.push (span_p
);
67 span_p
->pscore_l_
=this;
69 SCM p
= span_p
->remove_elt_property (break_helper_only_scm_sym
);
71 break_helpers_arr_
.push (span_p
);
75 Paper_score::add_column (Paper_column
*p
)
77 p
->set_rank (col_l_arr_
.size ());
85 Paper_score::print () const
90 DOUT
<< "Paper_score { ";
91 DOUT
<< "\n elements: ";
92 for (int i
=0; i
< span_p_arr_
.size (); i
++)
93 span_p_arr_
[i
]->print ();
94 for (int i
=0; i
< elem_p_arr_
.size (); i
++)
95 elem_p_arr_
[i
]->print();
102 Paper_score::find_col_idx (Paper_column
const *c
) const
104 Paper_column
const *what
= c
;
106 return col_l_arr_
.find_i ((Paper_column
*)what
);
109 Array
<Column_x_positions
>
110 Paper_score::calc_breaking ()
112 Break_algorithm
*algorithm_p
=0;
113 Array
<Column_x_positions
> sol
;
114 bool try_wrap
= !paper_l_
->get_var ("castingalgorithm");
118 algorithm_p
= new Gourlay_breaking
;
119 algorithm_p
->set_pscore (this);
120 sol
= algorithm_p
->solve ();
124 warning (_ ("Can't solve this casting problem exactly; revert to Word_wrap"));
130 algorithm_p
= new Word_wrap
;
131 algorithm_p
->set_pscore (this);
132 sol
= algorithm_p
->solve ();
141 not clean. Should update elem_p_arr_ and span_p_arr_. That would
142 also repair the stats.
144 This may be done efficiently by first sorting the arrays. */
146 delete_array_contents (Link_array
<Score_element
> &to_remove
, Dictionary
<int> &type_stats
)
148 for (int i
=0; i
< to_remove
.size (); i
++)
150 Score_element
* e
= to_remove
[i
];
151 String nm
= e
->name();
152 if (type_stats
.elem_b (nm
))
157 if (dynamic_cast<Item
*> (e
))
158 type_stats
["Item"] ++;
159 else if (dynamic_cast<Spanner
*>(e
))
160 type_stats
["Spanner"] ++;
161 type_stats
["Total"] ++;
169 to_remove
.tighten_maxsize ();
173 Paper_score::schedule_for_delete (Score_element
*e
)
175 to_delete_arr_
.push (e
);
179 Paper_score::process ()
181 Dictionary
<int> type_stats
;
182 type_stats
["Item"] =0;
183 type_stats
["Spanner"] =0;
184 type_stats
["Total"]=0;
187 *mlog
<< _ ("Preprocessing elements...") << " " << flush
;
188 line_l_
->breakable_col_processing ();
189 line_l_
->pre_processing ();
191 *mlog
<< '\n' << _ ("Calculating column positions...") << " " << flush
;
192 line_l_
->space_processing ();
194 Array
<Column_x_positions
> breaking
= calc_breaking ();
197 delete_array_contents (break_helpers_arr_
, type_stats
);
199 Paper_stream
* paper_stream_p
= paper_l_
->paper_stream_p ();
200 outputter_l_
= paper_l_
->paper_outputter_p (paper_stream_p
, header_l_
, origin_str_
);
202 Link_array
<Line_of_score
> lines
;
203 for (int i
=0; i
< breaking
.size (); i
++)
205 Line_of_score
*line_l
= line_l_
->set_breaking (breaking
, i
);
207 if (line_l
!= line_l_
)
208 typeset_element (line_l
);
211 if (experimental_features_global_b
)
212 *mlog
<< elem_p_arr_
.size () + span_p_arr_
.size () << " elements. ";
214 *mlog
<< "\nLine ... ";
215 line_l_
->break_processing ();
216 for (int i
=0; i
< lines
.size (); i
++)
218 *mlog
<< '[' << flush
;
220 Line_of_score
*line_l
= lines
[i
];
222 line_l
->post_processing ();
224 line_l
->output_all ();
226 if (experimental_features_global_b
)
227 *mlog
<< '(' << elem_p_arr_
.size () + span_p_arr_
.size () << ')';
229 *mlog
<< ']' << flush
;
231 delete_array_contents (to_delete_arr_
, type_stats
);
236 delete paper_stream_p
;
243 if (experimental_features_global_b
)
245 for (Dictionary_iter
<int> i(type_stats
); i
.ok(); i
++)
247 *mlog
<< i
.key () << ": " << i
.val () << " objects\n";
250 *mlog
<< '\n' << flush
;
255 Paper_score::broken_col_range (Item
const*l
, Item
const*r
) const
257 Link_array
<Item
> ret
;
263 ? find_col_idx (dynamic_cast<Paper_column
*> ((Item
*)l
))+1
267 ? find_col_idx (dynamic_cast<Paper_column
*>((Item
*)r
))
268 : col_l_arr_
.size ();
272 Paper_column
*c
= col_l_arr_
[start
];
273 if (c
->breakable_b () && !c
->line_l_
)