]> git.donarmstrong.com Git - lilypond.git/blob - lily/a2-engraver.cc
release: 1.3.118
[lilypond.git] / lily / a2-engraver.cc
1 /*
2   a2-engraver.cc -- implement A2_engraver
3
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 2000 Jan Nieuwenhuizen <janneke@gnu.org>
7 */
8
9 #include "engraver.hh"
10 #include "item.hh"
11 #include "note-head.hh"
12 #include "stem.hh"
13 #include "slur.hh"
14 #include "translator-group.hh"
15 #include "side-position-interface.hh"
16 #include "directional-element-interface.hh"
17
18 class A2_engraver : public Engraver
19 {
20 public:
21   A2_engraver ();
22   VIRTUAL_COPY_CONS (Translator);
23 protected:
24   virtual void acknowledge_grob (Grob_info);
25   virtual void create_grobs ();
26   virtual void stop_translation_timestep ();
27 private:
28   Item* text_p_;
29   enum State { SOLO, SPLIT_INTERVAL, UNIRHYTHM, UNISILENCE, UNISON } state_;
30 };
31
32 ADD_THIS_TRANSLATOR (A2_engraver);
33
34 A2_engraver::A2_engraver ()
35 {
36   text_p_ = 0;
37   state_ = UNISILENCE;
38 }
39
40 void
41 A2_engraver::create_grobs ()
42 {
43   if (!to_boolean (get_property ("combineParts")))
44     return ;
45   if (!text_p_)
46     {
47       SCM unison = get_property ("unison");
48       SCM solo = get_property ("solo");
49       SCM solo_adue = get_property ("soloADue");
50
51       if (solo_adue == SCM_BOOL_T
52           && ((solo == SCM_BOOL_T && state_ != SOLO)
53               || (unison == SCM_BOOL_T && state_ != UNISON
54                   && daddy_trans_l_->id_str_ == "one")))
55         {
56           text_p_ = new Item (get_property ("TextScript"));
57           Side_position::set_axis (text_p_, Y_AXIS);
58           announce_grob (text_p_, 0);
59       
60           Direction dir = UP;
61           SCM text;
62           if (solo == SCM_BOOL_T)
63             {
64               state_ = SOLO;
65               if (daddy_trans_l_->id_str_ == "one")
66                 {
67                   text = get_property ("soloText");
68                 }
69               else
70                 {
71                   text = get_property ("soloIIText");
72                   dir = DOWN;
73                 }
74             }
75           else if (unison == SCM_BOOL_T)
76             {
77               state_ = UNISON;
78               if (daddy_trans_l_->id_str_ == "one")
79                 text = get_property ("aDueText");
80             }
81           
82           Side_position::set_direction (text_p_, dir);
83           text_p_->set_grob_property ("text", text);
84         }
85     }
86 }
87
88 void
89 A2_engraver::acknowledge_grob (Grob_info i)
90 {
91   if (!to_boolean (get_property ("combineParts")))
92     return ;
93   
94   if (text_p_)
95     {
96       if (Note_head::has_interface (i.elem_l_))
97         {
98           Grob*t = text_p_;
99           Side_position::add_support (t, i.elem_l_);
100           if (Side_position::get_axis (t) == X_AXIS
101               && !t->parent_l (Y_AXIS))
102             t->set_parent (i.elem_l_, Y_AXIS);
103         }
104       if (Stem::has_interface (i.elem_l_))
105         {
106           Side_position::add_support (text_p_, i.elem_l_);
107         }
108     }
109           
110   SCM unisilence = get_property ("unisilence");
111   SCM unison = get_property ("unison");
112   SCM unirhythm = get_property ("unirhythm");
113   SCM solo = get_property ("solo");
114   SCM split_interval = get_property ("split-interval");
115   SCM solo_adue = get_property ("soloADue");
116   
117   State previous_state = state_;
118   if (unisilence == SCM_BOOL_T)
119     /*
120       state_ = UNISILENCE;
121     */
122     ;
123   else if (solo == SCM_BOOL_T)
124     state_ = SOLO;
125   else if (unison == SCM_BOOL_T)
126     state_ = UNISON;
127   else if (unirhythm == SCM_BOOL_T && split_interval == SCM_BOOL_T)
128     state_ = SPLIT_INTERVAL;
129   else if (unirhythm)
130     state_ = UNIRHYTHM;
131           
132   if (Stem::has_interface (i.elem_l_)
133       || Slur::has_interface (i.elem_l_)
134       // || Text_item::has_interface (i.elem_l_)
135       //|| Hairpin::has_interface (i.elem_l_)
136       )
137     {
138       /*
139         Hmm.  We must set dir when solo, in order to get
140         the rests collided to the right position
141       */
142       if ((unirhythm != SCM_BOOL_T) || (solo == SCM_BOOL_T)
143           || ((unisilence == SCM_BOOL_T && previous_state != UNISON))
144           || (unirhythm == SCM_BOOL_T && split_interval == SCM_BOOL_T
145               && (unison != SCM_BOOL_T || solo_adue != SCM_BOOL_T)))
146         {
147           if (daddy_trans_l_->id_str_ == "one")
148             {
149               i.elem_l_->set_grob_property ("direction", gh_int2scm (1));
150             }
151           else if (daddy_trans_l_->id_str_ == "two")
152             {
153               i.elem_l_->set_grob_property ("direction", gh_int2scm (-1));
154             }
155         }
156     }
157 }
158
159 void 
160 A2_engraver::stop_translation_timestep ()
161 {
162   if (text_p_)
163     {
164       Side_position::add_staff_support (text_p_);
165       typeset_grob (text_p_);
166       text_p_ = 0;
167     }
168 }
169