]> git.donarmstrong.com Git - lilypond.git/blob - lily/custos-engraver.cc
release: 1.3.101
[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 do_post_move_processing();
28   virtual void acknowledge_element(Score_element_info);
29   virtual void do_process_music ();
30   virtual void process_acknowledged ();
31   virtual void do_pre_move_processing ();
32   virtual void do_removal_processing ();
33   VIRTUAL_COPY_CONS(Translator);
34
35 private:
36   Item * create_custos();
37   bool custos_permitted;
38   Link_array<Score_element> custos_arr_;
39   Array<Musical_pitch> pitches_;
40 };
41
42 Custos_engraver::Custos_engraver ()
43 {
44   custos_permitted = false;
45 }
46
47
48 void
49 Custos_engraver::do_pre_move_processing()
50 {
51   /*
52     delay typeset until we're at the next moment, so we can silence custodes at the end of the piece.
53    */
54 }
55
56 void
57 Custos_engraver::do_post_move_processing ()
58 {
59   for (int i = custos_arr_.size (); i--;)
60     {
61       typeset_element (custos_arr_[i]);
62     }
63   custos_arr_.clear ();
64   pitches_.clear ();
65
66   custos_permitted = false;
67 }
68
69
70 /*
71   TODO check if this works with forced bar lines?
72  */
73 void
74 Custos_engraver::do_process_music ()
75 {
76   if (gh_string_p (get_property( "whichBar")))
77     custos_permitted = true;
78 }
79
80 void
81 Custos_engraver::acknowledge_element (Score_element_info info)
82 {
83   Item *item = dynamic_cast <Item *>(info.elem_l_);
84   if (item)
85     {
86       if (Bar::has_interface (info.elem_l_))
87         custos_permitted = true;
88       else if (Note_head::has_interface (info.elem_l_))
89         {
90
91           /*
92             ideally, we'd do custos->set_parent (Y_AXIS, notehead),
93             but since the note head lives on the other system, we can't
94
95             So we copy the position from the note head pitch.  We
96             don't look at the staff-position, since we can't be sure
97             whether Clef_engraver already applied a vertical shift.
98           */
99           
100           pitches_.push (dynamic_cast<Note_req*> (info.req_l_)->pitch_);
101         }
102     }
103 }
104
105 void
106 Custos_engraver::process_acknowledged ()
107 {
108   if (custos_permitted)
109     {
110       for (int i = pitches_.size (); i--;)
111         {
112           Item *c = create_custos ();
113           
114           c->set_elt_property ("staff-position",
115                                gh_int2scm (pitches_[i].steps ()));
116           
117         }
118
119       pitches_.clear ();
120     }
121 }
122
123 Item* 
124 Custos_engraver::create_custos()
125 {
126   SCM basicProperties = get_property ("Custos");
127   Item* custos = new Item (basicProperties);
128   
129   announce_element (custos, 0);
130   custos_arr_.push (custos);
131   
132   return custos;
133 }
134
135 void
136 Custos_engraver::do_removal_processing ()
137 {
138   for (int i = custos_arr_.size (); i--;)
139     {
140       custos_arr_[i]->suicide ();
141       typeset_element (custos_arr_[i]);
142     }
143   custos_arr_.clear ();
144 }
145
146 ADD_THIS_TRANSLATOR (Custos_engraver);
147