]> git.donarmstrong.com Git - lilypond.git/blob - lily/custos-engraver.cc
release: 1.3.108
[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<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           Note_req * nr = dynamic_cast<Note_req*> (info.req_l_);
100           if (nr)
101             pitches_.push (*unsmob_pitch (nr->get_mus_property ("pitch")));
102         }
103     }
104 }
105
106 void
107 Custos_engraver::process_acknowledged ()
108 {
109   if (custos_permitted)
110     {
111       for (int i = pitches_.size (); i--;)
112         {
113           Item *c = create_custos ();
114           
115           c->set_elt_property ("staff-position",
116                                gh_int2scm (pitches_[i].steps ()));
117           
118         }
119
120       pitches_.clear ();
121     }
122 }
123
124 Item* 
125 Custos_engraver::create_custos()
126 {
127   SCM basicProperties = get_property ("Custos");
128   Item* custos = new Item (basicProperties);
129   
130   announce_element (custos, 0);
131   custos_arr_.push (custos);
132   
133   return custos;
134 }
135
136 void
137 Custos_engraver::do_removal_processing ()
138 {
139   for (int i = custos_arr_.size (); i--;)
140     {
141       custos_arr_[i]->suicide ();
142       typeset_element (custos_arr_[i]);
143     }
144   custos_arr_.clear ();
145 }
146
147 ADD_THIS_TRANSLATOR (Custos_engraver);
148