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>
10 #include "protected-scm.hh"
11 #include "break-align-item.hh"
13 #include "align-interface.hh"
14 #include "axis-group-interface.hh"
17 class Break_align_engraver : public Engraver
20 Protected_scm column_alist_;
22 virtual void finalize ();
23 virtual void acknowledge_grob (Grob_info i);
24 virtual void stop_translation_timestep ();
25 void add_column (SCM);
28 TRANSLATOR_DECLARATIONS(Break_align_engraver);
32 Break_align_engraver::add_column (SCM smob)
34 Grob * e = unsmob_grob (smob);
35 Break_align_interface::add_element (align_l_,e);
40 Break_align_engraver::finalize ()
42 column_alist_ = SCM_EOL;
46 Break_align_engraver::stop_translation_timestep ()
48 SCM order = get_property ("breakAlignOrder");
49 for (; gh_pair_p (order); order = ly_cdr (order))
51 SCM p = scm_assoc (ly_car (order), column_alist_);
54 add_column (ly_cdr (p));
55 column_alist_ = scm_assoc_remove_x (column_alist_, ly_car (order));
59 for (SCM p = column_alist_; gh_pair_p (p); p = ly_cdr (p))
61 SCM pair = ly_car (p);
62 add_column (ly_cdr (pair));
66 column_alist_ = SCM_EOL;
70 typeset_grob (align_l_);
76 Break_align_engraver::Break_align_engraver ()
78 column_alist_ = SCM_EOL;
83 Break_align_engraver::acknowledge_grob (Grob_info inf)
85 if (Item * item_l = dynamic_cast <Item *> (inf.grob_l_))
87 if (item_l->empty_b (X_AXIS) || item_l->get_parent (X_AXIS))
90 SCM bp=item_l->get_grob_property ("breakable");
91 bool breakable = (to_boolean (bp));
95 SCM align_name = item_l->get_grob_property ("break-align-symbol");
96 if (!gh_symbol_p (align_name))
101 align_l_ = new Item (get_property ("BreakAlignment"));
102 Break_align_interface::set_interface (align_l_);
103 announce_grob (align_l_,0);
105 SCM edge_sym = ly_symbol2scm ("Left_edge_item");
106 Item * edge = new Item (get_property ("LeftEdge"));
111 If the element is empty, it will be ignored in the break
114 TODO: switch off ignoring empty stuff?
116 edge->set_extent_callback (Grob::point_dimension_callback_proc, X_AXIS);
119 We must have left-edge in the middle. Instrument-names
120 are left to left-edge, so they don't enter the staff.
122 align_l_->set_grob_property ("self-alignment-X", edge->self_scm ());
124 announce_grob (edge, 0);
125 column_alist_ = scm_assoc_set_x (column_alist_, edge_sym, edge->self_scm ());
128 SCM s = scm_assoc (align_name, column_alist_);
134 Grob *e = unsmob_grob (ly_cdr (s));
135 group = dynamic_cast<Item*> (e);
139 group = new Item (get_property ("BreakAlignGroup"));
141 Axis_group_interface::set_interface (group);
142 Axis_group_interface::set_axes (group, X_AXIS,X_AXIS);
144 group->set_grob_property ("break-align-symbol", align_name);
145 group->set_parent (align_l_, Y_AXIS);
146 announce_grob (group, 0);
147 column_alist_ = scm_assoc_set_x (column_alist_, align_name, group->self_scm ());
150 Axis_group_interface::add_element (group, item_l);
153 ENTER_DESCRIPTION(Break_align_engraver,
154 /* descr */ "Align grobs with corresponding break-align-symbols into groups, and order the groups according to breakAlignOrder",
155 /* creats*/ "BreakAlignment BreakAlignGroup LeftEdge",
156 /* acks */ "grob-interface", // break-aligned-interface ?
157 /* reads */ "breakAlignOrder",