]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/piano-pedal-engraver.cc
Fix some bugs in the dynamic engraver and PostScript backend
[lilypond.git] / lily / piano-pedal-engraver.cc
index c8a44bd4e402854cb567839cdbd3807e490c7e97..2d380fb3522699deece022a6c24e6c0ce4fba6ab 100644 (file)
@@ -3,8 +3,7 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 2000--2006 Jan Nieuwenhuizen <janneke@gnu.org>,
-                 Erik Sandberg <mandolaerik@gmail.com>
+  (c) 2000--2006 Jan Nieuwenhuizen <janneke@gnu.org>
 
   Chris Jackson <chris@fluffhouse.org.uk> - extended to support
   bracketed pedals.
 #include "note-column.hh"
 #include "side-position-interface.hh"
 #include "staff-symbol-referencer.hh"
-#include "stream-event.hh"
-#include "string-convert.hh"
 #include "warn.hh"
-#include "protected-scm.hh"
-#include "translator.icc"
 
 /*
   Urgh. This engraver is too complex. rewrite. --hwn
 */
 
-/* Ugh: This declaration is duplicated in piano-pedal-performer */
-typedef enum Pedal_type {SOSTENUTO, SUSTAIN, UNA_CORDA, NUM_PEDAL_TYPES};
-
-/*
-  Static precalculated data (symbols and strings) for the different
-  pedal types
-*/
-struct Pedal_type_info
-{
-  string base_name_;
-  SCM event_class_sym_;
-  SCM style_sym_;
-  SCM strings_sym_;
-  
-  const char *pedal_line_spanner_c_str_;
-  const char *pedal_c_str_;
-
-  Pedal_type_info ()
-  {
-    event_class_sym_ = SCM_EOL;
-    style_sym_ = SCM_EOL;
-    strings_sym_ = SCM_EOL;
-    pedal_line_spanner_c_str_ = 0;
-    pedal_c_str_ = 0;
-  }
-  void protect ()
-  {
-    scm_gc_protect_object (event_class_sym_);
-    scm_gc_protect_object (style_sym_);
-    scm_gc_protect_object (strings_sym_);
-  }
-};
-
 struct Pedal_info
 {
-  const Pedal_type_info *type_;
+  char const *name_;
 
   /*
     Event for currently running pedal.
   */
-  Stream_event *current_bracket_ev_;
+  Music *current_bracket_ev_;
 
   /*
     Event for currently starting pedal, (necessary?
@@ -78,12 +40,12 @@ struct Pedal_info
     distinct from current_bracket_ev_, since current_bracket_ev_ only
     necessary for brackets, not for text style.
   */
-  Stream_event *start_ev_;
+  Music *start_ev_;
 
   /*
     Events that were found in this timestep.
   */
-  Drul_array<Stream_event *> event_drul_;
+  Drul_array<Music *> event_drul_;
   Item *item_;
   Spanner *bracket_; // A single portion of a pedal bracket
   Spanner *finished_bracket_;
@@ -95,8 +57,6 @@ struct Pedal_info
   Spanner *finished_line_spanner_;
 };
 
