1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3 
4   Copyright (C) 1999--2021 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 "script-column.hh"
22 #include "side-position-interface.hh"
23 #include "item.hh"
24 
25 #include "translator.icc"
26 
27 using std::vector;
28 
29 /**
30    Find potentially colliding scripts, and put them in a
31    Script_column, that will fix the collisions.  */
32 class Script_column_engraver : public Engraver
33 {
34   Grob *script_column_;
35   vector<Grob *> scripts_;
36 
37 public:
38   TRANSLATOR_DECLARATIONS (Script_column_engraver);
39 protected:
40   void acknowledge_side_position (Grob_info);
41   void process_acknowledged ();
42   void stop_translation_timestep ();
43 };
44 
Script_column_engraver(Context * c)45 Script_column_engraver::Script_column_engraver (Context *c)
46   : Engraver (c)
47 {
48   script_column_ = 0;
49 }
50 
51 void
stop_translation_timestep()52 Script_column_engraver::stop_translation_timestep ()
53 {
54   if (script_column_)
55     {
56       for (vsize i = 0; i < scripts_.size (); i++)
57         if (Side_position_interface::is_on_y_axis (scripts_[i]))
58           Script_column::add_side_positioned (script_column_, scripts_[i]);
59     }
60 
61   script_column_ = 0;
62   scripts_.clear ();
63 }
64 
65 void
acknowledge_side_position(Grob_info inf)66 Script_column_engraver::acknowledge_side_position (Grob_info inf)
67 {
68   Item *thing = dynamic_cast<Item *> (inf.grob ());
69   if (thing)
70     {
71       if (!Item::is_non_musical (thing))
72         scripts_.push_back (thing);
73     }
74 }
75 
76 void
process_acknowledged()77 Script_column_engraver::process_acknowledged ()
78 {
79   if (!script_column_ && scripts_.size () > 1)
80     script_column_ = make_item ("ScriptColumn", SCM_EOL);
81 }
82 
83 void
boot()84 Script_column_engraver::boot ()
85 {
86   ADD_ACKNOWLEDGER (Script_column_engraver, side_position);
87 }
88 
89 ADD_TRANSLATOR (Script_column_engraver,
90                 /* doc */
91                 "Find potentially colliding scripts and put them into a"
92                 " @code{ScriptColumn} object; that will fix the collisions.",
93 
94                 /* create */
95                 "ScriptColumn ",
96 
97                 /* read */
98                 "",
99 
100                 /* write */
101                 ""
102                );
103