]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/new-fingering-engraver.cc
Release: bump Welcome versions.
[lilypond.git] / lily / new-fingering-engraver.cc
index 6444a06bff056609c20e93652587c85604c86957..06a3a8da9666669d7ab2d95672f167158887fe1b 100644 (file)
@@ -1,7 +1,7 @@
 /*
   This file is part of LilyPond, the GNU music typesetter.
 
-  Copyright (C) 1998--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  Copyright (C) 1998--2015 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
@@ -63,6 +63,7 @@ class New_fingering_engraver : public Engraver
   vector<Finger_tuple> string_numbers_;
 
   vector<Grob *> heads_;
+  vector<Grob *> accidentals_;
   Grob *stem_;
 
   void position_all ();
@@ -70,8 +71,9 @@ public:
   TRANSLATOR_DECLARATIONS (New_fingering_engraver);
 protected:
   void stop_translation_timestep ();
-  DECLARE_ACKNOWLEDGER (rhythmic_head);
-  DECLARE_ACKNOWLEDGER (stem);
+  void acknowledge_rhythmic_head (Grob_info);
+  void acknowledge_inline_accidental (Grob_info);
+  void acknowledge_stem (Grob_info);
   void add_fingering (Grob *, SCM,
                       vector<Finger_tuple> *,
                       Stream_event *, Stream_event *);
@@ -80,6 +82,12 @@ protected:
   void position_scripts (SCM orientations, vector<Finger_tuple> *);
 };
 
+void
+New_fingering_engraver::acknowledge_inline_accidental (Grob_info inf)
+{
+  accidentals_.push_back (inf.grob ());
+}
+
 void
 New_fingering_engraver::acknowledge_rhythmic_head (Grob_info inf)
 {
@@ -91,7 +99,7 @@ New_fingering_engraver::acknowledge_rhythmic_head (Grob_info inf)
 
   for (SCM s = arts; scm_is_pair (s); s = scm_cdr (s))
     {
-      Stream_event *ev = unsmob_stream_event (scm_car (s));
+      Stream_event *ev = unsmob<Stream_event> (scm_car (s));
 
       if (!ev)
         continue;
@@ -106,9 +114,17 @@ New_fingering_engraver::acknowledge_rhythmic_head (Grob_info inf)
       else if (ev->in_event_class ("script-event"))
         add_script (inf.grob (), ev, note_ev);
       else if (ev->in_event_class ("string-number-event"))
-        add_fingering (inf.grob (),
-                       ly_symbol2scm ("StringNumber"), &string_numbers_,
-                       ev, note_ev);
+        {
+          // String numbers are used in calculating harmonics even
+          // when we don't want them displayed.  So don't make space
+          // for them if 'stencil is #f
+          Grob *g = make_item ("StringNumber", ev->self_scm ());
+          if (scm_is_true (g->get_property ("stencil")))
+            add_fingering (inf.grob (),
+                           ly_symbol2scm ("StringNumber"), &string_numbers_,
+                           ev, note_ev);
+          g->suicide (); // Kill grob created to check stencil
+        }
       else if (ev->in_event_class ("stroke-finger-event"))
         add_fingering (inf.grob (),
                        ly_symbol2scm ("StrokeFinger"), &stroke_fingerings_,
@@ -116,7 +132,7 @@ New_fingering_engraver::acknowledge_rhythmic_head (Grob_info inf)
       else if (ev->in_event_class ("harmonic-event"))
         {
           inf.grob ()->set_property ("style", ly_symbol2scm ("harmonic"));
-          Grob *d = unsmob_grob (inf.grob ()->get_object ("dot"));
+          Grob *d = unsmob<Grob> (inf.grob ()->get_object ("dot"));
           if (d && !to_boolean (get_property ("harmonicDots")))
             d->suicide ();
         }
@@ -160,9 +176,7 @@ New_fingering_engraver::add_fingering (Grob *head,
 {
   Finger_tuple ft;
 
-  ft.script_ = internal_make_item (grob_sym, event->self_scm (),
-                                   ly_symbol2string (grob_sym).c_str (),
-                                   __FILE__, __LINE__, __FUNCTION__);
+  ft.script_ = make_item (grob_sym, event->self_scm ());
 
   Side_position_interface::add_support (ft.script_, head);
 
@@ -178,8 +192,12 @@ New_fingering_engraver::position_scripts (SCM orientations,
                                           vector<Finger_tuple> *scripts)
 {
   for (vsize i = 0; i < scripts->size (); i++)
-    if (stem_ && to_boolean (scripts->at (i).script_->get_property ("add-stem-support")))
-      Side_position_interface::add_support (scripts->at (i).script_, stem_);
+    if (stem_)
+      {
+        Side_position_interface::add_support (scripts->at (i).script_, stem_);
+        if (Grob *flag = unsmob<Grob> (stem_->get_object ("flag")))
+          Side_position_interface::add_support (scripts->at (i).script_, flag);
+      }
 
   /*
     This is not extremely elegant, but we have to do a little
@@ -210,10 +228,10 @@ New_fingering_engraver::position_scripts (SCM orientations,
 
   vector_sort (*scripts, less<Finger_tuple> ());
 
-  bool up_p = scm_c_memq (ly_symbol2scm ("up"), orientations) != SCM_BOOL_F;
-  bool down_p = scm_c_memq (ly_symbol2scm ("down"), orientations) != SCM_BOOL_F;
-  bool left_p = scm_c_memq (ly_symbol2scm ("left"), orientations) != SCM_BOOL_F;
-  bool right_p = scm_c_memq (ly_symbol2scm ("right"), orientations) != SCM_BOOL_F;
+  bool up_p = scm_is_true (scm_c_memq (ly_symbol2scm ("up"), orientations));
+  bool down_p = scm_is_true (scm_c_memq (ly_symbol2scm ("down"), orientations));
+  bool left_p = scm_is_true (scm_c_memq (ly_symbol2scm ("left"), orientations));
+  bool right_p = scm_is_true (scm_c_memq (ly_symbol2scm ("right"), orientations));
   Direction hordir = (right_p) ? RIGHT : LEFT;
   if (left_p || right_p)
     {
@@ -259,25 +277,23 @@ New_fingering_engraver::position_scripts (SCM orientations,
       Grob *f = ft.script_;
       f->set_parent (ft.head_, X_AXIS);
       f->set_parent (ft.head_, Y_AXIS);
-      f->set_property ("avoid-slur", SCM_BOOL_F);
+      f->set_property ("avoid-slur", ly_symbol2scm ("inside"));
       if (hordir == LEFT
-          && unsmob_grob (ft.head_->get_object ("accidental-grob")))
+          && unsmob<Grob> (ft.head_->get_object ("accidental-grob")))
         Side_position_interface::add_support (f,
-                                              unsmob_grob (ft.head_->get_object ("accidental-grob")));
-      else if (unsmob_grob (ft.head_->get_object ("dot")))
+                                              unsmob<Grob> (ft.head_->get_object ("accidental-grob")));
+      else if (unsmob<Grob> (ft.head_->get_object ("dot")))
         Side_position_interface::add_support (f,
-                                              unsmob_grob (ft.head_->get_object ("dot")));
+                                              unsmob<Grob> (ft.head_->get_object ("dot")));
 
-      Self_alignment_interface::set_align_self (f, Y_AXIS);
-      Self_alignment_interface::set_center_parent (f, Y_AXIS);
+      Self_alignment_interface::set_aligned_on_parent (f, Y_AXIS);
       Side_position_interface::set_axis (f, X_AXIS);
 
       f->set_property ("direction", scm_from_int (hordir));
     }
 
-  Direction d = DOWN;
   Drul_array< vector<Finger_tuple> > vertical (down, up);
-  do
+  for (DOWN_and_UP (d))
     {
       for (vsize i = 0; i < vertical[d].size (); i++)
         {
@@ -288,14 +304,12 @@ New_fingering_engraver::position_scripts (SCM orientations,
           f->set_property ("script-priority",
                            scm_from_int (finger_prio + d * ft.position_));
 
-          Self_alignment_interface::set_align_self (f, X_AXIS);
-          Self_alignment_interface::set_center_parent (f, X_AXIS);
+          Self_alignment_interface::set_aligned_on_parent (f, X_AXIS);
           Side_position_interface::set_axis (f, Y_AXIS);
 
           f->set_property ("direction", scm_from_int (d));
         }
     }
-  while (flip (&d) != DOWN);
 }
 
 void
@@ -334,6 +348,10 @@ New_fingering_engraver::position_all ()
     {
       Grob *script = articulations_[i].script_;
 
+      for (vsize j = 0; j < accidentals_.size (); j++)
+        Side_position_interface::add_support (script, accidentals_[j]);
+
+      accidentals_.resize (0);
       for (vsize j = heads_.size (); j--;)
         Side_position_interface::add_support (script, heads_[j]);
 
@@ -346,13 +364,20 @@ New_fingering_engraver::position_all ()
   articulations_.clear ();
 }
 
-New_fingering_engraver::New_fingering_engraver ()
+New_fingering_engraver::New_fingering_engraver (Context *c)
+  : Engraver (c)
 {
   stem_ = 0;
 }
 
-ADD_ACKNOWLEDGER (New_fingering_engraver, rhythmic_head);
-ADD_ACKNOWLEDGER (New_fingering_engraver, stem);
+
+void
+New_fingering_engraver::boot ()
+{
+  ADD_ACKNOWLEDGER (New_fingering_engraver, rhythmic_head);
+  ADD_ACKNOWLEDGER (New_fingering_engraver, inline_accidental);
+  ADD_ACKNOWLEDGER (New_fingering_engraver, stem);
+}
 
 ADD_TRANSLATOR (New_fingering_engraver,
                 /* doc */