lilypond-1.4.2
[lilypond.git] / lily / break-align-engraver.cc
bloba403c4a60ecd03fa8c5a1e7140795c8e87b77f23
1 /*
2 break-align-engraver.cc -- implement Break_align_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 1999--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 */
9 #include "engraver.hh"
10 #include "protected-scm.hh"
11 #include "break-align-item.hh"
12 #include "item.hh"
13 #include "align-interface.hh"
14 #include "axis-group-interface.hh"
17 class Break_align_engraver : public Engraver
19 Item *align_l_;
20 Protected_scm column_alist_;
21 protected:
22 virtual void finalize ();
23 virtual void acknowledge_grob (Grob_info i);
24 virtual void stop_translation_timestep ();
25 void add_column (SCM);
27 public:
28 VIRTUAL_COPY_CONS (Translator);
29 Break_align_engraver ();
34 ADD_THIS_TRANSLATOR (Break_align_engraver);
36 void
37 Break_align_engraver::add_column (SCM smob)
39 Grob * e = unsmob_grob (smob);
40 Break_align_interface::add_element (align_l_,e);
41 typeset_grob (e);
44 void
45 Break_align_engraver::finalize ()
47 column_alist_ = SCM_EOL;
50 void
51 Break_align_engraver::stop_translation_timestep ()
53 SCM order = get_property ("breakAlignOrder");
54 for (; gh_pair_p (order); order = gh_cdr (order))
56 SCM p = scm_assoc (gh_car (order), column_alist_);
57 if (gh_pair_p (p))
59 add_column (gh_cdr (p));
60 column_alist_ = scm_assoc_remove_x (column_alist_, gh_car (order));
64 for (SCM p = column_alist_; gh_pair_p (p); p = gh_cdr (p))
66 SCM pair = gh_car (p);
67 add_column (gh_cdr (pair));
71 column_alist_ = SCM_EOL;
73 if (align_l_)
75 typeset_grob (align_l_);
76 align_l_ = 0;
81 Break_align_engraver::Break_align_engraver ()
83 column_alist_ = SCM_EOL;
84 align_l_ =0;
87 void
88 Break_align_engraver::acknowledge_grob (Grob_info inf)
90 if (Item * item_l = dynamic_cast <Item *> (inf.elem_l_))
92 if (item_l->empty_b (X_AXIS) || item_l->parent_l (X_AXIS))
93 return;
95 SCM bp=item_l->get_grob_property ("breakable");
96 bool breakable = (to_boolean (bp));
97 if (!breakable)
98 return ;
100 SCM align_name = item_l->get_grob_property ("break-align-symbol");
101 if (!gh_symbol_p (align_name))
102 return ;
104 if (!align_l_)
106 align_l_ = new Item (get_property ("BreakAlignment"));
107 Break_align_interface::set_interface (align_l_);
108 announce_grob (align_l_,0);
110 SCM edge_sym = ly_symbol2scm ("Left_edge_item");
111 Item * edge = new Item (get_property ("LeftEdge"));
116 If the element is empty, it will be ignored in the break
117 alignment stuff.
119 TODO: switch off ignoring empty stuff?
121 edge->set_extent_callback (Grob::point_dimension_callback_proc, X_AXIS);
124 We must have left-edge in the middle. Instrument-names
125 are left to left-edge, so they don't enter the staff.
127 align_l_->set_grob_property ("self-alignment-X", edge->self_scm ());
129 announce_grob (edge, 0);
130 column_alist_ = scm_assoc_set_x (column_alist_, edge_sym, edge->self_scm ());
133 SCM s = scm_assoc (align_name, column_alist_);
135 Item * group = 0;
137 if (s != SCM_BOOL_F)
139 Grob *e = unsmob_grob (gh_cdr (s));
140 group = dynamic_cast<Item*> (e);
142 else
144 group = new Item (get_property ("BreakAlignGroup"));
146 Axis_group_interface::set_interface (group);
147 Axis_group_interface::set_axes (group, X_AXIS,X_AXIS);
149 group->set_grob_property ("break-align-symbol", align_name);
150 group->set_parent (align_l_, Y_AXIS);
151 announce_grob (group, 0);
152 column_alist_ = scm_assoc_set_x (column_alist_, align_name, group->self_scm ());
155 Axis_group_interface::add_element (group, item_l);