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