X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fporrectus-engraver.cc;h=fab7e7d86ef4c6220fe7dbf484a2c1279a407d75;hb=8d0267eb80a7cb026751db0a9eabeb61d958776e;hp=84d81f44605a449bd63494f301d259b63483b4b3;hpb=19125bf158fe23501e40eef6da3bbf876c664f2a;p=lilypond.git diff --git a/lily/porrectus-engraver.cc b/lily/porrectus-engraver.cc index 84d81f4460..fab7e7d86e 100644 --- a/lily/porrectus-engraver.cc +++ b/lily/porrectus-engraver.cc @@ -1,7 +1,7 @@ /* porrectus-engraver.cc -- implement Porrectus_engraver - Copyright (C) 2001 Juergen Reuter + Copyright (c) 2001--2003 Juergen Reuter written for the GNU LilyPond music typesetter */ @@ -11,93 +11,67 @@ * moment of the second note. Actually, it should take the moment of * the first note. * - * TODO: Introduce "\~" as alternative syntax for "\porrectus"? + * FIXME: Turn off typesetting of stems, flags, dots, etc. * * TODO: Hufnagel support. * - * TODO: Fine-tuning of porrectus shape. In particular, the mensural - * non-solid shape could either be slightly bigger in height, or the - * extrem points could be slightly vertically shifted apart. + * TODO: The following issues are currently not handled by this + * engraver: (1) accidentals placement, (2) spacing. For example, + * currently only the accidental for the second note (cp. the above + * FIXME) is printed. These issues should be resolved by some sort of + * ligature context that encloses use of this engraver, using syntax + * like: \ligature { e \~ c }. * - * TODO: For white mensural (i.e. #'style=#'mensural, #'solid=##f) - * porrectus grobs, it is possible to automatically determine all - * porrectus specific properties (add-stem, stem-direction) solely - * from the duration of the contributing notes and time-signature. - * Introduce a boolean grob property called auto-config, so that, if - * turned on, lily automatically sets the remaining properties - * properly. + * TODO: Do not allow a series of adjacent porrectus events, as in: + * e \~ d \~ c. * - * TODO: The following issues are not (and should not be) handled by - * this engraver: (1) accidentals placement, (2) avoiding line - * breaking inbetween porrectus, (3) spacing. For example, currently - * only the accidental for the second note (cp. the above FIXME) is - * printed. These issues should be resolved by some sort of ligature - * context that encloses use of this engraver, using syntax like: - * \ligature { e \porrectus c }. - * - * TODO: Do not allow a series of adjacent porrectus requests, as in: - * e \porrectus d \porrectus c. + * TODO: Junk duplicate (or rather triple) implementation of + * create_ledger_line in porrectus.cc, custos.cc and note-head.cc. */ #include "staff-symbol-referencer.hh" #include "porrectus.hh" -#include "musical-request.hh" -#include "command-request.hh" +#include "event.hh" + #include "rhythmic-head.hh" #include "item.hh" #include "engraver.hh" +#include "score-engraver.hh" #include "pqueue.hh" - -// TODO: PHead_melodic_tuple is duplicated code from tie-engraver.cc. -// Maybe put this into public class? -struct PHead_melodic_tuple { - Melodic_req *req_l_; - Grob *head_l_; - Moment end_; - PHead_melodic_tuple (); - PHead_melodic_tuple (Grob*, Melodic_req*, Moment); - static int pitch_compare (PHead_melodic_tuple const &, - PHead_melodic_tuple const &); - static int time_compare (PHead_melodic_tuple const &, - PHead_melodic_tuple const &); -}; - -inline int compare (PHead_melodic_tuple const &a, PHead_melodic_tuple const &b) -{ - return PHead_melodic_tuple::time_compare (a,b); -} +#include "warn.hh" +#include "grob-pitch-tuple.hh" class Porrectus_engraver : public Engraver { public: - Porrectus_engraver (); - VIRTUAL_COPY_CONS (Translator); + TRANSLATOR_DECLARATIONS(Porrectus_engraver); protected: - virtual bool try_music (Music *req_l); - virtual void create_grobs (); + virtual bool try_music (Music *req); + virtual void process_music (); + virtual void process_acknowledged_grobs (); virtual void stop_translation_timestep (); virtual void start_translation_timestep (); virtual void acknowledge_grob (Grob_info); private: - PQueue past_notes_pq_; - Porrectus_req *porrectus_req_l_; - Array left_heads_; - Array right_heads_; - Link_array porrectus_p_arr_; + PQueue past_notes_pq_; + Music *porrectus_req_; + Array left_heads_; + Array right_heads_; + Link_array porrectuses_; }; Porrectus_engraver::Porrectus_engraver () { - porrectus_req_l_ = 0; + porrectus_req_ = 0; } bool Porrectus_engraver::try_music (Music *m) { - if (Porrectus_req *req_l_ = dynamic_cast (m)) + if (m->is_mus_type ("porrectus-event")) { - porrectus_req_l_ = req_l_; + porrectus_req_ = m; return true; } else @@ -105,133 +79,95 @@ Porrectus_engraver::try_music (Music *m) } void -Porrectus_engraver::acknowledge_grob (Grob_info info_l_) +Porrectus_engraver::process_music () { - if (Rhythmic_head::has_interface (info_l_.elem_l_)) + if (porrectus_req_) { - Note_req *note_req_l_ = dynamic_cast (info_l_.req_l_); - if (!note_req_l_) - return; - left_heads_.push (PHead_melodic_tuple (info_l_.elem_l_, note_req_l_, - now_mom () + - note_req_l_->length_mom ())); + top_engraver ()->forbid_breaks (); } } void -Porrectus_engraver::create_grobs () +Porrectus_engraver::acknowledge_grob (Grob_info info_) { - if (porrectus_req_l_) + if (Rhythmic_head::has_interface (info_.grob_)) { - left_heads_.sort (PHead_melodic_tuple::pitch_compare); - right_heads_.sort (PHead_melodic_tuple::pitch_compare); + Music * m = info_.music_cause (); + if (m->is_mus_type ("note-event")) + right_heads_.push (Grob_pitch_tuple (info_.grob_, m, + now_mom () + + m->get_length ())); + } +} - SCM head_list = SCM_EOL; - +void +Porrectus_engraver::process_acknowledged_grobs () +{ + if (porrectus_req_) + { + left_heads_.sort (Grob_pitch_tuple::pitch_compare); + right_heads_.sort (Grob_pitch_tuple::pitch_compare); int i = left_heads_.size () - 1; int j = right_heads_.size () - 1; while ((i >= 0) && (j >= 0)) { - head_list = - gh_cons (gh_cons (right_heads_[j].head_l_->self_scm (), - left_heads_[i].head_l_->self_scm ()), - head_list); + Item *left_head = dynamic_cast (left_heads_[i].head_); + Item *right_head = dynamic_cast (right_heads_[j].head_); + left_head->set_grob_property("transparent", gh_bool2scm(true)); + right_head->set_grob_property("transparent", gh_bool2scm(true)); - past_notes_pq_. insert (left_heads_[i]); + Grob *porrectus_ = new Item (get_property ("Porrectus")); + Porrectus::set_left_head(porrectus_, left_head); + Porrectus::set_right_head(porrectus_, right_head); + porrectuses_.push (porrectus_); + announce_grob(porrectus_, porrectus_req_->self_scm()); + + past_notes_pq_. insert (right_heads_[i]); left_heads_.del (i); right_heads_.del (j); i--; j--; } - - for (SCM s = head_list; gh_pair_p (s); s = gh_cdr (s)) - { - SCM caar = gh_caar (s); - SCM cdar = gh_cdar (s); - - Item *left_head = dynamic_cast (unsmob_grob (caar)); - Item *right_head = dynamic_cast (unsmob_grob (cdar)); - left_head->set_grob_property("transparent", gh_bool2scm(true)); - right_head->set_grob_property("transparent", gh_bool2scm(true)); - - Grob *porrectus_p_ = new Item (get_property ("Porrectus")); - Porrectus::set_left_head(porrectus_p_, caar); - Porrectus::set_right_head(porrectus_p_, cdar); - porrectus_p_arr_.push (porrectus_p_); - announce_grob (porrectus_p_, 0); - } } } void Porrectus_engraver::stop_translation_timestep () { - for (int i = 0; i < left_heads_.size (); i++) + for (int i = 0; i < right_heads_.size (); i++) { - past_notes_pq_.insert (left_heads_[i]); + past_notes_pq_.insert (right_heads_[i]); } - left_heads_.clear (); + right_heads_.clear (); - for (int i = 0; i < porrectus_p_arr_.size (); i++) + for (int i = 0; i < porrectuses_.size (); i++) { - typeset_grob (porrectus_p_arr_[i]); + typeset_grob (porrectuses_[i]); } - porrectus_p_arr_.clear (); + porrectuses_.clear (); } void Porrectus_engraver::start_translation_timestep () { - porrectus_req_l_ = 0; + porrectus_req_ = 0; Moment now = now_mom (); while (past_notes_pq_.size () && past_notes_pq_.front ().end_ < now) past_notes_pq_.delmin (); - right_heads_.clear (); + left_heads_.clear (); while (past_notes_pq_.size () && (past_notes_pq_.front ().end_ == now)) - right_heads_.push (past_notes_pq_.get ()); + left_heads_.push (past_notes_pq_.get ()); } -ADD_THIS_TRANSLATOR (Porrectus_engraver); -// TODO: PHead_melodic_tuple is duplicated code from tie-engraver.cc. -// Maybe put this into public class? -PHead_melodic_tuple::PHead_melodic_tuple () -{ - head_l_ = 0; - req_l_ = 0; - end_ = 0; -} - -PHead_melodic_tuple::PHead_melodic_tuple (Grob *h, Melodic_req*m, Moment mom) -{ - head_l_ = h; - req_l_ = m; - end_ = mom; -} - -/* - signed compare, should use pitchget_mus_property ("pitch"); - SCM p2 = h2.req_l_->get_mus_property ("pitch"); - - int result = Pitch::compare (*unsmob_pitch (p1), - *unsmob_pitch (p2)); - return result; -} - -int -PHead_melodic_tuple::time_compare (PHead_melodic_tuple const&h1, - PHead_melodic_tuple const &h2) -{ - int result = Moment::compare(h1.end_, h2.end_); - return result; -} +ENTER_DESCRIPTION(Porrectus_engraver, +/* descr */ "Join adjacent notes to a porrectus ligature.", +/* creats*/ "Porrectus", +/* accepts */ "porrectus-event", +/* acks */ "rhythmic-head-interface", +/* reads */ "", +/* write */ "");