X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Falign-interface.cc;h=59575bba43fdd4cd02bfd6525ce1d6b7b9a21907;hb=ed4aec0ae52d484fba091196e1869e7cfc0c1ad7;hp=6a39e6b08d3b4ffb7c5d3c2576197ff09d79d294;hpb=7aabfb20c46e0a1de41698ddc6859ccd3a6dea85;p=lilypond.git diff --git a/lily/align-interface.cc b/lily/align-interface.cc index 6a39e6b08d..59575bba43 100644 --- a/lily/align-interface.cc +++ b/lily/align-interface.cc @@ -1,98 +1,91 @@ -/* - align-interface.cc -- implement Align_interface - +/* + align-interface.cc -- implement Align_interface + source file of the GNU LilyPond music typesetter - - (c) 2000--2003 Han-Wen Nienhuys - - */ + + (c) 2000--2005 Han-Wen Nienhuys +*/ #include "align-interface.hh" -#include "grob.hh" -#include "group-interface.hh" + +#include "spanner.hh" +#include "item.hh" #include "axis-group-interface.hh" #include "hara-kiri-group-spanner.hh" -#include "paper-def.hh" -MAKE_SCHEME_CALLBACK (Align_interface,alignment_callback,2); +MAKE_SCHEME_CALLBACK (Align_interface, alignment_callback, 2); SCM Align_interface::alignment_callback (SCM element_smob, SCM axis) { - Grob * me = unsmob_grob (element_smob); - Axis ax = (Axis)gh_scm2int (axis); - Grob * par = me->get_parent (ax); - if (par && !to_boolean (par->get_grob_property ("alignment-done"))) + Grob *me = unsmob_grob (element_smob); + Axis ax = (Axis)scm_to_int (axis); + Grob *par = me->get_parent (ax); + if (par && !to_boolean (par->get_property ("positioning-done"))) { Align_interface::align_elements_to_extents (par, ax); } - return gh_double2scm (0.0); + return scm_make_real (0.0); } -MAKE_SCHEME_CALLBACK (Align_interface,fixed_distance_alignment_callback,2); +MAKE_SCHEME_CALLBACK (Align_interface, fixed_distance_alignment_callback, 2); SCM Align_interface::fixed_distance_alignment_callback (SCM element_smob, SCM axis) { - Grob * me = unsmob_grob (element_smob); - Axis ax = (Axis)gh_scm2int (axis); - Grob * par = me->get_parent (ax); - if (par && !to_boolean (par->get_grob_property ("alignment-done"))) + Grob *me = unsmob_grob (element_smob); + Axis ax = (Axis)scm_to_int (axis); + Grob *par = me->get_parent (ax); + if (par && !to_boolean (par->get_property ("positioning-done"))) { Align_interface::align_to_fixed_distance (par, ax); } - return gh_double2scm (0.0); + return scm_make_real (0.0); } /* - merge with align-to-extents? - */ + merge with align-to-extents? +*/ void -Align_interface::align_to_fixed_distance (Grob *me , Axis a) +Align_interface::align_to_fixed_distance (Grob *me, Axis a) { - me->set_grob_property ("alignment-done", SCM_BOOL_T); - - SCM d = me->get_grob_property ("stacking-dir"); - - Direction stacking_dir = gh_number_p (d) ? to_dir (d) : CENTER; + me->set_property ("positioning-done", SCM_BOOL_T); + + SCM d = me->get_property ("stacking-dir"); + + Direction stacking_dir = scm_is_number (d) ? to_dir (d) : CENTER; if (!stacking_dir) stacking_dir = DOWN; - SCM force = me->get_grob_property ("forced-distance"); + Real dy = robust_scm2double (me->get_property ("forced-distance"), 0.0); - Real dy = 0.0; - if (gh_number_p (force)) - { - dy = gh_scm2double (force); - } - Link_array elems - = Pointer_group_interface__extract_grobs (me, (Grob*) 0, "elements"); + = extract_grob_array (me, ly_symbol2scm ("elements")); - Real where_f=0; + Real where_f = 0; Interval v; v.set_empty (); Array translates; - - for (int j= elems.size (); j--; ) + + for (int j = elems.size (); j--;) { /* This is not very elegant, in that we need special support for - hara kiri. Unfortunately, the generic wiring of + hara-kiri. Unfortunately, the generic wiring of force_hara_kiri_callback () (extent and offset callback) is - such that we might get into a loop if we call extent() or - offset() the elements. - - - */ + such that we might get into a loop if we call extent () or + offset () the elements. + + + */ if (a == Y_AXIS && Hara_kiri_group_spanner::has_interface (elems[j])) Hara_kiri_group_spanner::consider_suicide (elems[j]); - if (!elems[j]-> live()) - elems.del(j); + if (!elems[j]->is_live ()) + elems.del (j); } - for (int j =0; j < elems.size (); j++) + for (int j = 0; j < elems.size (); j++) { where_f += stacking_dir * dy; translates.push (where_f); @@ -100,8 +93,8 @@ Align_interface::align_to_fixed_distance (Grob *me , Axis a) } /* - TODO: support self-alignment-{Y,X} - */ + TODO: support self-alignment-{Y, X} + */ for (int i = 0; i < translates.size (); i++) { elems[i]->translate_axis (translates[i] - v.center (), a); @@ -121,154 +114,165 @@ Align_interface::align_to_fixed_distance (Grob *me , Axis a) TODO: maybe we should rethink and throw out thresholding altogether. The original function has been taken over by - align_to_fixed_distance(). + align_to_fixed_distance (). */ void -Align_interface::align_elements_to_extents (Grob * me, Axis a) +Align_interface::align_elements_to_extents (Grob *me, Axis a) { - me->set_grob_property ("alignment-done", SCM_BOOL_T); - - SCM d = me->get_grob_property ("stacking-dir"); + Spanner *me_spanner = dynamic_cast (me); + if (a == Y_AXIS + && me_spanner + && me_spanner->get_bound (LEFT)->break_status_dir () == CENTER) + { + me_spanner->warning (_("vertical alignment called before line-breaking. Only do cross-staff spanners with PianoStaff.")); + } - Direction stacking_dir = gh_number_p (d) ? to_dir (d) : CENTER; + me->set_property ("positioning-done", SCM_BOOL_T); + + SCM d = me->get_property ("stacking-dir"); + + Direction stacking_dir = scm_is_number (d) ? to_dir (d) : CENTER; if (!stacking_dir) stacking_dir = DOWN; - - Interval threshold = Interval (0, Interval::infinity ()); - SCM thr = me->get_grob_property ("threshold"); - if (gh_pair_p (thr)) - { - threshold[SMALLER] = gh_scm2double (ly_car (thr)); - threshold[BIGGER] = gh_scm2double (ly_cdr (thr)); - } - + Interval threshold = robust_scm2interval (me->get_property ("threshold"), + Interval (0, Interval::infinity ())); + Array dims; Link_array elems; Link_array all_grobs - = Pointer_group_interface__extract_grobs (me, (Grob*) 0, "elements"); - for (int i=0; i < all_grobs.size (); i++) + = extract_grob_array (me, ly_symbol2scm ("elements")); + for (int i = 0; i < all_grobs.size (); i++) { Interval y = all_grobs[i]->extent (me, a); - if (!y.empty_b ()) + if (!y.is_empty ()) { - Grob *e =dynamic_cast (all_grobs[i]); + Grob *e = dynamic_cast (all_grobs[i]); elems.push (e); - dims.push (y); + dims.push (y); } } - - + /* Read self-alignment-X and self-alignment-Y. This may seem like code duplication. (and really: it is), but this is necessary to prevent ugly cyclic dependencies that arise when you combine self-alignment on a child with alignment of children. */ - static SCM prop_syms[2]; + static SCM prop_syms[2]; if (!prop_syms[0]) { prop_syms[X_AXIS] = ly_symbol2scm ("self-alignment-X"); prop_syms[Y_AXIS] = ly_symbol2scm ("self-alignment-Y"); } - - SCM align (me->internal_get_grob_property (prop_syms[a])); - - Array translates ; + + SCM align (me->internal_get_property (prop_syms[a])); + + Array translates; Interval total; - Real where_f=0; - - for (int j=0 ; j < elems.size (); j++) + Real where_f = 0; + + for (int j = 0; j < elems.size (); j++) { - Real dy = - dims[j][-stacking_dir]; + Real dy = -dims[j][-stacking_dir]; if (j) - dy += dims[j-1][stacking_dir]; - + dy += dims[j - 1][stacking_dir]; /* we want dy to be > 0 - */ - dy *= stacking_dir; + */ + dy *= stacking_dir; if (j) { - dy = (dy >? threshold[SMALLER]) - all_translates; if (translates.size ()) { - int i =0; - int j =0; + int i = 0; + int j = 0; Real w = translates[0]; - while (j < all_grobs.size ()) + while (j < all_grobs.size ()) { if (i < elems.size () && all_grobs[j] == elems[i]) { w = translates[i++]; } - if (all_grobs[j] == align_center) - center_offset = w; - all_translates .push (w); + all_translates.push (w); j++; } - /* FIXME: uncommenting freaks out the Y-alignment of line-of-score. - */ - // Real align_param = ly_dir_p (align) ? gh_scm2double (align) : 0.0; - - if (gh_number_p (align)) - center_offset = total.linear_combination (gh_scm2double (align)); + */ + if (scm_is_number (align)) + center_offset = total.linear_combination (scm_to_double (align)); - for (int j = 0 ; j < all_grobs.size (); j++) + for (int j = 0; j < all_grobs.size (); j++) all_grobs[j]->translate_axis (all_translates[j] - center_offset, a); } } Axis -Align_interface::axis (Grob*me) +Align_interface::axis (Grob *me) { - return Axis (gh_scm2int (ly_car (me->get_grob_property ("axes")))); + return Axis (scm_to_int (scm_car (me->get_property ("axes")))); } void -Align_interface::add_element (Grob*me,Grob* s, SCM cb) +Align_interface::add_element (Grob *me, Grob *element, SCM call_back) { - s->add_offset_callback (cb, Align_interface::axis (me)); - Axis_group_interface::add_element (me, s); + element->add_offset_callback (call_back, Align_interface::axis (me)); + Axis_group_interface::add_element (me, element); } void -Align_interface::set_axis (Grob*me,Axis a) +Align_interface::set_axis (Grob *me, Axis a) { - Axis_group_interface::set_axes (me, a,a); + Axis_group_interface::set_axes (me, a, a); } +/* + Find Y-axis parent of G that has a #'forced-distance property. This + has the effect of finding the piano-staff given an object in that + piano staff. +*/ +Grob * +find_fixed_alignment_parent (Grob *g) +{ + while (g) + { + if (scm_is_number (g->get_property ("forced-distance"))) + return g; + g = g->get_parent (Y_AXIS); + } -ADD_INTERFACE (Align_interface, "align-interface", - " Order grobs top to bottom/left to right/right to left etc.", - "forced-distance stacking-dir align-dir threshold alignment-done center-element elements axes"); + return 0; +} +ADD_INTERFACE (Align_interface, "align-interface", + "Order grobs from top to bottom, left to right, right to left or bottom" + "to top.", + "forced-distance stacking-dir align-dir threshold positioning-done " + "center-element elements axes"); struct Foobar { - bool has_interface (Grob*); + bool has_interface (Grob *); }; +