]> git.donarmstrong.com Git - lilypond.git/blob - lily/horizontal-bracket-engraver.cc
Merge branch 'master' of git://git.sv.gnu.org/lilypond
[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--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
8 */
9
10 #include "engraver.hh"
11 #include "international.hh"
12 #include "note-column.hh"
13 #include "pointer-group-interface.hh"
14 #include "side-position-interface.hh"
15 #include "stream-event.hh"
16 #include "spanner.hh"
17 #include "item.hh"
18
19 #include "translator.icc"
20
21 class Horizontal_bracket_engraver : public Engraver
22 {
23 public:
24   TRANSLATOR_DECLARATIONS (Horizontal_bracket_engraver);
25   vector<Spanner*> bracket_stack_;
26   vector<Stream_event*> events_;
27   vsize pop_count_;
28   vsize push_count_;
29
30   void stop_translation_timestep ();
31   void process_music ();
32   DECLARE_ACKNOWLEDGER (note_column);
33   DECLARE_TRANSLATOR_LISTENER (note_grouping);
34 };
35
36 ADD_ACKNOWLEDGER (Horizontal_bracket_engraver, note_column);
37 ADD_TRANSLATOR (Horizontal_bracket_engraver,
38                 "Create horizontal brackets over notes for musical analysis purposes.",
39                 "HorizontalBracket",
40                 "",
41                 "");
42
43 Horizontal_bracket_engraver::Horizontal_bracket_engraver ()
44 {
45   pop_count_ = 0;
46   push_count_ = 0;
47 }
48
49 IMPLEMENT_TRANSLATOR_LISTENER (Horizontal_bracket_engraver, note_grouping);
50 void
51 Horizontal_bracket_engraver::listen_note_grouping (Stream_event *ev)
52 {
53   Direction d = to_dir (ev->get_property ("span-direction"));
54
55   if (d == STOP)
56     {
57       pop_count_++;
58       if (pop_count_ > bracket_stack_.size ())
59         ev->origin ()->warning (_ ("do not have that many brackets"));
60     }
61   else
62     {
63       push_count_++;
64       events_.push_back (ev);
65     }
66
67   if (pop_count_ && push_count_)
68     ev->origin ()->warning (_ ("conflicting note group events"));
69 }
70
71 void
72 Horizontal_bracket_engraver::acknowledge_note_column (Grob_info gi)
73 {
74   for (vsize i = 0; i < bracket_stack_.size (); i++)
75     {
76       Side_position_interface::add_support (bracket_stack_[i], gi.grob ());
77       Pointer_group_interface::add_grob (bracket_stack_[i],
78                                          ly_symbol2scm ("columns"), gi.grob ());
79       add_bound_item (bracket_stack_[i],
80                       gi.grob ());
81     }
82 }
83
84 void
85 Horizontal_bracket_engraver::process_music ()
86 {
87   for (vsize k = 0; k < push_count_; k++)
88     {
89       Spanner *sp = make_spanner ("HorizontalBracket", events_[k]->self_scm ());
90
91       for (vsize i = 0; i < bracket_stack_.size (); i++)
92         /* sp is the smallest, it should be added to the bigger brackets.  */
93         Side_position_interface::add_support (bracket_stack_[i], sp);
94       bracket_stack_.push_back (sp);
95     }
96 }
97
98 void
99 Horizontal_bracket_engraver::stop_translation_timestep ()
100 {
101   for (int i = pop_count_; i--;)
102     if (bracket_stack_.size ())
103       bracket_stack_.pop_back ();
104   pop_count_ = 0;
105   push_count_ = 0;
106 }
107