]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/word-wrap.cc
patch::: 1.2.12.jcn2
[lilypond.git] / lily / word-wrap.cc
index 5f61be35d3364aaf82ae03708d84f48bffded8c0..cf6a95e9febcba39e3280f8608ce2b27a1a7ed6b 100644 (file)
 
   source file of the LilyPond music typesetter
 
-  (c) 1997 Han-Wen Nienhuys <hanwen@stack.nl>
+  (c)  1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
 */
 
 #include "word-wrap.hh"
-#include "p-score.hh"
+#include "paper-def.hh"
+#include "paper-score.hh"
 #include "debug.hh"
-#include "p-col.hh"
-#include "spring-spacer.hh"
+#include "paper-column.hh"
+#include "line-spacer.hh"
+
+
+/** El stupido.  Add a measure until we're past the optimum.
 
 
-/** el stupido. 
-   
-  
    A Dynamic Programming type of algorithm
    similar to TeX's is in Gourlay_breaking
 
+   UGH.  Should think about pre/post break columns.
    */
-Array<Col_hpositions>
-Word_wrap::do_solve() const
+Array<Column_x_positions>
+Word_wrap::do_solve () const
 {
-  problem_OK();
+  problem_OK ();
+
+  Line_of_cols &allcols (pscore_l_->col_l_arr_);
+  int curcol_idx = 0;
   
-  PCursor<Paper_column*> curcol (pscore_l_->col_p_list_.top());
-  Array<Col_hpositions> breaking;
-  Line_of_cols breakpoints (find_breaks());
-  assert (breakpoints.size()>=2);
+  Array<Column_x_positions> breaking;
+  Line_of_cols breakpoints (find_breaks ());
+  assert (breakpoints.size ()>=2);
 
-  int break_idx_i=0;                   
-  while (break_idx_i < breakpoints.size() -1) 
+  int break_idx=0;
+  while (break_idx < breakpoints.size () -1)
     {
-      Col_hpositions minimum;
-      Col_hpositions current;
+      Column_x_positions minimum;
+      Column_x_positions current;
+
 
       // do  another line
-      Paper_column *post = breakpoints[break_idx_i]->postbreak_l();
-      current.add (post);
-      curcol++;                // skip the breakable.
-      break_idx_i++;
 
-      while (break_idx_i < breakpoints.size()) 
+      Item *post = breakpoints[break_idx]->find_broken_piece (RIGHT);
+      Paper_column *postcol =dynamic_cast<Paper_column*>(post);
+      
+      int start_break_idx = break_idx;
+      current.add_paper_column (postcol);
+      curcol_idx++;            // skip the breakable.
+      break_idx++;
+
+      while (break_idx < breakpoints.size ())
        {
-       
          // add another measure.
-         while (breakpoints[break_idx_i] != curcol.ptr())
+         while (breakpoints[break_idx] != allcols[curcol_idx])
            {
-             current.add (curcol);
-             curcol++;
+             current.add_paper_column (allcols[curcol_idx]);
+             curcol_idx++;
            }
-         current.add (breakpoints[break_idx_i]->prebreak_l());
 
-         current.spacer_l_ = generate_spacing_problem (current.cols);
+         Item * pre = breakpoints[break_idx]->find_broken_piece (LEFT);
+         Paper_column* precol = dynamic_cast<Paper_column*>(pre);
+         current.add_paper_column (precol);
+
+         current.spacer_l_ = generate_spacing_problem (current.cols_, 
+           pscore_l_->paper_l_->line_dimensions_int (breaking.size ()));
 
          // try to solve
-         if (!feasible (current.cols)) 
+         if (!feasible (current.cols_))
            {
-             if (!minimum.cols.size()) 
+             if (!minimum.cols_.size ())
                {
-                 warning ("Ugh, this measure is too long, breakpoint: "
-                          + String (break_idx_i) +
-                          " (generating stupido solution)");
-                 current.stupid_solution();
+                 warning (_f ("Ugh, this measure is too long, breakpoint: %d",
+                   break_idx));
+                 warning (_ ("Generating stupido solution"));
+                 current.stupid_solution ();
                  current.energy_f_ = - 1; // make sure we break out.
                }
              else
                current.energy_f_ = infinity_f; // make sure we go back
            }
-         else 
+         else
            {
-               
-             current.solve_line();
-             current.print();
+             current.solve_line ();
+             current.print ();
            }
 
          delete current.spacer_l_;
          current.spacer_l_ =0;
 
-         // update minimum, or backup.
-         if (current.energy_f_ < minimum.energy_f_ || current.energy_f_ < 0) 
+         if (!current.satisfies_constraints_b_ && start_break_idx == break_idx - 1)
            {
+             warning ( _ ("I don't fit; put me on Montignac"));
              minimum = current;
+             break;
+           }
+
+         /*
+           UGR! bug! 
+          */
+         if (current.energy_f_ < minimum.energy_f_ || current.energy_f_ < 0)
+           {
+             minimum = current;
+           }
+         else
+           {           // we're one col too far.
+             break_idx--;
+             while (allcols[curcol_idx] != breakpoints[break_idx])
+               curcol_idx --;
+             break;            // do the next line.
            }
-         else {                // we're one col too far.
-           break_idx_i--;
-           while (curcol.ptr() != breakpoints[break_idx_i])
-             curcol --;
-           break;              // do the next line.
-         }
 
 
          // add nobreak version of breakable column
-         current.cols.top()=breakpoints[break_idx_i];
-         curcol ++;
-         break_idx_i++;
+         current.cols_.top ()=breakpoints[break_idx];
+         curcol_idx ++;
+         break_idx++;
        }
 
-      *mlog << "[" <<break_idx_i<<"]"<<flush;
+      *mlog << "[" << break_idx << "]" << flush;
       breaking.push (minimum);
     }
+  *mlog << endl;
   return breaking;
 }
 
-Word_wrap::Word_wrap()
-{
-  get_line_spacer = Spring_spacer::constructor;
-}