2 porrectus-engraver.cc -- implement Porrectus_engraver
4 Copyright (c) 2001--2003 Juergen Reuter
6 written for the GNU LilyPond music typesetter
10 * FIXME: Currently, when creating a porrectus item, it takes the
11 * moment of the second note. Actually, it should take the moment of
14 * FIXME: Turn off typesetting of stems, flags, dots, etc.
16 * TODO: Hufnagel support.
18 * TODO: The following issues are currently not handled by this
19 * engraver: (1) accidentals placement, (2) spacing. For example,
20 * currently only the accidental for the second note (cp. the above
21 * FIXME) is printed. These issues should be resolved by some sort of
22 * ligature context that encloses use of this engraver, using syntax
23 * like: \ligature { e \~ c }.
25 * TODO: Do not allow a series of adjacent porrectus events, as in:
28 * TODO: Junk duplicate (or rather triple) implementation of
29 * create_ledger_line in porrectus.cc, custos.cc and note-head.cc.
32 #include "staff-symbol-referencer.hh"
33 #include "porrectus.hh"
36 #include "rhythmic-head.hh"
38 #include "engraver.hh"
39 #include "score-engraver.hh"
42 #include "grob-pitch-tuple.hh"
44 class Porrectus_engraver
: public Engraver
{
46 TRANSLATOR_DECLARATIONS(Porrectus_engraver
);
49 virtual bool try_music (Music
*req
);
50 virtual void process_music ();
51 virtual void process_acknowledged_grobs ();
52 virtual void stop_translation_timestep ();
53 virtual void start_translation_timestep ();
54 virtual void acknowledge_grob (Grob_info
);
57 PQueue
<Grob_pitch_tuple
> past_notes_pq_
;
58 Music
*porrectus_req_
;
59 Array
<Grob_pitch_tuple
> left_heads_
;
60 Array
<Grob_pitch_tuple
> right_heads_
;
61 Link_array
<Grob
> porrectuses_
;
64 Porrectus_engraver::Porrectus_engraver ()
70 Porrectus_engraver::try_music (Music
*m
)
72 if (m
->is_mus_type ("porrectus-event"))
82 Porrectus_engraver::process_music ()
86 top_engraver ()->forbid_breaks ();
91 Porrectus_engraver::acknowledge_grob (Grob_info info_
)
93 if (Rhythmic_head::has_interface (info_
.grob_
))
95 Music
* m
= info_
.music_cause ();
96 if (m
->is_mus_type ("note-event"))
97 right_heads_
.push (Grob_pitch_tuple (info_
.grob_
, m
,
104 Porrectus_engraver::process_acknowledged_grobs ()
108 left_heads_
.sort (Grob_pitch_tuple::pitch_compare
);
109 right_heads_
.sort (Grob_pitch_tuple::pitch_compare
);
110 int i
= left_heads_
.size () - 1;
111 int j
= right_heads_
.size () - 1;
113 while ((i
>= 0) && (j
>= 0))
115 Item
*left_head
= dynamic_cast<Item
*> (left_heads_
[i
].head_
);
116 Item
*right_head
= dynamic_cast<Item
*> (right_heads_
[j
].head_
);
117 left_head
->set_grob_property("transparent", gh_bool2scm(true));
118 right_head
->set_grob_property("transparent", gh_bool2scm(true));
120 Grob
*porrectus_
= new Item (get_property ("Porrectus"));
121 Porrectus::set_left_head(porrectus_
, left_head
);
122 Porrectus::set_right_head(porrectus_
, right_head
);
123 porrectuses_
.push (porrectus_
);
124 announce_grob(porrectus_
, porrectus_req_
->self_scm());
126 past_notes_pq_
. insert (right_heads_
[i
]);
128 right_heads_
.del (j
);
136 Porrectus_engraver::stop_translation_timestep ()
138 for (int i
= 0; i
< right_heads_
.size (); i
++)
140 past_notes_pq_
.insert (right_heads_
[i
]);
142 right_heads_
.clear ();
144 for (int i
= 0; i
< porrectuses_
.size (); i
++)
146 typeset_grob (porrectuses_
[i
]);
148 porrectuses_
.clear ();
152 Porrectus_engraver::start_translation_timestep ()
155 Moment now
= now_mom ();
156 while (past_notes_pq_
.size () && past_notes_pq_
.front ().end_
< now
)
157 past_notes_pq_
.delmin ();
159 left_heads_
.clear ();
160 while (past_notes_pq_
.size () &&
161 (past_notes_pq_
.front ().end_
== now
))
162 left_heads_
.push (past_notes_pq_
.get ());
167 ENTER_DESCRIPTION(Porrectus_engraver
,
168 /* descr */ "Join adjacent notes to a porrectus ligature.",
169 /* creats*/ "Porrectus",
170 /* accepts */ "porrectus-event",
171 /* acks */ "rhythmic-head-interface",