]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/script-engraver.cc
Issue 5148/2: three-sided-box snippet: use #:properties keyword
[lilypond.git] / lily / script-engraver.cc
index 87e6d72023e4bc075a4007bacca7ec9a53fb1809..1e989ae55d7800aee0e3e5ba7b5e52ab229c3cb6 100644 (file)
@@ -1,32 +1,46 @@
 /*
 /*
-  script-engraver.cc -- engrave Scripts: Articulations.
+  This file is part of LilyPond, the GNU music typesetter.
 
 
-  source file of the GNU LilyPond music typesetter
+  Copyright (C) 1997--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
 
 
-  (c) 1997--2005 Han-Wen Nienhuys <hanwen@cs.uu.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 "engraver.hh"
+
 #include "context.hh"
 #include "directional-element-interface.hh"
 #include "context.hh"
 #include "directional-element-interface.hh"
-#include "engraver.hh"
-#include "slur.hh"
+#include "international.hh"
 #include "note-column.hh"
 #include "paper-column.hh"
 #include "rhythmic-head.hh"
 #include "script-interface.hh"
 #include "side-position-interface.hh"
 #include "note-column.hh"
 #include "paper-column.hh"
 #include "rhythmic-head.hh"
 #include "script-interface.hh"
 #include "side-position-interface.hh"
+#include "slur.hh"
 #include "staff-symbol-referencer.hh"
 #include "stem.hh"
 #include "staff-symbol-referencer.hh"
 #include "stem.hh"
+#include "stream-event.hh"
 #include "warn.hh"
 
 #include "warn.hh"
 
+#include "translator.icc"
+
 struct Script_tuple
 {
 struct Script_tuple
 {
-  Music *event_;
+  Stream_event *event_;
   Grob *script_;
   Grob *script_;
-  bool follow_into_staff_;
   Script_tuple ()
   {
   Script_tuple ()
   {
-    follow_into_staff_ = false;
     event_ = 0;
     script_ = 0;
   }
     event_ = 0;
     script_ = 0;
   }
@@ -34,57 +48,53 @@ struct Script_tuple
 
 class Script_engraver : public Engraver
 {
 
 class Script_engraver : public Engraver
 {
-  Array<Script_tuple> scripts_;
-  Spanner *slur_;
+  vector<Script_tuple> scripts_;
 
 protected:
 
 protected:
-  virtual bool try_music (Music *);
   void stop_translation_timestep ();
   void process_music ();
 
   void stop_translation_timestep ();
   void process_music ();
 
-  DECLARE_ACKNOWLEDGER ( slur);
-  DECLARE_ACKNOWLEDGER ( rhythmic_head);
-  DECLARE_ACKNOWLEDGER ( stem);
-  DECLARE_ACKNOWLEDGER ( note_column);
+  void listen_articulation (Stream_event *);
+  void acknowledge_rhythmic_head (Grob_info);
+  void acknowledge_stem (Grob_info);
+  void acknowledge_stem_tremolo (Grob_info);
+  void acknowledge_tie (Grob_info);
+  void acknowledge_end_tie (Grob_info);
+  void acknowledge_note_column (Grob_info);
+  void acknowledge_inline_accidental (Grob_info);
 
 public:
   TRANSLATOR_DECLARATIONS (Script_engraver);
 };
 
 
 public:
   TRANSLATOR_DECLARATIONS (Script_engraver);
 };
 
-Script_engraver::Script_engraver ()
+Script_engraver::Script_engraver (Context *c)
+  : Engraver (c)
 {
 {
-  slur_ = 0;
 }
 
 }
 
-bool
-Script_engraver::try_music (Music *m)
+void
+Script_engraver::listen_articulation (Stream_event *ev)
 {
 {
-  if (m->is_mus_type ("articulation-event"))
-    {
-      /* Discard double articulations for part-combining.  */
-      int script_count = scripts_.size ();
-      for (int i = 0; i < script_count; i++)
-       if (ly_is_equal (scripts_[i].event_
-                        ->get_property ("articulation-type"),
-                        m->get_property ("articulation-type")))
-         return true;
-
-      Script_tuple t;
-      t.event_ = m;
-      scripts_.push (t);
-      return true;
-    }
-  return false;
+  /* Discard double articulations for part-combining.  */
+  for (vsize i = 0; i < scripts_.size (); i++)
+    if (ly_is_equal (scripts_[i].event_
+                     ->get_property ("articulation-type"),
+                     ev->get_property ("articulation-type")))
+      return;
+
+  Script_tuple t;
+  t.event_ = ev;
+  scripts_.push_back (t);
 }
 
 void
 copy_property (Grob *g, SCM sym, SCM alist)
 {
 }
 
 void
 copy_property (Grob *g, SCM sym, SCM alist)
 {
-  if (g->internal_get_property (sym) == SCM_EOL)
+  if (scm_is_null (g->get_property (sym)))
     {
       SCM entry = scm_assoc (sym, alist);
       if (scm_is_pair (entry))
     {
       SCM entry = scm_assoc (sym, alist);
       if (scm_is_pair (entry))
-       g->internal_set_property (sym, scm_cdr (entry));
+        g->set_property (sym, scm_cdr (entry));
     }
 }
 
     }
 }
 
