]> git.donarmstrong.com Git - lilypond.git/blob - lily/horizontal-bracket-engraver.cc
Web-ja: update introduction
[lilypond.git] / lily / horizontal-bracket-engraver.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 2002--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
5
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "engraver.hh"
21 #include "international.hh"
22 #include "item.hh"
23 #include "note-column.hh"
24 #include "pointer-group-interface.hh"
25 #include "side-position-interface.hh"
26 #include "spanner.hh"
27 #include "stream-event.hh"
28
29 #include "translator.icc"
30
31 class Horizontal_bracket_engraver : public Engraver
32 {
33 public:
34   TRANSLATOR_DECLARATIONS (Horizontal_bracket_engraver);
35   vector<Spanner *> bracket_stack_;
36   vector<Spanner *> text_stack_;
37   vector<Stream_event *> events_;
38   vsize pop_count_;
39   vsize push_count_;
40
41   void stop_translation_timestep ();
42   void process_music ();
43   void acknowledge_note_column (Grob_info);
44   void listen_note_grouping (Stream_event *);
45 };
46
47 Horizontal_bracket_engraver::Horizontal_bracket_engraver (Context *c)
48   : Engraver (c)
49 {
50   pop_count_ = 0;
51   push_count_ = 0;
52 }
53
54 void
55 Horizontal_bracket_engraver::listen_note_grouping (Stream_event *ev)
56 {
57   Direction d = to_dir (ev->get_property ("span-direction"));
58
59   if (d == STOP)
60     {
61       pop_count_++;
62       if (pop_count_ > bracket_stack_.size ())
63         ev->origin ()->warning (_ ("do not have that many brackets"));
64     }
65   else
66     {
67       push_count_++;
68       events_.push_back (ev);
69     }
70
71   if (pop_count_ && push_count_)
72     ev->origin ()->warning (_ ("conflicting note group events"));
73 }
74
75 void
76 Horizontal_bracket_engraver::acknowledge_note_column (Grob_info gi)
77 {
78   for (vsize 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       add_bound_item (text_stack_[i],
86                       gi.grob ());
87     }
88 }
89
90 void
91 Horizontal_bracket_engraver::process_music ()
92 {
93   for (vsize k = 0; k < push_count_; k++)
94     {
95       Spanner *sp = make_spanner ("HorizontalBracket", events_[k]->self_scm ());
96
97       Spanner *hbt = make_spanner ("HorizontalBracketText", sp->self_scm ());
98
99       sp->set_object ("bracket-text", hbt->self_scm ());
100
101       Side_position_interface::add_support (hbt, sp);
102
103       hbt->set_parent (sp, X_AXIS);
104       hbt->set_parent (sp, Y_AXIS);
105       hbt->set_object ("bracket", sp->self_scm ());
106
107       for (vsize i = 0; i < bracket_stack_.size (); i++)
108         /* sp is the smallest, it should be added to the bigger brackets.  */
109         {
110           Side_position_interface::add_support (bracket_stack_[i], sp);
111           Side_position_interface::add_support (bracket_stack_[i], hbt);
112         }
113
114       bracket_stack_.push_back (sp);
115       text_stack_.push_back (hbt);
116     }
117 }
118
119 void
120 Horizontal_bracket_engraver::stop_translation_timestep ()
121 {
122   for (vsize i = pop_count_; i--;)
123     {
124       if (bracket_stack_.size ())
125         bracket_stack_.pop_back ();
126       if (text_stack_.size ())
127         text_stack_.pop_back ();
128     }
129   pop_count_ = 0;
130   push_count_ = 0;
131   events_.clear ();
132 }
133
134 void
135 Horizontal_bracket_engraver::boot ()
136 {
137   ADD_LISTENER (Horizontal_bracket_engraver, note_grouping);
138   ADD_ACKNOWLEDGER (Horizontal_bracket_engraver, note_column);
139 }
140
141 ADD_TRANSLATOR (Horizontal_bracket_engraver,
142                 /* doc */
143                 "Create horizontal brackets over notes for musical analysis"
144                 " purposes.",
145
146                 /* create */
147                 "HorizontalBracket "
148                 "HorizontalBracketText ",
149
150                 /* read */
151                 "",
152
153                 /* write */
154                 ""
155                );