-static Pedal_type_info pedal_types_[NUM_PEDAL_TYPES];
-
 class Piano_pedal_engraver : public Engraver
 {
 public:
@@ -105,15 +65,14 @@ public:
 protected:
   virtual void initialize ();
   virtual void finalize ();
-  DECLARE_TRANSLATOR_LISTENER (sustain);
-  DECLARE_TRANSLATOR_LISTENER (una_corda);
-  DECLARE_TRANSLATOR_LISTENER (sostenuto);
+  virtual bool try_music (Music *);
   void stop_translation_timestep ();
   DECLARE_ACKNOWLEDGER (note_column);
   void process_music ();
 
 private:
-  Pedal_info info_list_[NUM_PEDAL_TYPES + 1];
+
+  Pedal_info *info_list_;
 
   /*
     Record a stack of the current pedal spanners, so if more than one pedal
@@ -128,78 +87,41 @@ private:
   void typeset_all (Pedal_info *p);
 };
 
-static void
-init_pedal_types ()
-{
-  const char *names [NUM_PEDAL_TYPES];
-  names[SOSTENUTO] = "Sostenuto";
-  names[SUSTAIN] = "Sustain";
-  names[UNA_CORDA] = "UnaCorda";
-
-  for (int i = 0; i < NUM_PEDAL_TYPES; i++)
-    {
-      const char *name = names[i];
-      /* FooBar */
-      string base_name = name;
-      /* foo-bar */
-      string base_ident = "";
-      int prev_pos=0;
-      int cur_pos;
-      for (cur_pos = 1; name[cur_pos]; cur_pos++)
-       if (isupper (name[cur_pos]))
-         {
-           base_ident = base_ident + String_convert::to_lower (string (name, prev_pos, cur_pos - prev_pos)) + "-";
-           prev_pos = cur_pos;
-         }
-      base_ident += String_convert::to_lower (string (name, prev_pos, cur_pos - prev_pos));
-
-      /*
-       be careful, as we don't want to loose references to the _sym_ members.
-       */
-      Pedal_type_info info;
-      info.event_class_sym_ = scm_str2symbol ((base_ident + "-event").c_str ());
-      info.style_sym_ = scm_str2symbol (("pedal" + base_name + "Style").c_str ());
-      info.strings_sym_ = scm_str2symbol (("pedal" + base_name + "Strings").c_str ());
-      
-      info.pedal_line_spanner_c_str_ = strdup ((base_name + "PedalLineSpanner").c_str ());
-      info.base_name_ = name;
-      info.pedal_c_str_ = strdup ((base_name + "Pedal").c_str ());
-
-      info.protect ();
-      
-      pedal_types_[i] = info;
-    }
-}
-ADD_SCM_INIT_FUNC (Piano_pedal_engraver_init_pedal_types_, init_pedal_types);
-
 Piano_pedal_engraver::Piano_pedal_engraver ()
 {
+  info_list_ = 0;
 }
 
 void
 Piano_pedal_engraver::initialize ()
 {
-  for (int i = 0; i < NUM_PEDAL_TYPES; i++)
+  char *names [] = { "Sostenuto", "Sustain", "UnaCorda", 0 };
+
+  info_list_ = new Pedal_info[sizeof (names) / sizeof (char const *)];
+  Pedal_info *p = info_list_;
+
+  char **np = names;
+  do
     {
-      Pedal_type_info *s = &pedal_types_[i];
-      Pedal_info *info = &info_list_[i];
-
-      info->type_ = s;
-      info->item_ = 0;
-      info->bracket_ = 0;
-      info->finished_bracket_ = 0;
-      info->line_spanner_ = 0;
-      info->finished_line_spanner_ = 0;
-      info->current_bracket_ev_ = 0;
-      info->event_drul_[START] = 0;
-      info->event_drul_[STOP] = 0;
-      info->start_ev_ = 0;
+      p->name_ = *np;
+      p->item_ = 0;
+      p->bracket_ = 0;
+      p->finished_bracket_ = 0;
+      p->line_spanner_ = 0;
+      p->finished_line_spanner_ = 0;
+      p->current_bracket_ev_ = 0;
+      p->event_drul_[START] = 0;
+      p->event_drul_[STOP] = 0;
+      p->start_ev_ = 0;
+
+      p++;
     }
-  info_list_[NUM_PEDAL_TYPES].type_ = 0;
+  while (* (np++));
 }
 
 Piano_pedal_engraver::~Piano_pedal_engraver ()
 {
+  delete[] info_list_;
 }
 
 /*
@@ -209,7 +131,7 @@ Piano_pedal_engraver::~Piano_pedal_engraver ()
 void
 Piano_pedal_engraver::acknowledge_note_column (Grob_info info)
 {
-  for (Pedal_info *p = info_list_; p->type_; p++)
+  for (Pedal_info *p = info_list_; p && p->name_; p++)
     {
       if (p->line_spanner_)
        {
@@ -223,42 +145,38 @@ Piano_pedal_engraver::acknowledge_note_column (Grob_info info)
     }
 }
 
-IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_engraver, sostenuto);
-void
-Piano_pedal_engraver::listen_sostenuto (Stream_event *ev)
+bool
+Piano_pedal_engraver::try_music (Music *m)
 {
-  Direction d = to_dir (ev->get_property ("span-direction"));
-  ASSIGN_EVENT_ONCE (info_list_[SOSTENUTO].event_drul_[d], ev);
-}
-
-IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_engraver, sustain);
-void
-Piano_pedal_engraver::listen_sustain (Stream_event *ev)
-{
-  Direction d = to_dir (ev->get_property ("span-direction"));
-  ASSIGN_EVENT_ONCE (info_list_[SUSTAIN].event_drul_[d], ev);
-}
-
-IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_engraver, una_corda);
-void
-Piano_pedal_engraver::listen_una_corda (Stream_event *ev)
-{
-  Direction d = to_dir (ev->get_property ("span-direction"));
-  ASSIGN_EVENT_ONCE (info_list_[UNA_CORDA].event_drul_[d], ev);
+  if (m->is_mus_type ("pedal-event"))
+    {
+      for (Pedal_info *p = info_list_; p->name_; p++)
+       {
+         string nm = p->name_ + string ("Event");
+         if (ly_is_equal (m->get_property ("name"),
+                          scm_str2symbol (nm.c_str ())))
+           {
+             Direction d = to_dir (m->get_property ("span-direction"));
+             p->event_drul_[d] = m;
+             return true;
+           }
+       }
+    }
+  return false;
 }
 
 void
 Piano_pedal_engraver::process_music ()
 {
-  for (Pedal_info *p = info_list_; p->type_; p++)
+  for (Pedal_info *p = info_list_; p && p->name_; p++)
     {
       if (p->event_drul_[STOP] || p->event_drul_[START])
        {
          if (!p->line_spanner_)
            {
-             const char *name = p->type_->pedal_line_spanner_c_str_;
-             Stream_event *rq = (p->event_drul_[START] ? p->event_drul_[START] : p->event_drul_[STOP]);
-             p->line_spanner_ = make_spanner (name, rq->self_scm ());
+             string name = string (p->name_) + "PedalLineSpanner";
+             Music *rq = (p->event_drul_[START] ? p->event_drul_[START] : p->event_drul_[STOP]);
+             p->line_spanner_ = make_spanner (name.c_str (), rq->self_scm ());
            }
 
          /* Choose the appropriate grobs to add to the line spanner
@@ -274,7 +192,8 @@ Piano_pedal_engraver::process_music ()
            mixed:   Ped. _____/\____|
          */
 
