]> git.donarmstrong.com Git - lilypond.git/commitdiff
new file.
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Wed, 17 Apr 2002 11:12:31 +0000 (11:12 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Wed, 17 Apr 2002 11:12:31 +0000 (11:12 +0000)
lily/ligature-bracket-engraver.cc [new file with mode: 0644]
lily/ligature-bracket.cc [new file with mode: 0644]

diff --git a/lily/ligature-bracket-engraver.cc b/lily/ligature-bracket-engraver.cc
new file mode 100644 (file)
index 0000000..d933448
--- /dev/null
@@ -0,0 +1,193 @@
+/*   
+  ligature-bracket-engraver.cc -- implement Ligature__bracket_engraver
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 2002 Juergen Reuter <reuter@ipd.uka.de>
+  
+ */
+#include "engraver.hh"
+#include "musical-request.hh"
+#include "warn.hh"
+#include "drul-array.hh"
+#include "item.hh"
+#include "spanner.hh"
+#include "score-engraver.hh"
+#include "note-head.hh"
+#include "stem.hh"
+#include "rest.hh"
+
+class Ligature_bracket_engraver : public Engraver
+{
+  Drul_array<Span_req*> reqs_drul_;
+  
+  Spanner *finished_ligature_bracket_p_;
+  Spanner *ligature_bracket_p_;
+  Span_req *prev_start_req_;
+
+  // moment where ligature started.
+  Moment ligature_start_mom_;
+  Grob *last_bound;
+
+protected:
+  virtual void stop_translation_timestep ();
+  virtual void start_translation_timestep ();
+  virtual void finalize ();
+
+  virtual void acknowledge_grob (Grob_info);
+  virtual bool try_music (Music*);
+  virtual void process_music ();
+
+public:
+  TRANSLATOR_DECLARATIONS(Ligature_bracket_engraver);
+
+private:
+  void typeset_ligature_bracket ();
+};
+
+
+Ligature_bracket_engraver::Ligature_bracket_engraver ()
+{
+  ligature_bracket_p_ = 0;
+  finished_ligature_bracket_p_ = 0;
+  reqs_drul_[LEFT] = reqs_drul_[RIGHT] = 0;
+  prev_start_req_ = 0;
+  last_bound = 0;
+}
+
+bool
+Ligature_bracket_engraver::try_music (Music *m)
+{
+  if (Span_req *req_ = dynamic_cast<Span_req*> (m))
+    {
+      if (scm_equal_p (req_->get_mus_property ("span-type"),
+                      ly_str02scm ("abort")) == SCM_BOOL_T)
+       {
+         reqs_drul_[START] = 0;
+         reqs_drul_[STOP] = 0;
+         if (ligature_bracket_p_)
+           ligature_bracket_p_->suicide ();
+         ligature_bracket_p_ = 0;
+       }
+      else if (scm_equal_p (req_->get_mus_property ("span-type"),
+                           ly_str02scm ("ligature-bracket")) == SCM_BOOL_T)
+       {
+         Direction d = req_->get_span_dir ();
+         reqs_drul_[d] = req_;
+         return true;
+       }
+    }
+  return false;
+}
+
+void
+Ligature_bracket_engraver::process_music ()
+{
+  if (reqs_drul_[STOP])
+    {
+      if (!ligature_bracket_p_)
+       reqs_drul_[STOP]->origin ()->warning (_ ("can't find start of ligature"));
+      else
+       {
+         if (!last_bound)
+           {
+             reqs_drul_[STOP]->origin ()->warning (_ ("no right bound"));
+           }
+         else
+           {
+             ligature_bracket_p_->set_bound (RIGHT, last_bound);
+           }
+       }
+      prev_start_req_ = 0;
+      finished_ligature_bracket_p_ = ligature_bracket_p_;
+      ligature_bracket_p_ = 0;
+    }
+  last_bound = unsmob_grob (get_property ("currentMusicalColumn"));
+
+  if (ligature_bracket_p_)
+    {
+      // TODO: maybe forbid breaks only if not transcribing
+      top_engraver ()->forbid_breaks ();
+    }
+  if (reqs_drul_[START])
+    {
+      if (ligature_bracket_p_)
+       {
+         reqs_drul_[START]->origin ()->warning (_ ("already have a ligature"));
+         return;
+       }
+
+      prev_start_req_ = reqs_drul_[START];
+      ligature_bracket_p_ = new Spanner (get_property ("LigatureBracket"));
+
+      Grob *bound = unsmob_grob (get_property ("currentMusicalColumn"));
+      if (!bound)
+       {
+         reqs_drul_[START]->origin ()->warning (_ ("no left bound"));
+       }
+      else
+       {
+         ligature_bracket_p_->set_bound (LEFT, bound);
+       }
+
+      ligature_start_mom_ = now_mom ();
+      
+      announce_grob(ligature_bracket_p_, reqs_drul_[START]->self_scm());
+    }
+}
+
+void
+Ligature_bracket_engraver::start_translation_timestep ()
+{
+  reqs_drul_[START] = 0;
+  reqs_drul_[STOP] = 0;
+}
+
+void
+Ligature_bracket_engraver::typeset_ligature_bracket ()
+{
+  if (finished_ligature_bracket_p_)
+    {
+      typeset_grob (finished_ligature_bracket_p_);
+      finished_ligature_bracket_p_ = 0;
+    }
+}
+
+void
+Ligature_bracket_engraver::stop_translation_timestep ()
+{
+  typeset_ligature_bracket ();
+}
+
+void
+Ligature_bracket_engraver::finalize ()
+{
+  typeset_ligature_bracket ();
+  if (ligature_bracket_p_)
+    {
+      prev_start_req_->origin ()->warning (_ ("unterminated ligature"));
+      ligature_bracket_p_->suicide ();
+    }
+}
+
+void
+Ligature_bracket_engraver::acknowledge_grob (Grob_info info)
+{
+  if (ligature_bracket_p_)
+    {
+      if (Rest::has_interface (info.grob_l_))
+       {
+         reqs_drul_[START]->origin ()->warning (_ ("ligature may not contain rest; ignoring rest"));
+         prev_start_req_->origin ()->warning (_ ("ligature was started here"));
+         // TODO: maybe better should stop ligature here rather than
+         // ignoring the rest?
+       }
+    }
+}
+
+ENTER_DESCRIPTION(Ligature_bracket_engraver,
+/* descr */       "Handles Ligature_requests by engraving Ligature brackets.",
+/* creats*/       "LigatureBracket",
+/* acks  */       "rest-interface",
+/* reads */       "",
+/* write */       "");
diff --git a/lily/ligature-bracket.cc b/lily/ligature-bracket.cc
new file mode 100644 (file)
index 0000000..2e7d816
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+  ligature-bracket.cc -- implement Ligature_bracket
+  
+  source file of the GNU LilyPond music typesetter
+  
+  (c) 2002 Juergen Reuter <reuter@ipd.uka.de>
+*/
+
+#include "ligature-bracket.hh"
+#include "item.hh"
+#include "paper-def.hh"
+#include "spanner.hh"
+#include "staff-symbol-referencer.hh"
+#include "lookup.hh"
+#include "box.hh"
+
+static Molecule
+brew_edge (Direction dir, Real thickness, Real width, Real height,
+          Real blotdiameter)
+{
+  Molecule hline = Lookup::roundfilledbox (Box (Interval (0, width),
+                                               Interval (0, thickness)),
+                                          blotdiameter);
+  hline.translate_axis (height - thickness, Y_AXIS);
+
+  Molecule vline = Lookup::roundfilledbox (Box (Interval (0, thickness),
+                                               Interval (0, height)),
+                                          blotdiameter);
+  if (dir == RIGHT)
+    {
+      vline.translate_axis (width - thickness, X_AXIS);
+    }
+
+  Molecule edge = Molecule ();
+  edge.add_molecule (hline);
+  edge.add_molecule (vline);
+  return edge;
+}
+
+MAKE_SCHEME_CALLBACK (Ligature_bracket, brew_molecule, 1);
+SCM
+Ligature_bracket::brew_molecule (SCM smob)
+{
+  Grob *me = unsmob_grob (smob);
+  Spanner *spanner = dynamic_cast<Spanner*> (me);
+  Real blotdiameter = me->paper_l ()->get_var ("blotdiameter");
+  Real staff_space = Staff_symbol_referencer::staff_space (me);
+
+  Real thickness = me->paper_l ()->get_var ("linethickness");  
+  SCM grob_thickness = me->get_grob_property ("thickness");
+  if (gh_number_p (grob_thickness))
+    thickness *= gh_scm2double (grob_thickness);
+
+  SCM edge_width_scm = me->get_grob_property ("width");
+  Real edge_width;
+  if (gh_number_p (edge_width_scm))
+    {
+      edge_width = gh_scm2double (edge_width_scm);
+    }
+  else
+    {
+      edge_width = 0.75;
+    }
+  edge_width *= staff_space;
+
+  SCM edge_height_scm = me->get_grob_property ("height");
+  Real edge_height;
+  if (gh_number_p (edge_height_scm))
+    {
+      edge_height = gh_scm2double (edge_height_scm);
+    }
+  else
+    {
+      edge_height = 0.5;
+    }
+  edge_height *= staff_space;
+
+  Item* left_bound = spanner->get_bound (LEFT);
+  Item* right_bound = spanner->get_bound (RIGHT);
+
+  Molecule bracket = Molecule ();
+
+  Real y_min_offs =
+    0.5 * Staff_symbol_referencer::line_count (me) * staff_space;
+  Real y_left_offs = y_min_offs;
+  Real y_right_offs = y_min_offs;
+
+  Real left_bound_left_extent = 0;
+
+  if (left_bound)
+    {
+      Molecule left_edge =
+       brew_edge (LEFT, thickness, edge_width, edge_height, blotdiameter);
+      Grob *left_common_x = me->common_refpoint (left_bound, X_AXIS);
+      left_bound_left_extent =
+       left_bound->extent (left_common_x, X_AXIS)[LEFT];
+      left_edge.translate_axis (left_bound_left_extent, X_AXIS);
+      bracket.add_molecule (left_edge);
+      Grob *left_common_y = me->common_refpoint (left_bound, Y_AXIS);
+      y_left_offs =
+       max(y_left_offs, left_bound->extent (left_common_y, Y_AXIS)[UP]);
+    }
+  else
+    {
+      me->warning (_ ("no left bound"));
+    }
+
+  if (right_bound)
+    {
+      Molecule right_edge =
+       brew_edge (RIGHT, thickness, edge_width, edge_height, blotdiameter);
+      Grob *staff_symbol = Staff_symbol_referencer::staff_symbol_l (me);
+      Grob *right_common_bound_x =
+       right_bound->common_refpoint (staff_symbol, X_AXIS);
+
+      Real left_offs = 0;
+      if (left_bound)
+       {
+         Grob *left_common_bound_x =
+           left_bound->common_refpoint (staff_symbol, X_AXIS);
+         left_offs = left_bound->extent (left_common_bound_x, X_AXIS)[LEFT];
+       }
+
+      Real right_offs =
+       right_bound->extent (right_common_bound_x, X_AXIS)[RIGHT];
+
+      right_edge.translate_axis (+ right_offs
+                                - left_offs
+                                + left_bound_left_extent
+                                - edge_width,
+                                X_AXIS);
+      bracket.add_molecule (right_edge);
+      Grob *right_common_y = me->common_refpoint (right_bound, Y_AXIS);
+      y_right_offs =
+       max(y_right_offs, right_bound->extent (right_common_y, Y_AXIS)[UP]);
+    }
+  else
+    {
+      me->warning (_ ("no left bound"));
+    }
+
+  bracket.translate_axis (max (y_left_offs, y_right_offs), Y_AXIS);
+
+  return bracket.smobbed_copy ();
+}