]> git.donarmstrong.com Git - lilypond.git/blob - lily/custos-engraver.cc
Fix some bugs in the dynamic engraver and PostScript backend
[lilypond.git] / lily / custos-engraver.cc
1 /*
2   custos-engraver.cc -- implement Custos_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2000--2006 Juergen Reuter <reuter@ipd.uka.de>,
7   Han-Wen Nienhuys <hanwen@xs4all.nl>
8 */
9
10 #include "engraver.hh"
11 #include "bar-line.hh"
12 #include "item.hh"
13 #include "note-head.hh"
14 #include "staff-symbol-referencer.hh"
15 #include "warn.hh"
16 #include "pitch.hh"
17
18 #include "translator.icc"
19
20 /*
21  * This class implements an engraver for custos symbols.
22  *
23  * FIXME: note heads inside of ligatures (i.e. ligature heads) are
24  * sometimes not recognized by this engraver. --jr
25  */
26 class Custos_engraver : public Engraver
27 {
28 public:
29   TRANSLATOR_DECLARATIONS (Custos_engraver);
30   void start_translation_timestep ();
31   DECLARE_ACKNOWLEDGER (bar);
32   DECLARE_ACKNOWLEDGER (note_head);
33   void process_acknowledged ();
34   void stop_translation_timestep ();
35   virtual void finalize ();
36
37 private:
38   Item *create_custos ();
39   bool custos_permitted_;
40   vector<Grob*> custodes_;
41   vector<Pitch> pitches_;
42 };
43
44 Custos_engraver::Custos_engraver ()
45 {
46   custos_permitted_ = false;
47 }
48
49 void
50 Custos_engraver::stop_translation_timestep ()
51 {
52   /*
53     delay typeset until we're at the next moment, so we can silence custodes at the end of the piece.
54   */
55   pitches_.clear ();
56
57   custos_permitted_ = false;
58 }
59
60 void
61 Custos_engraver::start_translation_timestep ()
62 {
63   custodes_.clear ();
64 }
65
66 void
67 Custos_engraver::acknowledge_bar (Grob_info info)
68 {
69   (void) info;
70   custos_permitted_ = true;
71 }
72
73 void
74 Custos_engraver::acknowledge_note_head (Grob_info info)
75 {
76   Music *m = info.music_cause ();
77   if (m && m->is_mus_type ("note-event"))
78     {
79
80       /*
81         ideally, we'd do custos->set_parent (Y_AXIS, notehead),
82         but since the note head lives on the other system, we can't
83
84         So we copy the position from the note head pitch.  We
85         don't look at the staff-position, since we can't be sure
86         whether Clef_engraver already applied a vertical shift.
87       */
88       pitches_.push_back (*unsmob_pitch (m->get_property ("pitch")));
89     }
90 }
91
92 void
93 Custos_engraver::process_acknowledged ()
94 {
95   if (scm_is_string (get_property ("whichBar")))
96     custos_permitted_ = true;
97
98   if (custos_permitted_)
99     {
100       for (vsize i = pitches_.size (); i--;)
101         {
102           Item *c = create_custos ();
103
104           int p = pitches_[i].steps ();
105           SCM c0 = get_property ("middleCPosition");
106           if (scm_is_number (c0))
107             p += scm_to_int (c0);
108
109           c->set_property ("staff-position",
110                            scm_from_int (p));
111         }
112
113       pitches_.clear ();
114     }
115 }
116
117 Item *
118 Custos_engraver::create_custos ()
119 {
120   Item *custos = make_item ("Custos", SCM_EOL);
121
122   custodes_.push_back (custos);
123
124   return custos;
125 }
126
127 void
128 Custos_engraver::finalize ()
129 {
130   for (vsize i = custodes_.size (); i--;)
131     custodes_[i]->suicide ();
132   custodes_.clear ();
133 }
134
135 ADD_ACKNOWLEDGER (Custos_engraver, bar);
136 ADD_ACKNOWLEDGER (Custos_engraver, note_head);
137
138 ADD_TRANSLATOR (Custos_engraver,
139                 /* doc */ "",
140                 /* create */ "Custos",
141                 /* accept */ "",
142                 /* read */ "",
143                 /* write */ "");