-         SCM style = internal_get_property (p->type_->style_sym_);
+         string prop = string ("pedal") + p->name_ + "Style";
+         SCM style = get_property (prop.c_str ());
 
          bool mixed = style == ly_symbol2scm ("mixed");
          bool bracket = (mixed
@@ -294,11 +213,11 @@ void
 Piano_pedal_engraver::create_text_grobs (Pedal_info *p, bool mixed)
 {
   SCM s = SCM_EOL;
-  SCM strings = internal_get_property (p->type_->strings_sym_);
+  SCM strings = get_property (("pedal" + string (p->name_) + "Strings").c_str ());
 
   if (scm_ilength (strings) < 3)
     {
-      Stream_event *m = p->event_drul_[START];
+      Music *m = p->event_drul_[START];
       if (!m) m = p->event_drul_ [STOP];
 
       string msg = _f ("expect 3 strings for piano pedals, found: %ld",
@@ -316,7 +235,7 @@ Piano_pedal_engraver::create_text_grobs (Pedal_info *p, bool mixed)
       if (!mixed)
        {
          if (!p->start_ev_)
-           p->event_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", p->type_->base_name_.c_str ()));
+           p->event_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", p->name_));
          else
            s = scm_cadr (strings);
          p->start_ev_ = p->event_drul_[START];
@@ -327,7 +246,7 @@ Piano_pedal_engraver::create_text_grobs (Pedal_info *p, bool mixed)
       if (!mixed)
        {
          if (!p->start_ev_)
-           p->event_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", p->type_->base_name_.c_str ()));
+           p->event_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", p->name_));
          else
            s = scm_caddr (strings);
          p->start_ev_ = 0;
@@ -352,11 +271,11 @@ Piano_pedal_engraver::create_text_grobs (Pedal_info *p, bool mixed)
 
   if (scm_is_string (s))
     {
-      const char *propname = p->type_->pedal_c_str_;
+      string propname = string (p->name_) + "Pedal";
 
-      p->item_ = make_item (propname, (p->event_drul_[START]
-                                      ? p->event_drul_[START]
-                                      : p->event_drul_[STOP])->self_scm ());
+      p->item_ = make_item (propname.c_str (), (p->event_drul_[START]
+                                                 ? p->event_drul_[START]
+                                                 : p->event_drul_[STOP])->self_scm ());
 
       p->item_->set_property ("text", s);
       Axis_group_interface::add_element (p->line_spanner_, p->item_);
@@ -374,7 +293,7 @@ Piano_pedal_engraver::create_bracket_grobs (Pedal_info *p, bool mixed)
 {
   if (!p->bracket_ && p->event_drul_[STOP])
     {
-      string msg = _f ("can't find start of piano pedal bracket: `%s'", p->type_->base_name_.c_str ());
+      string msg = _f ("can't find start of piano pedal bracket: `%s'", p->name_);
       p->event_drul_[STOP]->origin ()->warning (msg);
       p->event_drul_[STOP] = 0;
     }
@@ -480,7 +399,7 @@ Piano_pedal_engraver::create_bracket_grobs (Pedal_info *p, bool mixed)
 void
 Piano_pedal_engraver::finalize ()
 {
-  for (Pedal_info *p = info_list_; p->type_; p++)
+  for (Pedal_info *p = info_list_; p && p->name_; p++)
     {
       /*
        suicide?
@@ -527,7 +446,7 @@ Piano_pedal_engraver::del_linespanner (Spanner *g)
 void
 Piano_pedal_engraver::stop_translation_timestep ()
 {
-  for (Pedal_info *p = info_list_; p->type_; p++)
+  for (Pedal_info *p = info_list_; p && p->name_; p++)
     {
       if (!p->bracket_)
        {
@@ -539,7 +458,7 @@ Piano_pedal_engraver::stop_translation_timestep ()
       typeset_all (p);
     }
 
-  for (Pedal_info *p = info_list_; p->type_; p++)
+  for (Pedal_info *p = info_list_; p->name_; p++)
     {
       p->event_drul_[STOP] = 0;
       p->event_drul_[START] = 0;
@@ -591,6 +510,8 @@ Piano_pedal_engraver::typeset_all (Pedal_info *p)
     }
 }
 
+#include "translator.icc"
+
 ADD_ACKNOWLEDGER (Piano_pedal_engraver, note_column);
 
 ADD_TRANSLATOR (Piano_pedal_engraver,