lilypond-0.1.14
[lilypond.git] / lily / p-score.cc
blob0591e5cc1e2000ce999d4605680f309908e89439
1 /*
2 p-score.cc -- implement Paper_score
4 source file of the GNU LilyPond music typesetter
6 (c) 1996, 1997 Han-Wen Nienhuys <hanwen@stack.nl>
7 */
9 #include "super-elem.hh"
10 #include "debug.hh"
11 #include "lookup.hh"
12 #include "spanner.hh"
13 #include "paper-def.hh"
14 #include "scoreline.hh"
15 #include "p-score.hh"
16 #include "tex-stream.hh"
17 #include "p-col.hh"
18 #include "header.hh"
19 #include "word-wrap.hh"
20 #include "gourlay-breaking.hh"
21 #include "outputter.hh"
23 Paper_score::Paper_score ()
25 outputter_l_ =0;
26 super_elem_l_ = new Super_elem;
27 typeset_element (super_elem_l_);
30 Paper_score::~Paper_score ()
32 super_elem_l_->unlink_all ();
33 for (PCursor<Score_elem*> i(elem_p_list_.top()); i.ok(); i++)
34 assert(!i->linked_b());
37 void
38 Paper_score::typeset_element (Score_elem * elem_p)
40 elem_p_list_.bottom ().add (elem_p);
41 elem_p->pscore_l_ = this;
43 elem_p->add_processing ();
46 void
47 Paper_score::typeset_broken_spanner (Spanner*span_p)
49 typeset_element (span_p);
53 void
54 Paper_score::typeset_unbroken_spanner (Spanner*span_p)
56 span_p_list_.bottom ().add (span_p);
57 span_p->pscore_l_=this;
59 // do not init start/stop fields. These are for broken spans only.
60 span_p->add_processing ();
64 void
65 Paper_score::clean_cols ()
67 int rank_i = 0;
68 for (iter_top (col_p_list_,c); c.ok ();)
70 c->set_rank (rank_i++);
71 c++;
75 void
76 Paper_score::add_column (Paper_column *p)
78 col_p_list_.bottom ().add (p);
79 typeset_element(p);
84 void
85 Paper_score::print () const
87 #ifndef NPRINT
88 if (!check_debug)
89 return ;
90 DOUT << "Paper_score { ";
91 DOUT << "\n elements: ";
92 for (iter_top (elem_p_list_,cc); cc.ok (); cc++)
93 cc->print ();
94 DOUT << "\n unbroken spanners: ";
95 for (iter (span_p_list_.top (), i); i.ok (); i++)
96 i->print ();
98 DOUT << "}\n";
99 #endif
102 PCursor<Paper_column *>
103 Paper_score::find_col (Paper_column const *c) const
105 Paper_column const *what = c;
107 return col_p_list_.find ((Paper_column*)what);
111 void
112 Paper_score::set_breaking (Array<Col_hpositions> const &breaking)
114 super_elem_l_->line_of_score_l_->set_breaking (breaking);
115 super_elem_l_->break_processing ();
118 for (iter (span_p_list_.top (),i); i.ok ();)
120 Spanner *span_p = i.remove_p ();
121 if (span_p->broken_b ())
123 span_p->unlink ();
124 delete span_p;
125 }else
127 typeset_broken_spanner (span_p);
130 for (iter (elem_p_list_.top (),i); i.ok () ;)
132 Item *i_l =i->item ();
133 if (i_l && !i_l->line_l ())
135 i_l->unlink ();
136 delete i.remove_p ();
138 else
139 i++;
143 void
144 Paper_score::calc_breaking ()
146 Break_algorithm *algorithm_p=0;
147 Array<Col_hpositions> sol;
148 bool try_wrap = ! paper_l_->get_var ("castingalgorithm");
150 if (!try_wrap)
152 algorithm_p = new Gourlay_breaking ;
153 algorithm_p->set_pscore (this);
154 sol = algorithm_p->solve ();
155 delete algorithm_p;
156 if (! sol.size ())
158 warning ("Can not solve this casting problem exactly; revert to Word_wrap");
159 try_wrap = true;
162 if (try_wrap)
164 algorithm_p = new Word_wrap;
165 algorithm_p->set_pscore (this);
166 sol = algorithm_p->solve ();
167 delete algorithm_p;
169 set_breaking (sol);
172 void
173 Paper_score::process ()
175 clean_cols ();
176 print ();
177 *mlog << "Preprocessing elements... " <<flush;
178 super_elem_l_->breakable_col_processing ();
179 super_elem_l_->pre_processing ();
180 *mlog << "\nCalculating column positions ... " <<flush;
181 calc_breaking ();
182 *mlog << "\nPostprocessing elements..." << endl;
183 super_elem_l_->post_processing ();
184 tex_output ();
188 void
189 Paper_score::tex_output ()
191 // output
192 String outname = paper_l_->outfile_str_ ;
193 if (!outname)
194 outname = default_out_str_+ ".tex";
196 *mlog << "TeX output to " << outname << " ...\n";
198 Tex_stream tex_out (outname);
199 Tex_outputter interfees (&tex_out);
201 outputter_l_ = &interfees;
203 tex_out << "% outputting Score, defined at: " << origin_str_ << "\n";
204 if (header_l_)
206 tex_out << header_l_->TeX_string();
209 tex_out << "\n "<< paper_l_->lookup_l ()->texsetting << "%(Tex id)\n";
210 super_elem_l_->output_all ();
211 tex_out << "\n\\EndLilyPondOutput";
212 outputter_l_ = 0;
215 /** Get all breakable columns between l and r, (not counting l and r). */
216 Link_array<Paper_column>
217 Paper_score::breakable_col_range (Paper_column*l,Paper_column*r) const
219 Link_array<Paper_column> ret;
221 PCursor<Paper_column*> start (l ? find_col (l)+1 : col_p_list_.top ());
222 PCursor<Paper_column*> stop (r ? find_col (r) : col_p_list_.bottom ());
225 ugh! windows-suck-suck-suck.
227 while (PCursor<Paper_column*>::compare (start,stop) < 0)
229 if (start->breakable_b_)
230 ret.push (start);
231 start++;
234 return ret;
236 Link_array<Paper_column>
237 Paper_score::col_range (Paper_column*l, Paper_column*r) const
239 Link_array<Paper_column> ret;
241 PCursor<Paper_column*> start (l ? find_col (l)+1 : col_p_list_.top ());
242 PCursor<Paper_column*> stop (r ? find_col (r) : col_p_list_.bottom ());
243 ret.push (l);
246 ugh! windows-suck-suck-suck.
248 while (PCursor<Paper_column*>::compare (start,stop) < 0)
249 ret.push (start++);
250 ret.push (r);
251 return ret;
254 Link_array<Item>
255 Paper_score::broken_col_range (Item const*l_item_l, Item const*r_item_l) const
257 Link_array<Item> ret;
258 Item const*l=l_item_l;
259 Item const*r=r_item_l;
261 while (! l->is_type_b(Paper_column::static_name ()))
262 l = l->axis_group_l_a_[X_AXIS]->item ();
264 while (! r->is_type_b(Paper_column::static_name ()))
265 r = r->axis_group_l_a_[X_AXIS]->item ();
267 PCursor<Paper_column*> start (l ? find_col ((Paper_column*)l)+1 : col_p_list_.top ());
268 PCursor<Paper_column*> stop (r ? find_col ((Paper_column*)r) : col_p_list_.bottom ());
271 ugh! windows-suck-suck-suck.
273 while (PCursor<Paper_column*>::compare (start,stop) < 0)
275 if (start->breakable_b_ && !start->line_l_)
276 ret.push (start);
277 start++;
280 return ret;