2 engraver-group-engraver.cc -- implement Engraver_group_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2004 Han-Wen Nienhuys <hanwen@cs.uu.nl>
9 #include "engraver-group-engraver.hh"
11 #include "flower-proto.hh"
13 #include "paper-score.hh"
18 Engraver_group_engraver::announce_grob (Grob_info info)
20 announce_infos_.push (info);
21 get_daddy_engraver ()->announce_grob (info);
25 SCM find_acknowledge_engravers (SCM gravlist, SCM meta);
26 SCM find_accept_engravers (SCM gravlist, SCM music_descr);
29 Engraver_group_engraver::acknowledge_grobs ()
31 if (!announce_infos_.size ())
34 SCM tab = get_property ("acknowledgeHashTable");
35 SCM name_sym = ly_symbol2scm ("name");
36 SCM meta_sym = ly_symbol2scm ("meta");
39 for (int j = 0; j < announce_infos_.size (); j++)
41 Grob_info info = announce_infos_[j];
43 SCM meta = info.grob_->internal_get_property (meta_sym);
44 SCM nm = scm_assoc (name_sym, meta);
50 it's tempting to put an assert for
51 immutable_property_alist_ == '(), but in fact, some
52 engravers (clef-engraver) add some more information to the
53 immutable_property_alist_ (after it has been '()-ed).
55 We ignore the grob anyway. He who has no name, shall not
61 SCM acklist = scm_hashq_ref (tab, nm, SCM_UNDEFINED);
62 if (acklist == SCM_BOOL_F)
64 acklist = find_acknowledge_engravers (scm_cons (self_scm (), get_simple_trans_list ()), meta);
65 scm_hashq_set_x (tab, nm, acklist);
68 for (SCM p = acklist; scm_is_pair (p); p = scm_cdr (p))
70 Translator * t = unsmob_translator (scm_car (p));
71 Engraver * eng = dynamic_cast<Engraver*> (t);
72 if (eng && eng != info.origin_trans_)
73 eng->acknowledge_grob (info);
80 Ugh. This is slightly expensive. We could/should cache the value of
84 Engraver_group_engraver::pending_grob_count () const
86 int count = announce_infos_.size ();
87 for (SCM s = context ()->children_contexts ();
88 scm_is_pair (s); s = scm_cdr (s))
90 Context *c = unsmob_context (scm_car (s));
91 Engraver_group_engraver * group
92 = dynamic_cast<Engraver_group_engraver*> (c->implementation ());
95 count += group->pending_grob_count ();
101 Engraver_group_engraver::do_announces ()
104 for (SCM s = context ()->children_contexts ();
105 scm_is_pair (s); s = scm_cdr (s))
107 Context *c = unsmob_context (scm_car (s));
108 Engraver_group_engraver * group
109 = dynamic_cast<Engraver_group_engraver*> (c->implementation ());
111 group->do_announces ();
116 engraver_each (get_simple_trans_list (),
117 &Engraver::process_acknowledged_grobs);
120 if (announce_infos_.size () == 0)
123 acknowledge_grobs ();
124 announce_infos_.clear ();
128 } while (pending_grob_count () > 0);
134 Engraver_group_engraver::initialize ()
136 SCM tab = scm_make_vector (scm_int2num (61), SCM_BOOL_F);
137 context ()->set_property ("acknowledgeHashTable", tab);
139 Translator_group::initialize ();
142 Engraver_group_engraver::Engraver_group_engraver () {}
144 ADD_TRANSLATOR (Engraver_group_engraver,
145 /* descr */ "A group of engravers taken together",
158 engraver_valid (Translator*tr, SCM ifaces)
160 SCM ack_ifs = scm_assoc (ly_symbol2scm ("interfaces-acked"), tr->translator_description ());
161 ack_ifs = scm_cdr (ack_ifs);
162 for (SCM s = ifaces; scm_is_pair (s); s = scm_cdr (s))
163 if (scm_c_memq (scm_car (s), ack_ifs) != SCM_BOOL_F)
171 find_acknowledge_engravers (SCM gravlist, SCM meta_alist)
173 SCM ifaces = scm_cdr (scm_assoc (ly_symbol2scm ("interfaces"), meta_alist));
176 for (SCM s = gravlist; scm_is_pair (s); s = scm_cdr (s))
178 Translator* tr = unsmob_translator (scm_car (s));
179 if (engraver_valid (tr, ifaces))
180 l = scm_cons (tr->self_scm (), l);
182 l = scm_reverse_x (l, SCM_EOL);
188 /* c&p engraver-group.cc */
190 recurse_down_engravers (Context * c, Engraver_method ptr, bool context_first)
192 Engraver_group_engraver * tg
193 = dynamic_cast<Engraver_group_engraver*> (c->implementation ());
198 engraver_each (tg->get_simple_trans_list (),
204 for (SCM s = c->children_contexts () ; scm_is_pair (s);
207 recurse_down_engravers (unsmob_context (scm_car (s)), ptr, context_first);
212 engraver_each (tg->get_simple_trans_list (),
220 engraver_each (SCM list, Engraver_method method)
222 for (SCM p = list; scm_is_pair (p); p = scm_cdr (p))
224 Engraver * e = dynamic_cast<Engraver*>(unsmob_translator (scm_car (p)));