2 engraver.cc -- implement Engraver
4 Sourcefile of GNU LilyPond music type setter
6 (c) 1997--2008 Han-Wen Nienhuys <hanwen@xs4all.nl>
12 #include "international.hh"
14 #include "paper-column.hh"
15 #include "score-engraver.hh"
17 #include "stream-event.hh"
21 Engraver::get_daddy_engraver () const
23 return dynamic_cast<Engraver_group
*> (get_daddy_translator ());
27 Engraver::announce_grob (Grob_info inf
)
29 get_daddy_engraver ()->announce_grob (inf
);
33 Engraver::announce_end_grob (Grob_info inf
)
35 get_daddy_engraver ()->announce_grob (inf
);
39 CAUSE is the object (typically a Stream_event object) that
40 was the reason for making E.
43 Engraver::announce_grob (Grob
*e
, SCM cause
)
45 /* TODO: Remove Music code when it's no longer needed */
46 if (Music
*m
= unsmob_music (cause
))
48 cause
= m
->to_event ()->unprotect ();
50 if (unsmob_stream_event (cause
) || unsmob_grob (cause
))
51 e
->set_property ("cause", cause
);
53 Grob_info
i (this, e
);
55 Engraver_group
*g
= get_daddy_engraver ();
62 CAUSE is the object (typically a Music object) that
63 was the reason for making E.
66 Engraver::announce_end_grob (Grob
*e
, SCM cause
)
68 /* TODO: Remove Music code when it's no longer needed */
69 if (Music
*m
= unsmob_music (cause
))
71 cause
= m
->to_event ()->unprotect ();
73 if (e
->get_property ("cause") == SCM_EOL
74 && (unsmob_stream_event (cause
) || unsmob_grob (cause
)))
75 e
->set_property ("cause", cause
);
77 Grob_info
i (this, e
);
80 Engraver_group
*g
= get_daddy_engraver ();
91 static SCM creation_callback
= SCM_EOL
;
92 LY_DEFINE (ly_set_grob_creation_callback
, "ly:set-grob-creation-callback",
94 "Specify a procedure that will be called every time a new grob"
95 " is created. The callback will receive as arguments the grob"
96 " that was created, the name of the C++ source file that caused"
97 " the grob to be created, and the corresponding line number in"
98 " the C++ source file.")
100 LY_ASSERT_TYPE (ly_is_procedure
, cb
, 1);
102 creation_callback
= cb
;
104 return SCM_UNSPECIFIED
;
109 Engraver::internal_make_grob (SCM symbol
, SCM cause
, char const *name
, char const *file
, int line
, char const *fun
)
116 SCM props
= updated_grob_properties (context (), symbol
);
120 SCM handle
= scm_sloppy_assq (ly_symbol2scm ("meta"), props
);
121 SCM klass
= scm_cdr (scm_sloppy_assq (ly_symbol2scm ("class"), scm_cdr (handle
)));
123 if (klass
== ly_symbol2scm ("Item"))
124 grob
= new Item (props
);
125 else if (klass
== ly_symbol2scm ("Spanner"))
126 grob
= new Spanner (props
);
127 else if (klass
== ly_symbol2scm ("Paper_column"))
128 grob
= new Paper_column (props
);
131 announce_grob (grob
, cause
);
134 if (ly_is_procedure (creation_callback
))
135 scm_apply_0 (creation_callback
,
136 scm_list_n (grob
->self_scm (), scm_from_locale_string (file
),
137 scm_from_int (line
), scm_from_locale_string (fun
), SCM_UNDEFINED
));
144 Engraver::internal_make_item (SCM x
, SCM cause
,
146 char const *file
, int line
, char const *fun
)
148 Item
*it
= dynamic_cast<Item
*> (internal_make_grob (x
, cause
, name
, file
, line
, fun
));
154 Engraver::internal_make_column (SCM x
, char const *name
,
155 char const *file
, int line
, char const *fun
)
157 return dynamic_cast<Paper_column
*> (internal_make_grob (x
, SCM_EOL
, name
, file
, line
, fun
));
161 Engraver::internal_make_spanner (SCM x
, SCM cause
, char const *name
, char const *file
, int line
, char const *fun
)
163 Spanner
*sp
= dynamic_cast<Spanner
*> (internal_make_grob (x
, cause
, name
, file
, line
, fun
));
168 #include "translator.icc"
170 ADD_TRANSLATOR (Engraver
,
172 "Base class for engravers. Does nothing, so it is not used.",