@@ -92,17 +102,18 @@ copy_property (Grob *g, SCM sym, SCM alist)
    could be saved by tacking the props onto the Script grob (i.e. make
    ScriptStaccato , ScriptMarcato, etc. ).
 */
    could be saved by tacking the props onto the Script grob (i.e. make
    ScriptStaccato , ScriptMarcato, etc. ).
 */
-void make_script_from_event (Grob *p, bool *follow, Context *tg,
-                            SCM art_type, int index)
+void
+make_script_from_event (Grob *p, Context *tg,
+                        SCM art_type, int index)
 {
   SCM alist = tg->get_property ("scriptDefinitions");
   SCM art = scm_assoc (art_type, alist);
 
 {
   SCM alist = tg->get_property ("scriptDefinitions");
   SCM art = scm_assoc (art_type, alist);
 
-  if (art == SCM_BOOL_F)
+  if (scm_is_false (art))
     {
       /* FIXME: */
     {
       /* FIXME: */
-      warning (_ ("don't know how to interpret articulation: "));
-      warning (_ ("scheme encoding: "));
+      warning (_ ("do not know how to interpret articulation:"));
+      warning (_ (" scheme encoding: "));
       scm_write (art_type, scm_current_error_port ());
       message ("");
       return;
       scm_write (art_type, scm_current_error_port ());
       message ("");
       return;
@@ -110,10 +121,6 @@ void make_script_from_event (Grob *p, bool *follow, Context *tg,
 
   art = scm_cdr (art);
 
 
   art = scm_cdr (art);
 
-  SCM follow_scm = scm_assoc (ly_symbol2scm ("follow-into-staff"),
-                             art);
-
-  *follow = scm_is_pair (follow_scm) && to_boolean (scm_cdr (follow_scm));
   bool priority_found = false;
 
   for (SCM s = art; scm_is_pair (s); s = scm_cdr (s))
   bool priority_found = false;
 
   for (SCM s = art; scm_is_pair (s); s = scm_cdr (s))
@@ -121,68 +128,105 @@ void make_script_from_event (Grob *p, bool *follow, Context *tg,
       SCM sym = scm_caar (s);
       SCM type = scm_object_property (sym, ly_symbol2scm ("backend-type?"));
       if (!ly_is_procedure (type))
       SCM sym = scm_caar (s);
       SCM type = scm_object_property (sym, ly_symbol2scm ("backend-type?"));
       if (!ly_is_procedure (type))
-       continue;
+        continue;
 
       SCM val = scm_cdar (s);
 
 
       SCM val = scm_cdar (s);
 
-      if (sym == ly_symbol2scm ("script-priority"))
-       {
-         priority_found = true;
-         /* Make sure they're in order of user input by adding index i.
-            Don't use the direction in this priority. Smaller means closer
-            to the head.  */
-         int prio = scm_to_int (val) + index;
-
-         val = scm_from_int (prio);
-       }
-      if (p->internal_get_property (sym) == SCM_EOL)
-       p->internal_set_property (sym, val);
+      if (scm_is_eq (sym, ly_symbol2scm ("script-priority")))
+        {
+          priority_found = true;
+          /* Make sure they're in order of user input by adding index i.
+             Don't use the direction in this priority. Smaller means closer
+             to the head.  */
+          int prio = scm_to_int (val) + index;
+
+          val = scm_from_int (prio);
+        }
+
+      SCM preset = p->get_property_data (sym);
+      if (scm_is_null (val)
+          || scm_is_false (scm_call_1 (type, preset)))
+        p->set_property (sym, val);
     }
 
   if (!priority_found)
     {
       p->set_property ("script-priority",
     }
 
   if (!priority_found)
     {
       p->set_property ("script-priority",
-                      scm_from_int (index));
+                       scm_from_int (index));
     }
     }
-
-  Side_position_interface::set_axis (p, Y_AXIS);
 }
 
 void
 Script_engraver::process_music ()
 {
 }
 
 void
 Script_engraver::process_music ()
 {
-  for (int i = 0; i < scripts_.size(); i++)
-     {
-      Music *m = scripts_[i].event_;
+  for (vsize i = 0; i < scripts_.size (); i++)
+    {
+      Stream_event *ev = scripts_[i].event_;
 
 
-      Grob *p = make_item ("Script", m->self_scm ());
+      Grob *p = make_item ("Script", ev->self_scm ());
 
 
-      make_script_from_event (p, &scripts_[i].follow_into_staff_, context (),
-                             m->get_property ("articulation-type"),
-                             i);
+      make_script_from_event (p, context (),
+                              ev->get_property ("articulation-type"),
+                              i);
 
       scripts_[i].script_ = p;
 
 
       scripts_[i].script_ = p;
 
-      SCM force_dir = m->get_property ("direction");
+      SCM force_dir = ev->get_property ("direction");
       if (is_direction (force_dir) && to_dir (force_dir))
       if (is_direction (force_dir) && to_dir (force_dir))
-       p->set_property ("direction", force_dir);
+        p->set_property ("direction", force_dir);
     }
 }
 
     }
 }
 
-
 void
 Script_engraver::acknowledge_stem (Grob_info info)
 {
 void
 Script_engraver::acknowledge_stem (Grob_info info)
 {
-  int script_count = scripts_.size ();
-  for (int i = 0; i < script_count; i++)
+  for (vsize i = 0; i < scripts_.size (); i++)
     {
       Grob *e = scripts_[i].script_;
 
       if (to_dir (e->get_property ("side-relative-direction")))
     {
       Grob *e = scripts_[i].script_;
 
       if (to_dir (e->get_property ("side-relative-direction")))
-       e->set_object ("direction-source", info.grob ()->self_scm ());
+        e->set_object ("direction-source", info.grob ()->self_scm ());
+
+      Side_position_interface::add_support (e, info.grob ());
+    }
+}
+
+void
+Script_engraver::acknowledge_stem_tremolo (Grob_info info)
+{
+  for (vsize i = 0; i < scripts_.size (); i++)
+    {
+      Grob *e = scripts_[i].script_;
+      Side_position_interface::add_support (e, info.grob ());
+    }
+}
 
 
-      /* FIXME: add dependency */
-      e->add_dependency (info.grob ());
+void
+Script_engraver::acknowledge_tie (Grob_info info)
+{
+  for (vsize i = 0; i < scripts_.size (); i++)
+    {
+      Grob *e = scripts_[i].script_;
+      Side_position_interface::add_support (e, info.grob ());
+    }
+}
+
+void
+Script_engraver::acknowledge_end_tie (Grob_info info)
+{
+  for (vsize i = 0; i < scripts_.size (); i++)
+    {
+      Grob *e = scripts_[i].script_;
+      Side_position_interface::add_support (e, info.grob ());
+    }
+}
+
+void
+Script_engraver::acknowledge_inline_accidental (Grob_info info)
+{
+  for (vsize i = 0; i < scripts_.size (); i++)
+    {
+      Grob *e = scripts_[i].script_;
       Side_position_interface::add_support (e, info.grob ());
     }
 }
       Side_position_interface::add_support (e, info.grob ());
     }
 }
@@ -190,20 +234,19 @@ Script_engraver::acknowledge_stem (Grob_info info)
 void
 Script_engraver::acknowledge_rhythmic_head (Grob_info info)
 {
 void
 Script_engraver::acknowledge_rhythmic_head (Grob_info info)
 {
-  if(info.music_cause ())
+  if (info.event_cause ())
     {
     {
-     for (int i = 0; i < scripts_.size(); i++)
-       {
-         Grob *e = scripts_[i].script_;
-
-         if (Side_position_interface::get_axis (e) == X_AXIS
-             && !e->get_parent (Y_AXIS))
-           {
-             e->set_parent (info.grob (), Y_AXIS);
-             e->add_dependency (info.grob ());
-           }
-         Side_position_interface::add_support (e, info.grob ());
-       }
+      for (vsize i = 0; i < scripts_.size (); i++)
+        {
+          Grob *e = scripts_[i].script_;
+
+          if (Side_position_interface::get_axis (e) == X_AXIS
+              && !e->get_parent (Y_AXIS))
+            {
+              e->set_parent (info.grob (), Y_AXIS);
+            }
+          Side_position_interface::add_support (e, info.grob ());
+        }
     }
 }
 
     }
 }
 
@@ -215,50 +258,47 @@ Script_engraver::acknowledge_note_column (Grob_info info)
      swapped around horizontally.
 
      As the note head to put it on is not known now, postpone this
      swapped around horizontally.
 
      As the note head to put it on is not known now, postpone this
-     decision to Script_interface::before_line_breaking ().  */
-  
-  for (int i = 0; i < scripts_.size(); i++)
+     decision to Script_interface::calc_direction ().  */
+  for (vsize i = 0; i < scripts_.size (); i++)
     {
       Grob *e = scripts_[i].script_;
 
       if (!e->get_parent (X_AXIS)
     {
       Grob *e = scripts_[i].script_;
 
       if (!e->get_parent (X_AXIS)
-         && Side_position_interface::get_axis (e) == Y_AXIS)
-       e->set_parent (info.grob (), X_AXIS);
+          && Side_position_interface::get_axis (e) == Y_AXIS)
+        e->set_parent (info.grob (), X_AXIS);
     }
 }
     }
 }
