]> git.donarmstrong.com Git - lilypond.git/blob - lily/separating-line-group-engraver.cc
Another attempt at removing separating-group-spanner.
[lilypond.git] / lily / separating-line-group-engraver.cc
1 /*
2   separating-line-group-engraver.cc -- implement Separating_line_group_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 1998--2007 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
8
9 #include "engraver.hh"
10
11 #include "separation-item.hh"
12 #include "paper-column.hh"
13 #include "output-def.hh"
14 #include "axis-group-interface.hh"
15 #include "note-spacing.hh"
16 #include "accidental-placement.hh"
17 #include "context.hh"
18 #include "spanner.hh"
19 #include "grob-array.hh"
20 #include "pointer-group-interface.hh"
21
22 #include "translator.icc"
23
24 struct Spacings
25 {
26   Item *staff_spacing_;
27   vector<Item*> note_spacings_;
28
29   Spacings ()
30   {
31     staff_spacing_ = 0;
32   }
33
34   bool is_empty () const
35   {
36     return !staff_spacing_ && !note_spacings_.size ();
37   }
38   void clear ()
39   {
40     staff_spacing_ = 0;
41     note_spacings_.clear ();
42   }
43 };
44
45 class Separating_line_group_engraver : public Engraver
46 {
47 protected:
48   Item *break_item_;
49   Item *musical_item_;
50   Item *last_musical_item_;
51
52   Spacings current_spacings_;
53   Spacings last_spacings_;
54
55   DECLARE_ACKNOWLEDGER (item);
56   void stop_translation_timestep ();
57   void start_translation_timestep ();
58 public:
59   TRANSLATOR_DECLARATIONS (Separating_line_group_engraver);
60 };
61
62 Separating_line_group_engraver::Separating_line_group_engraver ()
63 {
64   break_item_ = 0;
65   musical_item_ = 0;
66 }
67
68 void
69 Separating_line_group_engraver::acknowledge_item (Grob_info i)
70 {
71   Item *it = i.item ();
72   if (it->get_parent (X_AXIS)
73       && it->get_parent (X_AXIS) == it->get_parent (Y_AXIS)
74       && Axis_group_interface::has_axis (it->get_parent (X_AXIS), X_AXIS)
75       && Axis_group_interface::has_axis (it->get_parent (Y_AXIS), Y_AXIS))
76     return;
77
78   if (to_boolean (it->get_property ("no-spacing-rods")))
79     return;
80
81   if (Note_spacing::has_interface (it))
82     {
83       current_spacings_.note_spacings_.push_back (it);
84       return;
85     }
86
87   bool ib = Item::is_non_musical (it);
88   Item *&p_ref_ (ib ? break_item_
89                  : musical_item_);
90
91   if (!p_ref_)
92     {
93       p_ref_ = make_item ("SeparationItem", SCM_EOL);
94
95       if (ib)
96         {
97           p_ref_->set_property ("non-musical", SCM_BOOL_T);
98           context ()->set_property ("breakableSeparationItem", p_ref_->self_scm ());
99         }
100
101       if (to_boolean (get_property ("createSpacing"))
102           && p_ref_ == break_item_)
103         {
104           Item *it = make_item ("StaffSpacing", SCM_EOL);
105           current_spacings_.staff_spacing_ = it;
106           Pointer_group_interface::add_grob (it, ly_symbol2scm ("left-items"),
107                                              break_item_);
108
109           if (!last_spacings_.note_spacings_.size ()
110               && last_spacings_.staff_spacing_)
111             {
112               SCM ri = last_spacings_.staff_spacing_->get_object ("right-items");
113               Grob_array *ga = unsmob_grob_array (ri);
114               if (!ga)
115                 {
116                   SCM ga_scm = Grob_array::make_array ();
117                   last_spacings_.staff_spacing_->set_object ("right-items", ga_scm);
118                   ga = unsmob_grob_array (ga_scm);
119                 }
120
121               ga->clear ();
122               ga->add (break_item_);
123             }
124         }
125     }
126
127   if (Accidental_placement::has_interface (it))
128     Separation_item::add_conditional_item (p_ref_, it);
129   else
130     Separation_item::add_item (p_ref_, it);
131 }
132
133 void
134 Separating_line_group_engraver::start_translation_timestep ()
135 {
136   if (break_item_)
137     {
138       context ()->unset_property (ly_symbol2scm ("breakableSeparationItem"));
139       break_item_ = 0;
140     }
141 }
142
143 void
144 Separating_line_group_engraver::stop_translation_timestep ()
145 {
146   if (Item *sp = current_spacings_.staff_spacing_)
147     {
148       /*
149         TODO: should really look at the left-items of following
150         note-spacing grobs.
151       */
152       if (musical_item_)
153         Pointer_group_interface::add_grob (sp, ly_symbol2scm ("right-items"),
154                                            musical_item_);
155     }
156
157   if (!current_spacings_.is_empty ())
158     last_spacings_ = current_spacings_;
159
160   current_spacings_.clear ();
161
162   musical_item_ = 0;
163 }
164
165 ADD_ACKNOWLEDGER (Separating_line_group_engraver, item);
166 ADD_TRANSLATOR (Separating_line_group_engraver,
167                 /* doc */ "Generates objects for computing spacing parameters.",
168
169                 /* create */
170                 "SeparationItem "
171                 "SeparatingGroupSpanner "
172                 "StaffSpacing",
173                 /* read */ "createSpacing",
174                 /* write */ "breakableSeparationItem");