]> git.donarmstrong.com Git - lilypond.git/blob - lily/horizontal-bracket-engraver.cc
* stepmake/stepmake/generic-vars.make (LOOP): Add PLUS to keep -j
[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
16 #include "translator.icc"
17
18 class Horizontal_bracket_engraver : public Engraver
19 {
20 public:
21   TRANSLATOR_DECLARATIONS (Horizontal_bracket_engraver);
22   Link_array__Spanner_ bracket_stack_;
23   Link_array__Music_ events_;
24   vsize pop_count_;
25   vsize push_count_;
26
27   virtual bool try_music (Music *);
28   void stop_translation_timestep ();
29   void process_music ();
30   DECLARE_ACKNOWLEDGER (note_column);
31 };
32
33 ADD_ACKNOWLEDGER (Horizontal_bracket_engraver, note_column);
34 ADD_TRANSLATOR (Horizontal_bracket_engraver,
35                 "Create horizontal brackets over notes for musical analysis purposes.",
36                 "HorizontalBracket",
37                 "note-grouping-event",
38                 "",
39                 "");
40
41 Horizontal_bracket_engraver::Horizontal_bracket_engraver ()
42 {
43   pop_count_ = 0;
44   push_count_ = 0;
45 }
46
47 bool
48 Horizontal_bracket_engraver::try_music (Music *m)
49 {
50   if (m->is_mus_type ("note-grouping-event"))
51     {
52       Direction d = to_dir (m->get_property ("span-direction"));
53
54       if (d == STOP)
55         {
56           pop_count_++;
57           if (pop_count_ > bracket_stack_.size ())
58             m->origin ()->warning (_ ("don't have that many brackets"));
59         }
60       else
61         {
62           push_count_++;
63           events_.push_back (m);
64         }
65
66       if (pop_count_ && push_count_)
67         m->origin ()->warning (_ ("conflicting note group events"));
68
69       return true;
70     }
71   return false;
72 }
73
74 void
75 Horizontal_bracket_engraver::acknowledge_note_column (Grob_info gi)
76 {
77   for (vsize i = 0; i < bracket_stack_.size (); i++)
78     {
79       Side_position_interface::add_support (bracket_stack_[i], gi.grob ());
80       Pointer_group_interface::add_grob (bracket_stack_[i],
81                                          ly_symbol2scm ("columns"), gi.grob ());
82       add_bound_item (bracket_stack_[i],
83                       gi.grob ());
84     }
85 }
86
87 void
88 Horizontal_bracket_engraver::process_music ()
89 {
90   for (vsize k = 0; k < push_count_; k++)
91     {
92       Spanner *sp = make_spanner ("HorizontalBracket", events_[k]->self_scm ());
93
94       for (vsize i = 0; i < bracket_stack_.size (); i++)
95         /* sp is the smallest, it should be added to the bigger brackets.  */
96         Side_position_interface::add_support (bracket_stack_[i], sp);
97       bracket_stack_.push_back (sp);
98     }
99 }
100
101 void
102 Horizontal_bracket_engraver::stop_translation_timestep ()
103 {
104   for (int i = pop_count_; i--;)
105     if (bracket_stack_.size ())
106       bracket_stack_.pop_back ();
107   pop_count_ = 0;
108   push_count_ = 0;
109 }
110