2 score-elem.cc -- implement Score_element
4 source file of the GNU LilyPond music typesetter
6 (c) 1997--1999 Han-Wen Nienhuys <hanwen@cs.uu.nl>
12 #include "paper-score.hh"
13 #include "paper-def.hh"
15 #include "molecule.hh"
16 #include "score-element.hh"
19 #include "line-of-score.hh"
21 #include "paper-column.hh"
22 #include "molecule.hh"
24 #include "paper-outputter.hh"
25 #include "dimension-cache.hh"
29 Score_element::dim_cache_callback (Dimension_cache
*c
)
31 Score_element
* e
=dynamic_cast<Score_element
*>( c
->element_l());
32 if(e
->dim_cache_
[X_AXIS
] == c
)
33 return e
->do_width ();
35 return e
->do_height ();
38 Score_element::Score_element()
41 dim_cache_
[X_AXIS
]->set_callback (dim_cache_callback
);
42 dim_cache_
[Y_AXIS
]->set_callback (dim_cache_callback
);
49 element_property_alist_
= SCM_EOL
;
54 Score_element::Score_element (Score_element
const&s
)
55 : Graphical_element (s
)
60 original_l_
=(Score_element
*) &s
;
61 element_property_alist_
= scm_protect_object (scm_list_copy (s
.element_property_alist_
));
62 dependency_arr_
= s
.dependency_arr_
;
64 status_i_
= s
.status_i_
;
65 lookup_l_
= s
.lookup_l_
;
66 pscore_l_
= s
.pscore_l_
;
71 Score_element::~Score_element()
74 assert (status_i_
>=0);
79 Score_element::dependency (int i
) const
81 return dependency_arr_
[i
];
85 Score_element::dependency_size () const
87 return dependency_arr_
.size ();
90 // should also have one that takes SCM arg.
92 Score_element::get_elt_property (String nm
) const
94 SCM sym
= ly_symbol2scm (nm
.ch_C());
95 SCM s
= scm_assq(sym
, element_property_alist_
);
102 SCM sym2
= ly_symbol2scm ((name () + ("::" + nm
)).ch_C());
105 // should probably check for Type::sym as well.
106 Paper_def
* p
= pscore_l_
->paper_l_
;
107 if (p
->default_properties_
.try_retrieve (sym2
, &val
))
109 else if (p
->default_properties_
.try_retrieve (sym
, &val
))
113 return SCM_UNDEFINED
;
117 Score_element::remove_elt_property (String key
)
119 SCM s
= get_elt_property (key
);
120 SCM sym
= ly_symbol2scm (key
.ch_C());
121 element_property_alist_
= scm_assq_remove_x (element_property_alist_
, sym
);
129 Score_element::set_elt_property (String k
, SCM v
)
131 SCM s
= ly_symbol2scm (k
.ch_C( ));
132 element_property_alist_
= scm_assoc_set_x (element_property_alist_
, s
, v
);
136 Score_element::do_width() const
140 Molecule
*m
= output_p_
? output_p_
: do_brew_molecule_p();
141 r
= m
->extent().x ();
150 Score_element::do_height() const
153 Molecule
*m
= output_p_
? output_p_
: do_brew_molecule_p();
154 r
= m
->extent().y ();
162 Score_element::print() const
165 DEBUG_OUT
<< classname(this) << "{\n";
166 if (flower_dstream
&& !flower_dstream
->silent_b ("Score_element"))
167 ly_display_scm (element_property_alist_
);
168 DEBUG_OUT
<< "dependencies: " << dependency_size();
170 DEBUG_OUT
<< "Copy ";
171 Graphical_element::do_print ();
179 Score_element::paper_l () const
181 return pscore_l_
->paper_l_
;
185 Score_element::lookup_l () const
189 Score_element
* urg
= (Score_element
*)this;
190 SCM sz
= urg
->remove_elt_property ("fontsize");
191 int i
= (sz
!= SCM_UNDEFINED
)
195 urg
->lookup_l_
= (Lookup
*)pscore_l_
->paper_l_
->lookup_l (i
);
201 Score_element::add_processing()
203 assert (status_i_
>=0);
211 Score_element::calculate_dependencies (int final
, int busy
,
212 Score_element_method_pointer funcptr
)
214 assert (status_i_
>=0);
216 if (status_i_
>= final
)
219 assert (status_i_
!= busy
);
222 for (int i
=0; i
< dependency_arr_
.size(); i
++)
223 dependency_arr_
[i
]->calculate_dependencies (final
, busy
, funcptr
);
225 Link_array
<Score_element
> extra (get_extra_dependencies());
226 for (int i
=0; i
< extra
.size(); i
++)
227 extra
[i
]->calculate_dependencies (final
, busy
, funcptr
);
229 invalidate_cache (X_AXIS
);
230 invalidate_cache (Y_AXIS
);
236 Score_element::output_processing ()
238 if (get_elt_property ("transparent") != SCM_UNDEFINED
)
241 // we're being silly here.
245 output_p_
= do_brew_molecule_p ();
246 Offset
o (relative_coordinate (0, X_AXIS
), relative_coordinate (0, Y_AXIS
));
248 SCM s
= get_elt_property ("extra-offset");
251 Real il
= paper_l ()->get_var ("interline");
252 o
[X_AXIS
] += il
* gh_scm2double (gh_car (s
));
253 o
[Y_AXIS
] += il
* gh_scm2double (gh_cdr (s
));
256 pscore_l_
->outputter_l_
->output_molecule (output_p_
,
270 Score_element::do_break_processing()
272 handle_broken_dependencies();
276 Score_element::do_post_processing()
281 Score_element::do_breakable_col_processing()
283 handle_prebroken_dependencies();
287 Score_element::do_pre_processing()
292 Score_element::do_space_processing ()
297 Score_element::do_add_processing()
302 Score_element::do_substitute_element_pointer (Score_element
*,Score_element
*)
308 Score_element::do_brew_molecule_p() const
310 Molecule
a (lookup_l ()->fill (Box (Interval (0,0), Interval (0,0))));
311 return new Molecule (a
);
316 Score_element::line_l() const
322 Score_element::add_dependency (Score_element
*e
)
326 dependency_arr_
.push (e
);
330 programming_error ("Null dependency added");
334 Score_element::substitute_dependency (Score_element
* old
, Score_element
* new_l
)
336 do_substitute_element_pointer (old
,new_l
);
337 old
->do_substitute_element_pointer (this, 0);
341 Score_element::handle_broken_dependencies()
343 Line_of_score
*line
= line_l();
347 do_substitute_arrays ();
349 Link_array
<Score_element
> new_deps
;
351 for (int i
=0; i
< dependency_size(); i
++)
353 Score_element
* elt
= dependency (i
);
354 if (elt
->line_l() != line
)
356 Score_element
* broken
= elt
->find_broken_piece (line
);
357 substitute_dependency (elt
, broken
);
363 dependency_arr_
= new_deps
;
371 unlike with spanners, the number of items can increase
377 span: item1 item2 item3
379 How to let span (a derived class) know that this happened?
385 Score_element::handle_prebroken_dependencies()
387 /* dynamic_cast<Item*> (this) &&
388 if (!break_status_dir ())
391 Link_array
<Score_element
> old_arr
, new_arr
;
393 for (int i
=0; i
< dependency_size(); i
++)
395 Score_element
* elt
= dependency (i
);
396 Item
*it_l
= dynamic_cast <Item
*> (elt
);
397 if (it_l
&& it_l
->broken_original_b ())
398 if (Item
*me
= dynamic_cast<Item
*> (this) )
400 Score_element
*new_l
= it_l
->find_broken_piece (me
->break_status_dir ());
403 new_arr
.push (new_l
);
412 new_arr
.push (it_l
->find_broken_piece (d
));
413 } while (flip(&d
)!= LEFT
);
417 for (int i
=0; i
< old_arr
.size(); i
++)
419 substitute_dependency (old_arr
[i
], new_arr
[i
]);
423 Score_element::handle_prebroken_dependents()
428 Score_element::handle_broken_dependents()
434 Link_array
<Score_element
>
435 Score_element::get_extra_dependencies() const
437 Link_array
<Score_element
> empty
;
442 Score_element::linked_b() const
448 Score_element::do_print () const
453 Score_element::do_substitute_arrays ()
459 Score_element::find_broken_piece (Line_of_score
*) const
465 Score_element::mark_smob (SCM ses
)
467 void * mp
= (void*) SCM_CDR(ses
);
468 Score_element
* s
= (Score_element
*) mp
;
470 assert (s
->self_scm_
== ses
);
471 return s
->element_property_alist_
;
476 Score_element::print_smob (SCM s
, SCM port
, scm_print_state
*)
478 Score_element
*sc
= (Score_element
*) SCM_CDR (s
);
480 scm_puts ("#<Score_element ", port
);
481 scm_puts ((char *)sc
->name (), port
);
482 scm_puts (" >", port
);
487 Score_element::do_smobify_self ()
489 scm_unprotect_object (element_property_alist_
); // ugh
491 #include "ly-smobs.icc"
492 IMPLEMENT_SMOBS(Score_element
);
495 Score_element::equal_p (SCM a
, SCM b
)
497 return SCM_CDR(a
) == SCM_CDR(b
) ? SCM_BOOL_T
: SCM_BOOL_F
;