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