]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/break-substitution.cc
Run grand-replace (issue 3765)
[lilypond.git] / lily / break-substitution.cc
index 20ae27b01ffc6fa3e1630da61542de2698068e68..75053c34fd00ebe243eb32d23ece6b987b201c17 100644 (file)
@@ -1,18 +1,29 @@
 /*
-  break-substitution.cc -- implement grob break substitution.
+  This file is part of LilyPond, the GNU music typesetter.
 
-  source file of the GNU LilyPond music typesetter
+  Copyright (C) 2001--2014 Han-Wen Nienhuys <hanwen@xs4all.nl>
 
-  (c) 2001--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  LilyPond is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LilyPond is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include <cstdio>
 #include <cstdlib>
 using namespace std;
 
-#include "grob-array.hh"
 #include "item.hh"
 #include "system.hh"
+#include "grob-array.hh"
 
 static SCM break_criterion;
 void
@@ -32,39 +43,39 @@ substitute_grob (Grob *sc)
       Item *i = dynamic_cast<Item *> (sc);
       Direction d = to_dir (break_criterion);
       if (i && i->break_status_dir () != d)
-       {
-         Item *br = i->find_prebroken_piece (d);
-         return br;
-       }
+        {
+          Item *br = i->find_prebroken_piece (d);
+          return br;
+        }
     }
   else
     {
       System *line
-       = dynamic_cast<System *> (unsmob_grob (break_criterion));
+        = dynamic_cast<System *> (unsmob_grob (break_criterion));
       if (sc->get_system () != line)
-       sc = sc->find_broken_piece (line);
+        sc = sc->find_broken_piece (line);
 
       /* now: !sc || (sc && sc->get_system () == line) */
       if (!sc)
-       return 0;
+        return 0;
 
       /* now: sc && sc->get_system () == line */
       if (!line)
-       return sc;
+        return sc;
 
       /*
-       We don't return SCM_UNDEFINED for
-       suicided grobs, for two reasons
+        We don't return SCM_UNDEFINED for
+        suicided grobs, for two reasons
 
-       - it doesn't work (strange disappearing objects)
+        - it doesn't work (strange disappearing objects)
 
-       - it forces us to mark the parents of a grob, leading to
-       a huge recursion in the GC routine.
+        - it forces us to mark the parents of a grob, leading to
+        a huge recursion in the GC routine.
       */
 
       if (sc->common_refpoint (line, X_AXIS)
-         && sc->common_refpoint (line, Y_AXIS))
-       return sc;
+          && sc->common_refpoint (line, Y_AXIS))
+        return sc;
       return 0;
     }
 
@@ -88,7 +99,7 @@ substitute_grob (Grob *sc)
 SCM
 do_break_substitution (SCM src)
 {
- again:
+again:
 
   if (unsmob_grob (src))
     {
@@ -100,33 +111,33 @@ do_break_substitution (SCM src)
       int len = scm_c_vector_length (src);
       SCM nv = scm_c_make_vector (len, SCM_UNDEFINED);
       for (int i = 0; i < len; i++)
-       {
-         SCM si = scm_from_int (i);
-         scm_vector_set_x (nv, si,
-                           do_break_substitution (scm_vector_ref (src, si)));
-       }
+        {
+          SCM si = scm_from_int (i);
+          scm_vector_set_x (nv, si,
+                            do_break_substitution (scm_vector_ref (src, si)));
+        }
     }
   else if (scm_is_pair (src))
     {
       /*
-       UGH! breaks on circular lists.
+        UGH! breaks on circular lists.
       */
       SCM newcar = do_break_substitution (scm_car (src));
       SCM oldcdr = scm_cdr (src);
 
       if (newcar == SCM_UNDEFINED
-         && (scm_is_pair (oldcdr) || oldcdr == SCM_EOL))
-       {
-         /*
-           This is tail-recursion, ie.
+          && (scm_is_pair (oldcdr) || oldcdr == SCM_EOL))
+        {
+          /*
+            This is tail-recursion, ie.
 
-           return do_break_substution (cdr);
+            return do_break_substution (cdr);
 
-           We don't want to rely on the compiler to do this.  Without
-           tail-recursion, this easily crashes with a stack overflow.  */
-         src = oldcdr;
-         goto again;
-       }
+            We don't want to rely on the compiler to do this.  Without
+            tail-recursion, this easily crashes with a stack overflow.  */
+          src = oldcdr;
+          goto again;
+        }
 
       return scm_cons (newcar, do_break_substitution (oldcdr));
     }
@@ -139,14 +150,14 @@ do_break_substitution (SCM src)
 /*
   Perform substitution on GROB_LIST using a constant amount of stack.
 */
