]> git.donarmstrong.com Git - lilypond.git/blob - lily/custos-engraver.cc
release: 1.3.110
[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 Juergen Reuter <reuterj@ira.uka.de>,
7
8   Han-Wen Nienhuys <hanwen@cs.uu.nl>
9   
10 */
11
12 #include "engraver.hh"
13 #include "bar.hh"
14 #include "item.hh"
15 #include "note-head.hh"
16 #include "staff-symbol-referencer.hh"
17 #include "warn.hh"
18 #include "musical-request.hh"
19
20 /*
21   This class implements an engraver for custos symbols.
22 */
23 class Custos_engraver : public Engraver
24 {
25 public:
26   Custos_engraver();
27   virtual void start_translation_timestep();
28   virtual void acknowledge_grob(Grob_info);
29   virtual void create_grobs ();
30   virtual void stop_translation_timestep ();
31   virtual void finalize ();
32   VIRTUAL_COPY_CONS(Translator);
33
34 private:
35   Item * create_custos();
36   bool custos_permitted;
37   Link_array<Grob> custos_arr_;
38   Array<Pitch> pitches_;
39 };
40
41 Custos_engraver::Custos_engraver ()
42 {
43   custos_permitted = false;
44 }
45
46
47 void
48 Custos_engraver::stop_translation_timestep()
49 {
50   /*
51     delay typeset until we're at the next moment, so we can silence custodes at the end of the piece.
52    */
53 }
54
55 void
56 Custos_engraver::start_translation_timestep ()
57 {
58   for (int i = custos_arr_.size (); i--;)
59     {
60       typeset_grob (custos_arr_[i]);
61     }
62   custos_arr_.clear ();
63   pitches_.clear ();
64
65   custos_permitted = false;
66 }
67
68
69 void
70 Custos_engraver::acknowledge_grob (Grob_info info)
71 {
72   Item *item = dynamic_cast <Item *>(info.elem_l_);
73   if (item)
74     {
75       if (Bar::has_interface (info.elem_l_))
76         custos_permitted = true;
77       else if (Note_head::has_interface (info.elem_l_))
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           Note_req * nr = dynamic_cast<Note_req*> (info.req_l_);
89           if (nr)
90             pitches_.push (*unsmob_pitch (nr->get_mus_property ("pitch")));
91         }
92     }
93 }
94
95 void
96 Custos_engraver::create_grobs ()
97 {
98   if (gh_string_p (get_property( "whichBar")))
99     custos_permitted = true;
100   
101   if (custos_permitted)
102     {
103       for (int i = pitches_.size (); i--;)
104         {
105           Item *c = create_custos ();
106           
107           c->set_grob_property ("staff-position",
108                                gh_int2scm (pitches_[i].steps ()));
109           
110         }
111
112       pitches_.clear ();
113     }
114 }
115
116 Item* 
117 Custos_engraver::create_custos()
118 {
119   SCM basicProperties = get_property ("Custos");
120   Item* custos = new Item (basicProperties);
121   
122   announce_grob (custos, 0);
123   custos_arr_.push (custos);
124   
125   return custos;
126 }
127
128 void
129 Custos_engraver::finalize ()
130 {
131   for (int i = custos_arr_.size (); i--;)
132     {
133       custos_arr_[i]->suicide ();
134       typeset_grob (custos_arr_[i]);
135     }
136   custos_arr_.clear ();
137 }
138
139 ADD_THIS_TRANSLATOR (Custos_engraver);
140