From: fred Date: Wed, 27 Mar 2002 02:41:46 +0000 (+0000) Subject: lilypond-1.5.37 X-Git-Tag: release/1.5.59~208 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=71c1c65afdc16d7615cc91d340db9a539e64366d;p=lilypond.git lilypond-1.5.37 --- diff --git a/lily/bar.cc b/lily/bar.cc deleted file mode 100644 index a390189a92..0000000000 --- a/lily/bar.cc +++ /dev/null @@ -1,200 +0,0 @@ -/* - bar.cc -- implement Bar - - source file of the GNU LilyPond music typesetter - - (c) 1997--2002 Han-Wen Nienhuys -*/ -#include - -#include "lookup.hh" -#include "paper-column.hh" -#include "main.hh" -#include "grob.hh" -#include "bar.hh" -#include "string.hh" -#include "molecule.hh" -#include "paper-def.hh" -#include "font-interface.hh" -#include "debug.hh" -#include "all-font-metrics.hh" -#include "item.hh" -#include "staff-symbol-referencer.hh" - -MAKE_SCHEME_CALLBACK (Bar,brew_molecule,1); - -SCM -Bar::brew_molecule (SCM smob) -{ - Grob * me = unsmob_grob (smob); - - SCM s = me->get_grob_property ("glyph"); - SCM barsiz_proc = me->get_grob_property ("bar-size-procedure"); - if (gh_string_p (s) && gh_procedure_p (barsiz_proc)) - { - String str =ly_scm2string (s); - SCM siz = gh_call1 (barsiz_proc, me->self_scm ()); - Real sz = gh_scm2double (siz); - if (sz < 0) - return SCM_EOL; - - return compound_barline (me, str, sz).smobbed_copy (); - } - return SCM_EOL; -} - - -Molecule -Bar::compound_barline (Grob*me, String str, Real h) -{ - Real kern = gh_scm2double (me->get_grob_property ("kern")); - Real thinkern = gh_scm2double (me->get_grob_property ("thin-kern")); - Real hair = gh_scm2double (me->get_grob_property ("hair-thickness")); - Real fatline = gh_scm2double (me->get_grob_property ("thick-thickness")); - - Real staffline = me->paper_l ()->get_var ("stafflinethickness"); - Real staff_space = Staff_symbol_referencer::staff_space (me); - Real staffspace = me->paper_l ()->get_var ("staffspace") - * staff_space; - - kern *= staffline; - thinkern *= staffline; - hair *= staffline; - fatline *= staffline; - - Molecule thin = simple_barline (me, hair, h); - Molecule thick = simple_barline (me, fatline, h); - Molecule colon; - Molecule dot = Font_interface::get_default_font (me)->find_by_name ("dots-dot"); - Real dist = ( Staff_symbol_referencer::line_count (me) & 1 ? 1 : - staff_space<2 ? 2 : .5 ) * staffspace; - dot.translate_axis(dist/2,Y_AXIS); - colon.add_molecule(dot); - dot.translate_axis(-dist,Y_AXIS); - colon.add_molecule(dot); - - Molecule m; - - if (str == "") - { - return Lookup::blank (Box (Interval (0, 0), Interval (-h/2, h/2))); - } - else if (str == "|") - { - return thin; - } - else if (str == "|." || (h == 0 && str == ":|")) - { - m.add_at_edge (X_AXIS, LEFT, thick, 0); - m.add_at_edge (X_AXIS, LEFT, thin, kern); - } - else if (str == ".|" || (h == 0 && str == "|:")) - { - m.add_at_edge (X_AXIS, RIGHT, thick, 0); - m.add_at_edge (X_AXIS, RIGHT, thin, kern); - } - else if (str == ":|") - { - m.add_at_edge (X_AXIS, LEFT, thick, 0); - m.add_at_edge (X_AXIS, LEFT, thin, kern); - m.add_at_edge (X_AXIS, LEFT, colon, kern); - } - else if (str == "|:") - { - m.add_at_edge (X_AXIS, RIGHT, thick, 0); - m.add_at_edge (X_AXIS, RIGHT, thin, kern); - m.add_at_edge (X_AXIS, RIGHT, colon, kern); - } - else if (str == ":|:") - { - m.add_at_edge (X_AXIS, LEFT, thick, thinkern); - m.add_at_edge (X_AXIS, LEFT, colon, kern); - m.add_at_edge (X_AXIS, RIGHT, thick, kern); - m.add_at_edge (X_AXIS, RIGHT, colon, kern); - } - else if (str == ".|.") - { - m.add_at_edge (X_AXIS, LEFT, thick, thinkern); - m.add_at_edge (X_AXIS, RIGHT, thick, kern); - } - else if (str == "||") - { - m.add_at_edge (X_AXIS, RIGHT, thin, 0); - m.add_at_edge (X_AXIS, RIGHT, thin, thinkern); - } - - return m; -} - - -Molecule -Bar::simple_barline (Grob*,Real w, Real h) -{ - return Lookup::filledbox (Box (Interval (0,w), Interval (-h/2, h/2))); -} - -MAKE_SCHEME_CALLBACK (Bar,before_line_breaking ,1); - -SCM -Bar::before_line_breaking (SCM smob) -{ - Grob*me=unsmob_grob (smob); - Item * item = dynamic_cast (me); - - SCM g = me->get_grob_property ("glyph"); - SCM orig = g; - Direction bsd = item->break_status_dir (); - if (gh_string_p (g) && bsd) - { - SCM proc = me->get_grob_property ("break-glyph-function"); - g = gh_call2 (proc, g, gh_int2scm (bsd)); - } - - - if (!gh_string_p (g)) - { - me->set_grob_property ("molecule-callback", SCM_EOL); - me->set_extent_callback (SCM_EOL, X_AXIS); - // leave y_extent for spanbar? - } - - if (! gh_equal_p (g, orig)) - me->set_grob_property ("glyph", g); - - return SCM_UNSPECIFIED; -} - -void -Bar::set_interface (Grob*me) -{ - me->set_interface (ly_symbol2scm ("bar-line-interface")); -} - -bool -Bar::has_interface (Grob*m) -{ - return m && m->has_interface (ly_symbol2scm ("bar-line-interface")); -} - - -MAKE_SCHEME_CALLBACK (Bar,get_staff_bar_size,1); -SCM -Bar::get_staff_bar_size (SCM smob) -{ - Grob*me = unsmob_grob (smob); - Real ss = Staff_symbol_referencer::staff_space (me); - SCM size = me->get_grob_property ("bar-size"); - if (gh_number_p (size)) - return gh_double2scm (gh_scm2double (size)*ss); - else if (Staff_symbol_referencer::staff_symbol_l (me)) - { - /* - If there is no staff-symbol, we get -1 from the next - calculation. That's a nonsense value, which would collapse the - barline so we return 0.0 in the next alternative. - */ - return gh_double2scm ((Staff_symbol_referencer::line_count (me) -1) * ss); - } - else - return gh_int2scm (0); -} diff --git a/lily/break-align-item.cc b/lily/break-align-item.cc deleted file mode 100644 index 48ac52ac32..0000000000 --- a/lily/break-align-item.cc +++ /dev/null @@ -1,254 +0,0 @@ -/* - break-align-item.cc -- implement Break_align_interface - - source file of the GNU LilyPond music typesetter - - (c) 1997--2002 Han-Wen Nienhuys -*/ - - -#include -#include // isinf - -#include "side-position-interface.hh" -#include "axis-group-interface.hh" -#include "warn.hh" -#include "lily-guile.hh" -#include "break-align-item.hh" -#include "dimensions.hh" -#include "paper-def.hh" -#include "paper-column.hh" -#include "group-interface.hh" -#include "align-interface.hh" - -MAKE_SCHEME_CALLBACK (Break_align_interface,before_line_breaking,1); - -SCM -Break_align_interface::before_line_breaking (SCM smob) -{ - Grob* me = unsmob_grob (smob); - do_alignment (me); - return SCM_UNSPECIFIED; -} -MAKE_SCHEME_CALLBACK (Break_align_interface,alignment_callback,2); - -SCM -Break_align_interface::alignment_callback (SCM element_smob, SCM axis) -{ - Grob *me = unsmob_grob (element_smob); - Axis a = (Axis) gh_scm2int (axis); - - assert (a == X_AXIS); - Grob *par = me->get_parent (a); - if (par && !to_boolean (par->get_grob_property ("break-alignment-done")))\ - { - par->set_grob_property ("break-alignment-done", SCM_BOOL_T); - Break_align_interface::do_alignment (par); - } - - return gh_double2scm (0); -} - -MAKE_SCHEME_CALLBACK (Break_align_interface,self_align_callback,2); -SCM -Break_align_interface::self_align_callback (SCM element_smob, SCM axis) -{ - Grob *me = unsmob_grob (element_smob); - Axis a = (Axis) gh_scm2int (axis); - assert (a == X_AXIS); - - Item* item = dynamic_cast (me); - Direction bsd = item->break_status_dir (); - if (bsd == LEFT) - { - me->set_grob_property ("self-alignment-X", gh_int2scm (RIGHT)); - } - - /* - Force break alignment itself to be done first, in the case - */ - - - return Side_position_interface::aligned_on_self (element_smob, axis); -} - -void -Break_align_interface::add_element (Grob*me, Grob *toadd) -{ - Axis_group_interface::add_element (me, toadd); -} - -void -Break_align_interface::do_alignment (Grob *me) -{ - Item * item = dynamic_cast (me); - Item *column = item->column_l (); - - Link_array elems; - Link_array all_elems - = Pointer_group_interface__extract_grobs (me, (Grob*)0, - "elements"); - - for (int i=0; i < all_elems.size (); i++) - { - Interval y = all_elems[i]->extent (all_elems[i], X_AXIS); - if (!y.empty_b ()) - elems.push (dynamic_cast (all_elems[i])); - } - - if (!elems.size ()) - return; - - SCM symbol_list = SCM_EOL; - Array dists; - SCM current_origin = ly_symbol2scm ("none"); - for (int i=0; i <= elems.size (); i++) - { - Grob *next_elt = i < elems.size () - ? elems[i] - : 0 ; - - SCM next_origin; - - if (next_elt) - { - next_origin = next_elt->get_grob_property ("break-align-symbol"); - next_origin = - gh_symbol_p (next_origin)? - next_origin : ly_symbol2scm ("none") -; - } - else - next_origin = ly_symbol2scm ("begin-of-note"); - - SCM alist = me->get_grob_property ("space-alist"); - SCM e = scm_assoc (scm_list_n (current_origin, - next_origin, - SCM_UNDEFINED), alist); - - SCM extra_space; - if (e != SCM_BOOL_F) - { - extra_space = ly_cdr (e); - } - else - { - warning (_f ("unknown spacing pair `%s', `%s'", - ly_symbol2string (current_origin), - ly_symbol2string (next_origin))); - extra_space = scm_list_n (ly_symbol2scm ("minimum-space-pair"), gh_double2scm (0.0), SCM_UNDEFINED); - } - - SCM symbol = ly_car (extra_space); - Real spc = gh_scm2double (ly_cadr (extra_space)); - - dists.push (spc); - symbol_list = gh_cons (symbol, symbol_list); - current_origin = next_origin; - } - - - // skip the first sym. - symbol_list = ly_cdr (scm_reverse (symbol_list)); - for (int i=0; i internal_set_grob_property (ly_car (symbol_list), - scm_cons (gh_double2scm (0), - gh_double2scm (dists[i+1]))); - - symbol_list = ly_cdr (symbol_list); - } - - - // urg - SCM first_pair = elems[0]->get_grob_property ("minimum-space-pair"); - if (gh_pair_p (first_pair)) - first_pair = first_pair; - else - first_pair = gh_cons (gh_double2scm (0.0), gh_double2scm (0.0)); - - scm_set_car_x (first_pair, gh_double2scm (-dists[0])); - elems[0]->set_grob_property ("minimum-space-pair", first_pair); - - Direction bsd = item->break_status_dir (); - if (bsd == LEFT) - { - me->set_grob_property ("self-alignment-X", gh_int2scm (RIGHT)); - } - - /* - Force callbacks for alignment to be called - */ - Align_interface::align_elements_to_extents (me, X_AXIS); - - Real pre_space = elems[0]->relative_coordinate (column, X_AXIS); - - Real xl = elems[0]->extent (elems[0],X_AXIS)[LEFT]; - if (!isinf (xl)) - pre_space += xl; - else - programming_error ("Infinity reached. "); - - Real xr = elems.top ()->extent (elems.top (), X_AXIS)[RIGHT]; - Real spring_len = elems.top ()->relative_coordinate (column, X_AXIS); - if (!isinf (xr)) - spring_len += xr; - else - programming_error ("Infinity reached."); - - Real stretch_distance =0.; - - if (ly_car (symbol_list) == ly_symbol2scm ("extra-space")) - { - spring_len += dists.top (); - stretch_distance = dists.top (); - } - else if (ly_car (symbol_list) == ly_symbol2scm ("minimum-space-pair")) - { - spring_len = spring_len >? dists.top (); - stretch_distance = spring_len; - } - - - /* - Hint the spacing engine how much space to put in. - - The pairs are in the format of an interval (ie. CAR < CDR). - */ - /* - UGH UGH UGH - - This is a side effect, and there is no guarantee that this info is - computed at a "sane" moment. - - (just spent some time tracking a bug that was caused by this info - being written halfway: - - self_alignment_callback (*) - -> child->relative_coordinate (self) - -> break_alignment - -> child->relative_coordinate (column) - - the last call incorporates the value that should've been computed - in (*), but--of course-- is not yet. - - The result is that an offsets of align_elements_to_extents () are - not compensated for, and spring_len is completely off. - - */ - column->set_grob_property ("extra-space", - scm_cons (gh_double2scm (pre_space), - gh_double2scm (spring_len))); - - column->set_grob_property ("stretch-distance", - gh_cons (gh_double2scm (-dists[0]), - gh_double2scm (stretch_distance))); -} - - -void -Break_align_interface::set_interface (Grob*me) -{ - Align_interface::set_interface (me); - Align_interface::set_axis (me,X_AXIS); -} diff --git a/lily/clef-item.cc b/lily/clef-item.cc deleted file mode 100644 index b1cde0874f..0000000000 --- a/lily/clef-item.cc +++ /dev/null @@ -1,75 +0,0 @@ -/* - clef-item.cc -- implement Clef_item - - source file of the GNU LilyPond music typesetter - - (c) 1997--2002 Han-Wen Nienhuys -*/ - - -#include "clef.hh" -#include "string.hh" -#include "molecule.hh" -#include "item.hh" -#include "font-interface.hh" - -/* - FIXME: should use symbol for #'style. -*/ -MAKE_SCHEME_CALLBACK (Clef,before_line_breaking,1); -SCM -Clef::before_line_breaking (SCM smob) -{ - Item * s = unsmob_item (smob); - - SCM glyph = s->get_grob_property ("glyph-name"); - - if (gh_string_p (glyph)) - { - String str = ly_scm2string (glyph); - - if (to_boolean (s->get_grob_property ("non-default")) - && s->break_status_dir () != RIGHT - && !to_boolean (s->get_grob_property ("full-size-change"))) - { - str += "_change"; - s->set_grob_property ("glyph-name", ly_str02scm (str.ch_C ())); - } - } - else - { - s->suicide (); - return SCM_UNSPECIFIED; - } - - return SCM_UNSPECIFIED; -} - -bool -Clef::has_interface (Grob* me) -{ - return me->has_interface (ly_symbol2scm ("clef-interface")); -} - - -void -Clef::set_interface (Grob* me) -{ - me->set_interface (ly_symbol2scm ("clef-interface")); -} - -MAKE_SCHEME_CALLBACK (Clef,brew_molecule,1) -SCM -Clef::brew_molecule (SCM smob) -{ - Grob * sc = unsmob_grob (smob); - SCM glyph = sc->get_grob_property ("glyph-name"); - if (gh_string_p (glyph)) - { - return Font_interface::get_default_font (sc)->find_by_name (String (ly_scm2string (glyph))).smobbed_copy (); - } - else - { - return SCM_EOL; - } -} diff --git a/lily/include/break-align-item.hh b/lily/include/break-align-item.hh deleted file mode 100644 index 5dc37f7841..0000000000 --- a/lily/include/break-align-item.hh +++ /dev/null @@ -1,26 +0,0 @@ -/* - break-align-item.hh -- declare Break_align_item - - source file of the GNU LilyPond music typesetter - - (c) 1997--2002 Han-Wen Nienhuys -*/ - - -#ifndef BREAK_ALIGN_ITEM_HH -#define BREAK_ALIGN_ITEM_HH - -#include "item.hh" - -class Break_align_interface -{ -public: - DECLARE_SCHEME_CALLBACK (before_line_breaking, (SCM )); - static void do_alignment (Grob*); - static void set_interface (Grob*); - static bool has_interface (Grob*); - static void add_element (Grob*me, Grob*add); - DECLARE_SCHEME_CALLBACK (alignment_callback, (SCM element, SCM axis)); - DECLARE_SCHEME_CALLBACK (self_align_callback, (SCM element, SCM axis)); -}; -#endif // BREAK_ALIGN_ITEM_HH diff --git a/lily/key-item.cc b/lily/key-item.cc deleted file mode 100644 index 39848d7378..0000000000 --- a/lily/key-item.cc +++ /dev/null @@ -1,172 +0,0 @@ -/* - key-item.cc -- implement Key_item - - source file of the GNU LilyPond music typesetter - - (c) 1996--2002 Han-Wen Nienhuys - - keyplacement by Mats Bengtsson -*/ - -#include "item.hh" -#include "key-item.hh" -#include "molecule.hh" -#include "paper-def.hh" -#include "font-interface.hh" -#include "staff-symbol-referencer.hh" -#include "lookup.hh" - -/* - FIXME: too much hardcoding here. - */ -const int FLAT_TOP_PITCH=2; /* fes,ges,as and bes typeset in lower octave */ -const int SHARP_TOP_PITCH=4; /* ais and bis typeset in lower octave */ - - -/* - FIXME: key-item should just get a list of (position, acc), and leave - the thinking to other parties. - - - TODO: put this in Scheme - - - lots of values trivially shared (key doesn't change very - often). Compute those once, and use that as cache for the rest. - -*/ -int -alteration_pos (SCM what, int alter, int c0p) -{ - if (gh_pair_p (what)) - return gh_scm2int (ly_car (what)) * 7 + gh_scm2int (ly_cdr (what)) + c0p; - - int p = gh_scm2int (what); - - // Find the c in the range -4 through 2 - int from_bottom_pos = c0p + 4; - from_bottom_pos = from_bottom_pos%7; - from_bottom_pos = (from_bottom_pos + 7)%7; // Precaution to get positive. - int c0 = from_bottom_pos - 4; - - - if ((alter <0 && ((p>FLAT_TOP_PITCH) || (p+c0>4)) && (p+c0>1)) - || - (alter >0 && ((p>SHARP_TOP_PITCH) || (p+c0>5)) && (p+c0>2))) - { - p -= 7; /* Typeset below c_position */ - } - /* Provide for the four cases in which there's a glitch - it's a hack, but probably not worth - the effort of finding a nicer solution. - --dl. */ - if (c0==2 && alter >0 && p==3) - p -= 7; - if (c0==-3 && alter>0 && p==-1) - p += 7; - if (c0==-4 && alter<0 && p==-1) - p += 7; - if (c0==-2 && alter<0 && p==-3) - p += 7; - - return p + c0; -} - -/* - TODO - - space the `natural' signs wider - */ -MAKE_SCHEME_CALLBACK (Key_item,brew_molecule,1); -SCM -Key_item::brew_molecule (SCM smob) -{ - Grob*me =unsmob_grob (smob); - - Real inter = Staff_symbol_referencer::staff_space (me)/2.0; - - SCM scm_style = me->get_grob_property ("style"); - String style; - if (gh_symbol_p (scm_style)) - { - style = ly_scm2string (scm_symbol_to_string (scm_style)); - } - else - { - style = ""; - } - - SCM newas = me->get_grob_property ("new-accidentals"); - Molecule mol; - - SCM c0s = me->get_grob_property ("c0-position"); - int c0p=0; - if (gh_number_p (c0s)) - c0p = gh_scm2int (c0s); - - /* - SCM lists are stacks, so we work from right to left, ending with - the cancellation signature. - */ - - for (SCM s = newas; gh_pair_p (s); s = ly_cdr (s)) - { - SCM what = ly_caar (s); - int alter = gh_scm2int (ly_cdar (s)); - int pos = alteration_pos (what, alter, c0p); - - Molecule m = Font_interface::get_default_font (me)-> - find_by_name (String ("accidentals-") + style + to_str (alter)); - m.translate_axis (pos * inter, Y_AXIS); - mol.add_at_edge (X_AXIS, LEFT, m, 0); - } - - Item *it = dynamic_cast (me) ; - if (it->break_status_dir () != RIGHT) - { - SCM old = me->get_grob_property ("old-accidentals"); - - /* - Add half a space between cancellation and key sig. - - As suggested by [Ross], p.148. - */ - Interval x (0, inter); - Interval y (0,0); - - mol.add_at_edge (X_AXIS, LEFT, Lookup::blank (Box (x,y)),0); - - Molecule natural; - if (gh_pair_p (old)) - natural=Font_interface::get_default_font (me)-> - find_by_name (String ("accidentals-") + style + String ("0")); - - for (; gh_pair_p (old); old = ly_cdr (old)) - { - SCM found = scm_assoc (ly_caar (old), newas); - if (found == SCM_BOOL_F - || ly_cdr (found) != ly_cdar (old)) - { - SCM what = ly_caar (old); - int alter = 0; - int pos = alteration_pos (what, alter, c0p); - - Molecule m = natural; - m.translate_axis (pos* inter, Y_AXIS); - - mol.add_at_edge (X_AXIS, LEFT, m, 0); - } - } - } - - return mol.smobbed_copy (); -} - -bool -Key_item::has_interface (Grob*m) -{ - return m && m->has_interface (ly_symbol2scm ("key-signature-interface")); -} - -void -Key_item::set_interface (Grob*m) -{ - m->set_interface (ly_symbol2scm ("key-signature-interface")); -} diff --git a/lily/third-try.cc b/lily/third-try.cc deleted file mode 100644 index c91e3fd697..0000000000 --- a/lily/third-try.cc +++ /dev/null @@ -1,593 +0,0 @@ -/* - spacing-spanner.cc -- implement Spacing_spanner - - source file of the GNU LilyPond music typesetter - - (c) 1999--2002 Han-Wen Nienhuys - - */ -#include "line-of-score.hh" -#include "paper-score.hh" -#include "paper-column.hh" -#include "item.hh" -#include "moment.hh" -#include "note-spacing.hh" -#include "misc.hh" -#include "warn.hh" - -/* - paper-column: - - right-neighbors = List of spacing-wish grobs that are close to the - current column. - - - left-neighbors = idem - - (TODO: property-doc these!) - - Don't be confused by right-items: each spacing wish can also contain - a number of items, with which a spacing constraint may be kept. It's - a little baroque, but it might come in handy later on? - - */ - -class Third_spacing_spanner -{ -public: - static Real default_bar_spacing (Grob*,Grob*,Grob*,Moment) ; - static Real note_spacing (Grob*,Grob*,Grob*,Moment) ; - static Real get_duration_space (Grob*,Moment dur, Moment shortest) ; - - static void breakable_column_spacing (Item* l, Item *r); - static void find_loose_columns () {} - static void prune_loose_colunms (Link_array *cols); - static void find_loose_columns (Link_array cols); - static void set_explicit_neighbor_columns (Link_array cols); - static void set_implicit_neighbor_columns (Link_array cols); - static void do_measure (Grob*me,Link_array *cols); - DECLARE_SCHEME_CALLBACK (set_springs, (SCM )); -}; - - - -/* - Return whether COL is fixed to its neighbors by some kind of spacing - constraint. -*/ -static bool -loose_column (Grob *l, Grob *c, Grob *r) -{ - SCM rns = c->get_grob_property ("right-neighbors"); - SCM lns = c->get_grob_property ("left-neighbors"); - - /* - If this column doesn't have a proper neighbor, we should really - make it loose, but spacing it correctly is more than we can - currently can handle. - - (this happens in the following situation: - - | - | clef G - * - - | | || - | | || - O O || - - - the column containing the clef is really loose, and should be - attached right to the first column, but that is a lot of work for - such a borderline case. - - ) - - */ - if (!gh_pair_p (lns) || !gh_pair_p (rns)) - return false; - - Item * l_neighbor = dynamic_cast (unsmob_grob (gh_car (lns))); - Item * r_neighbor = dynamic_cast (unsmob_grob (gh_car (rns))); - - if (!l_neighbor || !r_neighbor) - return false; - - l_neighbor = l_neighbor->column_l(); - r_neighbor = dynamic_cast (Note_spacing::right_column (r_neighbor)); - - if (l == l_neighbor && r == r_neighbor) - return false; - - if (!l_neighbor || !r_neighbor) - return false; - - /* - Only declare loose if the bounds make a little sense. This means - some cases (two isolated, consecutive clef changes) won't be - nicely folded, but hey, then don't do that. - */ - if( (Paper_column::musical_b (l_neighbor) || Item::breakable_b (l_neighbor)) - && (Paper_column::musical_b (r_neighbor) || Item::breakable_b (r_neighbor))) - { - return true; - } - - - /* - If in doubt: we're not loose; the spacing engine should space for - it, risking suboptimal spacing. - - (Otherwise, we might risk core dumps, and other weird stuff.) - - - */ - return false; -} - -/* - Remove columns that are not tightly fitting from COLS. In the - removed columns, set 'between-cols to the columns where it is in - between. -*/ -void -Third_spacing_spanner::prune_loose_colunms (Link_array *cols) -{ - Link_array newcols; - - for (int i=0; i < cols->size (); i++) - { - if (Item::breakable_b (cols->elem(i)) || Paper_column::musical_b (cols->elem (i))) - { - newcols.push (cols->elem(i)); - continue; - } - - Grob *c = cols->elem(i); - if (loose_column (cols->elem (i-1), c, cols->elem (i+1))) - { - SCM lns = c->get_grob_property ("left-neighbors"); - lns = gh_pair_p (lns) ? gh_car (lns) : SCM_BOOL_F; - - SCM rns = c->get_grob_property ("right-neighbors"); - rns = gh_pair_p (rns) ? gh_car (rns) : SCM_BOOL_F; - - /* - Either object can be non existent, if the score ends - prematurely. - */ - rns = gh_car (unsmob_grob (rns)->get_grob_property ("right-items")); - c->set_grob_property ("between-cols", gh_cons (lns, - rns)); - - /* - Set distance constraints for loose columns - */ - Drul_array next_door; - next_door[LEFT] =cols->elem (i - 1); - next_door[RIGHT] =cols->elem (i + 1); - Direction d = LEFT; - Drul_array dists(0,0); - - do - { - dists[d] = 0.0; - Grob *lc = d == LEFT ? lc : c; - Grob *rc = d == LEFT ? c : rc; - - for (SCM s = lc->get_grob_property ("spacing-wishes"); - gh_pair_p (s); s = gh_cdr (s)) - { - Grob *sp = unsmob_grob (gh_car (s)); - if (Note_spacing::left_column (sp) != lc - || Note_spacing::right_column (sp) != rc) - continue; - - dists[d] = dists[d] >? Note_spacing::get_spacing (sp); - } - } - while (flip (&d) != LEFT); - - Rod r; - r.distance_f_ = dists[LEFT] + dists[RIGHT]; - r.item_l_drul_[LEFT] = dynamic_cast (cols->elem(i-1)); - r.item_l_drul_[RIGHT] = dynamic_cast (cols->elem (i+1)); - - r.add_to_cols (); - } - else - { - newcols.push (c); - } - } - - *cols = newcols; -} - -/* - Set neighboring columns determined by the spacing-wishes grob property. -*/ -void -Third_spacing_spanner::set_explicit_neighbor_columns (Link_array cols) -{ - for (int i=0; i < cols.size(); i++) - { - SCM right_neighbors = SCM_EOL; - int min_rank = 100000; // inf. - - - SCM wishes= cols[i]->get_grob_property ("spacing-wishes"); - for (SCM s =wishes; gh_pair_p (s); s = gh_cdr (s)) - { - Item * wish = dynamic_cast (unsmob_grob (gh_car (s))); - - Item * lc = wish->column_l (); - Grob * right = Note_spacing::right_column (wish); - - if (!right) - continue; - - Item * rc = dynamic_cast (right); - - int right_rank = Paper_column::rank_i (rc); - int left_rank = Paper_column::rank_i (lc); - - /* - update the left column. - */ - if (right_rank <= min_rank) - { - if (right_rank < min_rank) - right_neighbors =SCM_EOL; - - min_rank = right_rank; - right_neighbors = gh_cons (wish->self_scm (), right_neighbors); - } - - /* - update the right column of the wish. - */ - int maxrank = 0; - SCM left_neighs = rc->get_grob_property ("left-neighbors"); - if (gh_pair_p (left_neighs) - && unsmob_grob (gh_car (left_neighs))) - { - Item * it = dynamic_cast (unsmob_grob (gh_car (left_neighs))); - maxrank = Paper_column::rank_i (it->column_l()); - } - - if (left_rank >= maxrank) - { - if (left_rank > maxrank) - left_neighs = SCM_EOL; - - left_neighs = gh_cons (wish->self_scm (), left_neighs); - rc->set_grob_property ("left-neighbors", right_neighbors); - } - } - - if (gh_pair_p (right_neighbors)) - { - cols[i]->set_grob_property ("right-neighbors", right_neighbors); - } - } -} - -/* - Set neighboring columns that have no left/right-neighbor set - yet. Only do breakable non-musical columns, and musical columns. -*/ -void -Third_spacing_spanner::set_implicit_neighbor_columns (Link_array cols) -{ - for (int i = 0; i < cols.size (); i++) - { - Item * it = dynamic_cast(cols[i]); - if (!Item::breakable_b (it) && !Paper_column::musical_b (it)) - continue; - - // it->breakable || it->musical - - /* - sloppy with typnig left/right-neighbors should take list, but paper-column found instead. - */ - SCM ln = cols[i] ->get_grob_property ("left-neighbors"); - if (!gh_pair_p (ln) && i ) - { - cols[i]->set_grob_property ("left-neighbors", gh_cons (cols[i-1]->self_scm(), SCM_EOL)); - } - - SCM rn = cols[i] ->get_grob_property ("right-neighbors"); - if (!gh_pair_p (rn) && i < cols.size () - 1) - { - cols[i]->set_grob_property ("right-neighbors", gh_cons (cols[i + 1]->self_scm(), SCM_EOL)); - } - } -} - - -MAKE_SCHEME_CALLBACK (Third_spacing_spanner, set_springs,1); -SCM -Third_spacing_spanner::set_springs (SCM smob) -{ - Grob *me = unsmob_grob (smob); - - Link_array all (me->pscore_l_->line_l_->column_l_arr ()) ; - - set_explicit_neighbor_columns (all); - prune_loose_colunms (&all); - set_implicit_neighbor_columns (all); - - int j = 0; - for (int i = 1; i < all.size (); i++) - { - Grob *sc = all[i]; - if (Item::breakable_b (sc)) - { - Link_array measure (all.slice (j, i+1)); - do_measure (me, &measure); - j = i; - } - } - - return SCM_UNSPECIFIED; -} - - -void -Third_spacing_spanner::do_measure (Grob*me, Link_array *cols) -{ - Moment shortest_in_measure; - - /* - space as if this duration is present. - */ - Moment base_shortest_duration = *unsmob_moment (me->get_grob_property ("maximum-duration-for-spacing")); - shortest_in_measure.set_infinite (1); - - for (int i =0 ; i < cols->size (); i++) - { - if (Paper_column::musical_b (cols->elem (i))) - { - Moment *when = unsmob_moment (cols->elem (i)->get_grob_property ("when")); - - /* - ignore grace notes for shortest notes. - */ - if (when && when->grace_part_) - continue; - - SCM st = cols->elem (i)->get_grob_property ("shortest-starter-duration"); - Moment this_shortest = *unsmob_moment (st); - shortest_in_measure = shortest_in_measure springs; - - for (int i= 0; i < cols->size () - 1; i++) - { - Item * l = dynamic_cast (cols->elem (i)); - Item * r = dynamic_cast (cols->elem (i+1)); - - Paper_column * lc = dynamic_cast (l); - Paper_column * rc = dynamic_cast (r); - - if (!Paper_column::musical_b (l)) - { - breakable_column_spacing (l, r); - - /* - - The case that the right part is broken as well is rather - rare, but it is possible, eg. with a single empty measure, - or if one staff finishes a tad earlier than the rest. - - */ - Item *lb = l->find_prebroken_piece (RIGHT); - Item *rb = r->find_prebroken_piece (LEFT); - - if (lb) - breakable_column_spacing (lb,r); - - if (rb) - breakable_column_spacing (l, rb); - if (lb && rb) - breakable_column_spacing (lb, rb); - - continue ; - } - - Real note_space = note_spacing (me,lc, rc, shortest_in_measure get_grob_property ("arithmetic-multiplier")); - - SCM seq = lc->get_grob_property ("right-neighbors"); - - /* - hinterfleisch = hind-meat = amount of space following a note. - - - We adjust the space following a note only if the next note - happens after the current note (this is set in the grob - property SPACING-SEQUENCE. */ - - Real stretch_distance = note_space; - - hinterfleisch = -1.0; - Real max_factor = 0.0; - for (SCM s = seq; gh_pair_p (s); s = ly_cdr (s)) - { - Grob * wish = unsmob_grob (gh_car (s)); - - if (Note_spacing::left_column (wish) != lc - || Note_spacing::right_column (wish) != rc) - continue; - - /* - This is probably a waste of time in the case of polyphonic - music. */ - if (Note_spacing::has_interface (wish)) - { - hinterfleisch = hinterfleisch >? - ( - headwid + - - (note_space + Note_spacing::get_spacing (wish)) - *gh_scm2double (wish->get_grob_property ("space-factor")) - - + Note_spacing::stem_dir_correction (wish)); - } - } - - if (hinterfleisch < 0) - { - // maybe should issue a programming error. - hinterfleisch = note_space; - } - else - stretch_distance -= headwid; // why? - - if (max_factor == 0.0) - max_factor = 1.0; - - Spring s; - s.distance_f_ = max_factor * hinterfleisch; - s.strength_f_ = 1 / stretch_distance; - - s.item_l_drul_[LEFT] = l; - s.item_l_drul_[RIGHT] = r; - - s.add_to_cols(); - if (r->find_prebroken_piece (LEFT)) - { - s.item_l_drul_[RIGHT] = r->find_prebroken_piece(LEFT); - s.add_to_cols(); - } - } - -} - - -/* - Read hints from L (todo: R) and generate springs. - */ -void -Third_spacing_spanner::breakable_column_spacing (Item* l, Item *r) -{ - Spring s; - - Real break_dist = 0.0; - SCM espace = l->get_grob_property ("extra-space"); - if (gh_pair_p (espace)) - break_dist += gh_scm2double (ly_cdr (espace)); - - if (!break_dist) - break_dist = 1.0; - - Real break_stretch = 0.0; - - // todo: naming of "distance" - espace = l->get_grob_property ("stretch-distance"); - if (gh_pair_p (espace)) - break_stretch += gh_scm2double (ly_cdr (espace)); - - if (!break_stretch) - break_stretch = 1.0; - - s.distance_f_ = break_dist; - s.strength_f_ = 1/break_stretch; - s.item_l_drul_[LEFT] = l; - s.item_l_drul_[RIGHT] = r; - - s.add_to_cols (); -} - - -/** - Get the measure wide ant for arithmetic spacing. - - @see - John S. Gourlay. ``Spacing a Line of Music,'' Technical Report - OSU-CISRC-10/87-TR35, Department of Computer and Information Science, - The Ohio State University, 1987. - - */ -Real -Third_spacing_spanner::get_duration_space (Grob*me, Moment d, Moment shortest) -{ - Real log = log_2 (shortest.main_part_); - Real k = gh_scm2double (me->get_grob_property ("arithmetic-basicspace")) - - log; - - Rational compdur = d.main_part_ + d.grace_part_ /Rational (3); - - return (log_2 (compdur) + k) * gh_scm2double (me->get_grob_property ("arithmetic-multiplier")); -} - - -Real -Third_spacing_spanner::note_spacing (Grob*me, Grob *lc, Grob *rc, - Moment shortest) -{ - Moment shortest_playing_len = 0; - SCM s = lc->get_grob_property ("shortest-playing-duration"); - - - if (unsmob_moment (s)) - shortest_playing_len = *unsmob_moment (s); - - if (! shortest_playing_len.to_bool ()) - { - programming_error ("can't find a ruling note at " + Paper_column::when_mom (lc).str ()); - shortest_playing_len = 1; - } - - if (! shortest.to_bool ()) - { - programming_error ("no minimum in measure at " + Paper_column::when_mom (lc).str ()); - shortest = 1; - } - Moment delta_t = Paper_column::when_mom (rc) - Paper_column::when_mom (lc); - Real dist = 0.0; - - if (delta_t.main_part_) - { - dist = get_duration_space (me, shortest_playing_len, shortest); - dist *= (double) (delta_t.main_part_ / shortest_playing_len.main_part_); - } - else if (delta_t.grace_part_) - { - dist = get_duration_space (me, shortest, shortest); - - Real grace_fact = 1.0; - SCM gf = me->get_grob_property ("grace-space-factor"); - if (gh_number_p (gf)) - grace_fact = gh_scm2double (gf); - - dist *= grace_fact; - } - -#if 0 - /* - TODO: figure out how to space grace notes. - */ - - dist *= - + grace_fact * (double) (delta_t.grace_part_ / shortest_playing_len.main_part_); - - - Moment *lm = unsmob_moment (lc->get_grob_property ("when")); - Moment *rm = unsmob_moment (rc->get_grob_property ("when")); - - if (lm && rm) - { - if (lm->grace_part_ && rm->grace_part_) - dist *= 0.5; - else if (!rm->grace_part_ && lm->grace_part_) - dist *= 0.7; - } -#endif - - return dist; -} -