-vector<Grob*> temporary_substition_array;
+vector<Grob *> temporary_substition_array;
 void
 substitute_grob_array (Grob_array *grob_arr, Grob_array *new_arr)
 {
-  vector<Grob*> &old_grobs (grob_arr->array_reference ());
-  vector<Grob*> *new_grobs (new_arr == grob_arr
-                              ? & temporary_substition_array
-                              : &new_arr->array_reference ());
+  vector<Grob *> &old_grobs (grob_arr->array_reference ());
+  vector<Grob *> *new_grobs (new_arr == grob_arr
+                             ? & temporary_substition_array
+                             : &new_arr->array_reference ());
 
   new_grobs->resize (old_grobs.size ());
   Grob **array = (Grob **) new_grobs->data ();
@@ -156,7 +167,7 @@ substitute_grob_array (Grob_array *grob_arr, Grob_array *new_arr)
       Grob *orig = old_grobs[i];
       Grob *new_grob = substitute_grob (orig);
       if (new_grob)
-       *ptr++ = new_grob;
+        *ptr++ = new_grob;
     }
 
   new_grobs->resize (ptr - array);
@@ -224,8 +235,8 @@ spanner_system_range (Spanner *sp)
   else
     {
       if (sp->broken_intos_.size ())
-       rv = Slice (sp->broken_intos_[0]->get_system ()->get_rank (),
-                   sp->broken_intos_.back ()->get_system ()->get_rank ());
+        rv = Slice (sp->broken_intos_[0]->get_system ()->get_rank (),
+                    sp->broken_intos_.back ()->get_system ()->get_rank ());
     }
   return rv;
 }
@@ -237,14 +248,12 @@ item_system_range (Item *it)
     return Slice (st->get_rank (), st->get_rank ());
 
   Slice sr;
-  Direction d = LEFT;
-  do
+  for (LEFT_and_RIGHT (d))
     {
       Item *bi = it->find_prebroken_piece (d);
       if (bi && bi->get_system ())
-       sr.add_point (bi->get_system ()->get_rank ());
+        sr.add_point (bi->get_system ()->get_rank ());
     }
-  while (flip (&d) != LEFT);
 
   return sr;
 }
@@ -263,6 +272,8 @@ grob_system_range (Grob *g)
 struct Substitution_entry
 {
   Grob *grob_;
+
+  /* Assumption: we have less than 32k paper columns. */
   short left_;
   short right_;
 
@@ -274,16 +285,16 @@ struct Substitution_entry
     */
     if (sr.is_empty ())
       {
-       /*
-         overflow if we don't treat this specially.
-       */
-       left_ = 1;
-       right_ = -1;
+        /*
+          overflow if we don't treat this specially.
+        */
+        left_ = 1;
+        right_ = -1;
       }
     else
       {
-       left_ = sr[LEFT];
-       right_ = sr[RIGHT];
+        left_ = (short) sr[LEFT];
+        right_ = (short) sr[RIGHT];
       }
   }
   Substitution_entry ()
@@ -297,20 +308,20 @@ struct Substitution_entry
   item_compare (void const *a, void const *b)
   {
     return ((Substitution_entry *)a)->left_
-      - ((Substitution_entry *)b)->left_;
+           - ((Substitution_entry *)b)->left_;
   }
 
   static int
   spanner_compare (void const *a, void const *b)
   {
     return ((Substitution_entry *)a)->length ()
-      - ((Substitution_entry *)b)->length ();
+           - ((Substitution_entry *)b)->length ();
   }
 };
 
 bool
 Spanner::fast_substitute_grob_array (SCM sym,
-                                    Grob_array *grob_array)
+                                     Grob_array *grob_array)
 {
   int len = grob_array->size ();
 
@@ -348,15 +359,15 @@ Spanner::fast_substitute_grob_array (SCM sym,
 
       int idx = 0;
       if (dynamic_cast<Spanner *> (g))
-       idx = --spanner_index;
+        idx = --spanner_index;
       else if (dynamic_cast<Item *> (g))
-       idx = item_index++;
+        idx = item_index++;
 
       vec[idx].set (g, sr);
     }
 
   qsort (vec, item_index,
-        sizeof (Substitution_entry), &Substitution_entry::item_compare);
+         sizeof (Substitution_entry), &Substitution_entry::item_compare);
 
   vector<Slice> item_indices;
   vector<Slice> spanner_indices;
@@ -367,14 +378,15 @@ Spanner::fast_substitute_grob_array (SCM sym,
     }
 
   vector<Slice> *arrs[]