-void
-Script_engraver::acknowledge_slur (Grob_info info)
-{
-  slur_ = info.spanner ();
-}
 
 void
 Script_engraver::stop_translation_timestep ()
 {
 
 void
 Script_engraver::stop_translation_timestep ()
 {
-  int script_count = scripts_.size ();
-  for (int i = 0; i < script_count; i++)
-    if (scripts_[i].follow_into_staff_)
-      {
-       Grob *sc = scripts_[i].script_;
-       sc->add_offset_callback (Side_position_interface
-                                ::quantised_position_proc, Y_AXIS);
-       sc->set_property ("staff-padding", SCM_EOL);
-      }
-
   scripts_.clear ();
 }
 
   scripts_.clear ();
 }
 
-#include "translator.icc"
 
 
-ADD_ACKNOWLEDGER (Script_engraver, slur);
-ADD_ACKNOWLEDGER (Script_engraver, rhythmic_head);
-ADD_ACKNOWLEDGER (Script_engraver, stem);
-ADD_ACKNOWLEDGER (Script_engraver, note_column);
+void
+Script_engraver::boot ()
+{
+  ADD_LISTENER (Script_engraver, articulation);
+  ADD_ACKNOWLEDGER (Script_engraver, rhythmic_head);
+  ADD_ACKNOWLEDGER (Script_engraver, stem);
+  ADD_ACKNOWLEDGER (Script_engraver, tie);
+  ADD_END_ACKNOWLEDGER (Script_engraver, tie);
+  ADD_ACKNOWLEDGER (Script_engraver, note_column);
+  ADD_ACKNOWLEDGER (Script_engraver, stem_tremolo);
+  ADD_ACKNOWLEDGER (Script_engraver, inline_accidental);
+}
 
 ADD_TRANSLATOR (Script_engraver,
 
 ADD_TRANSLATOR (Script_engraver,
-               /* doc */ "Handles note scripted articulations.",
-               /* create */ "Script",
-               /* accept */ "script-event articulation-event",
-               /* read */ "scriptDefinitions",
-               /* write */ "");
+                /* doc */
+                "Handle note scripted articulations.",
+
+                /* create */
+                "Script ",
+
+                /* read */
+                "scriptDefinitions ",
+
+                /* write */
+                ""
+               );