]> git.donarmstrong.com Git - lilypond.git/blob - lily/horizontal-bracket-engraver.cc
*** empty log message ***
[lilypond.git] / lily / horizontal-bracket-engraver.cc
1 /*   
2   horizontal-bracket-engraver.cc -- implement
3     Horizontal_bracket_engraver
4
5 source file of the GNU LilyPond music typesetter
6
7 (c) 2002--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8
9  */
10
11 #include "engraver.hh"
12 #include "side-position-interface.hh"
13 #include "note-column.hh"
14 #include "group-interface.hh"
15
16 class Horizontal_bracket_engraver : public Engraver
17 {
18 public:
19   TRANSLATOR_DECLARATIONS(Horizontal_bracket_engraver);
20   Link_array<Spanner> bracket_stack_;
21   Link_array<Music> events_;
22   int pop_count_;
23   int push_count_;
24
25   virtual  bool try_music(Music*);
26   virtual void start_translation_timestep ();
27   virtual void stop_translation_timestep ();
28   virtual  void process_music ();
29   virtual  void acknowledge_grob (Grob_info);
30 };
31
32 ENTER_DESCRIPTION(Horizontal_bracket_engraver,
33                   "Create horizontal brackets over notes for musical analysis purposes.",
34                   "HorizontalBracket",
35                   "note-grouping-event",
36                   "note-column-interface",
37                   "",
38                   "");
39
40 Horizontal_bracket_engraver::Horizontal_bracket_engraver()
41 {
42   pop_count_ = 0;
43   push_count_ = 0;
44 }
45
46 void
47 Horizontal_bracket_engraver::start_translation_timestep()
48 {
49   pop_count_ = 0;
50   push_count_ = 0;
51 }
52
53 bool
54 Horizontal_bracket_engraver::try_music (Music *m)
55 {
56   if (m->is_mus_type ("note-grouping-event"))
57     {
58       Direction d = to_dir (m->get_mus_property ("span-direction"));
59       
60       if (d == STOP)
61         {
62           pop_count_ ++;
63           if (pop_count_ > bracket_stack_.size())
64             m->origin()->warning (_("Don't have that many brackets."));
65         }
66       else
67         {
68           push_count_++;
69           events_.push (m);
70         }
71       
72       if (pop_count_ && push_count_)
73         m->origin()->warning (_("Conflicting note group events."));
74
75       return true;
76     }
77   return false;
78 }
79
80 void
81 Horizontal_bracket_engraver::acknowledge_grob (Grob_info gi)
82 {
83   if (Note_column::has_interface (gi.grob_))
84     {
85       for (int i = 0;  i < bracket_stack_.size(); i++)
86         {
87           Side_position_interface::add_support (bracket_stack_[i], gi.grob_);
88           Pointer_group_interface::add_grob (bracket_stack_[i],
89                                              ly_symbol2scm ("columns"), gi.grob_);
90           add_bound_item (bracket_stack_[i],
91                                              gi.grob_);
92         }
93     }
94 }
95
96 void
97 Horizontal_bracket_engraver::process_music ()
98 {
99   for  (int k = 0; k < push_count_; k++)
100     {
101       Spanner * sp = new Spanner (get_property ("HorizontalBracket"));
102
103       announce_grob (sp, events_[k]->self_scm());
104       for (int i = 0; i < bracket_stack_.size(); i++)
105         {
106           /*
107             sp is the smallest, it should be added to the bigger brackets.
108            */
109           Side_position_interface::add_support (bracket_stack_[i], sp);
110         }
111       bracket_stack_.push (sp);
112     }
113 }
114
115
116 void
117 Horizontal_bracket_engraver::stop_translation_timestep ()
118 {
119   for (int i = pop_count_; i--;)
120     {
121       if (bracket_stack_.size())
122         typeset_grob (bracket_stack_.pop());
123     }
124 }
125
126