]> git.donarmstrong.com Git - lilypond.git/blob - lily/grace-position-engraver.cc
release: 1.3.69
[lilypond.git] / lily / grace-position-engraver.cc
1 /*   
2   grace-position-engraver.cc --  implement Grace_position_engraver
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 1999--2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #include "engraver.hh"
11 #include "grace-align-item.hh"
12 #include "rhythmic-head.hh"
13 #include "local-key-item.hh"
14 #include "paper-column.hh"
15 #include "note-head.hh"
16 #include "side-position-interface.hh"
17 #include "axis-group-interface.hh"
18
19
20 class Grace_position_engraver:public Engraver
21 {
22   Paper_column *last_musical_col_l_;
23 protected:
24   VIRTUAL_COPY_CONS(Translator);
25   virtual void acknowledge_element (Score_element_info);
26   virtual void process_acknowledged ();
27   virtual void do_post_move_processing ();
28   virtual void do_pre_move_processing ();
29   Item*align_l_;
30   Link_array<Item> support_;
31 public:
32   Grace_position_engraver();
33 };
34
35
36 Grace_position_engraver::Grace_position_engraver ()
37 {
38   align_l_ =0;
39   last_musical_col_l_ =0;
40 }
41
42 void
43 Grace_position_engraver::acknowledge_element (Score_element_info i)
44 {
45   Item *item = dynamic_cast<Item*> (i.elem_l_);
46   if (item && Grace_align_item::has_interface (i.elem_l_))
47     {
48       align_l_ = item;
49     }
50   else if (item && Note_head::has_interface (i.elem_l_))
51     {
52       if (!to_boolean (item->get_elt_property ("grace")))
53         support_.push (item);
54     }
55   else if (item && Local_key_item::has_interface (i.elem_l_))
56     {
57       if (!to_boolean (item->get_elt_property ("grace")))
58         support_.push (item);
59       else if (align_l_) 
60         item->add_dependency (align_l_);
61     }
62 }
63
64 void
65 Grace_position_engraver::process_acknowledged ()
66 {
67   if (align_l_)
68     {
69       for (int i=0; i < support_.size (); i++)
70         Side_position::add_support (align_l_,support_[i]);
71       support_.clear ();
72     }
73 }
74
75 void
76 Grace_position_engraver::do_pre_move_processing ()
77 {
78   if (align_l_ && !Side_position::supported_b (align_l_))
79     {
80   /*
81      We don't have support. Either some moron tried attaching us to a rest,
82      or we're at the end of the piece.  In the latter case, we have a
83      problem if there are spanners in the grace section,
84      they will want to  be broken into pieces (their line_l () field  is nil).
85
86      Solution: attach ourselves to  the last musical column known.  A little intricate.
87      
88   */
89
90       Score_element * elt = align_l_->parent_l (X_AXIS);
91       if (elt)
92         return;
93
94       warning (_("Unattached grace notes.  Attaching to last musical column."));
95       
96       align_l_->set_parent (0, X_AXIS);
97       Axis_group_interface::add_element (last_musical_col_l_, align_l_);
98     }
99
100   last_musical_col_l_ = dynamic_cast<Paper_column*>( unsmob_element (get_property ("currentMusicalColumn")));
101 }
102
103 void
104 Grace_position_engraver::do_post_move_processing ()
105 {
106   support_.clear ();
107   align_l_ =0;
108 }
109
110 ADD_THIS_TRANSLATOR(Grace_position_engraver);
111