source file of the GNU LilyPond music typesetter
- (c) 1996, 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+ (c) 1996, 1997--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
*/
#include "main.hh"
#include "paper-score.hh"
#include "paper-column.hh"
#include "scope.hh"
-#include "word-wrap.hh"
#include "gourlay-breaking.hh"
#include "paper-stream.hh"
#include "paper-outputter.hh"
#include "file-results.hh"
#include "misc.hh"
+#include "all-font-metrics.hh"
Paper_score::Paper_score ()
{
- protected_scms_ = scm_protect_object (gh_cons (SCM_BOOL_T, SCM_EOL));
paper_l_ =0;
outputter_l_ =0;
Line_of_score * line_p = new Line_of_score;
- typeset_unbroken_spanner (line_p);
-
+ line_p->pscore_l_ = this;
+ element_smob_list_ = scm_protect_object (gh_cons (line_p->self_scm_, SCM_EOL));
line_l_ = line_p;
}
Paper_score::~Paper_score ()
{
- for (int i=span_p_arr_.size (); --i >=0 ; )
- delete span_p_arr_[i];
- for (int i=elem_p_arr_.size (); --i >=0 ; )
- delete elem_p_arr_[i];
-
- scm_unprotect_object (protected_scms_);
+ scm_unprotect_object (element_smob_list_);
}
void
Paper_score::typeset_element (Score_element * elem_p)
{
- elem_p_arr_.push (elem_p);
elem_p->pscore_l_ = this;
- // take over protection.
- SCM_CDR(protected_scms_) = gh_cons (elem_p->element_property_alist_,
- SCM_CDR (protected_scms_));
- scm_unprotect_object (elem_p->element_property_alist_);
+ gh_set_cdr_x(element_smob_list_,
+ gh_cons (elem_p->self_scm_, gh_cdr (element_smob_list_)));
+ elem_p->set_elt_property ("full-name",
+ gh_str02scm((char*)elem_p->name()));
- SCM p = elem_p->remove_elt_property (break_helper_only_scm_sym);
- if (p != SCM_BOOL_F)
- break_helpers_arr_.push (elem_p);
-}
-
-
-void
-Paper_score::typeset_unbroken_spanner (Spanner*span_p)
-{
- span_p_arr_.push (span_p);
- span_p->pscore_l_=this;
-
- SCM p = span_p->remove_elt_property (break_helper_only_scm_sym);
- if (p != SCM_BOOL_F)
- break_helpers_arr_.push (span_p);
+ scm_unprotect_object (elem_p->self_scm_);
}
void
typeset_element(p);
}
-
-
void
Paper_score::print () const
{
#ifndef NPRINT
- if (!check_debug)
+ if (!flower_dstream)
return ;
- DOUT << "Paper_score { ";
- DOUT << "\n elements: ";
- for (int i=0; i < span_p_arr_.size (); i++)
- span_p_arr_[i]->print ();
- for (int i=0; i < elem_p_arr_.size (); i++)
- elem_p_arr_[i]->print();
-
- DOUT << "}\n";
+
+ DEBUG_OUT << "Paper_score { ";
+ DEBUG_OUT << "\n elements: ";
+
+ for (SCM p = gh_cdr (element_smob_list_);
+ p != SCM_EOL;
+ p = gh_cdr(p))
+ gh_display (gh_car (p));
+ DEBUG_OUT << "}\n";
#endif
}
{
Break_algorithm *algorithm_p=0;
Array<Column_x_positions> sol;
- bool try_wrap = !paper_l_->get_var ("castingalgorithm");
- if (!try_wrap)
- {
- algorithm_p = new Gourlay_breaking ;
- algorithm_p->set_pscore (this);
- sol = algorithm_p->solve ();
- delete algorithm_p;
- if (! sol.size ())
- {
- warning (_ ("Can't solve this casting problem exactly; revert to Word_wrap"));
- try_wrap = true;
- }
- }
- if (try_wrap)
- {
- algorithm_p = new Word_wrap;
- algorithm_p->set_pscore (this);
- sol = algorithm_p->solve ();
- delete algorithm_p;
- }
+ algorithm_p = new Gourlay_breaking ;
+ algorithm_p->set_pscore (this);
+ sol = algorithm_p->solve ();
+ delete algorithm_p;
+
return sol;
}
void
Paper_score::process ()
{
- Dictionary<int> type_stats;
- type_stats["Item"] =0;
- type_stats["Spanner"] =0;
- type_stats["Total"]=0;
-
print ();
- *mlog << _ ("Preprocessing elements...") << " " << flush;
+ progress_indication (_ ("Preprocessing elements...") + " ");
line_l_->breakable_col_processing ();
+ fixup_refpoints ();
line_l_->pre_processing ();
- *mlog << '\n' << _ ("Calculating column positions...") << " " << flush;
+ progress_indication ("\n" + _ ("Calculating column positions...") + " " );
line_l_->space_processing ();
Array<Column_x_positions> breaking = calc_breaking ();
+ line_l_->break_into_pieces (breaking);
-
- Paper_stream* paper_stream_p = paper_l_->paper_stream_p ();
- outputter_l_ = paper_l_->paper_outputter_p (paper_stream_p, header_l_, origin_str_);
-
- Link_array<Line_of_score> lines;
- for (int i=0; i < breaking.size (); i++)
+ for (SCM s = element_smob_list_; gh_pair_p (s); s = gh_cdr (s))
+ {
+ Score_element *sc = unsmob_element (gh_car (s));
+ sc->do_break_processing ();
+ }
+ for (SCM s = element_smob_list_; gh_pair_p (s); s = gh_cdr (s))
{
- Line_of_score *line_l = line_l_->set_breaking (breaking, i);
- lines.push (line_l);
- if (line_l != line_l_)
- typeset_element (line_l);
+ Score_element *sc = unsmob_element (gh_car (s));
+ sc->handle_broken_dependencies ();
}
+
+ outputter_l_ = new Paper_outputter ;
+ outputter_l_->output_header ();
- if (experimental_features_global_b)
- *mlog << elem_p_arr_.size () + span_p_arr_.size () << _ (" elements. ");
+ outputter_l_->output_version();
+
+ if (header_global_p)
+ outputter_l_->output_scope (header_global_p, "mudela");
+ if (header_l_)
+ outputter_l_->output_scope (header_l_, "mudela");
- *mlog << "\n";
- *mlog << _ ("Line ... ");
- line_l_->break_processing ();
- for (int i=0; i < lines.size (); i++)
- {
- *mlog << '[' << flush;
-
- Line_of_score *line_l = lines[i];
-
- line_l->post_processing ();
- *mlog << i << flush;
- line_l->output_all (i + 1 == lines.size());
- if (experimental_features_global_b)
- *mlog << '(' << elem_p_arr_.size () + span_p_arr_.size () << ')';
-
- *mlog << ']' << flush;
- }
+ outputter_l_->output_comment (_ ("Outputting Score, defined at: "));
+ outputter_l_->output_comment (origin_str_);
+
+ if (paper_l_->scope_p_)
+ outputter_l_->output_scope (paper_l_->scope_p_, "mudelapaper");
- // huh?
- delete outputter_l_;
- delete paper_stream_p;
- outputter_l_ = 0;
+ SCM scm = gh_list (ly_symbol2scm ("experimental-on"), SCM_UNDEFINED);
+ outputter_l_->output_scheme (scm);
+ scm = gh_list (ly_symbol2scm ("header-end"), SCM_UNDEFINED);
+ outputter_l_->output_scheme (scm);
/*
- todo: sort output
+ This is tricky: we have to put the font definitions before the
+ actual output, but we don't know all fonts in advanced: generating
+ the output might trigger loading of a new font. So we store the
+ place to insert the font definitions, generate the output and then
+ insert the definitions
+
*/
- if (experimental_features_global_b)
- {
- for (Dictionary_iter<int> i(type_stats); i.ok(); i++)
- {
- *mlog << i.key () << ": " << i.val () << " objects\n";
- }
- }
- *mlog << '\n' << flush;
-
+ SCM before_output = outputter_l_->last_cons_;
+
+
+ fixup_refpoints ();
+ line_l_->output_lines ();
+
+
+ SCM font_names = ly_quote_scm (all_fonts_global_p->font_descriptions ());
+ gh_set_cdr_x (before_output,
+ gh_cons (gh_list (ly_symbol2scm ("define-fonts"),
+ font_names,
+ SCM_UNDEFINED),
+ gh_cdr (before_output)));
+
+ Paper_stream* psp = paper_l_->paper_stream_p ();
+ outputter_l_->dump_onto (psp);
+ // huh?
+ delete outputter_l_;
+
+ outputter_l_ = 0;
+ delete psp;
+
}
Link_array<Item>
return ret;
}
+
+
+void
+Paper_score::fixup_refpoints ()
+{
+ for (SCM s = element_smob_list_; gh_pair_p (s); s = gh_cdr (s))
+ {
+ SCM e = gh_car (s);
+ if (SMOB_IS_TYPE_B(Score_element, e))
+ {
+ Score_element * se = unsmob_element (e);
+ se->fixup_refpoint ();
+ }
+ }
+}