]> git.donarmstrong.com Git - lilypond.git/blob - lily/custos-engraver.cc
* configure.in: Test for and accept lmodern if EC fonts not found.
[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--2004 Juergen Reuter <reuter@ipd.uka.de>,
7                   Han-Wen Nienhuys <hanwen@cs.uu.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
17 /*
18  * This class implements an engraver for custos symbols.
19  *
20  * FIXME: note heads inside of ligatures (i.e. ligature heads) are
21  * sometimes not recognized by this engraver. --jr
22  */
23 class Custos_engraver : public Engraver
24 {
25 public:
26   TRANSLATOR_DECLARATIONS (Custos_engraver);
27   virtual void start_translation_timestep ();
28   virtual void acknowledge_grob (Grob_info);
29   virtual void process_acknowledged_grobs ();
30   virtual void stop_translation_timestep ();
31   virtual void finalize ();
32
33
34 private:
35   Item * create_custos ();
36   bool custos_permitted;
37   Link_array<Grob> custodes_;
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   pitches_.clear ();
54
55   custos_permitted = false;
56 }
57
58 void
59 Custos_engraver::start_translation_timestep ()
60 {
61   custodes_.clear ();
62 }
63
64
65 void
66 Custos_engraver::acknowledge_grob (Grob_info info)
67 {
68   Item *item = dynamic_cast <Item *> (info.grob_);
69   if (item)
70     {
71       Music * m = info.music_cause ();
72       if (Bar_line::has_interface (info.grob_))
73         custos_permitted = true;
74       else if (Note_head::has_interface (info.grob_)
75                && m
76                && m->is_mus_type ("note-event"))
77         {
78
79           /*
80             ideally, we'd do custos->set_parent (Y_AXIS, notehead),
81             but since the note head lives on the other system, we can't
82
83             So we copy the position from the note head pitch.  We
84             don't look at the staff-position, since we can't be sure
85             whether Clef_engraver already applied a vertical shift.
86           */
87             pitches_.push (*unsmob_pitch (m->get_property ("pitch")));
88         }
89     }
90 }
91
92 void
93 Custos_engraver::process_acknowledged_grobs ()
94 {
95   if (scm_is_string (get_property ("whichBar")))
96     custos_permitted = true;
97   
98   if (custos_permitted)
99     {
100       for (int 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           
110           c->set_property ("staff-position",
111                                 scm_int2num (p));
112           
113         }
114
115       pitches_.clear ();
116     }
117 }
118
119 Item* 
120 Custos_engraver::create_custos ()
121 {
122   Item* custos = make_item ("Custos", SCM_EOL);
123   
124   
125   custodes_.push (custos);
126   
127   return custos;
128 }
129
130 void
131 Custos_engraver::finalize ()
132 {
133   for (int i = custodes_.size (); i--;)
134     {
135       custodes_[i]->suicide ();
136     }
137   custodes_.clear ();
138 }
139
140
141
142 ENTER_DESCRIPTION (Custos_engraver,
143 /* descr */       "",
144 /* creats*/       "Custos",
145 /* accepts */     "",
146 /* acks  */      "bar-line-interface note-head-interface",
147 /* reads */       "",
148 /* write */       "");