2 engraver-group-engraver.cc -- implement Engraver_group_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--2005 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);
24 SCM find_acknowledge_engravers (SCM gravlist, SCM meta);
25 SCM find_accept_engravers (SCM gravlist, SCM music_descr);
28 Engraver_group_engraver::acknowledge_grobs ()
30 if (!announce_infos_.size ())
33 SCM tab = get_property ("acknowledgeHashTable");
34 SCM name_sym = ly_symbol2scm ("name");
35 SCM meta_sym = ly_symbol2scm ("meta");
37 for (int j = 0; j < announce_infos_.size (); j++)
39 Grob_info info = announce_infos_[j];
41 SCM meta = info.grob_->internal_get_property (meta_sym);
42 SCM nm = scm_assoc (name_sym, meta);
48 it's tempting to put an assert for
49 immutable_property_alist_ == '(), but in fact, some
50 engravers (clef-engraver) add some more information to the
51 immutable_property_alist_ (after it has been '()-ed).
53 We ignore the grob anyway. He who has no name, shall not
59 SCM acklist = scm_hashq_ref (tab, nm, SCM_UNDEFINED);
60 if (acklist == SCM_BOOL_F)
62 acklist = find_acknowledge_engravers (scm_cons (self_scm (), get_simple_trans_list ()), meta);
63 scm_hashq_set_x (tab, nm, acklist);
66 for (SCM p = acklist; scm_is_pair (p); p = scm_cdr (p))
68 Translator *t = unsmob_translator (scm_car (p));
69 Engraver *eng = dynamic_cast<Engraver *> (t);
70 if (eng && eng != info.origin_translator ())
71 eng->acknowledge_grob (info);
77 Ugh. This is slightly expensive. We could/should cache the value of
81 Engraver_group_engraver::pending_grob_count () const
83 int count = announce_infos_.size ();
84 for (SCM s = context ()->children_contexts ();
85 scm_is_pair (s); s = scm_cdr (s))
87 Context *c = unsmob_context (scm_car (s));
88 Engraver_group_engraver *group
89 = dynamic_cast<Engraver_group_engraver *> (c->implementation ());
92 count += group->pending_grob_count ();
98 Engraver_group_engraver::do_announces ()
102 for (SCM s = context ()->children_contexts ();
103 scm_is_pair (s); s = scm_cdr (s))
105 Context *c = unsmob_context (scm_car (s));
106 Engraver_group_engraver *group
107 = dynamic_cast<Engraver_group_engraver *> (c->implementation ());
109 group->do_announces ();
114 engraver_each (get_simple_trans_list (),
115 &Engraver::process_acknowledged_grobs);
117 if (announce_infos_.size () == 0)
120 acknowledge_grobs ();
121 announce_infos_.clear ();
124 while (pending_grob_count () > 0);
128 Engraver_group_engraver::initialize ()
130 SCM tab = scm_make_vector (scm_int2num (61), SCM_BOOL_F);
131 context ()->set_property ("acknowledgeHashTable", tab);
133 Translator_group::initialize ();
136 Engraver_group_engraver::Engraver_group_engraver () {}
138 ADD_TRANSLATOR (Engraver_group_engraver,
139 /* descr */ "A group of engravers taken together",
149 engraver_valid (Translator *tr, SCM ifaces)
151 SCM ack_ifs = scm_assoc (ly_symbol2scm ("interfaces-acked"), tr->translator_description ());
152 ack_ifs = scm_cdr (ack_ifs);
153 for (SCM s = ifaces; scm_is_pair (s); s = scm_cdr (s))
154 if (scm_c_memq (scm_car (s), ack_ifs) != SCM_BOOL_F)
160 find_acknowledge_engravers (SCM gravlist, SCM meta_alist)
162 SCM ifaces = scm_cdr (scm_assoc (ly_symbol2scm ("interfaces"), meta_alist));
165 for (SCM s = gravlist; scm_is_pair (s); s = scm_cdr (s))
167 Translator *tr = unsmob_translator (scm_car (s));
168 if (engraver_valid (tr, ifaces))
169 l = scm_cons (tr->self_scm (), l);
171 l = scm_reverse_x (l, SCM_EOL);
176 /* c&p engraver-group.cc */
178 recurse_down_engravers (Context *c, Engraver_method ptr, bool context_first)
180 Engraver_group_engraver *tg
181 = dynamic_cast<Engraver_group_engraver *> (c->implementation ());
185 engraver_each (tg->get_simple_trans_list (),
191 for (SCM s = c->children_contexts (); scm_is_pair (s);
194 recurse_down_engravers (unsmob_context (scm_car (s)), ptr, context_first);
199 engraver_each (tg->get_simple_trans_list (),
206 engraver_each (SCM list, Engraver_method method)
208 for (SCM p = list; scm_is_pair (p); p = scm_cdr (p))
210 Engraver *e = dynamic_cast<Engraver *> (unsmob_translator (scm_car (p)));