2 p-score.cc -- implement Paper_score
4 source file of the GNU LilyPond music typesetter
6 (c) 1996, 1997--1998 Han-Wen Nienhuys <hanwen@cs.uu.nl>
10 #include "super-element.hh"
14 #include "paper-def.hh"
15 #include "line-of-score.hh"
20 #include "tex-stream.hh"
23 #include "word-wrap.hh"
24 #include "gourlay-breaking.hh"
25 #include "tex-outputter.hh"
26 #include "file-results.hh"
29 // sucking Cygnus egcs - w32
33 Paper_score::Paper_score ()
36 super_elem_l_ = new Super_elem;
37 typeset_element (super_elem_l_);
40 Paper_score::~Paper_score ()
42 super_elem_l_->unlink_all ();
43 for (PCursor<Score_element*> i(elem_p_list_.top()); i.ok(); i++)
44 assert(!i->linked_b());
48 Paper_score::typeset_element (Score_element * elem_p)
50 elem_p_list_.bottom ().add (elem_p);
51 elem_p->pscore_l_ = this;
53 elem_p->add_processing ();
57 Paper_score::typeset_broken_spanner (Spanner*span_p)
59 typeset_element (span_p);
64 Paper_score::typeset_unbroken_spanner (Spanner*span_p)
66 span_p_list_.bottom ().add (span_p);
67 span_p->pscore_l_=this;
69 // do not init start/stop fields. These are for broken spans only.
70 span_p->add_processing ();
75 Paper_score::clean_cols ()
78 for (iter_top (col_p_list_,c); c.ok ();)
80 c->set_rank (rank_i++);
86 Paper_score::add_column (Paper_column *p)
88 col_p_list_.bottom ().add (p);
95 Paper_score::print () const
100 DOUT << "Paper_score { ";
101 DOUT << "\n elements: ";
102 for (iter_top (elem_p_list_,cc); cc.ok (); cc++)
104 DOUT << "\n unbroken spanners: ";
105 for (iter (span_p_list_.top (), i); i.ok (); i++)
112 PCursor<Paper_column *>
113 Paper_score::find_col (Paper_column const *c) const
115 Paper_column const *what = c;
117 return col_p_list_.find ((Paper_column*)what);
122 Paper_score::set_breaking (Array<Column_x_positions> const &breaking)
124 super_elem_l_->line_of_score_l_->set_breaking (breaking);
125 super_elem_l_->break_processing ();
127 for (iter (span_p_list_.top (),i); i.ok ();)
129 Spanner *span_p = i.remove_p ();
130 if (span_p->broken_b ()
131 || !((Score_element*)span_p)->line_l ())
135 int sz = span_p->class_size();
136 set_frobnify (span_p,sz);
142 typeset_broken_spanner (span_p);
145 for (iter (elem_p_list_.top (),i); i.ok () ;)
147 Item *i_l =i->access_Item ();
148 if (i_l && !i_l->line_l ())
151 Score_element * item_p= i.remove_p ();
153 int sz = item_p->class_size ();
154 set_frobnify (item_p, sz);
164 Paper_score::calc_breaking ()
166 Break_algorithm *algorithm_p=0;
167 Array<Column_x_positions> sol;
168 bool try_wrap = ! paper_l_->get_var ("castingalgorithm");
172 algorithm_p = new Gourlay_breaking ;
173 algorithm_p->set_pscore (this);
174 sol = algorithm_p->solve ();
178 warning (_ ("Can't solve this casting problem exactly; revert to Word_wrap"));
184 algorithm_p = new Word_wrap;
185 algorithm_p->set_pscore (this);
186 sol = algorithm_p->solve ();
193 Paper_score::process ()
197 *mlog << _ ("Preprocessing elements...") << " " << flush;
198 super_elem_l_->breakable_col_processing ();
199 super_elem_l_->pre_processing ();
201 *mlog << '\n' << _ ("Calculating column positions...") << " " << flush;
202 super_elem_l_->space_processing ();
205 *mlog << _ ("Postprocessing elements...") << " " << endl;
206 super_elem_l_->post_processing ();
212 Paper_score::tex_output ()
215 String base_outname = paper_l_->outfile_str_ ;
216 if (base_outname.empty_b ())
218 base_outname = default_outname_base_global;
219 int def = paper_l_->get_next_default_count ();
222 base_outname += "-" + to_str (def);
226 String outname = base_outname;
229 target_str_global_array.push (outname);
231 *mlog << _f ("TeX output to %s...",
232 outname == "-" ? String ("<stdout>") : outname ) << endl;
234 Tex_stream tex_out (outname);
235 Tex_outputter interfees (&tex_out);
237 outputter_l_ = &interfees;
241 tex_out << header_global_p->TeX_string ();
245 tex_out << _ ("% outputting Score, defined at: ") << origin_str_ << '\n';
249 tex_out << header_l_->TeX_string();
251 tex_out << paper_l_->TeX_output_settings_str ();
254 if (experimental_features_global_b)
255 tex_out << "\\turnOnExperimentalFeatures%\n";
257 tex_out << "\\turnOnPostScript%\n";
258 super_elem_l_->output_all ();
259 tex_out << "\n\\EndLilyPondOutput";
263 /** Get all breakable columns between l and r, (not counting l and r). */
264 Link_array<Paper_column>
265 Paper_score::breakable_col_range (Paper_column*l, Paper_column*r) const
267 Link_array<Paper_column> ret;
269 PCursor<Paper_column*> start (l ? find_col (l)+1 : col_p_list_.top ());
270 PCursor<Paper_column*> stop (r ? find_col (r) : col_p_list_.bottom ());
273 ugh! windows-suck-suck-suck.
275 while (PCursor<Paper_column*>::compare (start,stop) < 0)
277 if (start->breakable_b_)
286 Link_array<Paper_column>
287 Paper_score::col_range (Paper_column*l, Paper_column*r) const
289 Link_array<Paper_column> ret;
291 PCursor<Paper_column*> start (l ? find_col (l)+1 : col_p_list_.top ());
292 PCursor<Paper_column*> stop (r ? find_col (r) : col_p_list_.bottom ());
296 ugh! windows-suck-suck-suck.
298 while (PCursor<Paper_column*>::compare (start,stop) < 0)
305 Paper_score::broken_col_range (Item const*l_item_l, Item const*r_item_l) const
307 Link_array<Item> ret;
308 Item const*l=l_item_l;
309 Item const*r=r_item_l;
311 while (! l->is_type_b(Paper_column::static_name ()))
312 l = l->axis_group_l_a_[X_AXIS]->access_Score_element ()->access_Item ();
314 while (! r->is_type_b(Paper_column::static_name ()))
315 r = r->axis_group_l_a_[X_AXIS]->access_Score_element ()->access_Item ();
317 PCursor<Paper_column*> start (l ? find_col ((Paper_column*)l)+1 : col_p_list_.top ());
318 PCursor<Paper_column*> stop (r ? find_col ((Paper_column*)r) : col_p_list_.bottom ());
321 ugh! windows-suck-suck-suck.
323 while (PCursor<Paper_column*>::compare (start,stop) < 0)
325 if (start->breakable_b_ && !start->line_l_)