2 vertical-align-engraver.cc -- implement Vertical_align_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2009 Han-Wen Nienhuys <hanwen@xs4all.nl>
10 #include "paper-column.hh"
11 #include "align-interface.hh"
12 #include "span-bar.hh"
13 #include "axis-group-interface.hh"
14 #include "engraver.hh"
16 #include "pointer-group-interface.hh"
17 #include "grob-array.hh"
19 #include "translator.icc"
21 class Vertical_align_engraver
: public Engraver
24 bool qualifies (Grob_info
) const;
25 SCM id_to_group_hashtab_
;
28 TRANSLATOR_DECLARATIONS (Vertical_align_engraver
);
29 DECLARE_ACKNOWLEDGER (axis_group
);
32 virtual void derived_mark () const;
33 void process_music ();
34 virtual void finalize ();
35 virtual void initialize ();
38 ADD_ACKNOWLEDGER (Vertical_align_engraver
, axis_group
);
39 ADD_TRANSLATOR (Vertical_align_engraver
,
41 "Catch groups (staves, lyrics lines, etc.) and stack them"
55 Vertical_align_engraver::Vertical_align_engraver ()
58 id_to_group_hashtab_
= SCM_EOL
;
62 Vertical_align_engraver::derived_mark () const
64 scm_gc_mark (id_to_group_hashtab_
);
68 Vertical_align_engraver::initialize ()
70 id_to_group_hashtab_
= scm_c_make_hash_table (11);
74 Vertical_align_engraver::process_music ()
78 valign_
= make_spanner ("VerticalAlignment", SCM_EOL
);
79 valign_
->set_bound (LEFT
, unsmob_grob (get_property ("currentCommandColumn")));
80 Align_interface::set_ordered (valign_
);
85 Vertical_align_engraver::finalize ()
89 valign_
->set_bound (RIGHT
, unsmob_grob (get_property ("currentCommandColumn")));
95 Vertical_align_engraver::qualifies (Grob_info i
) const
97 int sz
= i
.origin_contexts ((Translator
*)this).size ();
99 return sz
> 0 && Axis_group_interface::has_interface (i
.grob ())
100 && !i
.grob ()->get_parent (Y_AXIS
)
101 && !to_boolean (i
.grob ()->get_property ("no-alignment"))
102 && Axis_group_interface::has_axis (i
.grob (), Y_AXIS
);
106 Vertical_align_engraver::acknowledge_axis_group (Grob_info i
)
110 string id
= i
.context ()->id_string ();
112 scm_hash_set_x (id_to_group_hashtab_
, ly_string2scm (id
),
113 i
.grob ()->self_scm ());
115 SCM before_id
= i
.context ()->get_property ("alignAboveContext");
116 SCM after_id
= i
.context ()->get_property ("alignBelowContext");
118 SCM before
= scm_hash_ref (id_to_group_hashtab_
, before_id
, SCM_BOOL_F
);
119 SCM after
= scm_hash_ref (id_to_group_hashtab_
, after_id
, SCM_BOOL_F
);
121 Grob
*before_grob
= unsmob_grob (before
);
122 Grob
*after_grob
= unsmob_grob (after
);
124 Align_interface::add_element (valign_
, i
.grob ());
126 if (before_grob
|| after_grob
)
128 Grob_array
*ga
= unsmob_grob_array (valign_
->get_object ("elements"));
129 vector
<Grob
*> &arr
= ga
->array_reference ();
131 Grob
*added
= arr
.back ();
133 for (vsize i
= 0; i
< arr
.size (); i
++)
135 if (arr
[i
] == before_grob
)
137 arr
.insert (arr
.begin () + i
, added
);
140 else if (arr
[i
] == after_grob
)
142 arr
.insert (arr
.begin () + i
+ 1, added
);