]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/p-score.cc
release: 0.0.70pre
[lilypond.git] / lily / p-score.cc
index 800d3287cf5292a26a7c9cb04d95365f693e0988..de266d1b20979def2121be2a398aa00eb31bc70b 100644 (file)
@@ -1,15 +1,70 @@
+/*
+  p-score.cc -- implement PScore
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 1996, 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+*/
+
+#include "super-elem.hh"
 #include "idealspacing.hh"
 #include "debug.hh"
 #include "lookup.hh"
 #include "spanner.hh"
 #include "paper-def.hh"
-#include "molecule.hh"
-#include "dimen.hh"
 #include "scoreline.hh"
 #include "p-score.hh"
 #include "tex-stream.hh"
-#include "item.hh"
 #include "break.hh"
+#include "p-col.hh"
+
+void
+PScore::typeset_element(Score_elem * elem_p)
+{
+    elem_p_list_.bottom().add(elem_p);
+    elem_p->pscore_l_ = this;
+
+    elem_p->add_processing();
+}
+
+void
+PScore::typeset_item(Item *i, PCol *c, int breakstat)
+{
+    assert(c && i);
+
+    if (breakstat == -1) {
+       typeset_item(i, c->prebreak_p_);
+       return;
+    }
+
+    if (breakstat == 1) {
+       typeset_item(i, c->postbreak_p_);
+       return;
+    }
+
+    c->add(i);
+    typeset_element(i);
+}
+
+void
+PScore::typeset_broken_spanner(Spanner*span_p)
+{
+    span_p->left_col_l_->starters.bottom().add (span_p);
+    span_p->right_col_l_->stoppers.bottom().add(span_p);
+    assert(span_p->left_col_l_->line_l_ == span_p->right_col_l_->line_l_);
+
+    typeset_element(span_p);
+}
+
+
+void
+PScore::typeset_unbroken_spanner(Spanner*span_p)
+{
+    spanners.bottom().add(span_p);
+    span_p->pscore_l_=this;
+    // do not init start/stop fields. These are for broken spans only.
+    span_p->add_processing();
+}
 
 Idealspacing*
 PScore::get_spacing(PCol*l, PCol*r)
@@ -34,18 +89,8 @@ PScore::clean_cols()
            c->set_rank(rank_i++);
            c++;
        }
-    
 }
 
-
-void
-PScore::add(PStaff *s)
-{
-    assert(s->pscore_l_ == this);
-    staffs.bottom().add(s);
-}
-
-
 void
 PScore::do_connect(PCol *c1, PCol *c2, Real d, Real h)
 {
@@ -67,42 +112,6 @@ PScore::connect(PCol* c1, PCol *c2, Real d, Real h)
     do_connect(c1->postbreak_p_, c2->prebreak_p_,d,h);
 }
 
-void
-PScore::typeset_item(Item *i, PCol *c, PStaff *s, int breakstat)
-{
-    assert(c && i && s);
-
-    if (breakstat == 0) {
-       typeset_item(i, c->prebreak_p_, s);
-       return;
-    }
-
-    if (breakstat == 2) {
-       typeset_item(i, c->postbreak_p_, s);
-       return;
-    }
-
-
-    its.bottom().add(i);
-    s->add(i);
-    c->add(i);
-
-    /* first do this, because i->width() may follow the 0-pointer */
-    i->add_processing();    
-}
-
-void
-PScore::typeset_spanner(Spanner*span_p, PStaff*ps)
-{
-    span_p->pstaff_l_ = ps;
-    spanners.bottom().add(span_p);
-    ps->spans.bottom().add(span_p);
-
-    // do not init start/stop fields. These are for broken spans only.
-    span_p->add_processing();
-}
-
-
 void
 PScore::add(PCol *p)
 {
@@ -114,42 +123,31 @@ PScore::add(PCol *p)
     cols.bottom().add(p);
 }
 
-PScore::PScore( Paper_def*p)
+PScore::PScore(Paper_def*p)
 {
     paper_l_ = p;
+    super_elem_l_   = new Super_elem;
+    typeset_element(super_elem_l_);
 }
 
 void
 PScore::output(Tex_stream &ts)
 {
-    int l=1;
-
     ts << "\n "<<  paper_l_->lookup_l()->texsetting << "%(Tex id)\n";
-    for (iter_top(lines,lic); lic.ok(); lic++) {
-       ts << "% line of score no. " << l++ <<"\n";
-       ts << lic->TeXstring();
-       if ((lic+1).ok())
-           ts << "\\interscoreline\n";
-    }  
+    ts<< super_elem_l_->TeX_string();
+    ts << "\n\\EndLilyPondOutput";
 }
 
 
