]> git.donarmstrong.com Git - lilypond.git/blob - lily/horizontal-bracket-engraver.cc
2003 -> 2004
[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--2004 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 stop_translation_timestep ();
27   virtual  void process_music ();
28   virtual  void acknowledge_grob (Grob_info);
29 };
30
31 ENTER_DESCRIPTION(Horizontal_bracket_engraver,
32                   "Create horizontal brackets over notes for musical analysis purposes.",
33                   "HorizontalBracket",
34                   "note-grouping-event",
35                   "note-column-interface",
36                   "",
37                   "");
38
39 Horizontal_bracket_engraver::Horizontal_bracket_engraver()
40 {
41   pop_count_ = 0;
42   push_count_ = 0;
43 }
44
45
46 bool
47 Horizontal_bracket_engraver::try_music (Music *m)
48 {
49   if (m->is_mus_type ("note-grouping-event"))
50     {
51       Direction d = to_dir (m->get_mus_property ("span-direction"));
52       
53       if (d == STOP)
54         {
55           pop_count_ ++;
56           if (pop_count_ > bracket_stack_.size())
57             m->origin()->warning (_("Don't have that many brackets."));
58         }
59       else
60         {
61           push_count_++;
62           events_.push (m);
63         }
64       
65       if (pop_count_ && push_count_)
66         m->origin()->warning (_("Conflicting note group events."));
67
68       return true;
69     }
70   return false;
71 }
72
73 void
74 Horizontal_bracket_engraver::acknowledge_grob (Grob_info gi)
75 {
76   if (Note_column::has_interface (gi.grob_))
77     {
78       for (int i = 0;  i < bracket_stack_.size(); i++)
79         {
80           Side_position_interface::add_support (bracket_stack_[i], gi.grob_);
81           Pointer_group_interface::add_grob (bracket_stack_[i],
82                                              ly_symbol2scm ("columns"), gi.grob_);
83           add_bound_item (bracket_stack_[i],
84                                              gi.grob_);
85         }
86     }
87 }
88
89 void
90 Horizontal_bracket_engraver::process_music ()
91 {
92   for  (int k = 0; k < push_count_; k++)
93     {
94       Spanner * sp = make_spanner ("HorizontalBracket");
95
96       announce_grob (sp, events_[k]->self_scm());
97       for (int i = 0; i < bracket_stack_.size(); i++)
98         {
99           /*
100             sp is the smallest, it should be added to the bigger brackets.
101            */
102           Side_position_interface::add_support (bracket_stack_[i], sp);
103         }
104       bracket_stack_.push (sp);
105     }
106 }
107
108
109 void
110 Horizontal_bracket_engraver::stop_translation_timestep ()
111 {
112   for (int i = pop_count_; i--;)
113     {
114       if (bracket_stack_.size())
115         typeset_grob (bracket_stack_.pop());
116     }
117   pop_count_ = 0;
118   push_count_ = 0;
119 }
120
121