]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/accidental-placement.cc
Run `make grand-replace'.
[lilypond.git] / lily / accidental-placement.cc
index 199ff98c93f8b219d34465af2ef75d8401e2bfd7..1c7d356cc93f1b17ce289277f99520745de6cc87 100644 (file)
@@ -3,18 +3,18 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 2002--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  (c) 2002--2008 Han-Wen Nienhuys <hanwen@xs4all.nl>
 */
 
 
 #include "accidental-placement.hh"
 
+#include "item.hh"
 #include "rhythmic-head.hh"
 #include "accidental-interface.hh"
 #include "music.hh"
 #include "note-collision.hh"
 #include "note-column.hh"
-#include "pitch.hh"
 #include "pointer-group-interface.hh"
 #include "skyline.hh"
 #include "stream-event.hh"
@@ -68,50 +68,38 @@ Accidental_placement::split_accidentals (Grob *accs,
       {
        Grob *a = unsmob_grob (scm_car (s));
 
-       if (unsmob_grob (a->get_object ("tie")))
+       if (unsmob_grob (a->get_object ("tie"))
+           && !to_boolean (a->get_property ("forced")))
          break_reminder->push_back (a);
        else
          real_acc->push_back (a);
       }
 }
 
-/*
-  Accidentals are special, because they appear and disappear after
-  ties at will.
-*/
-Interval
-Accidental_placement::get_relevant_accidental_extent (Grob *me,
-                                                     Item *item_col,
-                                                     Grob *left_object)
+vector<Grob*>
+Accidental_placement::get_relevant_accidentals (vector<Grob*> const &elts, Grob *left)
 {
-  vector<Grob*> br, ra;
-  vector<Grob*> *which = 0;
+  vector<Grob*> br;
+  vector<Grob*> ra;
+  vector<Grob*> ret;
+  bool right = dynamic_cast<Item *> (left)->break_status_dir () == RIGHT;
 
-  Accidental_placement::split_accidentals (me, &br, &ra);
-  concat (br, ra);
-
-  if (dynamic_cast<Item *> (left_object)->break_status_dir () == RIGHT)
-    which = &br;
-  else
-    which = &ra;
-
-  Interval extent;
-  for (vsize i = 0; i < which->size (); i++)
-    extent.unite (which->at (i)->extent (item_col, X_AXIS));
-
-  if (!extent.is_empty ())
+  for (vsize i = 0; i < elts.size (); i++)
     {
-      Real p = robust_scm2double (me->get_property ("left-padding"), 0.2);
-      extent[LEFT] -= p;
-    }
+      split_accidentals (elts[i], &br, &ra);
+      
+      ret.insert (ret.end (), ra.begin (), ra.end ());
 
-  return extent;
+      if (right)
+       ret.insert (ret.end (), br.begin (), br.end ());
+    }
+  return ret;
 }
 
 struct Accidental_placement_entry
 {
-  vector<Skyline_entry> left_skyline_;
-  vector<Skyline_entry> right_skyline_;
+  Skyline left_skyline_;
+  Skyline right_skyline_;
   Interval vertical_extent_;
   vector<Box> extents_;
   vector<Grob*> grobs_;
@@ -225,7 +213,7 @@ stagger_apes (vector<Accidental_placement_entry*> *apes)
 
 */
 
-MAKE_SCHEME_CALLBACK(Accidental_placement, calc_positioning_done, 1);
+MAKE_SCHEME_CALLBACK (Accidental_placement, calc_positioning_done, 1);
 SCM
 Accidental_placement::calc_positioning_done (SCM smob)
 {
@@ -233,6 +221,8 @@ Accidental_placement::calc_positioning_done (SCM smob)
   if (!me->is_live ())
     return SCM_BOOL_T;
 
+  me->set_property ("positioning-done", SCM_BOOL_T);
+  
   SCM accs = me->get_object ("accidental-grobs");
   if (!scm_is_pair (accs))
     return SCM_BOOL_T;
@@ -302,27 +292,46 @@ Accidental_placement::calc_positioning_done (SCM smob)
 
   vector_sort (heads, less<Grob*> ());
   uniq (heads);
+
+  vector<Grob *> stems;
+  for (vsize i = 0; i < heads.size  (); i++)
+    {
+      if (Grob *s = Rhythmic_head::get_stem (heads[i]))
+       stems.push_back (s);
+    }
+  
+  vector_sort (stems, less<Grob*> ());
+  uniq (stems);
+
   common[Y_AXIS] = common_refpoint_of_array (heads, common[Y_AXIS], Y_AXIS);
+  common[Y_AXIS] = common_refpoint_of_array (stems, common[Y_AXIS], Y_AXIS);
+
+  for (vsize i = 0; i < heads.size  (); i++)
+    {
+      if (Grob *s = Rhythmic_head::get_stem (heads[i]))
+       {
+         stems.push_back (s);
+         common[Y_AXIS] = s->common_refpoint (common[Y_AXIS], Y_AXIS);
+       }
+    }
+
+  vector_sort (stems, less<Grob*> ());
+  uniq (stems);
+  
 
   for (vsize i = apes.size (); i--;)
     {
       Accidental_placement_entry *ape = apes[i];
-      ape->left_skyline_ = empty_skyline (LEFT);
-      ape->right_skyline_ = empty_skyline (RIGHT);
 
       for (vsize j = apes[i]->grobs_.size (); j--;)
        {
          Grob *a = apes[i]->grobs_[j];
-
          vector<Box> boxes = Accidental_interface::accurate_boxes (a, common);
 
          ape->extents_.insert (ape->extents_.end (), boxes.begin (), boxes.end ());
-         for (vsize j = boxes.size (); j--;)
-           {
-             insert_extent_into_skyline (&ape->left_skyline_, boxes[j], Y_AXIS, LEFT);
-             insert_extent_into_skyline (&ape->right_skyline_, boxes[j], Y_AXIS, RIGHT);
-           }
        }
+      ape->left_skyline_ = Skyline (ape->extents_, 0, Y_AXIS, LEFT);
+      ape->right_skyline_ = Skyline (ape->extents_, 0, Y_AXIS, RIGHT);
     }
 
   Interval total;
@@ -340,61 +349,44 @@ Accidental_placement::calc_positioning_done (SCM smob)
 
   Accidental_placement_entry *head_ape = new Accidental_placement_entry;
   common[X_AXIS] = common_refpoint_of_array (heads, common[X_AXIS], X_AXIS);
-  vector<Skyline_entry> head_skyline (empty_skyline (LEFT));
   
   vector<Box> head_extents;
   for (vsize i = heads.size (); i--;)
-    {
-      Box b (heads[i]->extent (common[X_AXIS], X_AXIS),
-            heads[i]->extent (common[Y_AXIS], Y_AXIS));
-
-      insert_extent_into_skyline (&head_skyline, b, Y_AXIS, LEFT);
-    }
+    head_extents.push_back (Box (heads[i]->extent (common[X_AXIS], X_AXIS),
+                                heads[i]->extent (common[Y_AXIS], Y_AXIS)));
 
-  vector<Grob *> stems;
-  for (vsize i = 0; i < heads.size  (); i++)
-    {
-      if (Grob *s = Rhythmic_head::get_stem (heads[i]))
-       stems.push_back (s);
-    }
-  
-  vector_sort (stems, less<Grob*> ());
-  uniq (stems);
   for (vsize i = 0; i < stems.size (); i ++)
     {
       int very_large = INT_MAX;
       
-      Box b (heads[i]->extent (common[X_AXIS], X_AXIS),
-            heads[i]->pure_height (common[Y_AXIS], 0, very_large));
-
-      insert_extent_into_skyline (&head_skyline, b, Y_AXIS, LEFT);
+      head_extents.push_back (Box (stems[i]->extent (common[X_AXIS], X_AXIS),
+                                  stems[i]->pure_height (common[Y_AXIS], 0, very_large)));
     }
-  
-  head_ape->left_skyline_ = head_skyline;
+
+  head_ape->left_skyline_ = Skyline (head_extents, 0, Y_AXIS, LEFT);
   head_ape->offset_ = 0.0;
 
   Real padding = robust_scm2double (me->get_property ("padding"), 0.2);
 
-  vector<Skyline_entry> left_skyline = head_ape->left_skyline_;
-  heighten_skyline (&left_skyline,
-                   -robust_scm2double (me->get_property ("right-padding"), 0));
+  Skyline left_skyline = head_ape->left_skyline_;
+  left_skyline.raise (-robust_scm2double (me->get_property ("right-padding"), 0));
+  
   /*
     Add accs entries right-to-left.
   */
   for (vsize i = apes.size (); i-- > 0;)
     {
-      Real offset
-       = -skyline_meshing_distance (apes[i]->right_skyline_, left_skyline);
+      Real offset = -apes[i]->right_skyline_.distance (left_skyline);
       if (isinf (offset))
-       offset = (i < apes.size () - 1) ? apes[i + 1]->offset_ : 0.0;
+       offset = (i + 1 < apes.size ()) ? apes[i + 1]->offset_ : 0.0;
       else
        offset -= padding;
 
       apes[i]->offset_ = offset;
 
-      vector<Skyline_entry> new_left_skyline = apes[i]->left_skyline_;
-      heighten_skyline (&new_left_skyline, apes[i]->offset_);
-      merge_skyline (&new_left_skyline, left_skyline, LEFT);
+      Skyline new_left_skyline = apes[i]->left_skyline_;
+      new_left_skyline.raise (apes[i]->offset_);
+      new_left_skyline.merge (left_skyline);
       left_skyline = new_left_skyline;
     }
 
@@ -422,14 +414,14 @@ Accidental_placement::calc_positioning_done (SCM smob)
   me->flush_extent_cache (X_AXIS);
   me->set_property ("X-extent", scm_width);
 
-  for (vsize i = apes.size (); i--;)
-    delete apes[i];
+  junk_pointers (apes);
 
+  delete head_ape;
+  
   return SCM_BOOL_T;
 }
 
 ADD_INTERFACE (Accidental_placement,
-              "accidental-placement-interface",
               "Resolve accidental collisions.",
 
               /* properties */
@@ -437,4 +429,6 @@ ADD_INTERFACE (Accidental_placement,
               "left-padding "
               "padding "
               "positioning-done "
-              "right-padding ")
+              "right-padding "
+              "script-priority "
+              )