to Voice.
* lily/glissando-engraver.cc (acknowledge_grob): new file: split
out note-line and glissando functionality.
* lily/line-spanner.cc (brew_molecule): cleanup.
+2003-05-28 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+ * ly/engraver-init.ly (VoiceContext): move Note_head_line_engraver
+ to Voice.
+
+ * lily/glissando-engraver.cc (acknowledge_grob): new file: split
+ out note-line and glissando functionality.
+
+
+ * lily/line-spanner.cc (brew_molecule): cleanup.
+
2003-05-27 Jan Nieuwenhuizen <janneke@gnu.org>
* scripts/as2text.scm: Use rdelim module.
--- /dev/null
+/*
+ note-head-line-engraver.cc -- implement Note_head_line_engraver
+
+ source file of the GNU LilyPond music typesetter
+
+ (c) 2000--2003 Jan Nieuwenhuizen <janneke@gnu.org>
+ */
+
+#include "warn.hh"
+#include "event.hh"
+#include "spanner.hh"
+#include "rhythmic-head.hh"
+#include "engraver.hh"
+
+/**
+ Create line-spanner grobs for glissandi lines that connect note
+ heads.
+*/
+class Glissando_engraver : public Engraver
+{
+public:
+ TRANSLATOR_DECLARATIONS(Glissando_engraver);
+
+protected:
+ virtual void acknowledge_grob (Grob_info);
+ virtual void finalize ();
+ virtual void stop_translation_timestep ();
+ virtual bool try_music (Music *);
+ virtual void process_music ();
+private:
+ Spanner *line_;
+ Spanner *last_line_;
+ Music* event_;
+};
+
+Glissando_engraver::Glissando_engraver ()
+{
+ last_line_ = line_ = 0;
+ event_ = 0;
+}
+
+bool
+Glissando_engraver::try_music (Music* m)
+{
+ if (!event_)
+ {
+ event_ = m;
+ return true;
+ }
+ return false;
+}
+
+void
+Glissando_engraver::process_music ()
+{
+ if (event_)
+ {
+ last_line_ = line_;
+
+ line_ = new Spanner (get_property ("Glissando"));
+ announce_grob (line_, event_->self_scm ());
+ }
+}
+
+
+void
+Glissando_engraver::acknowledge_grob (Grob_info info)
+{
+ if (Rhythmic_head::has_interface (info.grob_))
+ {
+ Grob * g = info.grob_;
+ if (line_)
+ line_->set_bound (LEFT, g);
+
+ if (last_line_)
+ last_line_->set_bound (RIGHT, g);
+ }
+}
+
+
+void
+Glissando_engraver::stop_translation_timestep ()
+{
+ if (last_line_ && last_line_->get_bound (RIGHT))
+ {
+ typeset_grob (last_line_);
+ last_line_ =0;
+ }
+
+ last_line_ = line_;
+ line_ = 0;
+ event_ = 0;
+}
+
+void
+Glissando_engraver::finalize ()
+{
+ if (line_)
+ {
+ String msg = _("Unterminated glissando.");
+
+ if (event_)
+ event_->origin ()->warning (msg);
+ else
+ warning (msg);
+
+ line_->suicide ();
+ line_ =0;
+ }
+}
+
+
+
+ENTER_DESCRIPTION(Glissando_engraver,
+/* descr */ "Engrave a glissandi",
+/* creats*/ "Glissando",
+/* accepts */ "glissando-event",
+/* acks */ "rhythmic-head-interface",
+/* reads */ "followVoice",
+/* write */ "");
#include "paper-column.hh"
#include "staff-symbol-referencer.hh"
#include "font-interface.hh"
+#include "warn.hh"
#include <math.h>
Item** bound = bound_drul + 1;
- Grob *common[] = { 0, 0 };
- for (Axis a = X_AXIS; a < NO_AXES; a = Axis (a + 1))
+ Grob *common[] = { me, me };
+ for (int a = X_AXIS; a < NO_AXES; a++)
{
- common[a] = bound[LEFT]->common_refpoint (bound[RIGHT], a);
+ common[a] = me->common_refpoint (bound[RIGHT], Axis (a));
+ common[a] = common[a]->common_refpoint (bound[LEFT], Axis (a));
if (!common[a])
- return SCM_EOL;
+ {
+ programming_error ("No common point!");
+ return SCM_EOL;
+ }
}
Real gap = gh_scm2double (me->get_grob_property ("gap"));
else
{
Real off = gap + ((bound[LEFT]->extent (bound[LEFT], X_AXIS).length ()*3)/4); // distance from center to start of line
- dxy[X_AXIS] = bound[RIGHT]->extent (common[X_AXIS], X_AXIS).center ()
- - bound[LEFT]->extent (common[X_AXIS], X_AXIS).center ();
- dxy[Y_AXIS] = bound[RIGHT]->extent (common[Y_AXIS], Y_AXIS).center ()
- - bound[LEFT]->extent (common[Y_AXIS], Y_AXIS).center ();
- dist = sqrt (dxy[X_AXIS]*dxy[X_AXIS]+dxy[Y_AXIS]*dxy[Y_AXIS]);
- ofxy = dxy* (off/dist);
- dxy -= 2*ofxy;
+ for (int a = X_AXIS; a < NO_AXES; a++)
+ {
+ Axis ax = (Axis)a;
+ dxy[ax] =
+ + bound[RIGHT]->extent (common[X_AXIS], ax).center ()
+ - bound[LEFT]->extent (common[X_AXIS], ax).center ();
+
+ my_off[ax] =me->relative_coordinate (common[a], ax);
+ his_off[ax] = bound[LEFT]->relative_coordinate (common[a], ax);
+
+ }
- my_off = Offset (me->relative_coordinate (common[X_AXIS], X_AXIS),
- me->relative_coordinate (common[Y_AXIS], Y_AXIS));
-
- his_off = Offset (bound[LEFT]->relative_coordinate (common[X_AXIS],
- X_AXIS),
- bound[LEFT]->relative_coordinate (common[Y_AXIS],
- Y_AXIS));
-
- }
+ ofxy = dxy * (off/dxy.length ());
+ dxy -= 2*ofxy;
+ }
Real thick = me->get_paper ()->get_var ("linethickness");
#include "translator-group.hh"
/**
- Create line-spanner grobs for glissandi (and possibly other) lines
- that connect note heads.
-
+ Create line-spanner grobs for lines that connect note heads.
TODO: have the line commit suicide if the notes are connected with
either slur or beam.
virtual void acknowledge_grob (Grob_info);
virtual void process_acknowledged_grobs ();
virtual void stop_translation_timestep ();
- virtual bool try_music (Music *);
private:
Spanner* line_;
- Music* req_;
- Music* last_req_;
Translator* last_staff_;
bool follow_;
Grob* head_;
Note_head_line_engraver::Note_head_line_engraver ()
{
line_ = 0;
- req_ = 0;
- last_req_ = 0;
follow_ = false;
head_ = 0;
last_head_ = 0;
last_staff_ = 0;
}
-bool
-Note_head_line_engraver::try_music (Music* m)
-{
- if (!req_)
- {
- req_ = m;
- return true;
- }
- return false;
-}
-
void
Note_head_line_engraver::acknowledge_grob (Grob_info info)
{
void
Note_head_line_engraver::process_acknowledged_grobs ()
{
- if (!line_ && (follow_ || last_req_) && last_head_ && head_
- && (last_head_ != head_))
+ if (!line_ && follow_ && last_head_ && head_)
{
/* TODO: Don't follow if there's a beam.
later point */
if (follow_)
line_ = new Spanner (get_property ("VoiceFollower"));
- else
- line_ = new Spanner (get_property ("Glissando"));
line_->set_bound (LEFT, last_head_);
line_->set_bound (RIGHT, head_);
-
- /* Note, mustn't set y-parent of breakable symbol to simple item:
- one of the two broken parts won't have an y-parent! */
- /* X parent is set by set_bound */
- line_->set_parent (Staff_symbol_referencer::get_staff_symbol (last_head_),
- Y_AXIS);
-
- SCM c = last_req_? last_req_->self_scm () : SCM_EOL;
- announce_grob(line_, c);
- last_req_ = 0;
+
+ announce_grob(line_, head_->self_scm ());
follow_ = false;
}
if (head_)
last_head_ = head_;
head_ = 0;
-
- if (req_)
- {
- last_req_ = req_;
- req_ =0;
- }
}
\consists "Text_spanner_engraver"
\consists "Grob_pq_engraver"
+ \consists "Note_head_line_engraver"
+ \consists "Glissando_engraver"
\consists "Ligature_bracket_engraver"
\consists "Breathing_sign_engraver"
% \consists "Rest_engraver"
\consists "Rest_engraver"
% why here ?
- \consists "Note_head_line_engraver"
\consists "Output_property_engraver"
}