2 new-tie-engraver.cc -- implement Tie_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 1998--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
15 #include "tie-column.hh"
16 #include "engraver.hh"
18 #include "grob-pitch-tuple.hh"
20 #include "note-head.hh"
21 #include "staff-symbol-referencer.hh"
24 Manufacture ties. Acknowledge noteheads, and put them into a
25 priority queue. If we have a TieEvent, connect the notes that finish
26 just at this time, and note that start at this time.
28 TODO: Remove the dependency on musical info. We should tie on the
29 basis of position and duration-log of the heads (not of the events).
31 class Tie_engraver
: public Engraver
35 Link_array
<Grob
> now_heads_
;
36 Link_array
<Grob
> heads_to_tie_
;
37 Link_array
<Grob
> ties_
;
39 Spanner
* tie_column_
;
42 virtual void stop_translation_timestep ();
43 virtual void start_translation_timestep ();
44 virtual void acknowledge_grob (Grob_info
);
45 virtual bool try_music (Music
*);
46 virtual void process_music ();
47 void typeset_tie (Grob
*);
49 TRANSLATOR_DECLARATIONS (Tie_engraver
);
54 Tie_engraver::Tie_engraver ()
63 Tie_engraver::try_music (Music
*mus
)
65 if (mus
->is_mus_type ("tie-event"))
74 Tie_engraver::process_music ()
77 daddy_context_
->set_property ("tieMelismaBusy", SCM_BOOL_T
);
81 Tie_engraver::acknowledge_grob (Grob_info i
)
83 if (Note_head::has_interface (i
.grob_
))
87 for (int i
= heads_to_tie_
.size (); i
--;)
89 Grob
*th
= heads_to_tie_
[i
];
90 Music
* right_mus
= unsmob_music (h
->get_property ("cause"));
91 Music
* left_mus
= unsmob_music (th
->get_property ("cause"));
94 maybe should check positions too.
96 if (right_mus
&& left_mus
97 && ly_equal_p (right_mus
->get_property ("pitch"),
98 left_mus
->get_property ("pitch")))
100 Grob
* p
= make_spanner ("Tie");
101 Tie::set_interface (p
); // cannot remove yet!
103 Tie::set_head (p
, LEFT
, th
);
104 Tie::set_head (p
, RIGHT
, h
);
107 announce_grob (p
, last_event_
->self_scm ());
111 if (ties_
.size () && ! tie_column_
)
113 tie_column_
= make_spanner ("TieColumn");
114 announce_grob (tie_column_
, SCM_EOL
);
118 for (int i
= ties_
.size (); i
--;)
119 Tie_column::add_tie (tie_column_
,ties_
[i
]);
124 Tie_engraver::start_translation_timestep ()
126 daddy_context_
->set_property ("tieMelismaBusy",
127 ly_bool2scm (heads_to_tie_
.size ()));
132 Tie_engraver::stop_translation_timestep ()
136 heads_to_tie_
.clear ();
137 for (int i
=0; i
< ties_
.size (); i
++)
139 typeset_tie (ties_
[i
]);
146 typeset_grob (tie_column_
);
153 heads_to_tie_
= now_heads_
;
154 last_event_
= event_
;
161 Tie_engraver::typeset_tie (Grob
*her
)
163 if (! (Tie::head (her
,LEFT
) && Tie::head (her
,RIGHT
)))
164 warning (_ ("lonely tie"));
167 Drul_array
<Grob
*> new_head_drul
;
168 new_head_drul
[LEFT
] = Tie::head (her
,LEFT
);
169 new_head_drul
[RIGHT
] = Tie::head (her
,RIGHT
);
171 if (!Tie::head (her
,d
))
172 new_head_drul
[d
] = Tie::head (her
, (Direction
)-d
);
173 } while (flip (&d
) != LEFT
);
175 index_set_cell (her
->get_property ("head-pair"), LEFT
, new_head_drul
[LEFT
]->self_scm ());
176 index_set_cell (her
->get_property ("head-pair"), RIGHT
, new_head_drul
[RIGHT
]->self_scm ());
182 ENTER_DESCRIPTION (Tie_engraver
,
183 /* descr */ "Generate ties between noteheads of equal pitch.",
184 /* creats*/ "Tie TieColumn",
185 /* accepts */ "tie-event",
186 /* acks */ "rhythmic-head-interface",
187 /* reads */ "tieMelismaBusy",