-    = {
+  =
+  {
     &item_indices, &spanner_indices
   };
 
-  for (int i = 0; i < item_index;i++)
+  for (int i = 0; i < item_index; i++)
     {
       for (int j = vec[i].left_; j <= vec[i].right_; j++)
-       item_indices[j - system_range[LEFT]].add_point (i);
+        item_indices[j - system_range[LEFT]].add_point (i);
     }
 
   /*
@@ -388,7 +400,7 @@ Spanner::fast_substitute_grob_array (SCM sym,
   assert (item_index <= spanner_index);
 
   assert ((broken_intos_.size () == (vsize)system_range.length () + 1)
-         || (broken_intos_.empty () && system_range.length () == 0));
+          || (broken_intos_.empty () && system_range.length () == 0));
   for (vsize i = 0; i < broken_intos_.size (); i++)
     {
       Grob *sc = broken_intos_[i];
@@ -397,28 +409,28 @@ Spanner::fast_substitute_grob_array (SCM sym,
 
       SCM newval = sc->internal_get_object (sym);
       if (!unsmob_grob_array (newval))
-       {
-         newval = Grob_array::make_array ();
-         sc->set_object (sym, newval);
-       }
+        {
+          newval = Grob_array::make_array ();
+          sc->set_object (sym, newval);
+        }
 
       Grob_array *new_array = unsmob_grob_array (newval);
-      for (int k = 0; k < 2;k++)
-       for (int j = (*arrs[k])[i][LEFT]; j <= (*arrs[k])[i][RIGHT]; j++)
-         {
-           Grob *substituted = substitute_grob (vec[j].grob_);
-           if (substituted)
-             new_array->add (substituted);
-         }
+      for (int k = 0; k < 2; k++)
+        for (int j = (*arrs[k])[i][LEFT]; j <= (*arrs[k])[i][RIGHT]; j++)
+          {
+            Grob *substituted = substitute_grob (vec[j].grob_);
+            if (substituted)
+              new_array->add (substituted);
+          }
 
 #ifdef PARANOIA
       printf ("%d (%d), sp %d (%d)\n",
-             item_indices [i].length (), item_index,
-             spanner_indices[i].length (), len -spanner_index);
+              item_indices [i].length (), item_index,
+              spanner_indices[i].length (), len - spanner_index);
 
       {
-       SCM l1 = substitute_grob_list (grob_list);
-       assert (scm_ilength (l1) == scm_ilength (newval));
+        SCM l1 = substitute_grob_list (grob_list);
+        assert (scm_ilength (l1) == scm_ilength (newval));
       }
 #endif
     }
@@ -450,37 +462,37 @@ substitute_object_alist (SCM alist, SCM dest)
       SCM val = scm_cdar (s);
 
       if (Grob_array *orig = unsmob_grob_array (val))
-       {
-         SCM handle = scm_assq (sym, dest);
-         SCM newval
-           = (scm_is_pair (handle))
-           ? scm_cdr (handle)
-           : Grob_array::make_array ();
-
-         Grob_array *new_arr = unsmob_grob_array (newval);
-
-         substitute_grob_array (orig, new_arr);
-         val = newval;
-       }
+        {
+          SCM handle = scm_assq (sym, dest);
+          SCM newval
+            = (scm_is_pair (handle))
+              ? scm_cdr (handle)
+              : Grob_array::make_array ();
+
+          Grob_array *new_arr = unsmob_grob_array (newval);
+
+          substitute_grob_array (orig, new_arr);
+          val = newval;
+        }
       else
-       val = do_break_substitution (val);
+        val = do_break_substitution (val);
 
       if (val != SCM_UNDEFINED)
-       {
-         /*
-           for ly:grob? properties, SCM_UNDEFINED could leak out
-           through ly:grob-property
-         */
-         *tail = scm_cons (scm_cons (sym, val), SCM_EOL);
-         tail = SCM_CDRLOC (*tail);
-       }
+        {
+          /*
+            for ly:grob? properties, SCM_UNDEFINED could leak out
+            through ly:grob-property
+          */
+          *tail = scm_cons (scm_cons (sym, val), SCM_EOL);
+          tail = SCM_CDRLOC (*tail);
+        }
     }
   return l;
 }
 
 void
 Spanner::substitute_one_mutable_property (SCM sym,
-                                         SCM val)
+                                          SCM val)
 {
   Spanner *s = this;
 
@@ -492,25 +504,25 @@ Spanner::substitute_one_mutable_property (SCM sym,
   if (!fast_done)
     for (vsize i = 0; i < s->broken_intos_.size (); i++)
       {
-       Grob *sc = s->broken_intos_[i];
-       System *l = sc->get_system ();
-       set_break_subsititution (l ? l->self_scm () : SCM_UNDEFINED);
-
-       if (grob_array)
-         {
-           SCM newval = sc->internal_get_object (sym);
-           if (!unsmob_grob_array (newval))
-             {
-               newval = Grob_array::make_array ();
-               sc->set_object (sym, newval);
-             }
-           substitute_grob_array (grob_array, unsmob_grob_array (newval));
-         }
-       else
-         {
-           SCM newval = do_break_substitution (val);
-           sc->set_object (sym, newval);
-         }
+        Grob *sc = s->broken_intos_[i];
+        System *l = sc->get_system ();
+        set_break_subsititution (l ? l->self_scm () : SCM_UNDEFINED);
+
+        if (grob_array)
+          {
+            SCM newval = sc->internal_get_object (sym);
+            if (!unsmob_grob_array (newval))
+              {
+                newval = Grob_array::make_array ();
+                sc->set_object (sym, newval);
+              }
+            substitute_grob_array (grob_array, unsmob_grob_array (newval));
+          }
+        else
+          {
+            SCM newval = do_break_substitution (val);
+            sc->set_object (sym, newval);
+          }
       }
 }