-Array<Item*>
-PScore::select_items(PStaff*ps, PCol*pc)
+PScore::~PScore()
 {
-    Array<Item*> ret;
-    assert(ps && pc);
-    for (iter_top(pc->its,i); i.ok(); i++){
-       if (i->pstaff_l_ == ps)
-           ret.push((Item*)(Item const *)i);
-    }
-    return ret;
+    super_elem_l_->unlink_all();
 }
 
 void
 PScore::OK()const
 {
-#ifdef NDEBUG
+#ifndef NDEBUG
     for (iter_top(cols,cc); cc.ok(); cc++)
        cc->OK();
     for (iter_top(suz,i); i.ok(); i++)
@@ -163,8 +161,11 @@ PScore::print() const
 #ifndef NPRINT
     mtor << "PScore { ";
     paper_l_->print();
+    mtor << "\n elements: ";
+    for (iter_top(elem_p_list_,cc); cc.ok(); cc++)     
+       cc->print();
     mtor << "\ncolumns: ";
-    for (iter_top(cols,cc); cc.ok(); cc++)
+     for (iter_top(cols,cc); cc.ok(); cc++)
        cc->print();
     
     mtor << "\nideals: ";
@@ -177,34 +178,15 @@ PScore::print() const
 void
 PScore::preprocess()
 {
-    for (iter_top(spanners,i); i.ok(); i++) {
-       i->pre_processing();
-    }
-    for (iter_top(its,i); i.ok(); i++){
-       i->pre_processing();
-    }
+    super_elem_l_->breakable_col_processing();
+    super_elem_l_->pre_processing();
 }
 
 void
 PScore::postprocess()
 {
-    for (iter_top(broken_spans,i); i.ok(); i++) { // could chase spans as well.
-       i->post_processing();
-    }
-    for (iter_top(its,i); i.ok(); i++){
-       i->post_processing();
-    }
-    
-    for (iter_top(broken_spans,i); i.ok(); i++) {
-       i->molecule_processing();
-    }
-    for (iter_top(its,i); i.ok(); i++){
-       i->molecule_processing();
-    }
-
-    for (iter_top(lines,i); i.ok(); i++)
-       i->process();
-
+    super_elem_l_->post_processing();
+    super_elem_l_->molecule_processing();
 }
 
 PCursor<PCol *>
@@ -217,28 +199,34 @@ PScore::find_col(PCol const *c)const
     return cols.find((PCol*)what);
 }
 
-void
-PScore::add_broken(Spanner*s)
-{
-    assert(s->left->line_l_ == s->right->line_l_);
-    broken_spans.bottom().add(s);
-    s->left->starters.bottom().add (s);
-    s->right->stoppers.bottom().add (s);
-}
 
 void
-PScore::set_breaking(Array<Col_hpositions> breaking)
+PScore::set_breaking(Array<Col_hpositions> const &breaking)
 {
-    for (int j=0; j < breaking.size(); j++) {
-       Array<PCol*> &curline(breaking[j].cols);
-       Array<Real> &config(breaking[j].config);
-       
-       Line_of_score *s_p = new Line_of_score(curline,this);
-       lines.bottom().add(s_p);        
-       for (int i=0; i < curline.size(); i++){
-           curline[i]->hpos = config[i];
+    super_elem_l_->line_of_score_l_->set_breaking( breaking);
+    super_elem_l_->break_processing();
+
+
+    for (iter(spanners.top(),i); i.ok(); ) {
+       Spanner *span_p = i.remove_p();
+       if (span_p->broken_b()) {
+           span_p->unlink();
+           delete span_p;
+       }else{
+           typeset_broken_spanner(span_p);
        }
     }
+    for (iter(elem_p_list_.top(),i ); i.ok() ;) {
+       Item *i_l =i->item();
+       if ( i_l && !i_l->pcol_l_->line_l_) {
+           i_l->unlink();
+           delete i.remove_p();
+       } else
+           i++;
+    }
+
+    for (iter_top(cols, i); i.ok(); i++)
+       i->clean_breakable_items();
 }
 
 void
@@ -252,11 +240,69 @@ void
 PScore::process()
 {
     clean_cols();
-    
-    *mlog << "Preprocessing ... " <<flush;
+    print();
+    *mlog << "Preprocessing elements... " <<flush;
     preprocess();
     *mlog << "\nCalculating column positions ... " <<flush;
     calc_breaking();
-    *mlog << "\nPostprocessing ..." << endl;
+    *mlog << "\nPostprocessing elements..." << endl;
     postprocess();
 }
+
+/** Get all breakable columns between l and r, (not counting l and r).  */
+Link_array<PCol>
+PScore::breakable_col_range(PCol*l,PCol*r)const
+{
+    Link_array<PCol> ret;
+
+    PCursor<PCol*> start(l ? find_col(l)+1 : cols.top() );
+    PCursor<PCol*> stop(r ? find_col(r) : cols.bottom());
+
+    /*
+      ugh! windows-suck-suck-suck.
+     */
+    while ( PCursor<PCol*>::compare(start,stop) < 0 ) {
+       if (start->breakable_b())
+           ret.push(start);
+       start++;
+    }
+
+    return ret;
+}
+Link_array<PCol>
+PScore::col_range(PCol*l,PCol*r)const
+{
+    Link_array<PCol> ret;
+    
+    PCursor<PCol*> start(l ? find_col(l)+1 : cols.top() );
+    PCursor<PCol*> stop(r ? find_col(r) : cols.bottom());
+    ret.push(l);
+    
+    /*
+      ugh! windows-suck-suck-suck.
+     */
+    while ( PCursor<PCol*>::compare(start,stop) < 0 )
+       ret.push(start++);
+    ret.push(r);
+    return ret;
+}
+
+Link_array<PCol>
+PScore::broken_col_range(PCol*l,PCol*r)const
+{
+    Link_array<PCol> ret;
+
+    PCursor<PCol*> start(l ? find_col(l)+1 : cols.top() );
+    PCursor<PCol*> stop(r ? find_col(r) : cols.bottom());
+  
+    /*
+      ugh! windows-suck-suck-suck.
+      */
+    while ( PCursor<PCol*>::compare(start,stop) < 0 ) {
+       if (start->breakable_b() && !start->line_l_ )
+           ret.push(start);
+       start++;
+    }
+
+    return ret;
+}