2 script-engraver.cc -- implement Script_engraver
4 (c) 1997--2001 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 #include "side-position-interface.hh"
9 #include "musical-request.hh"
11 #include "rhythmic-head.hh"
12 #include "engraver.hh"
14 class Script_engraver
: public Engraver
16 Link_array
<Grob
> script_p_arr_
;
17 Link_array
<Articulation_req
> script_req_l_arr_
;
20 VIRTUAL_COPY_CONS (Translator
);
23 virtual bool try_music (Music
*);
24 virtual void initialize ();
25 virtual void stop_translation_timestep ();
26 virtual void start_translation_timestep ();
27 virtual void process_music ();
28 virtual void acknowledge_grob (Grob_info
);
32 Script_engraver::initialize ()
34 script_req_l_arr_
.clear ();
38 Script_engraver::try_music (Music
*r_l
)
40 if (Articulation_req
*mr
= dynamic_cast <Articulation_req
*> (r_l
))
42 for (int i
=0; i
< script_req_l_arr_
.size (); i
++)
44 if (script_req_l_arr_
[i
]->equal_b (mr
))
47 script_req_l_arr_
.push (mr
);
54 Script_engraver::process_music ()
56 for (int i
=0; i
< script_req_l_arr_
.size (); i
++)
58 Articulation_req
* l
=script_req_l_arr_
[i
];
60 SCM alist
= get_property ("scriptDefinitions");
61 SCM art
= scm_assoc (l
->get_mus_property ("articulation-type"), alist
);
63 if (art
== SCM_BOOL_F
)
65 String a
= ly_scm2string (l
->get_mus_property ("articulation-type"));
66 l
->origin ()->warning (_f ("Don't know how to interpret articulation `%s'", a
.ch_C ()));
70 // todo -> use result of articulation-to-scriptdef directly as basic prop list.
71 Grob
*p
=new Item (get_property ("Script"));
73 p
->set_grob_property ("molecule", gh_car (art
));
76 bool follow_staff
= gh_scm2bool (gh_car (art
));
78 SCM relative_stem_dir
= gh_car (art
);
81 SCM force_dir
= l
->get_mus_property ("direction");
82 if (isdir_b (force_dir
) && !to_dir (force_dir
))
83 force_dir
= gh_car (art
);
86 SCM priority
= gh_car (art
);
88 if (isdir_b (force_dir
) && to_dir (force_dir
))
89 p
->set_grob_property ("direction", force_dir
);
90 else if (to_dir (relative_stem_dir
))
91 p
->set_grob_property ("side-relative-direction", relative_stem_dir
);
95 FIXME: should figure this out in relation with basic props!
97 SCM axisprop
= get_property ("scriptHorizontal");
98 bool xaxis
= to_boolean (axisprop
);
99 Side_position_interface::set_axis (p
, xaxis
? X_AXIS
: Y_AXIS
);
101 if (!follow_staff
&& ! xaxis
)
102 p
->set_grob_property ("staff-support", SCM_BOOL_T
);
104 if (!xaxis
&& follow_staff
)
105 p
->add_offset_callback (Side_position_interface::quantised_position_proc
, Y_AXIS
);
108 p
->set_grob_property ("script-priority", priority
);
110 script_p_arr_
.push (p
);
112 announce_grob (p
, l
);
117 Script_engraver::acknowledge_grob (Grob_info inf
)
119 if (Stem::has_interface (inf
.elem_l_
))
121 for (int i
=0; i
< script_p_arr_
.size (); i
++)
123 Grob
*e
= script_p_arr_
[i
];
125 e
->set_grob_property ("direction-source", inf
.elem_l_
->self_scm ());
126 e
->add_dependency (inf
.elem_l_
);
127 Side_position_interface::add_support (e
, inf
.elem_l_
);
130 else if (Rhythmic_head::has_interface (inf
.elem_l_
))
132 for (int i
=0; i
< script_p_arr_
.size (); i
++)
134 Grob
*e
= script_p_arr_
[i
];
136 if (!e
->parent_l (X_AXIS
))
138 e
->set_parent (inf
.elem_l_
, X_AXIS
);
140 if (Side_position_interface::get_axis (e
) == X_AXIS
141 && !e
->parent_l (Y_AXIS
))
143 e
->set_parent (inf
.elem_l_
, Y_AXIS
);
144 e
->add_dependency (inf
.elem_l_
); // ??
146 Side_position_interface::add_support (e
,inf
.elem_l_
);
152 Script_engraver::stop_translation_timestep ()
154 for (int i
=0; i
< script_p_arr_
.size (); i
++)
156 Grob
* sc
= script_p_arr_
[i
];
157 if (to_boolean (sc
->get_grob_property ("staff-support")))
159 Side_position_interface::add_staff_support (sc
);
163 script_p_arr_
.clear ();
167 Script_engraver::start_translation_timestep ()
169 script_req_l_arr_
.clear ();
172 ADD_THIS_TRANSLATOR (Script_engraver
);