]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/context-def.cc
Fix some bugs in the dynamic engraver and PostScript backend
[lilypond.git] / lily / context-def.cc
index 0af5fabf4fdef003342bc705ffe19797b642be15..fee67b661d043ad86a7777039fd84c7fabc53bb4 100644 (file)
 
 #include "context-def.hh"
 
-#include "context.hh"
+#include "engraver-group.hh"
+#include "engraver.hh"
 #include "international.hh"
 #include "output-def.hh"
-#include "translator.hh"
+#include "performer-group.hh"
+#include "performer.hh"
+#include "score-context.hh"
+#include "translator-group.hh"
 #include "warn.hh"
 
 Context_def::Context_def ()
@@ -27,21 +31,14 @@ Context_def::Context_def ()
   context_name_ = SCM_EOL;
   default_child_ = SCM_EOL;
   description_ = SCM_EOL;
-  input_location_ = SCM_EOL;
 
   smobify_self ();
 
-  input_location_ = make_input (Input ());
   context_name_ = ly_symbol2scm ("");
 }
 
-Input *
-Context_def::origin () const
-{
-  return unsmob_input (input_location_);
-}
-
 Context_def::Context_def (Context_def const &s)
+  : Input (s)
 {
   context_aliases_ = SCM_EOL;
   translator_group_type_ = SCM_EOL;
@@ -51,11 +48,10 @@ Context_def::Context_def (Context_def const &s)
   context_name_ = SCM_EOL;
   description_ = SCM_EOL;
   default_child_ = SCM_EOL;
-  input_location_ = SCM_EOL;
-  smobify_self ();
 
+  smobify_self ();
   description_ = s.description_;
-  input_location_ = make_input (*s.origin ()); 
+
   default_child_ = s.default_child_;
   accept_mods_ = s.accept_mods_;
   property_ops_ = s.property_ops_;
@@ -96,7 +92,6 @@ Context_def::mark_smob (SCM smob)
   scm_gc_mark (me->property_ops_);
   scm_gc_mark (me->translator_group_type_);
   scm_gc_mark (me->default_child_);
-  scm_gc_mark (me->input_location_);
 
   return me->context_name_;
 }
@@ -148,6 +143,12 @@ Context_def::add_context_mod (SCM mod)
     programming_error ("unknown context mod tag");
 }
 
+SCM
+Context_def::get_context_name () const
+{
+  return context_name_;
+}
+
 SCM
 Context_def::get_accepted (SCM user_mod) const
 {
@@ -258,19 +259,107 @@ Context_def::get_translator_names (SCM user_mod) const
   return l1;
 }
 
+SCM
+filter_performers (SCM ell)
+{
+  SCM *tail = ℓ
+  for (SCM p = ell; scm_is_pair (p); p = scm_cdr (p))
+    {
+      if (dynamic_cast<Performer *> (unsmob_translator (scm_car (*tail))))
+       *tail = scm_cdr (*tail);
+      else
+       tail = SCM_CDRLOC (*tail);
+    }
+  return ell;
+}
+
+SCM
+filter_engravers (SCM ell)
+{
+  SCM *tail = &ell;
+  for (SCM p = ell; scm_is_pair (p); p = scm_cdr (p))
+    {
+      if (dynamic_cast<Engraver *> (unsmob_translator (scm_car (*tail))))
+       *tail = scm_cdr (*tail);
+      else
+       tail = SCM_CDRLOC (*tail);
+    }
+  return ell;
+}
+
 Context *
 Context_def::instantiate (SCM ops, Object_key const *key)
 {
-  Context *context = new Context (key);
+  Context *context = 0;
+
+  if (context_name_ == ly_symbol2scm ("Score"))
+    context = new Score_context (key);
+  else
+    context = new Context (key);
 
   context->definition_ = self_scm ();
   context->definition_mods_ = ops;
+
+  SCM trans_names = get_translator_names (ops);
+
+  Translator_group *g = get_translator_group (translator_group_type_);
+  SCM trans_list = SCM_EOL;
+
+  for (SCM s = trans_names; scm_is_pair (s); s = scm_cdr (s))
+    {
+      Translator *t = get_translator (scm_car (s));
+      if (!t)
+       warning (_f ("can't find: `%s'", ly_symbol2string (scm_car (s)).c_str ()));
+      else
+       {
+         Translator *tr = t->clone ();
+         SCM str = tr->self_scm ();
+
+         if (tr->must_be_last ())
+           {
+             SCM cons = scm_cons (str, SCM_EOL);
+             if (scm_is_pair (trans_list))
+               scm_set_cdr_x (scm_last_pair (trans_list), cons);
+             else
+               trans_list = cons;
+           }
+         else
+           trans_list = scm_cons (str, trans_list);
+
+         tr->daddy_context_ = context;
+         tr->unprotect ();
+       }
+    }
+
+  /*
+    Ugh,  todo: should just make a private
+    copy of Context_def with the user mods.
+  */
+
+  g->simple_trans_list_ = trans_list;
+
+  context->implementation_ = g;
+  if (dynamic_cast<Engraver_group *> (g))
+    g->simple_trans_list_ = filter_performers (g->simple_trans_list_);
+  else if (dynamic_cast<Performer_group *> (g))
+    g->simple_trans_list_ = filter_engravers (g->simple_trans_list_);
+
   context->aliases_ = context_aliases_;
+  g->connect_to_context (context);
+  g->unprotect ();
+
   context->accepts_list_ = get_accepted (ops);
 
   return context;
 }
 
+SCM
+Context_def::clone_scm () const
+{
+  Context_def *t = new Context_def (*this);
+  return t->unprotect ();
+}
+
 SCM
 Context_def::make_scm ()
 {